]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'for-linus' of git://git.o-hand.com/linux-rpurdie-leds
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 23 Oct 2008 23:07:32 +0000 (16:07 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 23 Oct 2008 23:07:32 +0000 (16:07 -0700)
* 'for-linus' of git://git.o-hand.com/linux-rpurdie-leds:
  leds/acpi: Fix merge fallout from acpi_driver_data change
  leds: Simplify logic in leds-ams-delta
  leds: Fix trigger registration race
  leds: Fix leds-class.c comment
  leds: Add driver for HP harddisk protection LEDs
  leds: leds-pca955x - Mark pca955x_led_set() static
  leds: Remove uneeded leds-cm-x270 driver
  leds: Remove uneeded strlen calls
  leds: Add leds-wrap default-trigger
  leds: Make default trigger fields const
  leds: Add backlight LED trigger
  leds: da903x: Add support for LEDs found on DA9030/DA9034

2280 files changed:
CREDITS
Documentation/ABI/testing/sysfs-bus-umc [new file with mode: 0644]
Documentation/ABI/testing/sysfs-bus-usb
Documentation/ABI/testing/sysfs-class-usb_host [new file with mode: 0644]
Documentation/ABI/testing/sysfs-class-uwb_rc [new file with mode: 0644]
Documentation/ABI/testing/sysfs-wusb_cbaf [new file with mode: 0644]
Documentation/DocBook/kernel-hacking.tmpl
Documentation/MSI-HOWTO.txt
Documentation/PCI/pci.txt
Documentation/PCI/pcieaer-howto.txt
Documentation/feature-removal-schedule.txt
Documentation/i2c/busses/i2c-i801
Documentation/i2c/porting-clients [deleted file]
Documentation/i2c/writing-clients
Documentation/ia64/xen.txt [new file with mode: 0644]
Documentation/kdump/kdump.txt
Documentation/kernel-parameters.txt
Documentation/laptops/acer-wmi.txt
Documentation/markers.txt
Documentation/powerpc/booting-without-of.txt
Documentation/powerpc/dts-bindings/fsl/board.txt
Documentation/sysrq.txt
Documentation/tracepoints.txt [new file with mode: 0644]
Documentation/tracers/mmiotrace.txt
Documentation/usb/WUSB-Design-overview.txt [new file with mode: 0644]
Documentation/usb/wusb-cbaf [new file with mode: 0644]
MAINTAINERS
Makefile
arch/alpha/kernel/osf_sys.c
arch/alpha/kernel/sys_sable.c
arch/alpha/oprofile/common.c
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/common/Kconfig
arch/arm/common/sa1111.c
arch/arm/configs/corgi_defconfig
arch/arm/configs/msm_defconfig
arch/arm/configs/spitz_defconfig
arch/arm/configs/trizeps4_defconfig
arch/arm/include/asm/div64.h
arch/arm/mach-at91/gpio.c
arch/arm/mach-clps711x/include/mach/memory.h
arch/arm/mach-iop13xx/include/mach/time.h
arch/arm/mach-ixp2000/ixdp2x00.c
arch/arm/mach-ixp4xx/Kconfig
arch/arm/mach-kirkwood/Makefile
arch/arm/mach-kirkwood/common.c
arch/arm/mach-kirkwood/common.h
arch/arm/mach-kirkwood/rd88f6281-setup.c
arch/arm/mach-msm/Kconfig
arch/arm/mach-msm/Makefile
arch/arm/mach-msm/board-halibut.c
arch/arm/mach-msm/clock-7x01a.c [new file with mode: 0644]
arch/arm/mach-msm/clock.c [new file with mode: 0644]
arch/arm/mach-msm/clock.h [new file with mode: 0644]
arch/arm/mach-msm/common.c [deleted file]
arch/arm/mach-msm/devices.c [new file with mode: 0644]
arch/arm/mach-msm/devices.h [new file with mode: 0644]
arch/arm/mach-msm/dma.c
arch/arm/mach-msm/include/mach/board.h
arch/arm/mach-msm/include/mach/debug-macro.S
arch/arm/mach-msm/include/mach/dma.h
arch/arm/mach-msm/include/mach/msm_iomap.h
arch/arm/mach-msm/include/mach/vreg.h [new file with mode: 0644]
arch/arm/mach-msm/io.c
arch/arm/mach-msm/irq.c
arch/arm/mach-msm/proc_comm.c [new file with mode: 0644]
arch/arm/mach-msm/proc_comm.h [new file with mode: 0644]
arch/arm/mach-msm/timer.c
arch/arm/mach-msm/vreg.c [new file with mode: 0644]
arch/arm/mach-mv78xx0/db78x00-bp-setup.c
arch/arm/mach-omap2/irq.c
arch/arm/mach-orion5x/common.c
arch/arm/mach-orion5x/common.h
arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
arch/arm/mach-orion5x/wrt350n-v2-setup.c
arch/arm/mach-pxa/Kconfig
arch/arm/mach-pxa/Makefile
arch/arm/mach-pxa/corgi_lcd.c [new file with mode: 0644]
arch/arm/mach-pxa/corgi_ssp.c [new file with mode: 0644]
arch/arm/mach-pxa/include/mach/corgi.h
arch/arm/mach-pxa/include/mach/irqs.h
arch/arm/mach-pxa/include/mach/spitz.h
arch/arm/mach-pxa/include/mach/tosa.h
arch/arm/mach-pxa/include/mach/zylonite.h
arch/arm/mach-pxa/pwm.c
arch/arm/mach-pxa/sharpsl_pm.c
arch/arm/mach-pxa/tosa.c
arch/arm/mach-pxa/trizeps4.c
arch/arm/mach-s3c2443/clock.c
arch/arm/mach-sa1100/include/mach/ide.h [deleted file]
arch/arm/mm/Kconfig
arch/arm/mm/cache-v4.S
arch/arm/mm/proc-v7.S
arch/arm/plat-s3c24xx/pwm-clock.c
arch/arm/plat-s3c24xx/pwm.c
arch/avr32/Kconfig
arch/avr32/Makefile
arch/avr32/boards/atngw100/Kconfig [new file with mode: 0644]
arch/avr32/boards/atngw100/Makefile
arch/avr32/boards/atngw100/evklcd10x.c [new file with mode: 0644]
arch/avr32/boards/atngw100/setup.c
arch/avr32/boards/atstk1000/atstk1002.c
arch/avr32/boards/atstk1000/atstk1003.c
arch/avr32/boards/atstk1000/atstk1004.c
arch/avr32/boards/favr-32/Kconfig [new file with mode: 0644]
arch/avr32/boards/favr-32/Makefile [new file with mode: 0644]
arch/avr32/boards/favr-32/flash.c [new file with mode: 0644]
arch/avr32/boards/favr-32/setup.c [new file with mode: 0644]
arch/avr32/boards/mimc200/Makefile [new file with mode: 0644]
arch/avr32/boards/mimc200/flash.c [new file with mode: 0644]
arch/avr32/boards/mimc200/fram.c [new file with mode: 0644]
arch/avr32/boards/mimc200/setup.c [new file with mode: 0644]
arch/avr32/configs/atngw100_evklcd100_defconfig [new file with mode: 0644]
arch/avr32/configs/atngw100_evklcd101_defconfig [new file with mode: 0644]
arch/avr32/configs/favr-32_defconfig [new file with mode: 0644]
arch/avr32/configs/mimc200_defconfig [new file with mode: 0644]
arch/avr32/mach-at32ap/at32ap700x.c
arch/avr32/mach-at32ap/cpufreq.c
arch/avr32/mach-at32ap/extint.c
arch/avr32/mach-at32ap/include/mach/board.h
arch/cris/Kconfig
arch/h8300/Kconfig
arch/ia64/Kconfig
arch/ia64/Makefile
arch/ia64/configs/generic_defconfig
arch/ia64/configs/tiger_defconfig
arch/ia64/dig/Makefile
arch/ia64/dig/dig_vtd_iommu.c [new file with mode: 0644]
arch/ia64/dig/machvec_vtd.c [new file with mode: 0644]
arch/ia64/ia32/audit.c
arch/ia64/ia32/ia32_entry.S
arch/ia64/ia32/sys_ia32.c
arch/ia64/include/asm/break.h
arch/ia64/include/asm/cacheflush.h
arch/ia64/include/asm/device.h
arch/ia64/include/asm/dma-mapping.h
arch/ia64/include/asm/iommu.h [new file with mode: 0644]
arch/ia64/include/asm/kregs.h
arch/ia64/include/asm/machvec.h
arch/ia64/include/asm/machvec_dig_vtd.h [new file with mode: 0644]
arch/ia64/include/asm/machvec_init.h
arch/ia64/include/asm/machvec_xen.h [new file with mode: 0644]
arch/ia64/include/asm/meminit.h
arch/ia64/include/asm/native/inst.h
arch/ia64/include/asm/native/pvchk_inst.h [new file with mode: 0644]
arch/ia64/include/asm/paravirt.h
arch/ia64/include/asm/pci.h
arch/ia64/include/asm/ptrace.h
arch/ia64/include/asm/pvclock-abi.h [new file with mode: 0644]
arch/ia64/include/asm/swiotlb.h [new file with mode: 0644]
arch/ia64/include/asm/sync_bitops.h [new file with mode: 0644]
arch/ia64/include/asm/syscall.h [new file with mode: 0644]
arch/ia64/include/asm/thread_info.h
arch/ia64/include/asm/timex.h
arch/ia64/include/asm/unistd.h
arch/ia64/include/asm/xen/events.h [new file with mode: 0644]
arch/ia64/include/asm/xen/grant_table.h [new file with mode: 0644]
arch/ia64/include/asm/xen/hypercall.h [new file with mode: 0644]
arch/ia64/include/asm/xen/hypervisor.h [new file with mode: 0644]
arch/ia64/include/asm/xen/inst.h [new file with mode: 0644]
arch/ia64/include/asm/xen/interface.h [new file with mode: 0644]
arch/ia64/include/asm/xen/irq.h [new file with mode: 0644]
arch/ia64/include/asm/xen/minstate.h [new file with mode: 0644]
arch/ia64/include/asm/xen/page.h [new file with mode: 0644]
arch/ia64/include/asm/xen/privop.h [new file with mode: 0644]
arch/ia64/include/asm/xen/xcom_hcall.h [new file with mode: 0644]
arch/ia64/include/asm/xen/xencomm.h [new file with mode: 0644]
arch/ia64/kernel/Makefile
arch/ia64/kernel/acpi.c
arch/ia64/kernel/asm-offsets.c
arch/ia64/kernel/entry.S
arch/ia64/kernel/ivt.S
arch/ia64/kernel/msi_ia64.c
arch/ia64/kernel/nr-irqs.c
arch/ia64/kernel/paravirt.c
arch/ia64/kernel/paravirt_inst.h
arch/ia64/kernel/pci-dma.c [new file with mode: 0644]
arch/ia64/kernel/pci-swiotlb.c [new file with mode: 0644]
arch/ia64/kernel/perfmon.c
arch/ia64/kernel/process.c
arch/ia64/kernel/ptrace.c
arch/ia64/kernel/setup.c
arch/ia64/kernel/signal.c
arch/ia64/kvm/kvm-ia64.c
arch/ia64/lib/flush.S
arch/ia64/mm/tlb.c
arch/ia64/oprofile/init.c
arch/ia64/oprofile/perfmon.c
arch/ia64/pci/pci.c
arch/ia64/scripts/pvcheck.sed [new file with mode: 0644]
arch/ia64/sn/kernel/io_acpi_init.c
arch/ia64/xen/Kconfig [new file with mode: 0644]
arch/ia64/xen/Makefile [new file with mode: 0644]
arch/ia64/xen/grant-table.c [new file with mode: 0644]
arch/ia64/xen/hypercall.S [new file with mode: 0644]
arch/ia64/xen/hypervisor.c [new file with mode: 0644]
arch/ia64/xen/irq_xen.c [new file with mode: 0644]
arch/ia64/xen/irq_xen.h [new file with mode: 0644]
arch/ia64/xen/machvec.c [new file with mode: 0644]
arch/ia64/xen/suspend.c [new file with mode: 0644]
arch/ia64/xen/time.c [new file with mode: 0644]
arch/ia64/xen/time.h [new file with mode: 0644]
arch/ia64/xen/xcom_hcall.c [new file with mode: 0644]
arch/ia64/xen/xen_pv_ops.c [new file with mode: 0644]
arch/ia64/xen/xencomm.c [new file with mode: 0644]
arch/ia64/xen/xenivt.S [new file with mode: 0644]
arch/ia64/xen/xensetup.S [new file with mode: 0644]
arch/m32r/kernel/smpboot.c
arch/m32r/oprofile/init.c
arch/m68k/amiga/config.c
arch/m68k/atari/config.c
arch/m68k/atari/stram.c
arch/m68k/bvme6000/config.c
arch/m68k/kernel/setup.c
arch/m68k/mvme147/config.c
arch/m68k/mvme16x/config.c
arch/m68k/q40/config.c
arch/m68k/sun3/config.c
arch/m68k/sun3x/config.c
arch/mips/oprofile/common.c
arch/mips/oprofile/op_impl.h
arch/mips/oprofile/op_model_rm9000.c
arch/parisc/Kconfig
arch/parisc/hpux/fs.c
arch/parisc/include/asm/Kbuild [moved from include/asm-parisc/Kbuild with 100% similarity]
arch/parisc/include/asm/agp.h [moved from include/asm-parisc/agp.h with 100% similarity]
arch/parisc/include/asm/asmregs.h [moved from include/asm-parisc/asmregs.h with 100% similarity]
arch/parisc/include/asm/assembly.h [moved from include/asm-parisc/assembly.h with 100% similarity]
arch/parisc/include/asm/atomic.h [moved from include/asm-parisc/atomic.h with 100% similarity]
arch/parisc/include/asm/auxvec.h [moved from include/asm-parisc/auxvec.h with 100% similarity]
arch/parisc/include/asm/bitops.h [moved from include/asm-parisc/bitops.h with 100% similarity]
arch/parisc/include/asm/bug.h [moved from include/asm-parisc/bug.h with 100% similarity]
arch/parisc/include/asm/bugs.h [moved from include/asm-parisc/bugs.h with 100% similarity]
arch/parisc/include/asm/byteorder.h [moved from include/asm-parisc/byteorder.h with 100% similarity]
arch/parisc/include/asm/cache.h [moved from include/asm-parisc/cache.h with 100% similarity]
arch/parisc/include/asm/cacheflush.h [moved from include/asm-parisc/cacheflush.h with 100% similarity]
arch/parisc/include/asm/checksum.h [moved from include/asm-parisc/checksum.h with 100% similarity]
arch/parisc/include/asm/compat.h [moved from include/asm-parisc/compat.h with 100% similarity]
arch/parisc/include/asm/compat_rt_sigframe.h [moved from include/asm-parisc/compat_rt_sigframe.h with 100% similarity]
arch/parisc/include/asm/compat_signal.h [moved from include/asm-parisc/compat_signal.h with 100% similarity]
arch/parisc/include/asm/compat_ucontext.h [moved from include/asm-parisc/compat_ucontext.h with 100% similarity]
arch/parisc/include/asm/cputime.h [moved from include/asm-parisc/cputime.h with 100% similarity]
arch/parisc/include/asm/current.h [moved from include/asm-parisc/current.h with 100% similarity]
arch/parisc/include/asm/delay.h [moved from include/asm-parisc/delay.h with 100% similarity]
arch/parisc/include/asm/device.h [moved from include/asm-parisc/device.h with 100% similarity]
arch/parisc/include/asm/div64.h [moved from include/asm-parisc/div64.h with 100% similarity]
arch/parisc/include/asm/dma-mapping.h [moved from include/asm-parisc/dma-mapping.h with 100% similarity]
arch/parisc/include/asm/dma.h [moved from include/asm-parisc/dma.h with 100% similarity]
arch/parisc/include/asm/eisa_bus.h [moved from include/asm-parisc/eisa_bus.h with 100% similarity]
arch/parisc/include/asm/eisa_eeprom.h [moved from include/asm-parisc/eisa_eeprom.h with 100% similarity]
arch/parisc/include/asm/elf.h [moved from include/asm-parisc/elf.h with 100% similarity]
arch/parisc/include/asm/emergency-restart.h [moved from include/asm-parisc/emergency-restart.h with 100% similarity]
arch/parisc/include/asm/errno.h [moved from include/asm-parisc/errno.h with 100% similarity]
arch/parisc/include/asm/fb.h [moved from include/asm-parisc/fb.h with 100% similarity]
arch/parisc/include/asm/fcntl.h [moved from include/asm-parisc/fcntl.h with 100% similarity]
arch/parisc/include/asm/fixmap.h [moved from include/asm-parisc/fixmap.h with 100% similarity]
arch/parisc/include/asm/floppy.h [moved from include/asm-parisc/floppy.h with 100% similarity]
arch/parisc/include/asm/futex.h [moved from include/asm-parisc/futex.h with 100% similarity]
arch/parisc/include/asm/grfioctl.h [moved from include/asm-parisc/grfioctl.h with 100% similarity]
arch/parisc/include/asm/hardirq.h [moved from include/asm-parisc/hardirq.h with 100% similarity]
arch/parisc/include/asm/hardware.h [moved from include/asm-parisc/hardware.h with 100% similarity]
arch/parisc/include/asm/hw_irq.h [moved from include/asm-parisc/hw_irq.h with 100% similarity]
arch/parisc/include/asm/ide.h [moved from include/asm-parisc/ide.h with 77% similarity]
arch/parisc/include/asm/io.h [moved from include/asm-parisc/io.h with 100% similarity]
arch/parisc/include/asm/ioctl.h [moved from include/asm-parisc/ioctl.h with 100% similarity]
arch/parisc/include/asm/ioctls.h [moved from include/asm-parisc/ioctls.h with 100% similarity]
arch/parisc/include/asm/ipcbuf.h [moved from include/asm-parisc/ipcbuf.h with 100% similarity]
arch/parisc/include/asm/irq.h [moved from include/asm-parisc/irq.h with 100% similarity]
arch/parisc/include/asm/irq_regs.h [moved from include/asm-parisc/irq_regs.h with 100% similarity]
arch/parisc/include/asm/kdebug.h [moved from include/asm-parisc/kdebug.h with 100% similarity]
arch/parisc/include/asm/kmap_types.h [moved from include/asm-parisc/kmap_types.h with 100% similarity]
arch/parisc/include/asm/led.h [moved from include/asm-parisc/led.h with 100% similarity]
arch/parisc/include/asm/linkage.h [moved from include/asm-parisc/linkage.h with 100% similarity]
arch/parisc/include/asm/local.h [moved from include/asm-parisc/local.h with 100% similarity]
arch/parisc/include/asm/machdep.h [moved from include/asm-parisc/machdep.h with 100% similarity]
arch/parisc/include/asm/mc146818rtc.h [moved from include/asm-parisc/mc146818rtc.h with 100% similarity]
arch/parisc/include/asm/mckinley.h [moved from include/asm-parisc/mckinley.h with 100% similarity]
arch/parisc/include/asm/mman.h [moved from include/asm-parisc/mman.h with 100% similarity]
arch/parisc/include/asm/mmu.h [moved from include/asm-parisc/mmu.h with 100% similarity]
arch/parisc/include/asm/mmu_context.h [moved from include/asm-parisc/mmu_context.h with 100% similarity]
arch/parisc/include/asm/mmzone.h [moved from include/asm-parisc/mmzone.h with 100% similarity]
arch/parisc/include/asm/module.h [moved from include/asm-parisc/module.h with 100% similarity]
arch/parisc/include/asm/msgbuf.h [moved from include/asm-parisc/msgbuf.h with 100% similarity]
arch/parisc/include/asm/mutex.h [moved from include/asm-parisc/mutex.h with 100% similarity]
arch/parisc/include/asm/page.h [moved from include/asm-parisc/page.h with 100% similarity]
arch/parisc/include/asm/param.h [moved from include/asm-parisc/param.h with 100% similarity]
arch/parisc/include/asm/parisc-device.h [moved from include/asm-parisc/parisc-device.h with 100% similarity]
arch/parisc/include/asm/parport.h [moved from include/asm-parisc/parport.h with 100% similarity]
arch/parisc/include/asm/pci.h [moved from include/asm-parisc/pci.h with 100% similarity]
arch/parisc/include/asm/pdc.h [moved from include/asm-parisc/pdc.h with 99% similarity]
arch/parisc/include/asm/pdc_chassis.h [moved from include/asm-parisc/pdc_chassis.h with 100% similarity]
arch/parisc/include/asm/pdcpat.h [moved from include/asm-parisc/pdcpat.h with 100% similarity]
arch/parisc/include/asm/percpu.h [moved from include/asm-parisc/percpu.h with 100% similarity]
arch/parisc/include/asm/perf.h [moved from include/asm-parisc/perf.h with 100% similarity]
arch/parisc/include/asm/pgalloc.h [moved from include/asm-parisc/pgalloc.h with 100% similarity]
arch/parisc/include/asm/pgtable.h [moved from include/asm-parisc/pgtable.h with 100% similarity]
arch/parisc/include/asm/poll.h [moved from include/asm-parisc/poll.h with 100% similarity]
arch/parisc/include/asm/posix_types.h [moved from include/asm-parisc/posix_types.h with 100% similarity]
arch/parisc/include/asm/prefetch.h [moved from include/asm-parisc/prefetch.h with 100% similarity]
arch/parisc/include/asm/processor.h [moved from include/asm-parisc/processor.h with 100% similarity]
arch/parisc/include/asm/psw.h [moved from include/asm-parisc/psw.h with 100% similarity]
arch/parisc/include/asm/ptrace.h [moved from include/asm-parisc/ptrace.h with 85% similarity]
arch/parisc/include/asm/real.h [moved from include/asm-parisc/real.h with 100% similarity]
arch/parisc/include/asm/resource.h [moved from include/asm-parisc/resource.h with 100% similarity]
arch/parisc/include/asm/ropes.h [moved from include/asm-parisc/ropes.h with 99% similarity]
arch/parisc/include/asm/rt_sigframe.h [moved from include/asm-parisc/rt_sigframe.h with 100% similarity]
arch/parisc/include/asm/rtc.h [moved from include/asm-parisc/rtc.h with 100% similarity]
arch/parisc/include/asm/runway.h [moved from include/asm-parisc/runway.h with 100% similarity]
arch/parisc/include/asm/scatterlist.h [moved from include/asm-parisc/scatterlist.h with 100% similarity]
arch/parisc/include/asm/sections.h [moved from include/asm-parisc/sections.h with 100% similarity]
arch/parisc/include/asm/segment.h [moved from include/asm-parisc/segment.h with 100% similarity]
arch/parisc/include/asm/sembuf.h [moved from include/asm-parisc/sembuf.h with 100% similarity]
arch/parisc/include/asm/serial.h [moved from include/asm-parisc/serial.h with 100% similarity]
arch/parisc/include/asm/setup.h [moved from include/asm-parisc/setup.h with 100% similarity]
arch/parisc/include/asm/shmbuf.h [moved from include/asm-parisc/shmbuf.h with 100% similarity]
arch/parisc/include/asm/shmparam.h [moved from include/asm-parisc/shmparam.h with 100% similarity]
arch/parisc/include/asm/sigcontext.h [moved from include/asm-parisc/sigcontext.h with 100% similarity]
arch/parisc/include/asm/siginfo.h [moved from include/asm-parisc/siginfo.h with 100% similarity]
arch/parisc/include/asm/signal.h [moved from include/asm-parisc/signal.h with 100% similarity]
arch/parisc/include/asm/smp.h [moved from include/asm-parisc/smp.h with 100% similarity]
arch/parisc/include/asm/socket.h [moved from include/asm-parisc/socket.h with 100% similarity]
arch/parisc/include/asm/sockios.h [moved from include/asm-parisc/sockios.h with 100% similarity]
arch/parisc/include/asm/spinlock.h [moved from include/asm-parisc/spinlock.h with 100% similarity]
arch/parisc/include/asm/spinlock_types.h [moved from include/asm-parisc/spinlock_types.h with 100% similarity]
arch/parisc/include/asm/stat.h [moved from include/asm-parisc/stat.h with 100% similarity]
arch/parisc/include/asm/statfs.h [moved from include/asm-parisc/statfs.h with 100% similarity]
arch/parisc/include/asm/string.h [moved from include/asm-parisc/string.h with 100% similarity]
arch/parisc/include/asm/superio.h [moved from include/asm-parisc/superio.h with 100% similarity]
arch/parisc/include/asm/system.h [moved from include/asm-parisc/system.h with 100% similarity]
arch/parisc/include/asm/termbits.h [moved from include/asm-parisc/termbits.h with 100% similarity]
arch/parisc/include/asm/termios.h [moved from include/asm-parisc/termios.h with 100% similarity]
arch/parisc/include/asm/thread_info.h [moved from include/asm-parisc/thread_info.h with 100% similarity]
arch/parisc/include/asm/timex.h [moved from include/asm-parisc/timex.h with 100% similarity]
arch/parisc/include/asm/tlb.h [moved from include/asm-parisc/tlb.h with 100% similarity]
arch/parisc/include/asm/tlbflush.h [moved from include/asm-parisc/tlbflush.h with 100% similarity]
arch/parisc/include/asm/topology.h [moved from include/asm-parisc/topology.h with 100% similarity]
arch/parisc/include/asm/traps.h [moved from include/asm-parisc/traps.h with 100% similarity]
arch/parisc/include/asm/types.h [moved from include/asm-parisc/types.h with 100% similarity]
arch/parisc/include/asm/uaccess.h [moved from include/asm-parisc/uaccess.h with 100% similarity]
arch/parisc/include/asm/ucontext.h [moved from include/asm-parisc/ucontext.h with 100% similarity]
arch/parisc/include/asm/unaligned.h [moved from include/asm-parisc/unaligned.h with 100% similarity]
arch/parisc/include/asm/unistd.h [moved from include/asm-parisc/unistd.h with 99% similarity]
arch/parisc/include/asm/unwind.h [moved from include/asm-parisc/unwind.h with 99% similarity]
arch/parisc/include/asm/user.h [moved from include/asm-parisc/user.h with 100% similarity]
arch/parisc/include/asm/vga.h [moved from include/asm-parisc/vga.h with 100% similarity]
arch/parisc/include/asm/xor.h [moved from include/asm-parisc/xor.h with 100% similarity]
arch/parisc/kernel/.gitignore [new file with mode: 0644]
arch/parisc/kernel/asm-offsets.c
arch/parisc/kernel/firmware.c
arch/parisc/kernel/head.S
arch/parisc/kernel/ptrace.c
arch/parisc/kernel/real2.S
arch/parisc/kernel/setup.c
arch/parisc/kernel/syscall_table.S
arch/parisc/kernel/time.c
arch/parisc/kernel/unwind.c
arch/parisc/oprofile/init.c
arch/powerpc/Kconfig
arch/powerpc/boot/Makefile
arch/powerpc/boot/addnote.c
arch/powerpc/boot/cuboot-52xx.c
arch/powerpc/boot/cuboot-acadia.c [new file with mode: 0644]
arch/powerpc/boot/dts/acadia.dts [new file with mode: 0644]
arch/powerpc/boot/dts/hcu4.dts [new file with mode: 0644]
arch/powerpc/boot/dts/mpc8315erdb.dts
arch/powerpc/boot/dts/mpc832x_mds.dts
arch/powerpc/boot/dts/mpc8349emitx.dts
arch/powerpc/boot/dts/mpc8349emitxgp.dts
arch/powerpc/boot/dts/mpc834x_mds.dts
arch/powerpc/boot/dts/mpc836x_mds.dts
arch/powerpc/boot/dts/mpc8377_rdb.dts
arch/powerpc/boot/dts/mpc8378_rdb.dts
arch/powerpc/boot/dts/mpc8379_rdb.dts
arch/powerpc/boot/dts/mpc8536ds.dts
arch/powerpc/boot/dts/mpc8568mds.dts
arch/powerpc/boot/dts/mpc8572ds.dts
arch/powerpc/boot/libfdt-wrapper.c
arch/powerpc/boot/main.c
arch/powerpc/boot/ops.h
arch/powerpc/boot/string.S
arch/powerpc/boot/wrapper
arch/powerpc/configs/40x/acadia_defconfig [new file with mode: 0644]
arch/powerpc/configs/40x/hcu4_defconfig [new file with mode: 0644]
arch/powerpc/include/asm/kdump.h
arch/powerpc/include/asm/page.h
arch/powerpc/include/asm/pci-bridge.h
arch/powerpc/include/asm/pci.h
arch/powerpc/include/asm/ptrace.h
arch/powerpc/include/asm/signal.h
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/crash_dump.c
arch/powerpc/kernel/head_64.S
arch/powerpc/kernel/iommu.c
arch/powerpc/kernel/machine_kexec.c
arch/powerpc/kernel/machine_kexec_64.c
arch/powerpc/kernel/misc_64.S
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/prom_init.c
arch/powerpc/kernel/prom_init_check.sh
arch/powerpc/kernel/setup-common.c
arch/powerpc/kernel/signal.h
arch/powerpc/kernel/signal_64.c
arch/powerpc/kernel/udbg_16550.c
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/mm/numa.c
arch/powerpc/oprofile/cell/pr_util.h
arch/powerpc/oprofile/cell/spu_profiler.c
arch/powerpc/oprofile/cell/spu_task_sync.c
arch/powerpc/oprofile/op_model_cell.c
arch/powerpc/platforms/40x/Kconfig
arch/powerpc/platforms/40x/Makefile
arch/powerpc/platforms/40x/hcu4.c [new file with mode: 0644]
arch/powerpc/platforms/40x/ppc40x_simple.c [new file with mode: 0644]
arch/powerpc/platforms/44x/Kconfig
arch/powerpc/platforms/52xx/mpc52xx_common.c
arch/powerpc/platforms/85xx/ksi8560.c
arch/powerpc/platforms/85xx/mpc85xx_ads.c
arch/powerpc/platforms/85xx/mpc85xx_cds.c
arch/powerpc/platforms/85xx/sbc8548.c
arch/powerpc/platforms/85xx/sbc8560.c
arch/powerpc/platforms/85xx/stx_gp3.c
arch/powerpc/platforms/85xx/tqm85xx.c
arch/powerpc/platforms/86xx/gef_sbc610.c
arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
arch/powerpc/platforms/86xx/sbc8641d.c
arch/powerpc/platforms/cell/ras.c
arch/powerpc/platforms/cell/smp.c
arch/powerpc/platforms/cell/spufs/file.c
arch/powerpc/platforms/cell/spufs/run.c
arch/powerpc/platforms/cell/spufs/sched.c
arch/powerpc/platforms/cell/spufs/spufs.h
arch/powerpc/platforms/cell/spufs/sputrace.c
arch/powerpc/platforms/cell/spufs/syscalls.c
arch/powerpc/platforms/embedded6xx/c2k.c
arch/powerpc/platforms/embedded6xx/prpmc2800.c
arch/powerpc/platforms/pseries/hotplug-memory.c
arch/powerpc/platforms/pseries/iommu.c
arch/powerpc/platforms/pseries/smp.c
arch/powerpc/sysdev/Makefile
arch/powerpc/sysdev/ppc4xx_gpio.c [new file with mode: 0644]
arch/sh/boards/board-ap325rxa.c
arch/sh/boards/board-rsk7203.c
arch/sh/boards/mach-highlander/Kconfig
arch/sh/boards/mach-highlander/Makefile
arch/sh/boards/mach-highlander/pinmux-r7785rp.c [new file with mode: 0644]
arch/sh/boards/mach-highlander/setup.c
arch/sh/boards/mach-migor/setup.c
arch/sh/configs/ap325rxa_defconfig
arch/sh/configs/cayman_defconfig
arch/sh/configs/dreamcast_defconfig
arch/sh/configs/edosk7760_defconfig
arch/sh/configs/hp6xx_defconfig
arch/sh/configs/landisk_defconfig
arch/sh/configs/lboxre2_defconfig
arch/sh/configs/magicpanelr2_defconfig
arch/sh/configs/microdev_defconfig
arch/sh/configs/migor_defconfig
arch/sh/configs/r7780mp_defconfig
arch/sh/configs/r7785rp_defconfig
arch/sh/configs/rsk7203_defconfig
arch/sh/configs/rts7751r2d1_defconfig
arch/sh/configs/rts7751r2dplus_defconfig
arch/sh/configs/rts7751r2dplus_qemu_defconfig
arch/sh/configs/sdk7780_defconfig
arch/sh/configs/se7206_defconfig
arch/sh/configs/se7343_defconfig
arch/sh/configs/se7619_defconfig
arch/sh/configs/se7705_defconfig
arch/sh/configs/se7712_defconfig
arch/sh/configs/se7721_defconfig
arch/sh/configs/se7722_defconfig
arch/sh/configs/se7750_defconfig
arch/sh/configs/se7751_defconfig
arch/sh/configs/se7780_defconfig
arch/sh/configs/sh03_defconfig
arch/sh/configs/sh7710voipgw_defconfig
arch/sh/configs/sh7763rdp_defconfig
arch/sh/configs/sh7785lcr_defconfig
arch/sh/configs/shmin_defconfig
arch/sh/configs/shx3_defconfig
arch/sh/configs/snapgear_defconfig
arch/sh/configs/systemh_defconfig
arch/sh/configs/titan_defconfig
arch/sh/include/asm/gpio.h
arch/sh/include/asm/kdebug.h
arch/sh/include/cpu-sh4/cpu/sh7785.h [new file with mode: 0644]
arch/sh/include/mach-common/mach/highlander.h
arch/sh/kernel/cpu/sh2a/pinmux-sh7203.c
arch/sh/kernel/cpu/sh4a/Makefile
arch/sh/kernel/cpu/sh4a/clock-sh7763.c
arch/sh/kernel/cpu/sh4a/pinmux-sh7785.c [new file with mode: 0644]
arch/sh/kernel/gpio.c
arch/sh/kernel/sh_ksyms_32.c
arch/sh/kernel/smp.c
arch/sh/kernel/traps_32.c
arch/sh/mm/init.c
arch/sparc/oprofile/init.c
arch/sparc64/oprofile/init.c
arch/um/Kconfig.common [new file with mode: 0644]
arch/um/Kconfig.rest [new file with mode: 0644]
arch/um/Kconfig.um [moved from arch/um/Kconfig with 77% similarity]
arch/um/Kconfig.x86 [moved from arch/um/Kconfig.i386 with 59% similarity]
arch/um/Kconfig.x86_64 [deleted file]
arch/um/Makefile
arch/um/Makefile-os-Linux
arch/um/drivers/Makefile
arch/um/drivers/ubd_kern.c
arch/um/include/asm/a.out-core.h [moved from include/asm-um/a.out-core.h with 100% similarity]
arch/um/include/asm/apic.h [moved from include/asm-um/apic.h with 100% similarity]
arch/um/include/asm/auxvec.h [moved from include/asm-um/auxvec.h with 100% similarity]
arch/um/include/asm/bugs.h [moved from include/asm-um/bugs.h with 100% similarity]
arch/um/include/asm/cache.h [moved from include/asm-um/cache.h with 100% similarity]
arch/um/include/asm/checksum.h [moved from include/asm-um/checksum.h with 100% similarity]
arch/um/include/asm/common.lds.S [moved from include/asm-um/common.lds.S with 100% similarity]
arch/um/include/asm/cputime.h [moved from include/asm-um/cputime.h with 100% similarity]
arch/um/include/asm/current.h [moved from include/asm-um/current.h with 100% similarity]
arch/um/include/asm/delay.h [moved from include/asm-um/delay.h with 100% similarity]
arch/um/include/asm/desc.h [moved from include/asm-um/desc.h with 100% similarity]
arch/um/include/asm/device.h [moved from include/asm-um/device.h with 100% similarity]
arch/um/include/asm/dma-mapping.h [moved from include/asm-um/dma-mapping.h with 100% similarity]
arch/um/include/asm/dma.h [moved from include/asm-um/dma.h with 100% similarity]
arch/um/include/asm/emergency-restart.h [moved from include/asm-um/emergency-restart.h with 100% similarity]
arch/um/include/asm/fixmap.h [moved from include/asm-um/fixmap.h with 99% similarity]
arch/um/include/asm/futex.h [moved from include/asm-um/futex.h with 100% similarity]
arch/um/include/asm/hardirq.h [moved from include/asm-um/hardirq.h with 100% similarity]
arch/um/include/asm/hw_irq.h [moved from include/asm-um/hw_irq.h with 100% similarity]
arch/um/include/asm/io.h [moved from include/asm-um/io.h with 100% similarity]
arch/um/include/asm/irq.h [moved from include/asm-um/irq.h with 100% similarity]
arch/um/include/asm/irq_regs.h [moved from include/asm-um/irq_regs.h with 100% similarity]
arch/um/include/asm/irq_vectors.h [moved from include/asm-um/irq_vectors.h with 100% similarity]
arch/um/include/asm/irqflags.h [moved from include/asm-um/irqflags.h with 100% similarity]
arch/um/include/asm/kdebug.h [moved from include/asm-um/kdebug.h with 100% similarity]
arch/um/include/asm/kmap_types.h [moved from include/asm-um/kmap_types.h with 100% similarity]
arch/um/include/asm/mmu.h [moved from include/asm-um/mmu.h with 100% similarity]
arch/um/include/asm/mmu_context.h [moved from include/asm-um/mmu_context.h with 100% similarity]
arch/um/include/asm/mutex.h [moved from include/asm-um/mutex.h with 100% similarity]
arch/um/include/asm/page.h [moved from include/asm-um/page.h with 99% similarity]
arch/um/include/asm/page_offset.h [moved from include/asm-um/page_offset.h with 100% similarity]
arch/um/include/asm/param.h [moved from include/asm-um/param.h with 100% similarity]
arch/um/include/asm/pci.h [moved from include/asm-um/pci.h with 100% similarity]
arch/um/include/asm/pda.h [moved from include/asm-um/pda.h with 100% similarity]
arch/um/include/asm/pgalloc.h [moved from include/asm-um/pgalloc.h with 100% similarity]
arch/um/include/asm/pgtable-2level.h [moved from include/asm-um/pgtable-2level.h with 100% similarity]
arch/um/include/asm/pgtable-3level.h [moved from include/asm-um/pgtable-3level.h with 100% similarity]
arch/um/include/asm/pgtable.h [moved from include/asm-um/pgtable.h with 97% similarity]
arch/um/include/asm/processor-generic.h [moved from include/asm-um/processor-generic.h with 100% similarity]
arch/um/include/asm/ptrace-generic.h [moved from include/asm-um/ptrace-generic.h with 97% similarity]
arch/um/include/asm/required-features.h [moved from include/asm-um/required-features.h with 100% similarity]
arch/um/include/asm/sections.h [moved from include/asm-um/sections.h with 100% similarity]
arch/um/include/asm/segment.h [moved from include/asm-um/segment.h with 100% similarity]
arch/um/include/asm/setup.h [moved from include/asm-um/setup.h with 100% similarity]
arch/um/include/asm/smp.h [moved from include/asm-um/smp.h with 100% similarity]
arch/um/include/asm/suspend.h [moved from include/asm-um/suspend.h with 100% similarity]
arch/um/include/asm/system.h [moved from include/asm-um/system-generic.h with 79% similarity]
arch/um/include/asm/thread_info.h [moved from include/asm-um/thread_info.h with 100% similarity]
arch/um/include/asm/timex.h [moved from include/asm-um/timex.h with 100% similarity]
arch/um/include/asm/tlb.h [moved from include/asm-um/tlb.h with 100% similarity]
arch/um/include/asm/tlbflush.h [moved from include/asm-um/tlbflush.h with 100% similarity]
arch/um/include/asm/topology.h [moved from include/asm-um/topology.h with 100% similarity]
arch/um/include/asm/uaccess.h [moved from include/asm-um/uaccess.h with 100% similarity]
arch/um/include/asm/xor.h [moved from include/asm-um/xor.h with 100% similarity]
arch/um/include/shared/aio.h [moved from arch/um/include/aio.h with 100% similarity]
arch/um/include/shared/arch.h [moved from arch/um/include/arch.h with 100% similarity]
arch/um/include/shared/as-layout.h [moved from arch/um/include/as-layout.h with 98% similarity]
arch/um/include/shared/chan_kern.h [moved from arch/um/include/chan_kern.h with 100% similarity]
arch/um/include/shared/chan_user.h [moved from arch/um/include/chan_user.h with 100% similarity]
arch/um/include/shared/common-offsets.h [moved from arch/um/include/common-offsets.h with 80% similarity]
arch/um/include/shared/elf_user.h [moved from arch/um/include/elf_user.h with 100% similarity]
arch/um/include/shared/frame_kern.h [moved from arch/um/include/frame_kern.h with 100% similarity]
arch/um/include/shared/init.h [moved from arch/um/include/init.h with 100% similarity]
arch/um/include/shared/initrd.h [moved from arch/um/include/initrd.h with 100% similarity]
arch/um/include/shared/irq_kern.h [moved from arch/um/include/irq_kern.h with 100% similarity]
arch/um/include/shared/irq_user.h [moved from arch/um/include/irq_user.h with 100% similarity]
arch/um/include/shared/kern.h [moved from arch/um/include/kern.h with 100% similarity]
arch/um/include/shared/kern_util.h [moved from arch/um/include/kern_util.h with 100% similarity]
arch/um/include/shared/ldt.h [moved from include/asm-um/ldt.h with 95% similarity]
arch/um/include/shared/line.h [moved from arch/um/include/line.h with 100% similarity]
arch/um/include/shared/longjmp.h [moved from arch/um/include/longjmp.h with 100% similarity]
arch/um/include/shared/mconsole.h [moved from arch/um/include/mconsole.h with 100% similarity]
arch/um/include/shared/mconsole_kern.h [moved from arch/um/include/mconsole_kern.h with 100% similarity]
arch/um/include/shared/mem.h [moved from arch/um/include/mem.h with 100% similarity]
arch/um/include/shared/mem_kern.h [moved from arch/um/include/mem_kern.h with 100% similarity]
arch/um/include/shared/mem_user.h [moved from arch/um/include/mem_user.h with 100% similarity]
arch/um/include/shared/net_kern.h [moved from arch/um/include/net_kern.h with 100% similarity]
arch/um/include/shared/net_user.h [moved from arch/um/include/net_user.h with 100% similarity]
arch/um/include/shared/os.h [moved from arch/um/include/os.h with 99% similarity]
arch/um/include/shared/process.h [moved from arch/um/include/process.h with 100% similarity]
arch/um/include/shared/ptrace_user.h [moved from arch/um/include/ptrace_user.h with 100% similarity]
arch/um/include/shared/registers.h [moved from arch/um/include/registers.h with 100% similarity]
arch/um/include/shared/sigio.h [moved from arch/um/include/sigio.h with 100% similarity]
arch/um/include/shared/skas/mm_id.h [moved from arch/um/include/skas/mm_id.h with 100% similarity]
arch/um/include/shared/skas/proc_mm.h [moved from arch/um/include/skas/proc_mm.h with 100% similarity]
arch/um/include/shared/skas/skas.h [moved from arch/um/include/skas/skas.h with 100% similarity]
arch/um/include/shared/skas/stub-data.h [moved from arch/um/include/skas/stub-data.h with 100% similarity]
arch/um/include/shared/skas_ptrace.h [moved from arch/um/include/skas_ptrace.h with 100% similarity]
arch/um/include/shared/skas_ptregs.h [moved from arch/um/include/skas_ptregs.h with 100% similarity]
arch/um/include/shared/syscall.h [moved from arch/um/include/syscall.h with 100% similarity]
arch/um/include/shared/sysrq.h [moved from arch/um/include/sysrq.h with 100% similarity]
arch/um/include/shared/task.h [moved from arch/um/include/task.h with 100% similarity]
arch/um/include/shared/tlb.h [moved from arch/um/include/tlb.h with 100% similarity]
arch/um/include/shared/ubd_user.h [moved from arch/um/include/ubd_user.h with 100% similarity]
arch/um/include/shared/um_malloc.h [moved from arch/um/include/um_malloc.h with 100% similarity]
arch/um/include/shared/um_mmu.h [moved from arch/um/include/um_mmu.h with 91% similarity]
arch/um/include/shared/um_uaccess.h [moved from arch/um/include/um_uaccess.h with 100% similarity]
arch/um/include/shared/user.h [moved from arch/um/include/user.h with 97% similarity]
arch/um/include/sigcontext.h [deleted file]
arch/um/kernel/exec.c
arch/um/kernel/internal.h [new file with mode: 0644]
arch/um/kernel/signal.c
arch/um/kernel/syscall.c
arch/um/os-Linux/include/file.h [deleted file]
arch/um/os-Linux/skas/mem.c
arch/um/sys-i386/asm/archparam.h [moved from include/asm-um/archparam-i386.h with 77% similarity]
arch/um/sys-i386/asm/elf.h [moved from include/asm-um/elf-i386.h with 100% similarity]
arch/um/sys-i386/asm/module.h [moved from include/asm-um/module-i386.h with 100% similarity]
arch/um/sys-i386/asm/processor.h [moved from include/asm-um/processor-i386.h with 97% similarity]
arch/um/sys-i386/asm/ptrace.h [moved from include/asm-um/ptrace-i386.h with 93% similarity]
arch/um/sys-i386/shared/sysdep/archsetjmp.h [moved from arch/um/include/sysdep-i386/archsetjmp.h with 100% similarity]
arch/um/sys-i386/shared/sysdep/barrier.h [moved from arch/um/include/sysdep-i386/barrier.h with 100% similarity]
arch/um/sys-i386/shared/sysdep/checksum.h [moved from arch/um/include/sysdep-i386/checksum.h with 100% similarity]
arch/um/sys-i386/shared/sysdep/faultinfo.h [moved from arch/um/include/sysdep-i386/faultinfo.h with 100% similarity]
arch/um/sys-i386/shared/sysdep/host_ldt.h [moved from include/asm-um/host_ldt-i386.h with 97% similarity]
arch/um/sys-i386/shared/sysdep/kernel-offsets.h [moved from arch/um/include/sysdep-i386/kernel-offsets.h with 100% similarity]
arch/um/sys-i386/shared/sysdep/ptrace.h [moved from arch/um/include/sysdep-i386/ptrace.h with 99% similarity]
arch/um/sys-i386/shared/sysdep/ptrace_user.h [moved from arch/um/include/sysdep-i386/ptrace_user.h with 100% similarity]
arch/um/sys-i386/shared/sysdep/sc.h [moved from arch/um/include/sysdep-i386/sc.h with 100% similarity]
arch/um/sys-i386/shared/sysdep/sigcontext.h [moved from arch/um/include/sysdep-i386/sigcontext.h with 100% similarity]
arch/um/sys-i386/shared/sysdep/skas_ptrace.h [moved from arch/um/include/sysdep-i386/skas_ptrace.h with 100% similarity]
arch/um/sys-i386/shared/sysdep/stub.h [moved from arch/um/include/sysdep-i386/stub.h with 98% similarity]
arch/um/sys-i386/shared/sysdep/syscalls.h [moved from arch/um/include/sysdep-i386/syscalls.h with 100% similarity]
arch/um/sys-i386/shared/sysdep/system.h [new file with mode: 0644]
arch/um/sys-i386/shared/sysdep/tls.h [moved from arch/um/include/sysdep-i386/tls.h with 97% similarity]
arch/um/sys-i386/shared/sysdep/vm-flags.h [moved from include/asm-um/vm-flags-i386.h with 100% similarity]
arch/um/sys-i386/stub.S
arch/um/sys-i386/syscalls.c
arch/um/sys-ia64/sysdep/ptrace.h [moved from arch/um/include/sysdep-ia64/ptrace.h with 100% similarity]
arch/um/sys-ia64/sysdep/sigcontext.h [moved from arch/um/include/sysdep-ia64/sigcontext.h with 100% similarity]
arch/um/sys-ia64/sysdep/skas_ptrace.h [moved from arch/um/include/sysdep-ia64/skas_ptrace.h with 100% similarity]
arch/um/sys-ia64/sysdep/syscalls.h [moved from arch/um/include/sysdep-ia64/syscalls.h with 100% similarity]
arch/um/sys-ppc/asm/archparam.h [moved from include/asm-um/archparam-ppc.h with 100% similarity]
arch/um/sys-ppc/asm/elf.h [moved from include/asm-um/elf-ppc.h with 100% similarity]
arch/um/sys-ppc/asm/processor.h [moved from include/asm-um/processor-ppc.h with 100% similarity]
arch/um/sys-ppc/shared/sysdep/ptrace.h [moved from arch/um/include/sysdep-ppc/ptrace.h with 100% similarity]
arch/um/sys-ppc/shared/sysdep/sigcontext.h [moved from arch/um/include/sysdep-ppc/sigcontext.h with 100% similarity]
arch/um/sys-ppc/shared/sysdep/skas_ptrace.h [moved from arch/um/include/sysdep-ppc/skas_ptrace.h with 100% similarity]
arch/um/sys-ppc/shared/sysdep/syscalls.h [moved from arch/um/include/sysdep-ppc/syscalls.h with 100% similarity]
arch/um/sys-x86_64/asm/archparam.h [moved from include/asm-um/archparam-x86_64.h with 100% similarity]
arch/um/sys-x86_64/asm/elf.h [moved from include/asm-um/elf-x86_64.h with 100% similarity]
arch/um/sys-x86_64/asm/module.h [moved from include/asm-um/module-x86_64.h with 100% similarity]
arch/um/sys-x86_64/asm/processor.h [moved from include/asm-um/processor-x86_64.h with 97% similarity]
arch/um/sys-x86_64/asm/ptrace.h [moved from include/asm-um/ptrace-x86_64.h with 85% similarity]
arch/um/sys-x86_64/shared/sysdep/archsetjmp.h [moved from arch/um/include/sysdep-x86_64/archsetjmp.h with 100% similarity]
arch/um/sys-x86_64/shared/sysdep/barrier.h [moved from arch/um/include/sysdep-x86_64/barrier.h with 100% similarity]
arch/um/sys-x86_64/shared/sysdep/checksum.h [moved from arch/um/include/sysdep-x86_64/checksum.h with 100% similarity]
arch/um/sys-x86_64/shared/sysdep/faultinfo.h [moved from arch/um/include/sysdep-x86_64/faultinfo.h with 100% similarity]
arch/um/sys-x86_64/shared/sysdep/host_ldt.h [moved from include/asm-um/host_ldt-x86_64.h with 97% similarity]
arch/um/sys-x86_64/shared/sysdep/kernel-offsets.h [moved from arch/um/include/sysdep-x86_64/kernel-offsets.h with 100% similarity]
arch/um/sys-x86_64/shared/sysdep/ptrace.h [moved from arch/um/include/sysdep-x86_64/ptrace.h with 99% similarity]
arch/um/sys-x86_64/shared/sysdep/ptrace_user.h [moved from arch/um/include/sysdep-x86_64/ptrace_user.h with 100% similarity]
arch/um/sys-x86_64/shared/sysdep/sc.h [moved from arch/um/include/sysdep-x86_64/sc.h with 100% similarity]
arch/um/sys-x86_64/shared/sysdep/sigcontext.h [moved from arch/um/include/sysdep-x86_64/sigcontext.h with 100% similarity]
arch/um/sys-x86_64/shared/sysdep/skas_ptrace.h [moved from arch/um/include/sysdep-x86_64/skas_ptrace.h with 100% similarity]
arch/um/sys-x86_64/shared/sysdep/stub.h [moved from arch/um/include/sysdep-x86_64/stub.h with 98% similarity]
arch/um/sys-x86_64/shared/sysdep/syscalls.h [moved from arch/um/include/sysdep-x86_64/syscalls.h with 100% similarity]
arch/um/sys-x86_64/shared/sysdep/system.h [new file with mode: 0644]
arch/um/sys-x86_64/shared/sysdep/tls.h [moved from arch/um/include/sysdep-x86_64/tls.h with 96% similarity]
arch/um/sys-x86_64/shared/sysdep/vm-flags.h [moved from include/asm-um/vm-flags-x86_64.h with 100% similarity]
arch/um/sys-x86_64/stub.S
arch/um/sys-x86_64/syscall_table.c
arch/x86/Kconfig
arch/x86/Makefile
arch/x86/boot/compressed/misc.c
arch/x86/boot/video-bios.c
arch/x86/boot/video-vesa.c
arch/x86/configs/i386_defconfig
arch/x86/include/asm/Kbuild [moved from include/asm-x86/Kbuild with 100% similarity]
arch/x86/include/asm/a.out-core.h [moved from include/asm-x86/a.out-core.h with 95% similarity]
arch/x86/include/asm/a.out.h [moved from include/asm-x86/a.out.h with 88% similarity]
arch/x86/include/asm/acpi.h [moved from include/asm-x86/acpi.h with 98% similarity]
arch/x86/include/asm/agp.h [moved from include/asm-x86/agp.h with 93% similarity]
arch/x86/include/asm/alternative-asm.h [moved from include/asm-x86/alternative-asm.h with 100% similarity]
arch/x86/include/asm/alternative.h [moved from include/asm-x86/alternative.h with 98% similarity]
arch/x86/include/asm/amd_iommu.h [moved from include/asm-x86/amd_iommu.h with 92% similarity]
arch/x86/include/asm/amd_iommu_types.h [moved from include/asm-x86/amd_iommu_types.h with 99% similarity]
arch/x86/include/asm/apic.h [moved from include/asm-x86/apic.h with 93% similarity]
arch/x86/include/asm/apicdef.h [moved from include/asm-x86/apicdef.h with 99% similarity]
arch/x86/include/asm/arch_hooks.h [moved from include/asm-x86/arch_hooks.h with 86% similarity]
arch/x86/include/asm/asm.h [moved from include/asm-x86/asm.h with 93% similarity]
arch/x86/include/asm/atomic.h [moved from include/asm-x86/atomic.h with 100% similarity]
arch/x86/include/asm/atomic_32.h [moved from include/asm-x86/atomic_32.h with 98% similarity]
arch/x86/include/asm/atomic_64.h [moved from include/asm-x86/atomic_64.h with 99% similarity]
arch/x86/include/asm/auxvec.h [moved from include/asm-x86/auxvec.h with 70% similarity]
arch/x86/include/asm/bigsmp/apic.h [moved from include/asm-x86/bigsmp/apic.h with 90% similarity]
arch/x86/include/asm/bigsmp/apicdef.h [moved from include/asm-x86/bigsmp/apicdef.h with 100% similarity]
arch/x86/include/asm/bigsmp/ipi.h [moved from include/asm-x86/bigsmp/ipi.h with 100% similarity]
arch/x86/include/asm/bios_ebda.h [moved from include/asm-x86/bios_ebda.h with 88% similarity]
arch/x86/include/asm/bitops.h [moved from include/asm-x86/bitops.h with 99% similarity]
arch/x86/include/asm/boot.h [moved from include/asm-x86/boot.h with 89% similarity]
arch/x86/include/asm/bootparam.h [moved from include/asm-x86/bootparam.h with 96% similarity]
arch/x86/include/asm/bug.h [moved from include/asm-x86/bug.h with 90% similarity]
arch/x86/include/asm/bugs.h [moved from include/asm-x86/bugs.h with 71% similarity]
arch/x86/include/asm/byteorder.h [moved from include/asm-x86/byteorder.h with 94% similarity]
arch/x86/include/asm/cache.h [moved from include/asm-x86/cache.h with 85% similarity]
arch/x86/include/asm/cacheflush.h [moved from include/asm-x86/cacheflush.h with 97% similarity]
arch/x86/include/asm/calgary.h [moved from include/asm-x86/calgary.h with 96% similarity]
arch/x86/include/asm/calling.h [moved from include/asm-x86/calling.h with 100% similarity]
arch/x86/include/asm/checksum.h [moved from include/asm-x86/checksum.h with 100% similarity]
arch/x86/include/asm/checksum_32.h [moved from include/asm-x86/checksum_32.h with 97% similarity]
arch/x86/include/asm/checksum_64.h [moved from include/asm-x86/checksum_64.h with 98% similarity]
arch/x86/include/asm/cmpxchg.h [moved from include/asm-x86/cmpxchg.h with 100% similarity]
arch/x86/include/asm/cmpxchg_32.h [moved from include/asm-x86/cmpxchg_32.h with 98% similarity]
arch/x86/include/asm/cmpxchg_64.h [moved from include/asm-x86/cmpxchg_64.h with 97% similarity]
arch/x86/include/asm/compat.h [moved from include/asm-x86/compat.h with 98% similarity]
arch/x86/include/asm/cpu.h [moved from include/asm-x86/cpu.h with 80% similarity]
arch/x86/include/asm/cpufeature.h [moved from include/asm-x86/cpufeature.h with 99% similarity]
arch/x86/include/asm/cputime.h [moved from include/asm-x86/cputime.h with 100% similarity]
arch/x86/include/asm/current.h [moved from include/asm-x86/current.h with 87% similarity]
arch/x86/include/asm/debugreg.h [moved from include/asm-x86/debugreg.h with 96% similarity]
arch/x86/include/asm/delay.h [moved from include/asm-x86/delay.h with 90% similarity]
arch/x86/include/asm/desc.h [moved from include/asm-x86/desc.h with 99% similarity]
arch/x86/include/asm/desc_defs.h [moved from include/asm-x86/desc_defs.h with 96% similarity]
arch/x86/include/asm/device.h [moved from include/asm-x86/device.h with 72% similarity]
arch/x86/include/asm/div64.h [moved from include/asm-x86/div64.h with 94% similarity]
arch/x86/include/asm/dma-mapping.h [moved from include/asm-x86/dma-mapping.h with 98% similarity]
arch/x86/include/asm/dma.h [moved from include/asm-x86/dma.h with 99% similarity]
arch/x86/include/asm/dmi.h [moved from include/asm-x86/dmi.h with 88% similarity]
arch/x86/include/asm/ds.h [moved from include/asm-x86/ds.h with 98% similarity]
arch/x86/include/asm/dwarf2.h [moved from include/asm-x86/dwarf2.h with 95% similarity]
arch/x86/include/asm/e820.h [moved from include/asm-x86/e820.h with 98% similarity]
arch/x86/include/asm/edac.h [moved from include/asm-x86/edac.h with 82% similarity]
arch/x86/include/asm/efi.h [moved from include/asm-x86/efi.h with 87% similarity]
arch/x86/include/asm/elf.h [moved from include/asm-x86/elf.h with 99% similarity]
arch/x86/include/asm/emergency-restart.h [moved from include/asm-x86/emergency-restart.h with 65% similarity]
arch/x86/include/asm/errno.h [moved from include/asm-x86/errno.h with 100% similarity]
arch/x86/include/asm/es7000/apic.h [moved from include/asm-x86/es7000/apic.h with 98% similarity]
arch/x86/include/asm/es7000/apicdef.h [moved from include/asm-x86/es7000/apicdef.h with 100% similarity]
arch/x86/include/asm/es7000/ipi.h [moved from include/asm-x86/es7000/ipi.h with 100% similarity]
arch/x86/include/asm/es7000/mpparse.h [moved from include/asm-x86/es7000/mpparse.h with 100% similarity]
arch/x86/include/asm/es7000/wakecpu.h [moved from include/asm-x86/es7000/wakecpu.h with 100% similarity]
arch/x86/include/asm/fb.h [moved from include/asm-x86/fb.h with 85% similarity]
arch/x86/include/asm/fcntl.h [moved from include/asm-x86/fcntl.h with 100% similarity]
arch/x86/include/asm/fixmap.h [moved from include/asm-x86/fixmap.h with 95% similarity]
arch/x86/include/asm/fixmap_32.h [moved from include/asm-x86/fixmap_32.h with 97% similarity]
arch/x86/include/asm/fixmap_64.h [moved from include/asm-x86/fixmap_64.h with 96% similarity]
arch/x86/include/asm/floppy.h [moved from include/asm-x86/floppy.h with 98% similarity]
arch/x86/include/asm/frame.h [moved from include/asm-x86/frame.h with 100% similarity]
arch/x86/include/asm/ftrace.h [new file with mode: 0644]
arch/x86/include/asm/futex.h [moved from include/asm-x86/futex.h with 97% similarity]
arch/x86/include/asm/gart.h [moved from include/asm-x86/gart.h with 95% similarity]
arch/x86/include/asm/genapic.h [moved from include/asm-x86/genapic.h with 100% similarity]
arch/x86/include/asm/genapic_32.h [moved from include/asm-x86/genapic_32.h with 95% similarity]
arch/x86/include/asm/genapic_64.h [moved from include/asm-x86/genapic_64.h with 94% similarity]
arch/x86/include/asm/geode.h [moved from include/asm-x86/geode.h with 98% similarity]
arch/x86/include/asm/gpio.h [moved from include/asm-x86/gpio.h with 92% similarity]
arch/x86/include/asm/hardirq.h [moved from include/asm-x86/hardirq.h with 100% similarity]
arch/x86/include/asm/hardirq_32.h [moved from include/asm-x86/hardirq_32.h with 87% similarity]
arch/x86/include/asm/hardirq_64.h [moved from include/asm-x86/hardirq_64.h with 84% similarity]
arch/x86/include/asm/highmem.h [moved from include/asm-x86/highmem.h with 96% similarity]
arch/x86/include/asm/hpet.h [moved from include/asm-x86/hpet.h with 80% similarity]
arch/x86/include/asm/hugetlb.h [moved from include/asm-x86/hugetlb.h with 95% similarity]
arch/x86/include/asm/hw_irq.h [moved from include/asm-x86/hw_irq.h with 91% similarity]
arch/x86/include/asm/hypertransport.h [moved from include/asm-x86/hypertransport.h with 91% similarity]
arch/x86/include/asm/i387.h [moved from include/asm-x86/i387.h with 99% similarity]
arch/x86/include/asm/i8253.h [moved from include/asm-x86/i8253.h with 77% similarity]
arch/x86/include/asm/i8259.h [moved from include/asm-x86/i8259.h with 95% similarity]
arch/x86/include/asm/ia32.h [moved from include/asm-x86/ia32.h with 97% similarity]
arch/x86/include/asm/ia32_unistd.h [moved from include/asm-x86/ia32_unistd.h with 81% similarity]
arch/x86/include/asm/idle.h [moved from include/asm-x86/idle.h with 59% similarity]
arch/x86/include/asm/intel_arch_perfmon.h [moved from include/asm-x86/intel_arch_perfmon.h with 87% similarity]
arch/x86/include/asm/io.h [moved from include/asm-x86/io.h with 97% similarity]
arch/x86/include/asm/io_32.h [moved from include/asm-x86/io_32.h with 98% similarity]
arch/x86/include/asm/io_64.h [moved from include/asm-x86/io_64.h with 98% similarity]
arch/x86/include/asm/io_apic.h [moved from include/asm-x86/io_apic.h with 93% similarity]
arch/x86/include/asm/ioctl.h [moved from include/asm-x86/ioctl.h with 100% similarity]
arch/x86/include/asm/ioctls.h [moved from include/asm-x86/ioctls.h with 97% similarity]
arch/x86/include/asm/iommu.h [moved from include/asm-x86/iommu.h with 84% similarity]
arch/x86/include/asm/ipcbuf.h [moved from include/asm-x86/ipcbuf.h with 86% similarity]
arch/x86/include/asm/ipi.h [moved from include/asm-x86/ipi.h with 97% similarity]
arch/x86/include/asm/irq.h [moved from include/asm-x86/irq.h with 93% similarity]
arch/x86/include/asm/irq_regs.h [moved from include/asm-x86/irq_regs.h with 100% similarity]
arch/x86/include/asm/irq_regs_32.h [moved from include/asm-x86/irq_regs_32.h with 84% similarity]
arch/x86/include/asm/irq_regs_64.h [moved from include/asm-x86/irq_regs_64.h with 100% similarity]
arch/x86/include/asm/irq_remapping.h [new file with mode: 0644]
arch/x86/include/asm/irq_vectors.h [moved from include/asm-x86/irq_vectors.h with 86% similarity]
arch/x86/include/asm/irqflags.h [moved from include/asm-x86/irqflags.h with 100% similarity]
arch/x86/include/asm/ist.h [moved from include/asm-x86/ist.h with 91% similarity]
arch/x86/include/asm/k8.h [moved from include/asm-x86/k8.h with 81% similarity]
arch/x86/include/asm/kdebug.h [moved from include/asm-x86/kdebug.h with 90% similarity]
arch/x86/include/asm/kexec.h [moved from include/asm-x86/kexec.h with 98% similarity]
arch/x86/include/asm/kgdb.h [moved from include/asm-x86/kgdb.h with 95% similarity]
arch/x86/include/asm/kmap_types.h [moved from include/asm-x86/kmap_types.h with 81% similarity]
arch/x86/include/asm/kprobes.h [moved from include/asm-x86/kprobes.h with 96% similarity]
arch/x86/include/asm/kvm.h [moved from include/asm-x86/kvm.h with 98% similarity]
arch/x86/include/asm/kvm_host.h [moved from include/asm-x86/kvm_host.h with 99% similarity]
arch/x86/include/asm/kvm_para.h [moved from include/asm-x86/kvm_para.h with 97% similarity]
arch/x86/include/asm/kvm_x86_emulate.h [moved from include/asm-x86/kvm_x86_emulate.h with 98% similarity]
arch/x86/include/asm/ldt.h [moved from include/asm-x86/ldt.h with 92% similarity]
arch/x86/include/asm/lguest.h [moved from include/asm-x86/lguest.h with 96% similarity]
arch/x86/include/asm/lguest_hcall.h [moved from include/asm-x86/lguest_hcall.h with 95% similarity]
arch/x86/include/asm/linkage.h [moved from include/asm-x86/linkage.h with 95% similarity]
arch/x86/include/asm/local.h [moved from include/asm-x86/local.h with 98% similarity]
arch/x86/include/asm/mach-default/apm.h [moved from include/asm-x86/mach-default/apm.h with 93% similarity]
arch/x86/include/asm/mach-default/do_timer.h [moved from include/asm-x86/mach-default/do_timer.h with 100% similarity]
arch/x86/include/asm/mach-default/entry_arch.h [moved from include/asm-x86/mach-default/entry_arch.h with 94% similarity]
arch/x86/include/asm/mach-default/mach_apic.h [moved from include/asm-x86/mach-default/mach_apic.h with 82% similarity]
arch/x86/include/asm/mach-default/mach_apicdef.h [moved from include/asm-x86/mach-default/mach_apicdef.h with 76% similarity]
arch/x86/include/asm/mach-default/mach_ipi.h [moved from include/asm-x86/mach-default/mach_ipi.h with 91% similarity]
arch/x86/include/asm/mach-default/mach_mpparse.h [moved from include/asm-x86/mach-default/mach_mpparse.h with 62% similarity]
arch/x86/include/asm/mach-default/mach_mpspec.h [new file with mode: 0644]
arch/x86/include/asm/mach-default/mach_timer.h [moved from include/asm-x86/mach-default/mach_timer.h with 91% similarity]
arch/x86/include/asm/mach-default/mach_traps.h [moved from include/asm-x86/mach-default/mach_traps.h with 80% similarity]
arch/x86/include/asm/mach-default/mach_wakecpu.h [moved from include/asm-x86/mach-default/mach_wakecpu.h with 85% similarity]
arch/x86/include/asm/mach-default/pci-functions.h [moved from include/asm-x86/mach-default/pci-functions.h with 100% similarity]
arch/x86/include/asm/mach-default/setup_arch.h [moved from include/asm-x86/mach-default/setup_arch.h with 100% similarity]
arch/x86/include/asm/mach-default/smpboot_hooks.h [moved from include/asm-x86/mach-default/smpboot_hooks.h with 100% similarity]
arch/x86/include/asm/mach-generic/gpio.h [moved from include/asm-x86/mach-generic/gpio.h with 76% similarity]
arch/x86/include/asm/mach-generic/mach_apic.h [moved from include/asm-x86/mach-generic/mach_apic.h with 86% similarity]
arch/x86/include/asm/mach-generic/mach_apicdef.h [moved from include/asm-x86/mach-generic/mach_apicdef.h with 50% similarity]
arch/x86/include/asm/mach-generic/mach_ipi.h [moved from include/asm-x86/mach-generic/mach_ipi.h with 57% similarity]
arch/x86/include/asm/mach-generic/mach_mpparse.h [moved from include/asm-x86/mach-generic/mach_mpparse.h with 52% similarity]
arch/x86/include/asm/mach-generic/mach_mpspec.h [moved from include/asm-x86/mach-generic/mach_mpspec.h with 67% similarity]
arch/x86/include/asm/mach-rdc321x/gpio.h [moved from include/asm-x86/mach-rdc321x/gpio.h with 91% similarity]
arch/x86/include/asm/mach-rdc321x/rdc321x_defs.h [moved from include/asm-x86/mach-rdc321x/rdc321x_defs.h with 100% similarity]
arch/x86/include/asm/mach-voyager/do_timer.h [moved from include/asm-x86/mach-voyager/do_timer.h with 100% similarity]
arch/x86/include/asm/mach-voyager/entry_arch.h [moved from include/asm-x86/mach-voyager/entry_arch.h with 100% similarity]
arch/x86/include/asm/mach-voyager/setup_arch.h [moved from include/asm-x86/mach-voyager/setup_arch.h with 100% similarity]
arch/x86/include/asm/math_emu.h [moved from include/asm-x86/math_emu.h with 86% similarity]
arch/x86/include/asm/mc146818rtc.h [moved from include/asm-x86/mc146818rtc.h with 96% similarity]
arch/x86/include/asm/mca.h [moved from include/asm-x86/mca.h with 94% similarity]
arch/x86/include/asm/mca_dma.h [moved from include/asm-x86/mca_dma.h with 98% similarity]
arch/x86/include/asm/mce.h [moved from include/asm-x86/mce.h with 97% similarity]
arch/x86/include/asm/microcode.h [moved from include/asm-x86/microcode.h with 91% similarity]
arch/x86/include/asm/mman.h [moved from include/asm-x86/mman.h with 90% similarity]
arch/x86/include/asm/mmconfig.h [moved from include/asm-x86/mmconfig.h with 74% similarity]
arch/x86/include/asm/mmu.h [moved from include/asm-x86/mmu.h with 81% similarity]
arch/x86/include/asm/mmu_context.h [moved from include/asm-x86/mmu_context.h with 87% similarity]
arch/x86/include/asm/mmu_context_32.h [moved from include/asm-x86/mmu_context_32.h with 92% similarity]
arch/x86/include/asm/mmu_context_64.h [moved from include/asm-x86/mmu_context_64.h with 92% similarity]
arch/x86/include/asm/mmx.h [moved from include/asm-x86/mmx.h with 75% similarity]
arch/x86/include/asm/mmzone.h [moved from include/asm-x86/mmzone.h with 100% similarity]
arch/x86/include/asm/mmzone_32.h [moved from include/asm-x86/mmzone_32.h with 97% similarity]
arch/x86/include/asm/mmzone_64.h [moved from include/asm-x86/mmzone_64.h with 93% similarity]
arch/x86/include/asm/module.h [moved from include/asm-x86/module.h with 96% similarity]
arch/x86/include/asm/mpspec.h [moved from include/asm-x86/mpspec.h with 97% similarity]
arch/x86/include/asm/mpspec_def.h [moved from include/asm-x86/mpspec_def.h with 97% similarity]
arch/x86/include/asm/msgbuf.h [moved from include/asm-x86/msgbuf.h with 92% similarity]
arch/x86/include/asm/msidef.h [moved from include/asm-x86/msidef.h with 95% similarity]
arch/x86/include/asm/msr-index.h [moved from include/asm-x86/msr-index.h with 99% similarity]
arch/x86/include/asm/msr.h [moved from include/asm-x86/msr.h with 98% similarity]
arch/x86/include/asm/mtrr.h [moved from include/asm-x86/mtrr.h with 98% similarity]
arch/x86/include/asm/mutex.h [moved from include/asm-x86/mutex.h with 100% similarity]
arch/x86/include/asm/mutex_32.h [moved from include/asm-x86/mutex_32.h with 97% similarity]
arch/x86/include/asm/mutex_64.h [moved from include/asm-x86/mutex_64.h with 96% similarity]
arch/x86/include/asm/nmi.h [moved from include/asm-x86/nmi.h with 96% similarity]
arch/x86/include/asm/nops.h [moved from include/asm-x86/nops.h with 97% similarity]
arch/x86/include/asm/numa.h [moved from include/asm-x86/numa.h with 100% similarity]
arch/x86/include/asm/numa_32.h [moved from include/asm-x86/numa_32.h with 62% similarity]
arch/x86/include/asm/numa_64.h [moved from include/asm-x86/numa_64.h with 92% similarity]
arch/x86/include/asm/numaq.h [moved from include/asm-x86/numaq.h with 98% similarity]
arch/x86/include/asm/numaq/apic.h [moved from include/asm-x86/numaq/apic.h with 98% similarity]
arch/x86/include/asm/numaq/apicdef.h [moved from include/asm-x86/numaq/apicdef.h with 100% similarity]
arch/x86/include/asm/numaq/ipi.h [moved from include/asm-x86/numaq/ipi.h with 100% similarity]
arch/x86/include/asm/numaq/mpparse.h [moved from include/asm-x86/numaq/mpparse.h with 100% similarity]
arch/x86/include/asm/numaq/wakecpu.h [moved from include/asm-x86/numaq/wakecpu.h with 100% similarity]
arch/x86/include/asm/olpc.h [moved from include/asm-x86/olpc.h with 97% similarity]
arch/x86/include/asm/page.h [moved from include/asm-x86/page.h with 98% similarity]
arch/x86/include/asm/page_32.h [moved from include/asm-x86/page_32.h with 97% similarity]
arch/x86/include/asm/page_64.h [moved from include/asm-x86/page_64.h with 97% similarity]
arch/x86/include/asm/param.h [moved from include/asm-x86/param.h with 82% similarity]
arch/x86/include/asm/paravirt.h [moved from include/asm-x86/paravirt.h with 99% similarity]
arch/x86/include/asm/parport.h [moved from include/asm-x86/parport.h with 70% similarity]
arch/x86/include/asm/pat.h [moved from include/asm-x86/pat.h with 86% similarity]
arch/x86/include/asm/pci-direct.h [moved from include/asm-x86/pci-direct.h with 88% similarity]
arch/x86/include/asm/pci.h [moved from include/asm-x86/pci.h with 97% similarity]
arch/x86/include/asm/pci_32.h [moved from include/asm-x86/pci_32.h with 91% similarity]
arch/x86/include/asm/pci_64.h [moved from include/asm-x86/pci_64.h with 95% similarity]
arch/x86/include/asm/pda.h [moved from include/asm-x86/pda.h with 98% similarity]
arch/x86/include/asm/percpu.h [moved from include/asm-x86/percpu.h with 98% similarity]
arch/x86/include/asm/pgalloc.h [moved from include/asm-x86/pgalloc.h with 97% similarity]
arch/x86/include/asm/pgtable-2level-defs.h [moved from include/asm-x86/pgtable-2level-defs.h with 67% similarity]
arch/x86/include/asm/pgtable-2level.h [moved from include/asm-x86/pgtable-2level.h with 94% similarity]
arch/x86/include/asm/pgtable-3level-defs.h [moved from include/asm-x86/pgtable-3level-defs.h with 78% similarity]
arch/x86/include/asm/pgtable-3level.h [moved from include/asm-x86/pgtable-3level.h with 97% similarity]
arch/x86/include/asm/pgtable.h [moved from include/asm-x86/pgtable.h with 99% similarity]
arch/x86/include/asm/pgtable_32.h [moved from include/asm-x86/pgtable_32.h with 98% similarity]
arch/x86/include/asm/pgtable_64.h [moved from include/asm-x86/pgtable_64.h with 98% similarity]
arch/x86/include/asm/poll.h [moved from include/asm-x86/poll.h with 100% similarity]
arch/x86/include/asm/posix_types.h [moved from include/asm-x86/posix_types.h with 100% similarity]
arch/x86/include/asm/posix_types_32.h [moved from include/asm-x86/posix_types_32.h with 95% similarity]
arch/x86/include/asm/posix_types_64.h [moved from include/asm-x86/posix_types_64.h with 96% similarity]
arch/x86/include/asm/prctl.h [moved from include/asm-x86/prctl.h with 58% similarity]
arch/x86/include/asm/processor-cyrix.h [moved from include/asm-x86/processor-cyrix.h with 100% similarity]
arch/x86/include/asm/processor-flags.h [moved from include/asm-x86/processor-flags.h with 96% similarity]
arch/x86/include/asm/processor.h [moved from include/asm-x86/processor.h with 99% similarity]
arch/x86/include/asm/proto.h [moved from include/asm-x86/proto.h with 88% similarity]
arch/x86/include/asm/ptrace-abi.h [moved from include/asm-x86/ptrace-abi.h with 97% similarity]
arch/x86/include/asm/ptrace.h [moved from include/asm-x86/ptrace.h with 98% similarity]
arch/x86/include/asm/pvclock-abi.h [moved from include/asm-x86/pvclock-abi.h with 92% similarity]
arch/x86/include/asm/pvclock.h [moved from include/asm-x86/pvclock.h with 82% similarity]
arch/x86/include/asm/reboot.h [moved from include/asm-x86/reboot.h with 83% similarity]
arch/x86/include/asm/reboot_fixups.h [new file with mode: 0644]
arch/x86/include/asm/required-features.h [moved from include/asm-x86/required-features.h with 94% similarity]
arch/x86/include/asm/resource.h [moved from include/asm-x86/resource.h with 100% similarity]
arch/x86/include/asm/resume-trace.h [moved from include/asm-x86/resume-trace.h with 81% similarity]
arch/x86/include/asm/rio.h [moved from include/asm-x86/rio.h with 97% similarity]
arch/x86/include/asm/rtc.h [moved from include/asm-x86/rtc.h with 100% similarity]
arch/x86/include/asm/rwlock.h [moved from include/asm-x86/rwlock.h with 55% similarity]
arch/x86/include/asm/rwsem.h [moved from include/asm-x86/rwsem.h with 98% similarity]
arch/x86/include/asm/scatterlist.h [moved from include/asm-x86/scatterlist.h with 87% similarity]
arch/x86/include/asm/seccomp.h [moved from include/asm-x86/seccomp.h with 100% similarity]
arch/x86/include/asm/seccomp_32.h [moved from include/asm-x86/seccomp_32.h with 74% similarity]
arch/x86/include/asm/seccomp_64.h [moved from include/asm-x86/seccomp_64.h with 84% similarity]
arch/x86/include/asm/sections.h [moved from include/asm-x86/sections.h with 100% similarity]
arch/x86/include/asm/segment.h [moved from include/asm-x86/segment.h with 98% similarity]
arch/x86/include/asm/sembuf.h [moved from include/asm-x86/sembuf.h with 88% similarity]
arch/x86/include/asm/serial.h [moved from include/asm-x86/serial.h with 92% similarity]
arch/x86/include/asm/setup.h [moved from include/asm-x86/setup.h with 96% similarity]
arch/x86/include/asm/shmbuf.h [moved from include/asm-x86/shmbuf.h with 93% similarity]
arch/x86/include/asm/shmparam.h [new file with mode: 0644]
arch/x86/include/asm/sigcontext.h [moved from include/asm-x86/sigcontext.h with 98% similarity]
arch/x86/include/asm/sigcontext32.h [moved from include/asm-x86/sigcontext32.h with 93% similarity]
arch/x86/include/asm/siginfo.h [moved from include/asm-x86/siginfo.h with 56% similarity]
arch/x86/include/asm/signal.h [moved from include/asm-x86/signal.h with 98% similarity]
arch/x86/include/asm/smp.h [moved from include/asm-x86/smp.h with 98% similarity]
arch/x86/include/asm/socket.h [moved from include/asm-x86/socket.h with 93% similarity]
arch/x86/include/asm/sockios.h [moved from include/asm-x86/sockios.h with 76% similarity]
arch/x86/include/asm/sparsemem.h [moved from include/asm-x86/sparsemem.h with 89% similarity]
arch/x86/include/asm/spinlock.h [moved from include/asm-x86/spinlock.h with 99% similarity]
arch/x86/include/asm/spinlock_types.h [moved from include/asm-x86/spinlock_types.h with 74% similarity]
arch/x86/include/asm/srat.h [moved from include/asm-x86/srat.h with 93% similarity]
arch/x86/include/asm/stacktrace.h [moved from include/asm-x86/stacktrace.h with 85% similarity]
arch/x86/include/asm/stat.h [moved from include/asm-x86/stat.h with 96% similarity]
arch/x86/include/asm/statfs.h [moved from include/asm-x86/statfs.h with 76% similarity]
arch/x86/include/asm/string.h [moved from include/asm-x86/string.h with 100% similarity]
arch/x86/include/asm/string_32.h [moved from include/asm-x86/string_32.h with 98% similarity]
arch/x86/include/asm/string_64.h [moved from include/asm-x86/string_64.h with 94% similarity]
arch/x86/include/asm/summit/apic.h [moved from include/asm-x86/summit/apic.h with 99% similarity]
arch/x86/include/asm/summit/apicdef.h [moved from include/asm-x86/summit/apicdef.h with 100% similarity]
arch/x86/include/asm/summit/ipi.h [moved from include/asm-x86/summit/ipi.h with 100% similarity]
arch/x86/include/asm/summit/mpparse.h [moved from include/asm-x86/summit/mpparse.h with 100% similarity]
arch/x86/include/asm/suspend.h [moved from include/asm-x86/suspend.h with 100% similarity]
arch/x86/include/asm/suspend_32.h [moved from include/asm-x86/suspend_32.h with 92% similarity]
arch/x86/include/asm/suspend_64.h [moved from include/asm-x86/suspend_64.h with 92% similarity]
arch/x86/include/asm/swiotlb.h [moved from include/asm-x86/swiotlb.h with 95% similarity]
arch/x86/include/asm/sync_bitops.h [moved from include/asm-x86/sync_bitops.h with 97% similarity]
arch/x86/include/asm/syscall.h [moved from include/asm-x86/syscall.h with 96% similarity]
arch/x86/include/asm/syscalls.h [moved from include/asm-x86/syscalls.h with 100% similarity]
arch/x86/include/asm/system.h [moved from include/asm-x86/system.h with 99% similarity]
arch/x86/include/asm/system_64.h [moved from include/asm-x86/system_64.h with 77% similarity]
arch/x86/include/asm/tce.h [moved from include/asm-x86/tce.h with 95% similarity]
arch/x86/include/asm/termbits.h [moved from include/asm-x86/termbits.h with 98% similarity]
arch/x86/include/asm/termios.h [moved from include/asm-x86/termios.h with 97% similarity]
arch/x86/include/asm/therm_throt.h [new file with mode: 0644]
arch/x86/include/asm/thread_info.h [moved from include/asm-x86/thread_info.h with 98% similarity]
arch/x86/include/asm/time.h [moved from include/asm-x86/time.h with 93% similarity]
arch/x86/include/asm/timer.h [moved from include/asm-x86/timer.h with 95% similarity]
arch/x86/include/asm/timex.h [moved from include/asm-x86/timex.h with 84% similarity]
arch/x86/include/asm/tlb.h [moved from include/asm-x86/tlb.h with 76% similarity]
arch/x86/include/asm/tlbflush.h [moved from include/asm-x86/tlbflush.h with 97% similarity]
arch/x86/include/asm/topology.h [moved from include/asm-x86/topology.h with 98% similarity]
arch/x86/include/asm/trampoline.h [moved from include/asm-x86/trampoline.h with 79% similarity]
arch/x86/include/asm/traps.h [moved from include/asm-x86/traps.h with 97% similarity]
arch/x86/include/asm/tsc.h [moved from include/asm-x86/tsc.h with 93% similarity]
arch/x86/include/asm/types.h [moved from include/asm-x86/types.h with 87% similarity]
arch/x86/include/asm/uaccess.h [moved from include/asm-x86/uaccess.h with 99% similarity]
arch/x86/include/asm/uaccess_32.h [moved from include/asm-x86/uaccess_32.h with 98% similarity]
arch/x86/include/asm/uaccess_64.h [moved from include/asm-x86/uaccess_64.h with 98% similarity]
arch/x86/include/asm/ucontext.h [moved from include/asm-x86/ucontext.h with 81% similarity]
arch/x86/include/asm/unaligned.h [moved from include/asm-x86/unaligned.h with 69% similarity]
arch/x86/include/asm/unistd.h [moved from include/asm-x86/unistd.h with 100% similarity]
arch/x86/include/asm/unistd_32.h [moved from include/asm-x86/unistd_32.h with 99% similarity]
arch/x86/include/asm/unistd_64.h [moved from include/asm-x86/unistd_64.h with 99% similarity]
arch/x86/include/asm/unwind.h [moved from include/asm-x86/unwind.h with 70% similarity]
arch/x86/include/asm/user.h [moved from include/asm-x86/user.h with 100% similarity]
arch/x86/include/asm/user32.h [moved from include/asm-x86/user32.h with 96% similarity]
arch/x86/include/asm/user_32.h [moved from include/asm-x86/user_32.h with 98% similarity]
arch/x86/include/asm/user_64.h [moved from include/asm-x86/user_64.h with 98% similarity]
arch/x86/include/asm/uv/bios.h [new file with mode: 0644]
arch/x86/include/asm/uv/uv_bau.h [moved from include/asm-x86/uv/uv_bau.h with 99% similarity]
arch/x86/include/asm/uv/uv_hub.h [moved from include/asm-x86/uv/uv_hub.h with 99% similarity]
arch/x86/include/asm/uv/uv_irq.h [new file with mode: 0644]
arch/x86/include/asm/uv/uv_mmrs.h [moved from include/asm-x86/uv/uv_mmrs.h with 99% similarity]
arch/x86/include/asm/vdso.h [moved from include/asm-x86/vdso.h with 94% similarity]
arch/x86/include/asm/vga.h [moved from include/asm-x86/vga.h with 81% similarity]
arch/x86/include/asm/vgtod.h [moved from include/asm-x86/vgtod.h with 87% similarity]
arch/x86/include/asm/vic.h [moved from include/asm-x86/vic.h with 100% similarity]
arch/x86/include/asm/visws/cobalt.h [moved from include/asm-x86/visws/cobalt.h with 97% similarity]
arch/x86/include/asm/visws/lithium.h [moved from include/asm-x86/visws/lithium.h with 92% similarity]
arch/x86/include/asm/visws/piix4.h [moved from include/asm-x86/visws/piix4.h with 96% similarity]
arch/x86/include/asm/visws/sgivw.h [moved from include/asm-x86/visws/sgivw.h with 100% similarity]
arch/x86/include/asm/vm86.h [moved from include/asm-x86/vm86.h with 98% similarity]
arch/x86/include/asm/vmi.h [moved from include/asm-x86/vmi.h with 100% similarity]
arch/x86/include/asm/vmi_time.h [moved from include/asm-x86/vmi_time.h with 97% similarity]
arch/x86/include/asm/voyager.h [moved from include/asm-x86/voyager.h with 100% similarity]
arch/x86/include/asm/vsyscall.h [moved from include/asm-x86/vsyscall.h with 92% similarity]
arch/x86/include/asm/xcr.h [moved from include/asm-x86/xcr.h with 100% similarity]
arch/x86/include/asm/xen/events.h [moved from include/asm-x86/xen/events.h with 78% similarity]
arch/x86/include/asm/xen/grant_table.h [new file with mode: 0644]
arch/x86/include/asm/xen/hypercall.h [moved from include/asm-x86/xen/hypercall.h with 99% similarity]
arch/x86/include/asm/xen/hypervisor.h [moved from include/asm-x86/xen/hypervisor.h with 96% similarity]
arch/x86/include/asm/xen/interface.h [moved from include/asm-x86/xen/interface.h with 98% similarity]
arch/x86/include/asm/xen/interface_32.h [moved from include/asm-x86/xen/interface_32.h with 95% similarity]
arch/x86/include/asm/xen/interface_64.h [moved from include/asm-x86/xen/interface_64.h with 97% similarity]
arch/x86/include/asm/xen/page.h [moved from include/asm-x86/xen/page.h with 98% similarity]
arch/x86/include/asm/xor.h [moved from include/asm-x86/xor.h with 100% similarity]
arch/x86/include/asm/xor_32.h [moved from include/asm-x86/xor_32.h with 99% similarity]
arch/x86/include/asm/xor_64.h [moved from include/asm-x86/xor_64.h with 98% similarity]
arch/x86/include/asm/xsave.h [moved from include/asm-x86/xsave.h with 100% similarity]
arch/x86/kernel/Makefile
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/acpi/sleep.c
arch/x86/kernel/amd_iommu_init.c
arch/x86/kernel/apic.c [moved from arch/x86/kernel/apic_32.c with 79% similarity]
arch/x86/kernel/apic_64.c [deleted file]
arch/x86/kernel/asm-offsets_64.c
arch/x86/kernel/bios_uv.c
arch/x86/kernel/cpu/Makefile
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
arch/x86/kernel/cpu/cpufreq/longhaul.c
arch/x86/kernel/cpu/cpufreq/powernow-k6.c
arch/x86/kernel/cpu/cpufreq/powernow-k7.c
arch/x86/kernel/cpu/cpufreq/powernow-k8.c
arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/cpu/mcheck/k7.c
arch/x86/kernel/cpu/mcheck/mce_32.c
arch/x86/kernel/cpu/mcheck/non-fatal.c
arch/x86/kernel/cpu/perfctr-watchdog.c
arch/x86/kernel/cpu/proc.c
arch/x86/kernel/dumpstack_32.c
arch/x86/kernel/early-quirks.c
arch/x86/kernel/efi.c
arch/x86/kernel/entry_32.S
arch/x86/kernel/entry_64.S
arch/x86/kernel/ftrace.c
arch/x86/kernel/genapic_flat_64.c
arch/x86/kernel/genx2apic_cluster.c
arch/x86/kernel/genx2apic_phys.c
arch/x86/kernel/genx2apic_uv_x.c
arch/x86/kernel/hpet.c
arch/x86/kernel/io_apic.c [moved from arch/x86/kernel/io_apic_64.c with 68% similarity]
arch/x86/kernel/io_apic_32.c [deleted file]
arch/x86/kernel/irq.c [new file with mode: 0644]
arch/x86/kernel/irq_32.c
arch/x86/kernel/irq_64.c
arch/x86/kernel/irqinit_32.c
arch/x86/kernel/irqinit_64.c
arch/x86/kernel/pci-dma.c
arch/x86/kernel/process_64.c
arch/x86/kernel/quirks.c
arch/x86/kernel/setup.c
arch/x86/kernel/setup_percpu.c
arch/x86/kernel/smpboot.c
arch/x86/kernel/syscall_64.c
arch/x86/kernel/tlb_uv.c
arch/x86/kernel/traps.c
arch/x86/kernel/uv_irq.c [new file with mode: 0644]
arch/x86/kernel/uv_sysfs.c [new file with mode: 0644]
arch/x86/kernel/visws_quirks.c
arch/x86/kernel/vmiclock_32.c
arch/x86/kernel/xsave.c
arch/x86/kvm/i8254.c
arch/x86/kvm/lapic.c
arch/x86/lguest/boot.c
arch/x86/mach-generic/bigsmp.c
arch/x86/mach-generic/es7000.c
arch/x86/mach-generic/numaq.c
arch/x86/mach-generic/summit.c
arch/x86/mach-voyager/voyager_smp.c
arch/x86/mm/memtest.c
arch/x86/mm/mmio-mod.c
arch/x86/mm/pageattr.c
arch/x86/mm/pf_in.c
arch/x86/mm/testmmiotrace.c
arch/x86/oprofile/backtrace.c
arch/x86/oprofile/nmi_int.c
arch/x86/oprofile/op_counter.h
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/irq.c
arch/x86/xen/irq.c
arch/x86/xen/spinlock.c
arch/xtensa/Kconfig
arch/xtensa/Makefile
arch/xtensa/kernel/irq.c
arch/xtensa/platforms/iss/network.c
block/bsg.c
block/cmd-filter.c
block/compat_ioctl.c
block/genhd.c
block/ioctl.c
block/scsi_ioctl.c
crypto/async_tx/async_tx.c
drivers/Kconfig
drivers/Makefile
drivers/acpi/Kconfig
drivers/acpi/Makefile
drivers/acpi/ac.c
drivers/acpi/acpi_memhotplug.c
drivers/acpi/asus_acpi.c
drivers/acpi/battery.c
drivers/acpi/bay.c [deleted file]
drivers/acpi/bus.c
drivers/acpi/button.c
drivers/acpi/cm_sbs.c
drivers/acpi/container.c
drivers/acpi/debug.c
drivers/acpi/dispatcher/dsmethod.c
drivers/acpi/dispatcher/dsmthdat.c
drivers/acpi/dispatcher/dsobject.c
drivers/acpi/dispatcher/dsopcode.c
drivers/acpi/dispatcher/dswexec.c
drivers/acpi/dock.c
drivers/acpi/ec.c
drivers/acpi/executer/exconfig.c
drivers/acpi/executer/exconvrt.c
drivers/acpi/executer/exdump.c
drivers/acpi/executer/exmisc.c
drivers/acpi/executer/exoparg1.c
drivers/acpi/executer/exoparg2.c
drivers/acpi/executer/exresnte.c
drivers/acpi/executer/exresolv.c
drivers/acpi/executer/exresop.c
drivers/acpi/executer/exstore.c
drivers/acpi/executer/exstoren.c
drivers/acpi/fan.c
drivers/acpi/hardware/hwsleep.c
drivers/acpi/namespace/Makefile
drivers/acpi/namespace/nsdump.c
drivers/acpi/namespace/nseval.c
drivers/acpi/namespace/nsnames.c
drivers/acpi/namespace/nspredef.c [new file with mode: 0644]
drivers/acpi/namespace/nssearch.c
drivers/acpi/namespace/nsxfeval.c
drivers/acpi/namespace/nsxfname.c
drivers/acpi/numa.c
drivers/acpi/osl.c
drivers/acpi/parser/psloop.c
drivers/acpi/parser/psparse.c
drivers/acpi/pci_link.c
drivers/acpi/pci_root.c
drivers/acpi/pci_slot.c
drivers/acpi/power.c
drivers/acpi/processor_core.c
drivers/acpi/processor_idle.c
drivers/acpi/processor_perflib.c
drivers/acpi/processor_throttling.c
drivers/acpi/reboot.c
drivers/acpi/resources/rscalc.c
drivers/acpi/resources/rscreate.c
drivers/acpi/sbs.c
drivers/acpi/sbshc.c
drivers/acpi/scan.c
drivers/acpi/sleep/main.c
drivers/acpi/system.c
drivers/acpi/tables/tbfadt.c
drivers/acpi/tables/tbinstal.c
drivers/acpi/thermal.c
drivers/acpi/toshiba_acpi.c
drivers/acpi/utilities/utalloc.c
drivers/acpi/utilities/utcopy.c
drivers/acpi/utilities/utdelete.c
drivers/acpi/utilities/utglobal.c
drivers/acpi/utilities/utmisc.c
drivers/acpi/utilities/utobject.c
drivers/acpi/utilities/utxface.c
drivers/acpi/utils.c
drivers/acpi/video.c
drivers/acpi/wmi.c
drivers/ata/libata-acpi.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/libata-scsi.c
drivers/ata/libata-sff.c
drivers/ata/libata.h
drivers/ata/sata_via.c
drivers/block/DAC960.c
drivers/block/amiflop.c
drivers/block/aoe/aoeblk.c
drivers/block/ataflop.c
drivers/block/brd.c
drivers/block/cciss.c
drivers/block/cpqarray.c
drivers/block/floppy.c
drivers/block/loop.c
drivers/block/nbd.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/swim3.c
drivers/block/ub.c
drivers/block/viodasd.c
drivers/block/virtio_blk.c
drivers/block/xd.c
drivers/block/xd.h
drivers/block/xen-blkfront.c
drivers/block/xsysace.c
drivers/block/z2ram.c
drivers/cdrom/cdrom.c
drivers/cdrom/gdrom.c
drivers/cdrom/viocd.c
drivers/char/agp/ali-agp.c
drivers/char/agp/amd64-agp.c
drivers/char/agp/ati-agp.c
drivers/char/agp/backend.c
drivers/char/agp/intel-agp.c
drivers/char/agp/nvidia-agp.c
drivers/char/agp/parisc-agp.c
drivers/char/agp/via-agp.c
drivers/char/hpet.c
drivers/char/hvc_console.c
drivers/char/hvc_console.h
drivers/char/hvc_irq.c
drivers/char/hvc_iseries.c
drivers/char/hvc_vio.c
drivers/char/hvc_xen.c
drivers/char/nvram.c
drivers/char/random.c
drivers/char/raw.c
drivers/char/sysrq.c
drivers/char/tty_port.c
drivers/char/virtio_console.c
drivers/char/vr41xx_giu.c
drivers/clocksource/acpi_pm.c
drivers/cpuidle/cpuidle.c
drivers/dma/Kconfig
drivers/dma/dmatest.c
drivers/dma/fsldma.c
drivers/dma/fsldma.h
drivers/dma/ioat_dma.c
drivers/gpio/Kconfig
drivers/gpio/Makefile
drivers/gpio/gpiolib.c
drivers/gpio/twl4030-gpio.c [new file with mode: 0644]
drivers/gpu/drm/Kconfig
drivers/gpu/drm/drm_drawable.c
drivers/gpu/drm/drm_ioc32.c
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/drm_lock.c
drivers/gpu/drm/drm_proc.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_proc.c
drivers/gpu/drm/i915/i915_irq.c
drivers/i2c/algos/i2c-algo-pcf.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-amd756.c
drivers/i2c/busses/i2c-cpm.c
drivers/i2c/busses/i2c-elektor.c
drivers/i2c/busses/i2c-hydra.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-viapro.c
drivers/i2c/chips/Kconfig
drivers/i2c/chips/Makefile
drivers/i2c/i2c-core.c
drivers/ide/Kconfig
drivers/ide/Makefile
drivers/ide/aec62xx.c [moved from drivers/ide/pci/aec62xx.c with 100% similarity]
drivers/ide/ali14xx.c [moved from drivers/ide/legacy/ali14xx.c with 100% similarity]
drivers/ide/alim15x3.c [moved from drivers/ide/pci/alim15x3.c with 100% similarity]
drivers/ide/amd74xx.c [moved from drivers/ide/pci/amd74xx.c with 100% similarity]
drivers/ide/arm/Makefile [deleted file]
drivers/ide/atiixp.c [moved from drivers/ide/pci/atiixp.c with 100% similarity]
drivers/ide/au1xxx-ide.c [moved from drivers/ide/mips/au1xxx-ide.c with 100% similarity]
drivers/ide/buddha.c [moved from drivers/ide/legacy/buddha.c with 100% similarity]
drivers/ide/cmd640.c [moved from drivers/ide/pci/cmd640.c with 100% similarity]
drivers/ide/cmd64x.c [moved from drivers/ide/pci/cmd64x.c with 100% similarity]
drivers/ide/cs5520.c [moved from drivers/ide/pci/cs5520.c with 100% similarity]
drivers/ide/cs5530.c [moved from drivers/ide/pci/cs5530.c with 100% similarity]
drivers/ide/cs5535.c [moved from drivers/ide/pci/cs5535.c with 100% similarity]
drivers/ide/cy82c693.c [moved from drivers/ide/pci/cy82c693.c with 100% similarity]
drivers/ide/delkin_cb.c [moved from drivers/ide/pci/delkin_cb.c with 81% similarity]
drivers/ide/dtc2278.c [moved from drivers/ide/legacy/dtc2278.c with 100% similarity]
drivers/ide/falconide.c [moved from drivers/ide/legacy/falconide.c with 100% similarity]
drivers/ide/gayle.c [moved from drivers/ide/legacy/gayle.c with 100% similarity]
drivers/ide/generic.c [moved from drivers/ide/pci/generic.c with 100% similarity]
drivers/ide/h8300/Makefile [deleted file]
drivers/ide/hpt366.c [moved from drivers/ide/pci/hpt366.c with 98% similarity]
drivers/ide/ht6560b.c [moved from drivers/ide/legacy/ht6560b.c with 100% similarity]
drivers/ide/icside.c [moved from drivers/ide/arm/icside.c with 100% similarity]
drivers/ide/ide-4drives.c [moved from drivers/ide/legacy/ide-4drives.c with 100% similarity]
drivers/ide/ide-atapi.c
drivers/ide/ide-cd.c
drivers/ide/ide-cd_ioctl.c
drivers/ide/ide-cs.c [moved from drivers/ide/legacy/ide-cs.c with 100% similarity]
drivers/ide/ide-disk.c
drivers/ide/ide-disk.h
drivers/ide/ide-disk_ioctl.c
drivers/ide/ide-disk_proc.c
drivers/ide/ide-dma-sff.c
drivers/ide/ide-floppy.c
drivers/ide/ide-floppy.h
drivers/ide/ide-floppy_ioctl.c
drivers/ide/ide-floppy_proc.c
drivers/ide/ide-gd.c [new file with mode: 0644]
drivers/ide/ide-gd.h [new file with mode: 0644]
drivers/ide/ide-h8300.c [moved from drivers/ide/h8300/ide-h8300.c with 100% similarity]
drivers/ide/ide-ioctls.c
drivers/ide/ide-iops.c
drivers/ide/ide-probe.c
drivers/ide/ide-proc.c
drivers/ide/ide-tape.c
drivers/ide/ide_arm.c [moved from drivers/ide/arm/ide_arm.c with 100% similarity]
drivers/ide/ide_platform.c [moved from drivers/ide/legacy/ide_platform.c with 100% similarity]
drivers/ide/it8213.c [moved from drivers/ide/pci/it8213.c with 100% similarity]
drivers/ide/it821x.c [moved from drivers/ide/pci/it821x.c with 100% similarity]
drivers/ide/jmicron.c [moved from drivers/ide/pci/jmicron.c with 100% similarity]
drivers/ide/legacy/Makefile [deleted file]
drivers/ide/macide.c [moved from drivers/ide/legacy/macide.c with 100% similarity]
drivers/ide/mips/Makefile [deleted file]
drivers/ide/ns87415.c [moved from drivers/ide/pci/ns87415.c with 100% similarity]
drivers/ide/opti621.c [moved from drivers/ide/pci/opti621.c with 100% similarity]
drivers/ide/palm_bk3710.c [moved from drivers/ide/arm/palm_bk3710.c with 100% similarity]
drivers/ide/pci/Makefile [deleted file]
drivers/ide/pci/hpt34x.c [deleted file]
drivers/ide/pdc202xx_new.c [moved from drivers/ide/pci/pdc202xx_new.c with 100% similarity]
drivers/ide/pdc202xx_old.c [moved from drivers/ide/pci/pdc202xx_old.c with 100% similarity]
drivers/ide/piix.c [moved from drivers/ide/pci/piix.c with 100% similarity]
drivers/ide/pmac.c [moved from drivers/ide/ppc/pmac.c with 100% similarity]
drivers/ide/ppc/Makefile [deleted file]
drivers/ide/q40ide.c [moved from drivers/ide/legacy/q40ide.c with 100% similarity]
drivers/ide/qd65xx.c [moved from drivers/ide/legacy/qd65xx.c with 100% similarity]
drivers/ide/qd65xx.h [moved from drivers/ide/legacy/qd65xx.h with 100% similarity]
drivers/ide/rapide.c [moved from drivers/ide/arm/rapide.c with 100% similarity]
drivers/ide/rz1000.c [moved from drivers/ide/pci/rz1000.c with 100% similarity]
drivers/ide/sc1200.c [moved from drivers/ide/pci/sc1200.c with 100% similarity]
drivers/ide/scc_pata.c [moved from drivers/ide/pci/scc_pata.c with 99% similarity]
drivers/ide/serverworks.c [moved from drivers/ide/pci/serverworks.c with 100% similarity]
drivers/ide/sgiioc4.c [moved from drivers/ide/pci/sgiioc4.c with 93% similarity]
drivers/ide/siimage.c [moved from drivers/ide/pci/siimage.c with 100% similarity]
drivers/ide/sis5513.c [moved from drivers/ide/pci/sis5513.c with 100% similarity]
drivers/ide/sl82c105.c [moved from drivers/ide/pci/sl82c105.c with 100% similarity]
drivers/ide/slc90e66.c [moved from drivers/ide/pci/slc90e66.c with 100% similarity]
drivers/ide/tc86c001.c [moved from drivers/ide/pci/tc86c001.c with 100% similarity]
drivers/ide/triflex.c [moved from drivers/ide/pci/triflex.c with 100% similarity]
drivers/ide/trm290.c [moved from drivers/ide/pci/trm290.c with 100% similarity]
drivers/ide/umc8672.c [moved from drivers/ide/legacy/umc8672.c with 100% similarity]
drivers/ide/via82cxxx.c [moved from drivers/ide/pci/via82cxxx.c with 100% similarity]
drivers/idle/Kconfig [new file with mode: 0644]
drivers/idle/Makefile [new file with mode: 0644]
drivers/idle/i7300_idle.c [new file with mode: 0644]
drivers/infiniband/core/mad.c
drivers/infiniband/core/ucma.c
drivers/infiniband/hw/cxgb3/iwch_cm.c
drivers/infiniband/hw/ehca/ehca_classes.h
drivers/infiniband/hw/ehca/ehca_cq.c
drivers/infiniband/hw/ehca/ehca_main.c
drivers/infiniband/hw/ehca/ehca_qp.c
drivers/infiniband/hw/mlx4/mad.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx4/mlx4_ib.h
drivers/infiniband/hw/mlx4/qp.c
drivers/infiniband/ulp/ipoib/ipoib.h
drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_vlan.c
drivers/input/touchscreen/Kconfig
drivers/leds/Kconfig
drivers/md/Makefile
drivers/md/dm-crypt.c
drivers/md/dm-delay.c
drivers/md/dm-exception-store.c
drivers/md/dm-io.c
drivers/md/dm-ioctl.c
drivers/md/dm-kcopyd.c
drivers/md/dm-linear.c
drivers/md/dm-log.c
drivers/md/dm-mpath.c
drivers/md/dm-path-selector.c
drivers/md/dm-raid1.c
drivers/md/dm-region-hash.c [new file with mode: 0644]
drivers/md/dm-round-robin.c
drivers/md/dm-snap.c
drivers/md/dm-snap.h
drivers/md/dm-stripe.c
drivers/md/dm-table.c
drivers/md/dm-zero.c
drivers/md/dm.c
drivers/md/dm.h
drivers/md/md.c
drivers/media/common/saa7146_fops.c
drivers/media/common/saa7146_video.c
drivers/media/dvb/frontends/s5h1411.c
drivers/media/dvb/frontends/s5h1411.h
drivers/media/radio/dsbr100.c
drivers/media/radio/radio-mr800.c
drivers/media/video/arv.c
drivers/media/video/bt8xx/bttv-driver.c
drivers/media/video/c-qcam.c
drivers/media/video/cafe_ccic.c
drivers/media/video/cpia.c
drivers/media/video/cpia2/cpia2_v4l.c
drivers/media/video/cx18/cx18-driver.c
drivers/media/video/cx18/cx18-io.h
drivers/media/video/cx18/cx18-streams.c
drivers/media/video/cx23885/cx23885-417.c
drivers/media/video/cx23885/cx23885-video.c
drivers/media/video/cx88/cx88-blackbird.c
drivers/media/video/cx88/cx88-cards.c
drivers/media/video/cx88/cx88-dvb.c
drivers/media/video/cx88/cx88-i2c.c
drivers/media/video/cx88/cx88-mpeg.c
drivers/media/video/cx88/cx88-video.c
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/et61x251/et61x251_core.c
drivers/media/video/ivtv/ivtv-driver.c
drivers/media/video/ivtv/ivtv-i2c.c
drivers/media/video/ivtv/ivtv-ioctl.c
drivers/media/video/ivtv/ivtv-ioctl.h
drivers/media/video/ivtv/ivtv-streams.c
drivers/media/video/ivtv/ivtvfb.c
drivers/media/video/pvrusb2/pvrusb2-encoder.c
drivers/media/video/pvrusb2/pvrusb2-hdw.c
drivers/media/video/pvrusb2/pvrusb2-v4l2.c
drivers/media/video/pwc/pwc-if.c
drivers/media/video/saa7134/saa7134-core.c
drivers/media/video/saa7134/saa7134-empress.c
drivers/media/video/se401.c
drivers/media/video/sn9c102/sn9c102_core.c
drivers/media/video/stk-webcam.c
drivers/media/video/stv680.c
drivers/media/video/usbvideo/usbvideo.c
drivers/media/video/usbvideo/vicam.c
drivers/media/video/usbvision/usbvision-i2c.c
drivers/media/video/usbvision/usbvision-video.c
drivers/media/video/uvc/uvc_v4l2.c
drivers/media/video/v4l1-compat.c
drivers/media/video/v4l2-int-device.c
drivers/media/video/v4l2-ioctl.c
drivers/media/video/videobuf-dvb.c
drivers/media/video/vivi.c
drivers/media/video/w9968cf.c
drivers/media/video/zc0301/zc0301_core.c
drivers/media/video/zr364xx.c
drivers/memstick/core/mspro_block.c
drivers/message/fusion/mptscsih.c
drivers/message/i2o/i2o_block.c
drivers/mfd/Makefile
drivers/mfd/asic3.c
drivers/mfd/htc-egpio.c
drivers/mfd/sm501.c
drivers/mfd/twl4030-core.c
drivers/mfd/twl4030-irq.c [new file with mode: 0644]
drivers/mfd/wm8350-core.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/acer-wmi.c
drivers/misc/asus-laptop.c
drivers/misc/eeepc-laptop.c
drivers/misc/fujitsu-laptop.c
drivers/misc/intel_menlow.c
drivers/misc/panasonic-laptop.c [new file with mode: 0644]
drivers/misc/sony-laptop.c
drivers/misc/thinkpad_acpi.c
drivers/mmc/card/block.c
drivers/mtd/devices/block2mtd.c
drivers/mtd/mtd_blkdevs.c
drivers/mtd/mtdchar.c
drivers/net/3c59x.c
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/fec_mpc52xx_phy.c
drivers/net/hamradio/baycom_ser_fdx.c
drivers/net/hamradio/scc.c
drivers/net/ibm_newemac/core.c
drivers/net/ibm_newemac/mal.c
drivers/net/mlx4/Makefile
drivers/net/mlx4/alloc.c
drivers/net/mlx4/cq.c
drivers/net/mlx4/en_cq.c [new file with mode: 0644]
drivers/net/mlx4/en_main.c [new file with mode: 0644]
drivers/net/mlx4/en_netdev.c [new file with mode: 0644]
drivers/net/mlx4/en_params.c [new file with mode: 0644]
drivers/net/mlx4/en_port.c [new file with mode: 0644]
drivers/net/mlx4/en_port.h [new file with mode: 0644]
drivers/net/mlx4/en_resources.c [new file with mode: 0644]
drivers/net/mlx4/en_rx.c [new file with mode: 0644]
drivers/net/mlx4/en_tx.c [new file with mode: 0644]
drivers/net/mlx4/eq.c
drivers/net/mlx4/fw.c
drivers/net/mlx4/fw.h
drivers/net/mlx4/main.c
drivers/net/mlx4/mcg.c
drivers/net/mlx4/mlx4.h
drivers/net/mlx4/mlx4_en.h [new file with mode: 0644]
drivers/net/mlx4/mr.c
drivers/net/mlx4/pd.c
drivers/net/mlx4/port.c [new file with mode: 0644]
drivers/net/mlx4/qp.c
drivers/net/mlx4/srq.c
drivers/net/usb/pegasus.c
drivers/net/wan/sbni.c
drivers/net/xtsonic.c [new file with mode: 0644]
drivers/of/of_i2c.c
drivers/of/of_spi.c
drivers/oprofile/buffer_sync.c
drivers/oprofile/buffer_sync.h
drivers/oprofile/cpu_buffer.c
drivers/oprofile/cpu_buffer.h
drivers/oprofile/event_buffer.c
drivers/oprofile/event_buffer.h
drivers/oprofile/oprof.c
drivers/oprofile/oprof.h
drivers/oprofile/oprofile_files.c
drivers/oprofile/oprofile_stats.c
drivers/oprofile/oprofile_stats.h
drivers/oprofile/oprofilefs.c
drivers/oprofile/timer_int.c
drivers/parisc/ccio-dma.c
drivers/parisc/dino.c
drivers/parisc/eisa.c
drivers/parisc/eisa_eeprom.c
drivers/parisc/gsc.c
drivers/parisc/iosapic.c
drivers/parisc/superio.c
drivers/parport/parport_pc.c
drivers/pci/bus.c
drivers/pci/dmar.c
drivers/pci/hotplug/acpiphp.h
drivers/pci/hotplug/acpiphp_core.c
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/hotplug/acpiphp_ibm.c
drivers/pci/hotplug/cpci_hotplug.h
drivers/pci/hotplug/cpci_hotplug_core.c
drivers/pci/hotplug/cpci_hotplug_pci.c
drivers/pci/hotplug/cpqphp.h
drivers/pci/hotplug/cpqphp_core.c
drivers/pci/hotplug/cpqphp_ctrl.c
drivers/pci/hotplug/fakephp.c
drivers/pci/hotplug/ibmphp.h
drivers/pci/hotplug/ibmphp_ebda.c
drivers/pci/hotplug/pci_hotplug_core.c
drivers/pci/hotplug/pciehp.h
drivers/pci/hotplug/pciehp_core.c
drivers/pci/hotplug/pciehp_ctrl.c
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/hotplug/pciehp_pci.c
drivers/pci/hotplug/rpaphp.h
drivers/pci/hotplug/rpaphp_core.c
drivers/pci/hotplug/rpaphp_pci.c
drivers/pci/hotplug/rpaphp_slot.c
drivers/pci/hotplug/sgi_hotplug.c
drivers/pci/hotplug/shpchp.h
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/msi.c
drivers/pci/pci-acpi.c
drivers/pci/pci-driver.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/pcie/aer/aerdrv.c
drivers/pci/pcie/aer/aerdrv_core.c
drivers/pci/pcie/aspm.c
drivers/pci/pcie/portdrv.h
drivers/pci/pcie/portdrv_core.c
drivers/pci/pcie/portdrv_pci.c
drivers/pci/probe.c
drivers/pci/quirks.c
drivers/pci/remove.c
drivers/pci/search.c
drivers/pci/setup-bus.c
drivers/pci/setup-res.c
drivers/pci/slot.c
drivers/pcmcia/Makefile
drivers/pcmcia/at91_cf.c
drivers/pcmcia/hd64465_ss.c
drivers/pcmcia/vrc4171_card.c
drivers/pnp/Kconfig
drivers/pnp/Makefile
drivers/pnp/base.h
drivers/pnp/core.c
drivers/pnp/driver.c
drivers/pnp/isapnp/Makefile
drivers/pnp/isapnp/core.c
drivers/pnp/manager.c
drivers/pnp/pnpacpi/Makefile
drivers/pnp/pnpacpi/core.c
drivers/pnp/pnpacpi/rsparser.c
drivers/pnp/pnpbios/Makefile
drivers/pnp/pnpbios/core.c
drivers/pnp/pnpbios/rsparser.c
drivers/pnp/quirks.c
drivers/pnp/resource.c
drivers/pnp/support.c
drivers/rtc/Kconfig
drivers/rtc/Makefile
drivers/rtc/rtc-parisc.c [new file with mode: 0644]
drivers/rtc/rtc-twl4030.c [new file with mode: 0644]
drivers/rtc/rtc-vr41xx.c
drivers/s390/block/dasd.c
drivers/s390/block/dasd_genhd.c
drivers/s390/block/dasd_int.h
drivers/s390/block/dasd_ioctl.c
drivers/s390/block/dcssblk.c
drivers/s390/char/tape_block.c
drivers/s390/crypto/ap_bus.c
drivers/scsi/3w-9xxx.c
drivers/scsi/3w-xxxx.c
drivers/scsi/aha152x.c
drivers/scsi/aic7xxx/aic79xx.reg
drivers/scsi/aic7xxx/aic79xx_core.c
drivers/scsi/aic7xxx/aic79xx_pci.c
drivers/scsi/aic7xxx/aic79xx_reg.h_shipped
drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped
drivers/scsi/aic7xxx/aic7xxx.reg
drivers/scsi/aic7xxx/aic7xxx_core.c
drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped
drivers/scsi/aic7xxx/aic7xxx_reg_print.c_shipped
drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
drivers/scsi/aic7xxx/aicasm/aicasm_scan.l
drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c
drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h
drivers/scsi/device_handler/scsi_dh_rdac.c
drivers/scsi/ide-scsi.c
drivers/scsi/ipr.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/scsi_ioctl.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_netlink.c
drivers/scsi/sd.c
drivers/scsi/sg.c
drivers/scsi/sr.c
drivers/scsi/st.c
drivers/scsi/sun3x_esp.c
drivers/serial/68328serial.c
drivers/serial/8250.c
drivers/serial/8250_pci.c
drivers/serial/Kconfig
drivers/serial/amba-pl010.c
drivers/serial/amba-pl011.c
drivers/serial/cpm_uart/cpm_uart_core.c
drivers/serial/m32r_sio.c
drivers/serial/serial_core.c
drivers/serial/serial_lh7a40x.c
drivers/serial/sh-sci.c
drivers/serial/ucc_uart.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/at76_usb/at76_usb.c
drivers/staging/echo/bit_operations.h
drivers/staging/echo/echo.c
drivers/staging/echo/echo.h
drivers/staging/echo/fir.h
drivers/staging/echo/mmx.h
drivers/staging/echo/oslec.h [new file with mode: 0644]
drivers/staging/et131x/et1310_phy.c
drivers/staging/et131x/et131x_debug.c
drivers/staging/et131x/et131x_initpci.c
drivers/staging/go7007/go7007-driver.c
drivers/staging/go7007/go7007-fw.c
drivers/staging/go7007/go7007-i2c.c
drivers/staging/go7007/go7007-usb.c
drivers/staging/go7007/snd-go7007.c
drivers/staging/go7007/wis-ov7640.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/go7007/wis-uda1342.c
drivers/staging/me4000/me4000.c
drivers/staging/me4000/me4000.h
drivers/staging/poch/Kconfig [new file with mode: 0644]
drivers/staging/poch/Makefile [new file with mode: 0644]
drivers/staging/poch/README [new file with mode: 0644]
drivers/staging/poch/poch.c [new file with mode: 0644]
drivers/staging/poch/poch.h [new file with mode: 0644]
drivers/staging/slicoss/slicoss.c
drivers/staging/sxg/README
drivers/staging/sxg/sxg.c
drivers/staging/sxg/sxg_os.h
drivers/staging/sxg/sxgdbg.h
drivers/staging/sxg/sxghif.h
drivers/staging/sxg/sxghw.h
drivers/staging/sxg/sxgphycode.h
drivers/staging/usbip/usbip_common.c
drivers/staging/usbip/vhci_rx.c
drivers/staging/winbond/Kconfig
drivers/staging/winbond/README
drivers/staging/winbond/bss_f.h
drivers/staging/winbond/ds_tkip.h
drivers/staging/winbond/linux/common.h
drivers/staging/winbond/linux/wb35reg.c
drivers/staging/winbond/linux/wb35reg_f.h
drivers/staging/winbond/linux/wb35reg_s.h
drivers/staging/winbond/linux/wb35rx.c
drivers/staging/winbond/linux/wb35rx_s.h
drivers/staging/winbond/linux/wb35tx.c
drivers/staging/winbond/linux/wb35tx_f.h
drivers/staging/winbond/linux/wbusb.c
drivers/staging/winbond/mds.c
drivers/staging/winbond/mds_f.h
drivers/staging/winbond/mds_s.h
drivers/staging/winbond/mlme_s.h
drivers/staging/winbond/mlmetxrx.c
drivers/staging/winbond/mlmetxrx_f.h
drivers/staging/winbond/reg.c
drivers/staging/winbond/sme_api.c
drivers/staging/winbond/sme_api.h
drivers/staging/winbond/wbhal.c
drivers/staging/winbond/wbhal_f.h
drivers/staging/winbond/wbhal_s.h
drivers/staging/winbond/wblinux.c
drivers/staging/winbond/wblinux_s.h
drivers/staging/wlan-ng/Kconfig
drivers/staging/wlan-ng/hfa384x.h
drivers/staging/wlan-ng/p80211wep.c
drivers/staging/wlan-ng/prism2mib.c
drivers/staging/wlan-ng/wlan_compat.h
drivers/uio/uio.c
drivers/usb/Kconfig
drivers/usb/Makefile
drivers/usb/atm/speedtch.c
drivers/usb/class/cdc-acm.c
drivers/usb/class/cdc-wdm.c
drivers/usb/core/driver.c
drivers/usb/core/hub.c
drivers/usb/gadget/config.c
drivers/usb/gadget/pxa27x_udc.c
drivers/usb/gadget/s3c2410_udc.c
drivers/usb/host/Kconfig
drivers/usb/host/Makefile
drivers/usb/host/ehci-hcd.c
drivers/usb/host/hwa-hc.c [new file with mode: 0644]
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-tmio.c [new file with mode: 0644]
drivers/usb/host/whci/Kbuild [new file with mode: 0644]
drivers/usb/host/whci/asl.c [new file with mode: 0644]
drivers/usb/host/whci/hcd.c [new file with mode: 0644]
drivers/usb/host/whci/hw.c [new file with mode: 0644]
drivers/usb/host/whci/init.c [new file with mode: 0644]
drivers/usb/host/whci/int.c [new file with mode: 0644]
drivers/usb/host/whci/pzl.c [new file with mode: 0644]
drivers/usb/host/whci/qset.c [new file with mode: 0644]
drivers/usb/host/whci/whcd.h [new file with mode: 0644]
drivers/usb/host/whci/whci-hc.h [new file with mode: 0644]
drivers/usb/host/whci/wusb.c [new file with mode: 0644]
drivers/usb/misc/usbtest.c
drivers/usb/serial/option.c
drivers/usb/storage/initializers.c
drivers/usb/storage/unusual_devs.h
drivers/usb/wusbcore/Kconfig [new file with mode: 0644]
drivers/usb/wusbcore/Makefile [new file with mode: 0644]
drivers/usb/wusbcore/cbaf.c [new file with mode: 0644]
drivers/usb/wusbcore/crypto.c [new file with mode: 0644]
drivers/usb/wusbcore/dev-sysfs.c [new file with mode: 0644]
drivers/usb/wusbcore/devconnect.c [new file with mode: 0644]
drivers/usb/wusbcore/mmc.c [new file with mode: 0644]
drivers/usb/wusbcore/pal.c [new file with mode: 0644]
drivers/usb/wusbcore/reservation.c [new file with mode: 0644]
drivers/usb/wusbcore/rh.c [new file with mode: 0644]
drivers/usb/wusbcore/security.c [new file with mode: 0644]
drivers/usb/wusbcore/wa-hc.c [new file with mode: 0644]
drivers/usb/wusbcore/wa-hc.h [new file with mode: 0644]
drivers/usb/wusbcore/wa-nep.c [new file with mode: 0644]
drivers/usb/wusbcore/wa-rpipe.c [new file with mode: 0644]
drivers/usb/wusbcore/wa-xfer.c [new file with mode: 0644]
drivers/usb/wusbcore/wusbhc.c [new file with mode: 0644]
drivers/usb/wusbcore/wusbhc.h [new file with mode: 0644]
drivers/uwb/Kconfig [new file with mode: 0644]
drivers/uwb/Makefile [new file with mode: 0644]
drivers/uwb/address.c [new file with mode: 0644]
drivers/uwb/beacon.c [new file with mode: 0644]
drivers/uwb/driver.c [new file with mode: 0644]
drivers/uwb/drp-avail.c [new file with mode: 0644]
drivers/uwb/drp-ie.c [new file with mode: 0644]
drivers/uwb/drp.c [new file with mode: 0644]
drivers/uwb/est.c [new file with mode: 0644]
drivers/uwb/hwa-rc.c [new file with mode: 0644]
drivers/uwb/i1480/Makefile [new file with mode: 0644]
drivers/uwb/i1480/dfu/Makefile [new file with mode: 0644]
drivers/uwb/i1480/dfu/dfu.c [new file with mode: 0644]
drivers/uwb/i1480/dfu/i1480-dfu.h [new file with mode: 0644]
drivers/uwb/i1480/dfu/mac.c [new file with mode: 0644]
drivers/uwb/i1480/dfu/phy.c [new file with mode: 0644]
drivers/uwb/i1480/dfu/usb.c [new file with mode: 0644]
drivers/uwb/i1480/i1480-est.c [new file with mode: 0644]
drivers/uwb/i1480/i1480-wlp.h [new file with mode: 0644]
drivers/uwb/i1480/i1480u-wlp/Makefile [new file with mode: 0644]
drivers/uwb/i1480/i1480u-wlp/i1480u-wlp.h [new file with mode: 0644]
drivers/uwb/i1480/i1480u-wlp/lc.c [new file with mode: 0644]
drivers/uwb/i1480/i1480u-wlp/netdev.c [new file with mode: 0644]
drivers/uwb/i1480/i1480u-wlp/rx.c [new file with mode: 0644]
drivers/uwb/i1480/i1480u-wlp/sysfs.c [new file with mode: 0644]
drivers/uwb/i1480/i1480u-wlp/tx.c [new file with mode: 0644]
drivers/uwb/ie.c [new file with mode: 0644]
drivers/uwb/lc-dev.c [new file with mode: 0644]
drivers/uwb/lc-rc.c [new file with mode: 0644]
drivers/uwb/neh.c [new file with mode: 0644]
drivers/uwb/pal.c [new file with mode: 0644]
drivers/uwb/reset.c [new file with mode: 0644]
drivers/uwb/rsv.c [new file with mode: 0644]
drivers/uwb/scan.c [new file with mode: 0644]
drivers/uwb/umc-bus.c [new file with mode: 0644]
drivers/uwb/umc-dev.c [new file with mode: 0644]
drivers/uwb/umc-drv.c [new file with mode: 0644]
drivers/uwb/uwb-debug.c [new file with mode: 0644]
drivers/uwb/uwb-internal.h [new file with mode: 0644]
drivers/uwb/uwbd.c [new file with mode: 0644]
drivers/uwb/whc-rc.c [new file with mode: 0644]
drivers/uwb/whci.c [new file with mode: 0644]
drivers/uwb/wlp/Makefile [new file with mode: 0644]
drivers/uwb/wlp/driver.c [new file with mode: 0644]
drivers/uwb/wlp/eda.c [new file with mode: 0644]
drivers/uwb/wlp/messages.c [new file with mode: 0644]
drivers/uwb/wlp/sysfs.c [new file with mode: 0644]
drivers/uwb/wlp/txrx.c [new file with mode: 0644]
drivers/uwb/wlp/wlp-internal.h [new file with mode: 0644]
drivers/uwb/wlp/wlp-lc.c [new file with mode: 0644]
drivers/uwb/wlp/wss-lc.c [new file with mode: 0644]
drivers/video/backlight/Kconfig
drivers/video/backlight/Makefile
drivers/video/backlight/da903x.c [new file with mode: 0644]
drivers/video/backlight/kb3886_bl.c [new file with mode: 0644]
drivers/video/backlight/tosa_bl.c [new file with mode: 0644]
drivers/video/backlight/tosa_lcd.c [new file with mode: 0644]
drivers/watchdog/ib700wdt.c
drivers/watchdog/w83697ug_wdt.c
drivers/xen/cpu_hotplug.c
drivers/xen/events.c
fs/9p/vfs_file.c
fs/Kconfig
fs/afs/dir.c
fs/attr.c
fs/bfs/dir.c
fs/binfmt_elf.c
fs/binfmt_elf_fdpic.c
fs/block_dev.c
fs/char_dev.c
fs/cifs/CHANGES
fs/cifs/README
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifsglob.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/inode.c
fs/cifs/readdir.c
fs/coda/dir.c
fs/coda/pioctl.c
fs/compat.c
fs/configfs/symlink.c
fs/dcache.c
fs/dquot.c
fs/ecryptfs/main.c
fs/efs/namei.c
fs/exportfs/expfs.c
fs/ext2/dir.c
fs/ext2/ext2.h
fs/ext2/namei.c
fs/ext2/xip.c
fs/ext3/ioctl.c
fs/ext3/namei.c
fs/ext3/super.c
fs/ext4/namei.c
fs/ext4/super.c
fs/fat/dir.c
fs/fat/inode.c
fs/fifo.c
fs/file_table.c
fs/filesystems.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/fuse/inode.c
fs/gfs2/ops_export.c
fs/gfs2/ops_inode.c
fs/hfs/inode.c
fs/hfsplus/inode.c
fs/hostfs/hostfs_kern.c
fs/hpfs/file.c
fs/hpfs/hpfs_fn.h
fs/hpfs/inode.c
fs/hpfs/namei.c
fs/isofs/export.c
fs/jbd/checkpoint.c
fs/jbd/journal.c
fs/jbd/recovery.c
fs/jffs2/dir.c
fs/jffs2/super.c
fs/jfs/jfs_logmgr.c
fs/jfs/namei.c
fs/libfs.c
fs/locks.c
fs/namei.c
fs/namespace.c
fs/nfs/dir.c
fs/nfs/getroot.c
fs/nfsd/export.c
fs/nfsd/nfs4recover.c
fs/nfsd/nfs4state.c
fs/nfsd/nfsctl.c
fs/nfsd/nfssvc.c
fs/nfsd/vfs.c
fs/ntfs/namei.c
fs/ocfs2/cluster/heartbeat.c
fs/ocfs2/export.c
fs/omfs/dir.c
fs/open.c
fs/openpromfs/inode.c
fs/partitions/check.c
fs/proc/Makefile
fs/proc/array.c
fs/proc/base.c
fs/proc/cmdline.c [new file with mode: 0644]
fs/proc/cpuinfo.c [new file with mode: 0644]
fs/proc/devices.c [new file with mode: 0644]
fs/proc/generic.c
fs/proc/inode.c
fs/proc/internal.h
fs/proc/interrupts.c [new file with mode: 0644]
fs/proc/kcore.c
fs/proc/kmsg.c
fs/proc/loadavg.c [new file with mode: 0644]
fs/proc/meminfo.c [new file with mode: 0644]
fs/proc/page.c [new file with mode: 0644]
fs/proc/proc_devtree.c
fs/proc/proc_misc.c [deleted file]
fs/proc/proc_sysctl.c
fs/proc/root.c
fs/proc/stat.c [new file with mode: 0644]
fs/proc/task_mmu.c
fs/proc/uptime.c [new file with mode: 0644]
fs/proc/version.c [new file with mode: 0644]
fs/proc/vmcore.c
fs/read_write.c
fs/readdir.c
fs/reiserfs/file.c
fs/reiserfs/inode.c
fs/reiserfs/journal.c
fs/reiserfs/namei.c
fs/reiserfs/super.c
fs/select.c
fs/super.c
fs/sysfs/dir.c
fs/timerfd.c
fs/udf/namei.c
fs/ufs/dir.c
fs/xfs/linux-2.6/xfs_export.c
fs/xfs/linux-2.6/xfs_file.c
fs/xfs/linux-2.6/xfs_ioctl.c
fs/xfs/linux-2.6/xfs_super.c
include/acpi/acconfig.h
include/acpi/acdebug.h
include/acpi/acdisasm.h
include/acpi/acdispat.h
include/acpi/acexcep.h
include/acpi/aclocal.h
include/acpi/acmacros.h
include/acpi/acnamesp.h
include/acpi/acobject.h
include/acpi/acoutput.h
include/acpi/acpi_bus.h
include/acpi/acpi_drivers.h
include/acpi/acpiosxf.h
include/acpi/acpredef.h [new file with mode: 0644]
include/acpi/actbl1.h
include/acpi/actypes.h
include/acpi/acutils.h
include/acpi/platform/aclinux.h
include/asm-frv/ide.h
include/asm-generic/bug.h
include/asm-generic/mutex-dec.h
include/asm-generic/mutex-xchg.h
include/asm-generic/vmlinux.lds.h
include/asm-m68k/ide.h
include/asm-m68k/machdep.h
include/asm-um/a.out.h [deleted file]
include/asm-um/alternative-asm.h [deleted file]
include/asm-um/alternative.h [deleted file]
include/asm-um/asm.h [deleted file]
include/asm-um/atomic.h [deleted file]
include/asm-um/bitops.h [deleted file]
include/asm-um/boot.h [deleted file]
include/asm-um/bug.h [deleted file]
include/asm-um/byteorder.h [deleted file]
include/asm-um/cacheflush.h [deleted file]
include/asm-um/calling.h [deleted file]
include/asm-um/cmpxchg.h [deleted file]
include/asm-um/cobalt.h [deleted file]
include/asm-um/cpufeature.h [deleted file]
include/asm-um/div64.h [deleted file]
include/asm-um/dwarf2.h [deleted file]
include/asm-um/errno.h [deleted file]
include/asm-um/fcntl.h [deleted file]
include/asm-um/floppy.h [deleted file]
include/asm-um/frame.h [deleted file]
include/asm-um/highmem.h [deleted file]
include/asm-um/ide.h [deleted file]
include/asm-um/ioctl.h [deleted file]
include/asm-um/ioctls.h [deleted file]
include/asm-um/ipcbuf.h [deleted file]
include/asm-um/linkage.h [deleted file]
include/asm-um/local.h [deleted file]
include/asm-um/locks.h [deleted file]
include/asm-um/mca_dma.h [deleted file]
include/asm-um/mman.h [deleted file]
include/asm-um/module-generic.h [deleted file]
include/asm-um/msgbuf.h [deleted file]
include/asm-um/mtrr.h [deleted file]
include/asm-um/nops.h [deleted file]
include/asm-um/paravirt.h [deleted file]
include/asm-um/percpu.h [deleted file]
include/asm-um/poll.h [deleted file]
include/asm-um/posix_types.h [deleted file]
include/asm-um/prctl.h [deleted file]
include/asm-um/resource.h [deleted file]
include/asm-um/rwlock.h [deleted file]
include/asm-um/rwsem.h [deleted file]
include/asm-um/scatterlist.h [deleted file]
include/asm-um/sembuf.h [deleted file]
include/asm-um/serial.h [deleted file]
include/asm-um/shmbuf.h [deleted file]
include/asm-um/shmparam.h [deleted file]
include/asm-um/sigcontext-generic.h [deleted file]
include/asm-um/sigcontext-i386.h [deleted file]
include/asm-um/sigcontext-ppc.h [deleted file]
include/asm-um/sigcontext-x86_64.h [deleted file]
include/asm-um/siginfo.h [deleted file]
include/asm-um/signal.h [deleted file]
include/asm-um/socket.h [deleted file]
include/asm-um/sockios.h [deleted file]
include/asm-um/spinlock.h [deleted file]
include/asm-um/spinlock_types.h [deleted file]
include/asm-um/stat.h [deleted file]
include/asm-um/statfs.h [deleted file]
include/asm-um/string.h [deleted file]
include/asm-um/system-i386.h [deleted file]
include/asm-um/system-ppc.h [deleted file]
include/asm-um/system-x86_64.h [deleted file]
include/asm-um/termbits.h [deleted file]
include/asm-um/termios.h [deleted file]
include/asm-um/types.h [deleted file]
include/asm-um/ucontext.h [deleted file]
include/asm-um/unaligned.h [deleted file]
include/asm-um/unistd.h [deleted file]
include/asm-um/user.h [deleted file]
include/asm-um/vga.h [deleted file]
include/asm-um/vm86.h [deleted file]
include/asm-x86/ftrace.h [deleted file]
include/asm-x86/irq_remapping.h [deleted file]
include/asm-x86/mach-default/mach_mpspec.h [deleted file]
include/asm-x86/mach-generic/irq_vectors_limits.h [deleted file]
include/asm-x86/reboot_fixups.h [deleted file]
include/asm-x86/shmparam.h [deleted file]
include/asm-x86/summit/irq_vectors_limits.h [deleted file]
include/asm-x86/therm_throt.h [deleted file]
include/asm-x86/uv/bios.h [deleted file]
include/asm-x86/xen/grant_table.h [deleted file]
include/asm-xtensa/io.h
include/asm-xtensa/rwsem.h
include/asm-xtensa/variant-dc232b/core.h [new file with mode: 0644]
include/asm-xtensa/variant-dc232b/tie-asm.h [new file with mode: 0644]
include/asm-xtensa/variant-dc232b/tie.h [new file with mode: 0644]
include/linux/acpi.h
include/linux/aer.h
include/linux/bitmap.h
include/linux/blkdev.h
include/linux/cdrom.h
include/linux/clocksource.h
include/linux/compiler.h
include/linux/crash_dump.h
include/linux/dcache.h
include/linux/device-mapper.h
include/linux/device.h
include/linux/dm-region-hash.h [new file with mode: 0644]
include/linux/dma_remapping.h
include/linux/dmar.h
include/linux/efi.h
include/linux/file.h
include/linux/fs.h
include/linux/fsnotify.h
include/linux/ftrace.h
include/linux/fuse.h
include/linux/genhd.h
include/linux/hrtimer.h
include/linux/hugetlb.h
include/linux/i2c-algo-pcf.h
include/linux/i2c.h
include/linux/i2c/twl4030.h
include/linux/ide.h
include/linux/init.h
include/linux/init_task.h
include/linux/intel-iommu.h
include/linux/interrupt.h
include/linux/irq.h
include/linux/irqnr.h [new file with mode: 0644]
include/linux/jbd.h
include/linux/kernel.h
include/linux/kernel_stat.h
include/linux/kprobes.h
include/linux/libata.h
include/linux/linkage.h
include/linux/marker.h
include/linux/mlx4/cmd.h
include/linux/mlx4/device.h
include/linux/mmiotrace.h
include/linux/module.h
include/linux/moduleparam.h
include/linux/namei.h
include/linux/oprofile.h
include/linux/page_cgroup.h
include/linux/pci.h
include/linux/pci_hotplug.h
include/linux/pci_ids.h
include/linux/pci_regs.h
include/linux/pnp.h
include/linux/poll.h
include/linux/posix-timers.h
include/linux/prctl.h
include/linux/proc_fs.h
include/linux/profile.h
include/linux/reiserfs_fs_sb.h
include/linux/ring_buffer.h [new file with mode: 0644]
include/linux/sched.h
include/linux/slab.h
include/linux/thread_info.h
include/linux/tick.h
include/linux/time.h
include/linux/timex.h
include/linux/tracepoint.h [new file with mode: 0644]
include/linux/types.h
include/linux/usb/wusb-wa.h [new file with mode: 0644]
include/linux/usb/wusb.h [new file with mode: 0644]
include/linux/uwb.h [new file with mode: 0644]
include/linux/uwb/debug-cmd.h [new file with mode: 0644]
include/linux/uwb/debug.h [new file with mode: 0644]
include/linux/uwb/spec.h [new file with mode: 0644]
include/linux/uwb/umc.h [new file with mode: 0644]
include/linux/uwb/whci.h [new file with mode: 0644]
include/linux/videodev2.h
include/linux/vmalloc.h
include/linux/vmstat.h
include/linux/wlp.h [new file with mode: 0644]
include/linux/workqueue.h
include/media/v4l2-int-device.h
include/media/v4l2-ioctl.h
include/media/videobuf-dvb.h
include/net/9p/9p.h
include/net/9p/client.h
include/scsi/scsi_ioctl.h
include/trace/sched.h [new file with mode: 0644]
init/Kconfig
init/main.c
ipc/shm.c
kernel/Makefile
kernel/audit_tree.c
kernel/compat.c
kernel/exec_domain.c
kernel/exit.c
kernel/fork.c
kernel/futex.c
kernel/hrtimer.c
kernel/irq/autoprobe.c
kernel/irq/chip.c
kernel/irq/handle.c
kernel/irq/internals.h
kernel/irq/manage.c
kernel/irq/migration.c
kernel/irq/proc.c
kernel/irq/resend.c
kernel/irq/spurious.c
kernel/itimer.c
kernel/kexec.c
kernel/kthread.c
kernel/marker.c
kernel/module.c
kernel/notifier.c
kernel/panic.c
kernel/params.c
kernel/posix-cpu-timers.c
kernel/posix-timers.c
kernel/power/disk.c
kernel/power/power.h
kernel/power/swap.c
kernel/rcupdate.c
kernel/rcutorture.c
kernel/rtmutex.c
kernel/sched.c
kernel/sched_fair.c
kernel/sched_features.h
kernel/sched_rt.c
kernel/sched_stats.h
kernel/signal.c
kernel/softirq.c
kernel/stop_machine.c
kernel/sys.c
kernel/sysctl.c
kernel/time.c
kernel/time/clocksource.c
kernel/time/jiffies.c
kernel/time/ntp.c
kernel/time/tick-broadcast.c
kernel/time/tick-internal.h
kernel/time/tick-sched.c
kernel/time/timekeeping.c
kernel/time/timer_list.c
kernel/timer.c
kernel/trace/Kconfig
kernel/trace/Makefile
kernel/trace/ftrace.c
kernel/trace/ring_buffer.c [new file with mode: 0644]
kernel/trace/trace.c
kernel/trace/trace.h
kernel/trace/trace_boot.c [new file with mode: 0644]
kernel/trace/trace_functions.c
kernel/trace/trace_irqsoff.c
kernel/trace/trace_mmiotrace.c
kernel/trace/trace_nop.c [new file with mode: 0644]
kernel/trace/trace_sched_switch.c
kernel/trace/trace_sched_wakeup.c
kernel/trace/trace_selftest.c
kernel/trace/trace_stack.c [new file with mode: 0644]
kernel/trace/trace_sysprof.c
kernel/tracepoint.c [new file with mode: 0644]
kernel/workqueue.c
lib/bitmap.c
lib/string_helpers.c
mm/hugetlb.c
mm/memcontrol.c
mm/memory.c
mm/page_cgroup.c
mm/slab.c
mm/slub.c
mm/tiny-shmem.c
mm/vmalloc.c
mm/vmstat.c
net/9p/Kconfig
net/9p/Makefile
net/9p/client.c
net/9p/protocol.c
net/9p/trans_fd.c
net/9p/trans_rdma.c [new file with mode: 0644]
net/sched/sch_cbq.c
net/unix/af_unix.c
samples/Kconfig
samples/Makefile
samples/markers/probe-example.c
samples/tracepoints/Makefile [new file with mode: 0644]
samples/tracepoints/tp-samples-trace.h [new file with mode: 0644]
samples/tracepoints/tracepoint-probe-sample.c [new file with mode: 0644]
samples/tracepoints/tracepoint-probe-sample2.c [new file with mode: 0644]
samples/tracepoints/tracepoint-sample.c [new file with mode: 0644]
scripts/Makefile.build
scripts/bootgraph.pl
scripts/checkpatch.pl
scripts/checksyscalls.sh
scripts/kconfig/Makefile
scripts/recordmcount.pl [new file with mode: 0755]
security/selinux/hooks.c
sound/aoa/soundbus/i2sbus/i2sbus-core.c
sound/arm/pxa2xx-pcm-lib.c
sound/core/oss/pcm_oss.c
sound/drivers/pcsp/pcsp_lib.c
sound/oss/au1550_ac97.c
sound/oss/dmasound/dmasound.h
sound/oss/dmasound/dmasound_atari.c
sound/oss/dmasound/dmasound_core.c
sound/oss/msnd.h
sound/oss/sound_config.h
sound/oss/swarm_cs4297a.c
sound/oss/vwsnd.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/soc/codecs/tlv320aic3x.c
sound/soc/omap/omap-mcbsp.c

diff --git a/CREDITS b/CREDITS
index c62dcb3b7e2621d918815a656f2682fda044afcb..b50db1767554bf2cb63e9f5b4fdb4864af0ce5b9 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -598,6 +598,11 @@ S: Tamsui town, Taipei county,
 S: Taiwan 251
 S: Republic of China
 
+N: Reinette Chatre
+E: reinette.chatre@intel.com
+D: WiMedia Link Protocol implementation
+D: UWB stack bits and pieces
+
 N: Michael Elizabeth Chastain
 E: mec@shout.net
 D: Configure, Menuconfig, xconfig
@@ -1653,14 +1658,14 @@ S: Chapel Hill, North Carolina 27514-4818
 S: USA
 
 N: Dave Jones
-E: davej@codemonkey.org.uk
+E: davej@redhat.com
 W: http://www.codemonkey.org.uk
-D: x86 errata/setup maintenance.
-D: AGPGART driver.
+D: Assorted VIA x86 support.
+D: 2.5 AGPGART overhaul.
 D: CPUFREQ maintenance.
-D: Backport/Forwardport merge monkey.
-D: Various Janitor work.
-S: United Kingdom
+D: Fedora kernel maintainence.
+D: Misc/Other.
+S: 314 Littleton Rd, Westford, MA 01886, USA
 
 N: Martin Josfsson
 E: gandalf@wlug.westbo.se
@@ -2695,6 +2700,12 @@ S: Demonstratsii 8-382
 S: Tula 300000
 S: Russia
 
+N: Inaky Perez-Gonzalez
+E: inaky.perez-gonzalez@intel.com
+D: UWB stack, HWA-RC driver and HWA-HC drivers
+D: Wireless USB additions to the USB stack
+D: WiMedia Link Protocol bits and pieces
+
 N: Gordon Peters
 E: GordPeters@smarttech.com
 D: Isochronous receive for IEEE 1394 driver (OHCI module).
diff --git a/Documentation/ABI/testing/sysfs-bus-umc b/Documentation/ABI/testing/sysfs-bus-umc
new file mode 100644 (file)
index 0000000..948fec4
--- /dev/null
@@ -0,0 +1,28 @@
+What:           /sys/bus/umc/
+Date:           July 2008
+KernelVersion:  2.6.27
+Contact:        David Vrabel <david.vrabel@csr.com>
+Description:
+                The Wireless Host Controller Interface (WHCI)
+                specification describes a PCI-based device with
+                multiple capabilities; the UWB Multi-interface
+                Controller (UMC).
+
+                The umc bus presents each of the individual
+                capabilties as a device.
+
+What:           /sys/bus/umc/devices/.../capability_id
+Date:           July 2008
+KernelVersion:  2.6.27
+Contact:        David Vrabel <david.vrabel@csr.com>
+Description:
+                The ID of this capability, with 0 being the radio
+                controller capability.
+
+What:           /sys/bus/umc/devices/.../version
+Date:           July 2008
+KernelVersion:  2.6.27
+Contact:        David Vrabel <david.vrabel@csr.com>
+Description:
+                The specification version this capability's hardware
+                interface complies with.
index df6c8a0159f1c9abeaf54931384fdf36255f60a5..7772928ee48f6edfa61d52921164ed106501515b 100644 (file)
@@ -101,3 +101,46 @@ Description:
 Users:
                USB PM tool
                git://git.moblin.org/users/sarah/usb-pm-tool/
+
+What:          /sys/bus/usb/device/.../authorized
+Date:          July 2008
+KernelVersion: 2.6.26
+Contact:       David Vrabel <david.vrabel@csr.com>
+Description:
+               Authorized devices are available for use by device
+               drivers, non-authorized one are not.  By default, wired
+               USB devices are authorized.
+
+               Certified Wireless USB devices are not authorized
+               initially and should be (by writing 1) after the
+               device has been authenticated.
+
+What:          /sys/bus/usb/device/.../wusb_cdid
+Date:          July 2008
+KernelVersion: 2.6.27
+Contact:       David Vrabel <david.vrabel@csr.com>
+Description:
+               For Certified Wireless USB devices only.
+
+               A devices's CDID, as 16 space-separated hex octets.
+
+What:          /sys/bus/usb/device/.../wusb_ck
+Date:          July 2008
+KernelVersion: 2.6.27
+Contact:       David Vrabel <david.vrabel@csr.com>
+Description:
+               For Certified Wireless USB devices only.
+
+               Write the device's connection key (CK) to start the
+               authentication of the device.  The CK is 16
+               space-separated hex octets.
+
+What:          /sys/bus/usb/device/.../wusb_disconnect
+Date:          July 2008
+KernelVersion: 2.6.27
+Contact:       David Vrabel <david.vrabel@csr.com>
+Description:
+               For Certified Wireless USB devices only.
+
+               Write a 1 to force the device to disconnect
+               (equivalent to unplugging a wired USB device).
diff --git a/Documentation/ABI/testing/sysfs-class-usb_host b/Documentation/ABI/testing/sysfs-class-usb_host
new file mode 100644 (file)
index 0000000..46b66ad
--- /dev/null
@@ -0,0 +1,25 @@
+What:           /sys/class/usb_host/usb_hostN/wusb_chid
+Date:           July 2008
+KernelVersion:  2.6.27
+Contact:        David Vrabel <david.vrabel@csr.com>
+Description:
+                Write the CHID (16 space-separated hex octets) for this host controller.
+                This starts the host controller, allowing it to accept connection from
+                WUSB devices.
+
+                Set an all zero CHID to stop the host controller.
+
+What:           /sys/class/usb_host/usb_hostN/wusb_trust_timeout
+Date:           July 2008
+KernelVersion:  2.6.27
+Contact:        David Vrabel <david.vrabel@csr.com>
+Description:
+                Devices that haven't sent a WUSB packet to the host
+                within 'wusb_trust_timeout' ms are considered to have
+                disconnected and are removed.  The default value of
+                4000 ms is the value required by the WUSB
+                specification.
+
+                Since this relates to security (specifically, the
+                lifetime of PTKs and GTKs) it should not be changed
+                from the default.
diff --git a/Documentation/ABI/testing/sysfs-class-uwb_rc b/Documentation/ABI/testing/sysfs-class-uwb_rc
new file mode 100644 (file)
index 0000000..a0d18db
--- /dev/null
@@ -0,0 +1,144 @@
+What:           /sys/class/uwb_rc
+Date:           July 2008
+KernelVersion:  2.6.27
+Contact:        linux-usb@vger.kernel.org
+Description:
+                Interfaces for WiMedia Ultra Wideband Common Radio
+                Platform (UWB) radio controllers.
+
+                Familiarity with the ECMA-368 'High Rate Ultra
+                Wideband MAC and PHY Specification' is assumed.
+
+What:           /sys/class/uwb_rc/beacon_timeout_ms
+Date:           July 2008
+KernelVersion:  2.6.27
+Description:
+                If no beacons are received from a device for at least
+                this time, the device will be considered to have gone
+                and it will be removed.  The default is 3 superframes
+                (~197 ms) as required by the specification.
+
+What:           /sys/class/uwb_rc/uwbN/
+Date:           July 2008
+KernelVersion:  2.6.27
+Contact:        linux-usb@vger.kernel.org
+Description:
+                An individual UWB radio controller.
+
+What:           /sys/class/uwb_rc/uwbN/beacon
+Date:           July 2008
+KernelVersion:  2.6.27
+Contact:        linux-usb@vger.kernel.org
+Description:
+                Write:
+
+                <channel> [<bpst offset>]
+
+                to start beaconing on a specific channel, or stop
+                beaconing if <channel> is -1.  Valid channels depends
+                on the radio controller's supported band groups.
+
+                <bpst offset> may be used to try and join a specific
+                beacon group if more than one was found during a scan.
+
+What:           /sys/class/uwb_rc/uwbN/scan
+Date:           July 2008
+KernelVersion:  2.6.27
+Contact:        linux-usb@vger.kernel.org
+Description:
+                Write:
+
+                <channel> <type> [<bpst offset>]
+
+                to start (or stop) scanning on a channel.  <type> is one of:
+                    0 - scan
+                    1 - scan outside BP
+                    2 - scan while inactive
+                    3 - scanning disabled
+                    4 - scan (with start time of <bpst offset>)
+
+What:           /sys/class/uwb_rc/uwbN/mac_address
+Date:           July 2008
+KernelVersion:  2.6.27
+Contact:        linux-usb@vger.kernel.org
+Description:
+                The EUI-48, in colon-separated hex octets, for this
+                radio controller.  A write will change the radio
+                controller's EUI-48 but only do so while the device is
+                not beaconing or scanning.
+
+What:           /sys/class/uwb_rc/uwbN/wusbhc
+Date:           July 2008
+KernelVersion:  2.6.27
+Contact:        linux-usb@vger.kernel.org
+Description:
+                A symlink to the device (if any) of the WUSB Host
+                Controller PAL using this radio controller.
+
+What:           /sys/class/uwb_rc/uwbN/<EUI-48>/
+Date:           July 2008
+KernelVersion:  2.6.27
+Contact:        linux-usb@vger.kernel.org
+Description:
+                A neighbour UWB device that has either been detected
+                as part of a scan or is a member of the radio
+                controllers beacon group.
+
+What:           /sys/class/uwb_rc/uwbN/<EUI-48>/BPST
+Date:           July 2008
+KernelVersion:  2.6.27
+Contact:        linux-usb@vger.kernel.org
+Description:
+                The time (using the radio controllers internal 1 ms
+                interval superframe timer) of the last beacon from
+                this device was received.
+
+What:           /sys/class/uwb_rc/uwbN/<EUI-48>/DevAddr
+Date:           July 2008
+KernelVersion:  2.6.27
+Contact:        linux-usb@vger.kernel.org
+Description:
+                The current DevAddr of this device in colon separated
+                hex octets.
+
+What:           /sys/class/uwb_rc/uwbN/<EUI-48>/EUI_48
+Date:           July 2008
+KernelVersion:  2.6.27
+Contact:        linux-usb@vger.kernel.org
+Description:
+
+                The EUI-48 of this device in colon separated hex
+                octets.
+
+What:           /sys/class/uwb_rc/uwbN/<EUI-48>/BPST
+Date:           July 2008
+KernelVersion:  2.6.27
+Contact:        linux-usb@vger.kernel.org
+Description:
+
+What:           /sys/class/uwb_rc/uwbN/<EUI-48>/IEs
+Date:           July 2008
+KernelVersion:  2.6.27
+Contact:        linux-usb@vger.kernel.org
+Description:
+                The latest IEs included in this device's beacon, in
+                space separated hex octets with one IE per line.
+
+What:           /sys/class/uwb_rc/uwbN/<EUI-48>/LQE
+Date:           July 2008
+KernelVersion:  2.6.27
+Contact:        linux-usb@vger.kernel.org
+Description:
+                Link Quality Estimate - the Signal to Noise Ratio
+                (SNR) of all packets received from this device in dB.
+                This gives an estimate on a suitable PHY rate. Refer
+                to [ECMA-368] section 13.3 for more details.
+
+What:           /sys/class/uwb_rc/uwbN/<EUI-48>/RSSI
+Date:           July 2008
+KernelVersion:  2.6.27
+Contact:        linux-usb@vger.kernel.org
+Description:
+                Received Signal Strength Indication - the strength of
+                the received signal in dB.  LQE is a more useful
+                measure of the radio link quality.
diff --git a/Documentation/ABI/testing/sysfs-wusb_cbaf b/Documentation/ABI/testing/sysfs-wusb_cbaf
new file mode 100644 (file)
index 0000000..a99c5f8
--- /dev/null
@@ -0,0 +1,100 @@
+What:           /sys/bus/usb/drivers/wusb_cbaf/.../wusb_*
+Date:           August 2008
+KernelVersion:  2.6.27
+Contact:        David Vrabel <david.vrabel@csr.com>
+Description:
+                Various files for managing Cable Based Association of
+                (wireless) USB devices.
+
+                The sequence of operations should be:
+
+                1. Device is plugged in.
+
+                2. The connection manager (CM) sees a device with CBA capability.
+                   (the wusb_chid etc. files in /sys/devices/blah/OURDEVICE).
+
+                3. The CM writes the host name, supported band groups,
+                   and the CHID (host ID) into the wusb_host_name,
+                   wusb_host_band_groups and wusb_chid files. These
+                   get sent to the device and the CDID (if any) for
+                   this host is requested.
+
+                4. The CM can verify that the device's supported band
+                   groups (wusb_device_band_groups) are compatible
+                   with the host.
+
+                5. The CM reads the wusb_cdid file.
+
+                6. The CM looks it up its database.
+
+                   - If it has a matching CHID,CDID entry, the device
+                     has been authorized before and nothing further
+                     needs to be done.
+
+                   - If the CDID is zero (or the CM doesn't find a
+                     matching CDID in its database), the device is
+                     assumed to be not known.  The CM may associate
+                     the host with device by: writing a randomly
+                     generated CDID to wusb_cdid and then a random CK
+                     to wusb_ck (this uploads the new CC to the
+                     device).
+
+                     CMD may choose to prompt the user before
+                     associating with a new device.
+
+                7. Device is unplugged.
+
+                References:
+                  [WUSB-AM] Association Models Supplement to the
+                            Certified Wireless Universal Serial Bus
+                            Specification, version 1.0.
+
+What:           /sys/bus/usb/drivers/wusb_cbaf/.../wusb_chid
+Date:           August 2008
+KernelVersion:  2.6.27
+Contact:        David Vrabel <david.vrabel@csr.com>
+Description:
+                The CHID of the host formatted as 16 space-separated
+                hex octets.
+
+                Writes fetches device's supported band groups and the
+                the CDID for any existing association with this host.
+
+What:           /sys/bus/usb/drivers/wusb_cbaf/.../wusb_host_name
+Date:           August 2008
+KernelVersion:  2.6.27
+Contact:        David Vrabel <david.vrabel@csr.com>
+Description:
+                A friendly name for the host as a UTF-8 encoded string.
+
+What:           /sys/bus/usb/drivers/wusb_cbaf/.../wusb_host_band_groups
+Date:           August 2008
+KernelVersion:  2.6.27
+Contact:        David Vrabel <david.vrabel@csr.com>
+Description:
+                The band groups supported by the host, in the format
+                defined in [WUSB-AM].
+
+What:           /sys/bus/usb/drivers/wusb_cbaf/.../wusb_device_band_groups
+Date:           August 2008
+KernelVersion:  2.6.27
+Contact:        David Vrabel <david.vrabel@csr.com>
+Description:
+                The band groups supported by the device, in the format
+                defined in [WUSB-AM].
+
+What:           /sys/bus/usb/drivers/wusb_cbaf/.../wusb_cdid
+Date:           August 2008
+KernelVersion:  2.6.27
+Contact:        David Vrabel <david.vrabel@csr.com>
+Description:
+                The device's CDID formatted as 16 space-separated hex
+                octets.
+
+What:           /sys/bus/usb/drivers/wusb_cbaf/.../wusb_ck
+Date:           August 2008
+KernelVersion:  2.6.27
+Contact:        David Vrabel <david.vrabel@csr.com>
+Description:
+                Write 16 space-separated random, hex octets to
+                associate with the device.
index 4c63e5864160f159fd073039ba80efefb161ff68..ae15d55350ec8bf93e2eb79dac2ee730cd6de054 100644 (file)
@@ -1105,7 +1105,7 @@ static struct block_device_operations opt_fops = {
     </listitem>
     <listitem>
      <para>
-      Function names as strings (__FUNCTION__).
+      Function names as strings (__func__).
      </para>
     </listitem>
     <listitem>
index a51f693c15419e9b2da87df025b69d898f648b51..256defd7e1742be45497e1bcc8912d493241c5af 100644 (file)
@@ -236,10 +236,8 @@ software system can set different pages for controlling accesses to the
 MSI-X structure. The implementation of MSI support requires the PCI
 subsystem, not a device driver, to maintain full control of the MSI-X
 table/MSI-X PBA (Pending Bit Array) and MMIO address space of the MSI-X
-table/MSI-X PBA.  A device driver is prohibited from requesting the MMIO
-address space of the MSI-X table/MSI-X PBA. Otherwise, the PCI subsystem
-will fail enabling MSI-X on its hardware device when it calls the function
-pci_enable_msix().
+table/MSI-X PBA.  A device driver should not access the MMIO address
+space of the MSI-X table/MSI-X PBA.
 
 5.3.2 API pci_enable_msix
 
index 8d4dc6250c582821ccca5b89127833e2b14bd4ee..fd4907a2968cb3fab71e92286c24da0244dcfcae 100644 (file)
@@ -163,6 +163,10 @@ need pass only as many optional fields as necessary:
        o class and classmask fields default to 0
        o driver_data defaults to 0UL.
 
+Note that driver_data must match the value used by any of the pci_device_id
+entries defined in the driver. This makes the driver_data field mandatory
+if all the pci_device_id entries have a non-zero driver_data value.
+
 Once added, the driver probe routine will be invoked for any unclaimed
 PCI devices listed in its (newly updated) pci_ids list.
 
index 16c251230c82398a1ad26a3754762e49fc819922..ddeb14beacc8fe8592334ba11303ef6fcd2a7404 100644 (file)
@@ -203,22 +203,17 @@ to mmio_enabled.
 
 3.3 helper functions
 
-3.3.1 int pci_find_aer_capability(struct pci_dev *dev);
-pci_find_aer_capability locates the PCI Express AER capability
-in the device configuration space. If the device doesn't support
-PCI-Express AER, the function returns 0.
-
-3.3.2 int pci_enable_pcie_error_reporting(struct pci_dev *dev);
+3.3.1 int pci_enable_pcie_error_reporting(struct pci_dev *dev);
 pci_enable_pcie_error_reporting enables the device to send error
 messages to root port when an error is detected. Note that devices
 don't enable the error reporting by default, so device drivers need
 call this function to enable it.
 
-3.3.3 int pci_disable_pcie_error_reporting(struct pci_dev *dev);
+3.3.2 int pci_disable_pcie_error_reporting(struct pci_dev *dev);
 pci_disable_pcie_error_reporting disables the device to send error
 messages to root port when an error is detected.
 
-3.3.4 int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev);
+3.3.3 int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev);
 pci_cleanup_aer_uncorrect_error_status cleanups the uncorrectable
 error status register.
 
index f5f812daf9f439658bcc710164b2912dc2430e75..05d71b4b9430f9fb2f9dcc932e0f95deac759555 100644 (file)
@@ -359,3 +359,11 @@ Why:  The 2.6 kernel supports direct writing to ide CD drives, which
       eliminates the need for ide-scsi. The new method is more
       efficient in every way.
 Who:  FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
+
+---------------------------
+
+What:  i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client()
+When:  2.6.29 (ideally) or 2.6.30 (more likely)
+Why:   Deprecated by the new (standard) device driver binding model. Use
+       i2c_driver->probe() and ->remove() instead.
+Who:   Jean Delvare <khali@linux-fr.org>
index c31e0291e167bf528f8fa255c321905e048552ff..81c0c59a60eae20da2bd33a8037fdceb002f7fa7 100644 (file)
@@ -13,8 +13,9 @@ Supported adapters:
   * Intel 631xESB/632xESB (ESB2)
   * Intel 82801H (ICH8)
   * Intel 82801I (ICH9)
-  * Intel Tolapai
-  * Intel ICH10
+  * Intel EP80579 (Tolapai)
+  * Intel 82801JI (ICH10)
+  * Intel PCH
    Datasheets: Publicly available at the Intel website
 
 Authors: 
@@ -32,7 +33,7 @@ Description
 -----------
 
 The ICH (properly known as the 82801AA), ICH0 (82801AB), ICH2 (82801BA),
-ICH3 (82801CA/CAM) and later devices are Intel chips that are a part of
+ICH3 (82801CA/CAM) and later devices (PCH) are Intel chips that are a part of
 Intel's '810' chipset for Celeron-based PCs, '810E' chipset for
 Pentium-based PCs, '815E' chipset, and others.
 
diff --git a/Documentation/i2c/porting-clients b/Documentation/i2c/porting-clients
deleted file mode 100644 (file)
index 7bf82c0..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-Revision 7, 2007-04-19
-Jean Delvare <khali@linux-fr.org>
-Greg KH <greg@kroah.com>
-
-This is a guide on how to convert I2C chip drivers from Linux 2.4 to
-Linux 2.6. I have been using existing drivers (lm75, lm78) as examples.
-Then I converted a driver myself (lm83) and updated this document.
-Note that this guide is strongly oriented towards hardware monitoring
-drivers. Many points are still valid for other type of drivers, but
-others may be irrelevant.
-
-There are two sets of points below. The first set concerns technical
-changes. The second set concerns coding policy. Both are mandatory.
-
-Although reading this guide will help you porting drivers, I suggest
-you keep an eye on an already ported driver while porting your own
-driver. This will help you a lot understanding what this guide
-exactly means. Choose the chip driver that is the more similar to
-yours for best results.
-
-Technical changes:
-
-* [Driver type] Any driver that was relying on i2c-isa has to be
-  converted to a proper isa, platform or pci driver. This is not
-  covered by this guide.
-
-* [Includes] Get rid of "version.h" and <linux/i2c-proc.h>.
-  Includes typically look like that:
-  #include <linux/module.h>
-  #include <linux/init.h>
-  #include <linux/slab.h>
-  #include <linux/jiffies.h>
-  #include <linux/i2c.h>
-  #include <linux/hwmon.h>     /* for hardware monitoring drivers */
-  #include <linux/hwmon-sysfs.h>
-  #include <linux/hwmon-vid.h> /* if you need VRM support */
-  #include <linux/err.h>       /* for class registration */
-  Please respect this inclusion order. Some extra headers may be
-  required for a given driver (e.g. "lm75.h").
-
-* [Addresses] SENSORS_I2C_END becomes I2C_CLIENT_END, ISA addresses
-  are no more handled by the i2c core. Address ranges are no more
-  supported either, define each individual address separately.
-  SENSORS_INSMOD_<n> becomes I2C_CLIENT_INSMOD_<n>.
-
-* [Client data] Get rid of sysctl_id. Try using standard names for
-  register values (for example, temp_os becomes temp_max). You're
-  still relatively free here, but you *have* to follow the standard
-  names for sysfs files (see the Sysctl section below).
-
-* [Function prototypes] The detect functions loses its flags
-  parameter. Sysctl (e.g. lm75_temp) and miscellaneous functions
-  are off the list of prototypes. This usually leaves five
-  prototypes:
-  static int lm75_attach_adapter(struct i2c_adapter *adapter);
-  static int lm75_detect(struct i2c_adapter *adapter, int address,
-      int kind);
-  static void lm75_init_client(struct i2c_client *client);
-  static int lm75_detach_client(struct i2c_client *client);
-  static struct lm75_data lm75_update_device(struct device *dev);
-
-* [Sysctl] All sysctl stuff is of course gone (defines, ctl_table
-  and functions). Instead, you have to define show and set functions for
-  each sysfs file. Only define set for writable values. Take a look at an
-  existing 2.6 driver for details (it87 for example). Don't forget
-  to define the attributes for each file (this is that step that
-  links callback functions). Use the file names specified in
-  Documentation/hwmon/sysfs-interface for the individual files. Also
-  convert the units these files read and write to the specified ones.
-  If you need to add a new type of file, please discuss it on the
-  sensors mailing list <lm-sensors@lm-sensors.org> by providing a
-  patch to the Documentation/hwmon/sysfs-interface file.
-
-* [Attach] The attach function should make sure that the adapter's
-  class has I2C_CLASS_HWMON (or whatever class is suitable for your
-  driver), using the following construct:
-  if (!(adapter->class & I2C_CLASS_HWMON))
-          return 0;
-  Call i2c_probe() instead of i2c_detect().
-
-* [Detect] As mentioned earlier, the flags parameter is gone.
-  The type_name and client_name strings are replaced by a single
-  name string, which will be filled with a lowercase, short string.
-  The labels used for error paths are reduced to the number needed.
-  It is advised that the labels are given descriptive names such as
-  exit and exit_free. Don't forget to properly set err before
-  jumping to error labels. By the way, labels should be left-aligned.
-  Use kzalloc instead of kmalloc.
-  Use i2c_set_clientdata to set the client data (as opposed to
-  a direct access to client->data).
-  Use strlcpy instead of strcpy or snprintf to copy the client name.
-  Replace the sysctl directory registration by calls to
-  device_create_file. Move the driver initialization before any
-  sysfs file creation.
-  Register the client with the hwmon class (using hwmon_device_register)
-  if applicable.
-  Drop client->id.
-  Drop any 24RF08 corruption prevention you find, as this is now done
-  at the i2c-core level, and doing it twice voids it.
-  Don't add I2C_CLIENT_ALLOW_USE to client->flags, it's the default now.
-
-* [Init] Limits must not be set by the driver (can be done later in
-  user-space). Chip should not be reset default (although a module
-  parameter may be used to force it), and initialization should be
-  limited to the strictly necessary steps.
-
-* [Detach] Remove the call to i2c_deregister_entry. Do not log an
-  error message if i2c_detach_client fails, as i2c-core will now do
-  it for you.
-  Unregister from the hwmon class if applicable.
-
-* [Update] The function prototype changed, it is now
-  passed a device structure, which you have to convert to a client
-  using to_i2c_client(dev). The update function should return a
-  pointer to the client data.
-  Don't access client->data directly, use i2c_get_clientdata(client)
-  instead.
-  Use time_after() instead of direct jiffies comparison.
-
-* [Interface] Make sure there is a MODULE_LICENSE() line, at the bottom
-  of the file (after MODULE_AUTHOR() and MODULE_DESCRIPTION(), in this
-  order).
-
-* [Driver] The flags field of the i2c_driver structure is gone.
-  I2C_DF_NOTIFY is now the default behavior.
-  The i2c_driver structure has a driver member, which is itself a
-  structure, those name member should be initialized to a driver name
-  string. i2c_driver itself has no name member anymore.
-
-* [Driver model] Instead of shutdown or reboot notifiers, provide a
-  shutdown() method in your driver.
-
-* [Power management] Use the driver model suspend() and resume()
-  callbacks instead of the obsolete pm_register() calls.
-
-Coding policy:
-
-* [Copyright] Use (C), not (c), for copyright.
-
-* [Debug/log] Get rid of #ifdef DEBUG/#endif constructs whenever you
-  can. Calls to printk for debugging purposes are replaced by calls to
-  dev_dbg where possible, else to pr_debug. Here is an example of how
-  to call it (taken from lm75_detect):
-  dev_dbg(&client->dev, "Starting lm75 update\n");
-  Replace other printk calls with the dev_info, dev_err or dev_warn
-  function, as appropriate.
-
-* [Constants] Constants defines (registers, conversions) should be
-  aligned. This greatly improves readability.
-  Alignments are achieved by the means of tabs, not spaces. Remember
-  that tabs are set to 8 in the Linux kernel code.
-
-* [Layout] Avoid extra empty lines between comments and what they
-  comment. Respect the coding style (see Documentation/CodingStyle),
-  in particular when it comes to placing curly braces.
-
-* [Comments] Make sure that no comment refers to a file that isn't
-  part of the Linux source tree (typically doc/chips/<chip name>),
-  and that remaining comments still match the code. Merging comment
-  lines when possible is encouraged.
index d73ee117a8caecfaf0585aeb4239c27828a7b5df..6b9af7d479c21b88b373674cdaa50a5e0dfc18e2 100644 (file)
@@ -10,23 +10,21 @@ General remarks
 ===============
 
 Try to keep the kernel namespace as clean as possible. The best way to
-do this is to use a unique prefix for all global symbols. This is 
+do this is to use a unique prefix for all global symbols. This is
 especially important for exported symbols, but it is a good idea to do
 it for non-exported symbols too. We will use the prefix `foo_' in this
-tutorial, and `FOO_' for preprocessor variables.
+tutorial.
 
 
 The driver structure
 ====================
 
 Usually, you will implement a single driver structure, and instantiate
-all clients from it. Remember, a driver structure contains general access 
+all clients from it. Remember, a driver structure contains general access
 routines, and should be zero-initialized except for fields with data you
 provide.  A client structure holds device-specific information like the
 driver model device node, and its I2C address.
 
-/* iff driver uses driver model ("new style") binding model: */
-
 static struct i2c_device_id foo_idtable[] = {
        { "foo", my_id_for_foo },
        { "bar", my_id_for_bar },
@@ -40,7 +38,6 @@ static struct i2c_driver foo_driver = {
                .name   = "foo",
        },
 
-       /* iff driver uses driver model ("new style") binding model: */
        .id_table       = foo_ids,
        .probe          = foo_probe,
        .remove         = foo_remove,
@@ -49,24 +46,19 @@ static struct i2c_driver foo_driver = {
        .detect         = foo_detect,
        .address_data   = &addr_data,
 
-       /* else, driver uses "legacy" binding model: */
-       .attach_adapter = foo_attach_adapter,
-       .detach_client  = foo_detach_client,
-
-       /* these may be used regardless of the driver binding model */
        .shutdown       = foo_shutdown, /* optional */
        .suspend        = foo_suspend,  /* optional */
        .resume         = foo_resume,   /* optional */
-       .command        = foo_command,  /* optional */
+       .command        = foo_command,  /* optional, deprecated */
 }
+
 The name field is the driver name, and must not contain spaces.  It
 should match the module name (if the driver can be compiled as a module),
 although you can use MODULE_ALIAS (passing "foo" in this example) to add
 another name for the module.  If the driver name doesn't match the module
 name, the module won't be automatically loaded (hotplug/coldplug).
 
-All other fields are for call-back functions which will be explained 
+All other fields are for call-back functions which will be explained
 below.
 
 
@@ -74,34 +66,13 @@ Extra client data
 =================
 
 Each client structure has a special `data' field that can point to any
-structure at all.  You should use this to keep device-specific data,
-especially in drivers that handle multiple I2C or SMBUS devices.  You
-do not always need this, but especially for `sensors' drivers, it can
-be very useful.
+structure at all.  You should use this to keep device-specific data.
 
        /* store the value */
        void i2c_set_clientdata(struct i2c_client *client, void *data);
 
        /* retrieve the value */
-       void *i2c_get_clientdata(struct i2c_client *client);
-
-An example structure is below.
-
-  struct foo_data {
-    struct i2c_client client;
-    enum chips type;       /* To keep the chips type for `sensors' drivers. */
-   
-    /* Because the i2c bus is slow, it is often useful to cache the read
-       information of a chip for some time (for example, 1 or 2 seconds).
-       It depends of course on the device whether this is really worthwhile
-       or even sensible. */
-    struct mutex update_lock;     /* When we are reading lots of information,
-                                     another process should not update the
-                                     below information */
-    char valid;                   /* != 0 if the following fields are valid. */
-    unsigned long last_updated;   /* In jiffies */
-    /* Add the read information here too */
-  };
+       void *i2c_get_clientdata(const struct i2c_client *client);
 
 
 Accessing the client
@@ -109,11 +80,9 @@ Accessing the client
 
 Let's say we have a valid client structure. At some time, we will need
 to gather information from the client, or write new information to the
-client. How we will export this information to user-space is less 
-important at this moment (perhaps we do not need to do this at all for
-some obscure clients). But we need generic reading and writing routines.
+client.
 
-I have found it useful to define foo_read and foo_write function for this.
+I have found it useful to define foo_read and foo_write functions for this.
 For some cases, it will be easier to call the i2c functions directly,
 but many chips have some kind of register-value idea that can easily
 be encapsulated.
@@ -121,33 +90,33 @@ be encapsulated.
 The below functions are simple examples, and should not be copied
 literally.
 
-  int foo_read_value(struct i2c_client *client, u8 reg)
-  {
-    if (reg < 0x10) /* byte-sized register */
-      return i2c_smbus_read_byte_data(client,reg);
-    else /* word-sized register */
-      return i2c_smbus_read_word_data(client,reg);
-  }
-
-  int foo_write_value(struct i2c_client *client, u8 reg, u16 value)
-  {
-    if (reg == 0x10) /* Impossible to write - driver error! */ {
-      return -1;
-    else if (reg < 0x10) /* byte-sized register */
-      return i2c_smbus_write_byte_data(client,reg,value);
-    else /* word-sized register */
-      return i2c_smbus_write_word_data(client,reg,value);
-  }
+int foo_read_value(struct i2c_client *client, u8 reg)
+{
+       if (reg < 0x10) /* byte-sized register */
+               return i2c_smbus_read_byte_data(client, reg);
+       else            /* word-sized register */
+               return i2c_smbus_read_word_data(client, reg);
+}
+
+int foo_write_value(struct i2c_client *client, u8 reg, u16 value)
+{
+       if (reg == 0x10)        /* Impossible to write - driver error! */
+               return -EINVAL;
+       else if (reg < 0x10)    /* byte-sized register */
+               return i2c_smbus_write_byte_data(client, reg, value);
+       else                    /* word-sized register */
+               return i2c_smbus_write_word_data(client, reg, value);
+}
 
 
 Probing and attaching
 =====================
 
 The Linux I2C stack was originally written to support access to hardware
-monitoring chips on PC motherboards, and thus it embeds some assumptions
-that are more appropriate to SMBus (and PCs) than to I2C.  One of these
-assumptions is that most adapters and devices drivers support the SMBUS_QUICK
-protocol to probe device presence.  Another is that devices and their drivers
+monitoring chips on PC motherboards, and thus used to embed some assumptions
+that were more appropriate to SMBus (and PCs) than to I2C.  One of these
+assumptions was that most adapters and devices drivers support the SMBUS_QUICK
+protocol to probe device presence.  Another was that devices and their drivers
 can be sufficiently configured using only such probe primitives.
 
 As Linux and its I2C stack became more widely used in embedded systems
@@ -164,6 +133,9 @@ since the "legacy" model requires drivers to create "i2c_client" device
 objects after SMBus style probing, while the Linux driver model expects
 drivers to be given such device objects in their probe() routines.
 
+The legacy model is deprecated now and will soon be removed, so we no
+longer document it here.
+
 
 Standard Driver Model Binding ("New Style")
 -------------------------------------------
@@ -193,8 +165,8 @@ matches the device's name. It is passed the entry that was matched so
 the driver knows which one in the table matched.
 
 
-Device Creation (Standard driver model)
----------------------------------------
+Device Creation
+---------------
 
 If you know for a fact that an I2C device is connected to a given I2C bus,
 you can instantiate that device by simply filling an i2c_board_info
@@ -221,8 +193,8 @@ in the I2C bus driver. You may want to save the returned i2c_client
 reference for later use.
 
 
-Device Detection (Standard driver model)
-----------------------------------------
+Device Detection
+----------------
 
 Sometimes you do not know in advance which I2C devices are connected to
 a given I2C bus.  This is for example the case of hardware monitoring
@@ -246,8 +218,8 @@ otherwise misdetections are likely to occur and things can get wrong
 quickly.
 
 
-Device Deletion (Standard driver model)
----------------------------------------
+Device Deletion
+---------------
 
 Each I2C device which has been created using i2c_new_device() or
 i2c_new_probed_device() can be unregistered by calling
@@ -256,264 +228,37 @@ called automatically before the underlying I2C bus itself is removed, as a
 device can't survive its parent in the device driver model.
 
 
-Legacy Driver Binding Model
----------------------------
+Initializing the driver
+=======================
+
+When the kernel is booted, or when your foo driver module is inserted,
+you have to do some initializing. Fortunately, just registering the
+driver module is usually enough.
 
-Most i2c devices can be present on several i2c addresses; for some this
-is determined in hardware (by soldering some chip pins to Vcc or Ground),
-for others this can be changed in software (by writing to specific client
-registers). Some devices are usually on a specific address, but not always;
-and some are even more tricky. So you will probably need to scan several
-i2c addresses for your clients, and do some sort of detection to see
-whether it is actually a device supported by your driver.
+static int __init foo_init(void)
+{
+       return i2c_add_driver(&foo_driver);
+}
+
+static void __exit foo_cleanup(void)
+{
+       i2c_del_driver(&foo_driver);
+}
+
+/* Substitute your own name and email address */
+MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"
+MODULE_DESCRIPTION("Driver for Barf Inc. Foo I2C devices");
 
-To give the user a maximum of possibilities, some default module parameters
-are defined to help determine what addresses are scanned. Several macros
-are defined in i2c.h to help you support them, as well as a generic
-detection algorithm.
-
-You do not have to use this parameter interface; but don't try to use
-function i2c_probe() if you don't.
-
-
-Probing classes (Legacy model)
-------------------------------
-
-All parameters are given as lists of unsigned 16-bit integers. Lists are
-terminated by I2C_CLIENT_END.
-The following lists are used internally:
-
-  normal_i2c: filled in by the module writer. 
-     A list of I2C addresses which should normally be examined.
-   probe: insmod parameter. 
-     A list of pairs. The first value is a bus number (-1 for any I2C bus), 
-     the second is the address. These addresses are also probed, as if they 
-     were in the 'normal' list.
-   ignore: insmod parameter.
-     A list of pairs. The first value is a bus number (-1 for any I2C bus), 
-     the second is the I2C address. These addresses are never probed. 
-     This parameter overrules the 'normal_i2c' list only.
-   force: insmod parameter. 
-     A list of pairs. The first value is a bus number (-1 for any I2C bus),
-     the second is the I2C address. A device is blindly assumed to be on
-     the given address, no probing is done. 
-
-Additionally, kind-specific force lists may optionally be defined if
-the driver supports several chip kinds. They are grouped in a
-NULL-terminated list of pointers named forces, those first element if the
-generic force list mentioned above. Each additional list correspond to an
-insmod parameter of the form force_<kind>.
-
-Fortunately, as a module writer, you just have to define the `normal_i2c' 
-parameter. The complete declaration could look like this:
-
-  /* Scan 0x4c to 0x4f */
-  static const unsigned short normal_i2c[] = { 0x4c, 0x4d, 0x4e, 0x4f,
-                                               I2C_CLIENT_END };
-
-  /* Magic definition of all other variables and things */
-  I2C_CLIENT_INSMOD;
-  /* Or, if your driver supports, say, 2 kind of devices: */
-  I2C_CLIENT_INSMOD_2(foo, bar);
-
-If you use the multi-kind form, an enum will be defined for you:
-  enum chips { any_chip, foo, bar, ... }
-You can then (and certainly should) use it in the driver code.
-
-Note that you *have* to call the defined variable `normal_i2c',
-without any prefix!
-
-
-Attaching to an adapter (Legacy model)
---------------------------------------
-
-Whenever a new adapter is inserted, or for all adapters if the driver is
-being registered, the callback attach_adapter() is called. Now is the
-time to determine what devices are present on the adapter, and to register
-a client for each of them.
-
-The attach_adapter callback is really easy: we just call the generic
-detection function. This function will scan the bus for us, using the
-information as defined in the lists explained above. If a device is
-detected at a specific address, another callback is called.
-
-  int foo_attach_adapter(struct i2c_adapter *adapter)
-  {
-    return i2c_probe(adapter,&addr_data,&foo_detect_client);
-  }
-
-Remember, structure `addr_data' is defined by the macros explained above,
-so you do not have to define it yourself.
-
-The i2c_probe function will call the foo_detect_client
-function only for those i2c addresses that actually have a device on
-them (unless a `force' parameter was used). In addition, addresses that
-are already in use (by some other registered client) are skipped.
-
-
-The detect client function (Legacy model)
------------------------------------------
-
-The detect client function is called by i2c_probe. The `kind' parameter
-contains -1 for a probed detection, 0 for a forced detection, or a positive
-number for a forced detection with a chip type forced.
-
-Returning an error different from -ENODEV in a detect function will cause
-the detection to stop: other addresses and adapters won't be scanned.
-This should only be done on fatal or internal errors, such as a memory
-shortage or i2c_attach_client failing.
-
-For now, you can ignore the `flags' parameter. It is there for future use.
-
-  int foo_detect_client(struct i2c_adapter *adapter, int address, 
-                        int kind)
-  {
-    int err = 0;
-    int i;
-    struct i2c_client *client;
-    struct foo_data *data;
-    const char *name = "";
-   
-    /* Let's see whether this adapter can support what we need.
-       Please substitute the things you need here! */
-    if (!i2c_check_functionality(adapter,I2C_FUNC_SMBUS_WORD_DATA |
-                                        I2C_FUNC_SMBUS_WRITE_BYTE))
-       goto ERROR0;
-
-    /* OK. For now, we presume we have a valid client. We now create the
-       client structure, even though we cannot fill it completely yet.
-       But it allows us to access several i2c functions safely */
-    
-    if (!(data = kzalloc(sizeof(struct foo_data), GFP_KERNEL))) {
-      err = -ENOMEM;
-      goto ERROR0;
-    }
-
-    client = &data->client;
-    i2c_set_clientdata(client, data);
-
-    client->addr = address;
-    client->adapter = adapter;
-    client->driver = &foo_driver;
-
-    /* Now, we do the remaining detection. If no `force' parameter is used. */
-
-    /* First, the generic detection (if any), that is skipped if any force
-       parameter was used. */
-    if (kind < 0) {
-      /* The below is of course bogus */
-      if (foo_read(client, FOO_REG_GENERIC) != FOO_GENERIC_VALUE)
-         goto ERROR1;
-    }
-
-    /* Next, specific detection. This is especially important for `sensors'
-       devices. */
-
-    /* Determine the chip type. Not needed if a `force_CHIPTYPE' parameter
-       was used. */
-    if (kind <= 0) {
-      i = foo_read(client, FOO_REG_CHIPTYPE);
-      if (i == FOO_TYPE_1) 
-        kind = chip1; /* As defined in the enum */
-      else if (i == FOO_TYPE_2)
-        kind = chip2;
-      else {
-        printk("foo: Ignoring 'force' parameter for unknown chip at "
-               "adapter %d, address 0x%02x\n",i2c_adapter_id(adapter),address);
-        goto ERROR1;
-      }
-    }
-
-    /* Now set the type and chip names */
-    if (kind == chip1) {
-      name = "chip1";
-    } else if (kind == chip2) {
-      name = "chip2";
-    }
-   
-    /* Fill in the remaining client fields. */
-    strlcpy(client->name, name, I2C_NAME_SIZE);
-    data->type = kind;
-    mutex_init(&data->update_lock); /* Only if you use this field */
-
-    /* Any other initializations in data must be done here too. */
-
-    /* This function can write default values to the client registers, if
-       needed. */
-    foo_init_client(client);
-
-    /* Tell the i2c layer a new client has arrived */
-    if ((err = i2c_attach_client(client)))
-      goto ERROR1;
-
-    return 0;
-
-    /* OK, this is not exactly good programming practice, usually. But it is
-       very code-efficient in this case. */
-
-    ERROR1:
-      kfree(data);
-    ERROR0:
-      return err;
-  }
-
-
-Removing the client (Legacy model)
-==================================
-
-The detach_client call back function is called when a client should be
-removed. It may actually fail, but only when panicking. This code is
-much simpler than the attachment code, fortunately!
-
-  int foo_detach_client(struct i2c_client *client)
-  {
-    int err;
-
-    /* Try to detach the client from i2c space */
-    if ((err = i2c_detach_client(client)))
-      return err;
-
-    kfree(i2c_get_clientdata(client));
-    return 0;
-  }
-
-
-Initializing the module or kernel
-=================================
-
-When the kernel is booted, or when your foo driver module is inserted, 
-you have to do some initializing. Fortunately, just attaching (registering)
-the driver module is usually enough.
-
-  static int __init foo_init(void)
-  {
-    int res;
-    
-    if ((res = i2c_add_driver(&foo_driver))) {
-      printk("foo: Driver registration failed, module not inserted.\n");
-      return res;
-    }
-    return 0;
-  }
-
-  static void __exit foo_cleanup(void)
-  {
-    i2c_del_driver(&foo_driver);
-  }
-
-  /* Substitute your own name and email address */
-  MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"
-  MODULE_DESCRIPTION("Driver for Barf Inc. Foo I2C devices");
-
-  /* a few non-GPL license types are also allowed */
-  MODULE_LICENSE("GPL");
-
-  module_init(foo_init);
-  module_exit(foo_cleanup);
-
-Note that some functions are marked by `__init', and some data structures
-by `__initdata'.  These functions and structures can be removed after
-kernel booting (or module loading) is completed.
+/* a few non-GPL license types are also allowed */
+MODULE_LICENSE("GPL");
+
+module_init(foo_init);
+module_exit(foo_cleanup);
+
+Note that some functions are marked by `__init'.  These functions can
+be removed after kernel booting (or module loading) is completed.
+Likewise, functions marked by `__exit' are dropped by the compiler when
+the code is built into the kernel, as they would never be called.
 
 
 Power Management
@@ -548,33 +293,35 @@ Command function
 
 A generic ioctl-like function call back is supported. You will seldom
 need this, and its use is deprecated anyway, so newer design should not
-use it. Set it to NULL.
+use it.
 
 
 Sending and receiving
 =====================
 
 If you want to communicate with your device, there are several functions
-to do this. You can find all of them in i2c.h.
+to do this. You can find all of them in <linux/i2c.h>.
 
-If you can choose between plain i2c communication and SMBus level
-communication, please use the last. All adapters understand SMBus level
-commands, but only some of them understand plain i2c!
+If you can choose between plain I2C communication and SMBus level
+communication, please use the latter. All adapters understand SMBus level
+commands, but only some of them understand plain I2C!
 
 
-Plain i2c communication
+Plain I2C communication
 -----------------------
 
-  extern int i2c_master_send(struct i2c_client *,const char* ,int);
-  extern int i2c_master_recv(struct i2c_client *,char* ,int);
+       int i2c_master_send(struct i2c_client *client, const char *buf,
+                           int count);
+       int i2c_master_recv(struct i2c_client *client, char *buf, int count);
 
 These routines read and write some bytes from/to a client. The client
 contains the i2c address, so you do not have to include it. The second
-parameter contains the bytes the read/write, the third the length of the
-buffer. Returned is the actual number of bytes read/written.
-  
-  extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msg,
-                          int num);
+parameter contains the bytes to read/write, the third the number of bytes
+to read/write (must be less than the length of the buffer.) Returned is
+the actual number of bytes read/written.
+
+       int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msg,
+                        int num);
 
 This sends a series of messages. Each message can be a read or write,
 and they can be mixed in any way. The transactions are combined: no
@@ -583,49 +330,45 @@ for each message the client address, the number of bytes of the message
 and the message data itself.
 
 You can read the file `i2c-protocol' for more information about the
-actual i2c protocol.
+actual I2C protocol.
 
 
 SMBus communication
 -------------------
 
-  extern s32 i2c_smbus_xfer (struct i2c_adapter * adapter, u16 addr, 
-                             unsigned short flags,
-                             char read_write, u8 command, int size,
-                             union i2c_smbus_data * data);
-
-  This is the generic SMBus function. All functions below are implemented
-  in terms of it. Never use this function directly!
-
-
-  extern s32 i2c_smbus_read_byte(struct i2c_client * client);
-  extern s32 i2c_smbus_write_byte(struct i2c_client * client, u8 value);
-  extern s32 i2c_smbus_read_byte_data(struct i2c_client * client, u8 command);
-  extern s32 i2c_smbus_write_byte_data(struct i2c_client * client,
-                                       u8 command, u8 value);
-  extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command);
-  extern s32 i2c_smbus_write_word_data(struct i2c_client * client,
-                                       u8 command, u16 value);
-  extern s32 i2c_smbus_process_call(struct i2c_client *client,
-                                    u8 command, u16 value);
-  extern s32 i2c_smbus_read_block_data(struct i2c_client * client,
-                                       u8 command, u8 *values);
-  extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
-                                        u8 command, u8 length,
-                                        u8 *values);
-  extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
-                                           u8 command, u8 length, u8 *values);
-  extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
-                                            u8 command, u8 length,
-                                            u8 *values);
+       s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
+                          unsigned short flags, char read_write, u8 command,
+                          int size, union i2c_smbus_data *data);
+
+This is the generic SMBus function. All functions below are implemented
+in terms of it. Never use this function directly!
+
+       s32 i2c_smbus_read_byte(struct i2c_client *client);
+       s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value);
+       s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command);
+       s32 i2c_smbus_write_byte_data(struct i2c_client *client,
+                                     u8 command, u8 value);
+       s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command);
+       s32 i2c_smbus_write_word_data(struct i2c_client *client,
+                                     u8 command, u16 value);
+       s32 i2c_smbus_process_call(struct i2c_client *client,
+                                  u8 command, u16 value);
+       s32 i2c_smbus_read_block_data(struct i2c_client *client,
+                                     u8 command, u8 *values);
+       s32 i2c_smbus_write_block_data(struct i2c_client *client,
+                                      u8 command, u8 length, const u8 *values);
+       s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client,
+                                         u8 command, u8 length, u8 *values);
+       s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client,
+                                          u8 command, u8 length,
+                                          const u8 *values);
 
 These ones were removed from i2c-core because they had no users, but could
 be added back later if needed:
 
-  extern s32 i2c_smbus_write_quick(struct i2c_client * client, u8 value);
-  extern s32 i2c_smbus_block_process_call(struct i2c_client *client,
-                                          u8 command, u8 length,
-                                          u8 *values)
+       s32 i2c_smbus_write_quick(struct i2c_client *client, u8 value);
+       s32 i2c_smbus_block_process_call(struct i2c_client *client,
+                                        u8 command, u8 length, u8 *values);
 
 All these transactions return a negative errno value on failure. The 'write'
 transactions return 0 on success; the 'read' transactions return the read
@@ -642,7 +385,5 @@ General purpose routines
 Below all general purpose routines are listed, that were not mentioned
 before.
 
-  /* This call returns a unique low identifier for each registered adapter.
-   */
-  extern int i2c_adapter_id(struct i2c_adapter *adap);
-
+       /* Return the adapter number for a specific adapter */
+       int i2c_adapter_id(struct i2c_adapter *adap);
diff --git a/Documentation/ia64/xen.txt b/Documentation/ia64/xen.txt
new file mode 100644 (file)
index 0000000..c61a99f
--- /dev/null
@@ -0,0 +1,183 @@
+       Recipe for getting/building/running Xen/ia64 with pv_ops
+       --------------------------------------------------------
+
+This recipe describes how to get xen-ia64 source and build it,
+and run domU with pv_ops.
+
+============
+Requirements
+============
+
+  - python
+  - mercurial
+    it (aka "hg") is an open-source source code
+    management software. See the below.
+    http://www.selenic.com/mercurial/wiki/
+  - git
+  - bridge-utils
+
+=================================
+Getting and Building Xen and Dom0
+=================================
+
+  My environment is;
+    Machine  : Tiger4
+    Domain0 OS  : RHEL5
+    DomainU OS  : RHEL5
+
+ 1. Download source
+    # hg clone http://xenbits.xensource.com/ext/ia64/xen-unstable.hg
+    # cd xen-unstable.hg
+    # hg clone http://xenbits.xensource.com/ext/ia64/linux-2.6.18-xen.hg
+
+ 2. # make world
+
+ 3. # make install-tools
+
+ 4. copy kernels and xen
+    # cp xen/xen.gz /boot/efi/efi/redhat/
+    # cp build-linux-2.6.18-xen_ia64/vmlinux.gz \
+      /boot/efi/efi/redhat/vmlinuz-2.6.18.8-xen
+
+ 5. make initrd for Dom0/DomU
+    # make -C linux-2.6.18-xen.hg ARCH=ia64 modules_install \
+      O=$(/bin/pwd)/build-linux-2.6.18-xen_ia64
+    # mkinitrd -f /boot/efi/efi/redhat/initrd-2.6.18.8-xen.img \
+      2.6.18.8-xen --builtin mptspi --builtin mptbase \
+      --builtin mptscsih --builtin uhci-hcd --builtin ohci-hcd \
+      --builtin ehci-hcd
+
+================================
+Making a disk image for guest OS
+================================
+
+ 1. make file
+    # dd if=/dev/zero of=/root/rhel5.img bs=1M seek=4096 count=0
+    # mke2fs -F -j /root/rhel5.img
+    # mount -o loop /root/rhel5.img /mnt
+    # cp -ax /{dev,var,etc,usr,bin,sbin,lib} /mnt
+    # mkdir /mnt/{root,proc,sys,home,tmp}
+
+    Note: You may miss some device files. If so, please create them
+    with mknod. Or you can use tar instead of cp.
+
+ 2. modify DomU's fstab
+    # vi /mnt/etc/fstab
+       /dev/xvda1  /            ext3    defaults        1 1
+       none        /dev/pts     devpts  gid=5,mode=620  0 0
+       none        /dev/shm     tmpfs   defaults        0 0
+       none        /proc        proc    defaults        0 0
+       none        /sys         sysfs   defaults        0 0
+
+ 3. modify inittab
+    set runlevel to 3 to avoid X trying to start
+    # vi /mnt/etc/inittab
+       id:3:initdefault:
+    Start a getty on the hvc0 console
+       X0:2345:respawn:/sbin/mingetty hvc0
+    tty1-6 mingetty can be commented out
+
+ 4. add hvc0 into /etc/securetty
+    # vi /mnt/etc/securetty (add hvc0)
+
+ 5. umount
+    # umount /mnt
+
+FYI, virt-manager can also make a disk image for guest OS.
+It's GUI tools and easy to make it.
+
+==================
+Boot Xen & Domain0
+==================
+
+ 1. replace elilo
+    elilo of RHEL5 can boot Xen and Dom0.
+    If you use old elilo (e.g RHEL4), please download from the below
+    http://elilo.sourceforge.net/cgi-bin/blosxom
+    and copy into /boot/efi/efi/redhat/
+    # cp elilo-3.6-ia64.efi /boot/efi/efi/redhat/elilo.efi
+
+ 2. modify elilo.conf (like the below)
+    # vi /boot/efi/efi/redhat/elilo.conf
+     prompt
+     timeout=20
+     default=xen
+     relocatable
+
+     image=vmlinuz-2.6.18.8-xen
+             label=xen
+             vmm=xen.gz
+             initrd=initrd-2.6.18.8-xen.img
+             read-only
+             append=" -- rhgb root=/dev/sda2"
+
+The append options before "--" are for xen hypervisor,
+the options after "--" are for dom0.
+
+FYI, your machine may need console options like
+"com1=19200,8n1 console=vga,com1". For example,
+append="com1=19200,8n1 console=vga,com1 -- rhgb console=tty0 \
+console=ttyS0 root=/dev/sda2"
+
+=====================================
+Getting and Building domU with pv_ops
+=====================================
+
+ 1. get pv_ops tree
+    # git clone http://people.valinux.co.jp/~yamahata/xen-ia64/linux-2.6-xen-ia64.git/
+
+ 2. git branch (if necessary)
+    # cd linux-2.6-xen-ia64/
+    # git checkout -b your_branch origin/xen-ia64-domu-minimal-2008may19
+    (Note: The current branch is xen-ia64-domu-minimal-2008may19.
+    But you would find the new branch. You can see with
+    "git branch -r" to get the branch lists.
+    http://people.valinux.co.jp/~yamahata/xen-ia64/for_eagl/linux-2.6-ia64-pv-ops.git/
+    is also available. The tree is based on
+    git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6 test)
+
+
+ 3. copy .config for pv_ops of domU
+    # cp arch/ia64/configs/xen_domu_wip_defconfig .config
+
+ 4. make kernel with pv_ops
+    # make oldconfig
+    # make
+
+ 5. install the kernel and initrd
+    # cp vmlinux.gz /boot/efi/efi/redhat/vmlinuz-2.6-pv_ops-xenU
+    # make modules_install
+    # mkinitrd -f /boot/efi/efi/redhat/initrd-2.6-pv_ops-xenU.img \
+      2.6.26-rc3xen-ia64-08941-g1b12161 --builtin mptspi \
+      --builtin mptbase --builtin mptscsih --builtin uhci-hcd \
+      --builtin ohci-hcd --builtin ehci-hcd
+
+========================
+Boot DomainU with pv_ops
+========================
+
+ 1. make config of DomU
+   # vi /etc/xen/rhel5
+     kernel = "/boot/efi/efi/redhat/vmlinuz-2.6-pv_ops-xenU"
+     ramdisk = "/boot/efi/efi/redhat/initrd-2.6-pv_ops-xenU.img"
+     vcpus = 1
+     memory = 512
+     name = "rhel5"
+     disk = [ 'file:/root/rhel5.img,xvda1,w' ]
+     root = "/dev/xvda1 ro"
+     extra= "rhgb console=hvc0"
+
+ 2. After boot xen and dom0, start xend
+   # /etc/init.d/xend start
+   ( In the debugging case, # XEND_DEBUG=1 xend trace_start )
+
+ 3. start domU
+   # xm create -c rhel5
+
+=========
+Reference
+=========
+- Wiki of Xen/IA64 upstream merge
+  http://wiki.xensource.com/xenwiki/XenIA64/UpstreamMerge
+
+Written by Akio Takebe <takebe_akio@jp.fujitsu.com> on 28 May 2008
index 0705040531a534c2c153c1289fe0febf92926a61..3f4bc840da8b7c068076dd057216e846e098db9f 100644 (file)
@@ -109,7 +109,8 @@ There are two possible methods of using Kdump.
 2) Or use the system kernel binary itself as dump-capture kernel and there is
    no need to build a separate dump-capture kernel. This is possible
    only with the architecutres which support a relocatable kernel. As
-   of today, i386, x86_64 and ia64 architectures support relocatable kernel.
+   of today, i386, x86_64, ppc64 and ia64 architectures support relocatable
+   kernel.
 
 Building a relocatable kernel is advantageous from the point of view that
 one does not have to build a second kernel for capturing the dump. But
@@ -207,8 +208,15 @@ Dump-capture kernel config options (Arch Dependent, i386 and x86_64)
 Dump-capture kernel config options (Arch Dependent, ppc64)
 ----------------------------------------------------------
 
-*  Make and install the kernel and its modules. DO NOT add this kernel
-   to the boot loader configuration files.
+1) Enable "Build a kdump crash kernel" support under "Kernel" options:
+
+   CONFIG_CRASH_DUMP=y
+
+2)   Enable "Build a relocatable kernel" support
+
+   CONFIG_RELOCATABLE=y
+
+   Make and install the kernel and its modules.
 
 Dump-capture kernel config options (Arch Dependent, ia64)
 ----------------------------------------------------------
index 0f1544f67400b4288887649bf73b9fb09449b92c..343e0f0f84b60e9f62bcdef4963f5c8912073c8a 100644 (file)
@@ -101,6 +101,7 @@ parameter is applicable:
        X86-64  X86-64 architecture is enabled.
                        More X86-64 boot options can be found in
                        Documentation/x86_64/boot-options.txt .
+       X86     Either 32bit or 64bit x86 (same as X86-32+X86-64)
 
 In addition, the following text indicates that the option:
 
@@ -217,20 +218,47 @@ and is between 256 and 4096 characters. It is defined in the file
        acpi.debug_level=       [HW,ACPI]
                        Format: <int>
                        Each bit of the <int> indicates an ACPI debug level,
-                       1: enable, 0: disable. It is useful for boot time
-                       debugging. After system has booted up, it can be set
-                       via /sys/module/acpi/parameters/debug_level.
-                       CONFIG_ACPI_DEBUG must be enabled for this to produce any output.
-                       Available bits (add the numbers together) to enable different
-                       debug output levels of the ACPI subsystem:
-                       0x01 error 0x02 warn 0x04 init 0x08 debug object
-                       0x10 info 0x20 init names 0x40 parse 0x80 load
-                       0x100 dispatch 0x200 execute 0x400 names 0x800 operation region
-                       0x1000 bfield 0x2000 tables 0x4000 values 0x8000 objects
-                       0x10000 resources 0x20000 user requests 0x40000 package.
-                       The number can be in decimal or prefixed with 0x in hex.
-                       Warning: Many of these options can produce a lot of
-                       output and make your system unusable. Be very careful.
+                       which corresponds to the level in an ACPI_DEBUG_PRINT
+                       statement.  After system has booted up, this mask
+                       can be set via /sys/module/acpi/parameters/debug_level.
+
+                       CONFIG_ACPI_DEBUG must be enabled for this to produce
+                       any output.  The number can be in decimal or prefixed
+                       with 0x in hex.  Some of these options produce so much
+                       output that the system is unusable.
+
+                       The following global components are defined by the
+                       ACPI CA:
+                              0x01 error
+                              0x02 warn
+                              0x04 init
+                              0x08 debug object
+                              0x10 info
+                              0x20 init names
+                              0x40 parse
+                              0x80 load
+                             0x100 dispatch
+                             0x200 execute
+                             0x400 names
+                             0x800 operation region
+                            0x1000 bfield
+                            0x2000 tables
+                            0x4000 values
+                            0x8000 objects
+                           0x10000 resources
+                           0x20000 user requests
+                           0x40000 package
+                       The number can be in decimal or prefixed with 0x in hex.
+                       Warning: Many of these options can produce a lot of
+                       output and make your system unusable. Be very careful.
+
+       acpi.power_nocheck=     [HW,ACPI]
+                       Format: 1/0 enable/disable the check of power state.
+                       On some bogus BIOS the _PSC object/_STA object of
+                       power resource can't return the correct device power
+                       state. In such case it is unneccessary to check its
+                       power state again in power transition.
+                       1 : disable the power state check
 
        acpi_pm_good    [X86-32,X86-64]
                        Override the pmtimer bug detection: force the kernel
@@ -1588,7 +1616,7 @@ and is between 256 and 4096 characters. It is defined in the file
                        See also Documentation/paride.txt.
 
        pci=option[,option...]  [PCI] various PCI subsystem options:
-               off             [X86-32] don't probe for the PCI bus
+               off             [X86] don't probe for the PCI bus
                bios            [X86-32] force use of PCI BIOS, don't access
                                the hardware directly. Use this if your machine
                                has a non-standard PCI host bridge.
@@ -1596,9 +1624,9 @@ and is between 256 and 4096 characters. It is defined in the file
                                hardware access methods are allowed. Use this
                                if you experience crashes upon bootup and you
                                suspect they are caused by the BIOS.
-               conf1           [X86-32] Force use of PCI Configuration
+               conf1           [X86] Force use of PCI Configuration
                                Mechanism 1.
-               conf2           [X86-32] Force use of PCI Configuration
+               conf2           [X86] Force use of PCI Configuration
                                Mechanism 2.
                noaer           [PCIE] If the PCIEAER kernel config parameter is
                                enabled, this kernel boot option can be used to
@@ -1618,37 +1646,37 @@ and is between 256 and 4096 characters. It is defined in the file
                                this option if the kernel is unable to allocate
                                IRQs or discover secondary PCI buses on your
                                motherboard.
-               rom             [X86-32] Assign address space to expansion ROMs.
+               rom             [X86] Assign address space to expansion ROMs.
                                Use with caution as certain devices share
                                address decoders between ROMs and other
                                resources.
-               norom           [X86-32,X86_64] Do not assign address space to
+               norom           [X86] Do not assign address space to
                                expansion ROMs that do not already have
                                BIOS assigned address ranges.
-               irqmask=0xMMMM  [X86-32] Set a bit mask of IRQs allowed to be
+               irqmask=0xMMMM  [X86] Set a bit mask of IRQs allowed to be
                                assigned automatically to PCI devices. You can
                                make the kernel exclude IRQs of your ISA cards
                                this way.
-               pirqaddr=0xAAAAA        [X86-32] Specify the physical address
+               pirqaddr=0xAAAAA        [X86] Specify the physical address
                                of the PIRQ table (normally generated
                                by the BIOS) if it is outside the
                                F0000h-100000h range.
-               lastbus=N       [X86-32] Scan all buses thru bus #N. Can be
+               lastbus=N       [X86] Scan all buses thru bus #N. Can be
                                useful if the kernel is unable to find your
                                secondary buses and you want to tell it
                                explicitly which ones they are.
-               assign-busses   [X86-32] Always assign all PCI bus
+               assign-busses   [X86] Always assign all PCI bus
                                numbers ourselves, overriding
                                whatever the firmware may have done.
-               usepirqmask     [X86-32] Honor the possible IRQ mask stored
+               usepirqmask     [X86] Honor the possible IRQ mask stored
                                in the BIOS $PIR table. This is needed on
                                some systems with broken BIOSes, notably
                                some HP Pavilion N5400 and Omnibook XE3
                                notebooks. This will have no effect if ACPI
                                IRQ routing is enabled.
-               noacpi          [X86-32] Do not use ACPI for IRQ routing
+               noacpi          [X86] Do not use ACPI for IRQ routing
                                or for PCI scanning.
-               use_crs         [X86-32] Use _CRS for PCI resource
+               use_crs         [X86] Use _CRS for PCI resource
                                allocation.
                routeirq        Do IRQ routing for all PCI devices.
                                This is normally done in pci_enable_device(),
@@ -1677,6 +1705,12 @@ and is between 256 and 4096 characters. It is defined in the file
                                reserved for the CardBus bridge's memory
                                window. The default value is 64 megabytes.
 
+       pcie_aspm=      [PCIE] Forcibly enable or disable PCIe Active State Power
+                       Management.
+               off     Disable ASPM.
+               force   Enable ASPM even on devices that claim not to support it.
+                       WARNING: Forcing ASPM on may cause system lockups.
+
        pcmv=           [HW,PCMCIA] BadgePAD 4
 
        pd.             [PARIDE]
@@ -1704,6 +1738,10 @@ and is between 256 and 4096 characters. It is defined in the file
                        Override pmtimer IOPort with a hex value.
                        e.g. pmtmr=0x508
 
+       pnp.debug       [PNP]
+                       Enable PNP debug messages.  This depends on the
+                       CONFIG_PNP_DEBUG_MESSAGES option.
+
        pnpacpi=        [ACPI]
                        { off }
 
@@ -2201,7 +2239,7 @@ and is between 256 and 4096 characters. It is defined in the file
 
        thermal.crt=    [HW,ACPI]
                        -1: disable all critical trip points in all thermal zones
-                       <degrees C>: lower all critical trip points
+                       <degrees C>: override all critical trip points
 
        thermal.nocrt=  [HW,ACPI]
                        Set to disable actions on ACPI thermal zone
index 69b5dd4e5a59bd74550397266122c465a8a12b5f..2b3a6b5260bfd64d37a86ca957cf69a6f25dda08 100644 (file)
@@ -1,7 +1,7 @@
 Acer Laptop WMI Extras Driver
 http://code.google.com/p/aceracpi
-Version 0.1
-9th February 2008
+Version 0.2
+18th August 2008
 
 Copyright 2007-2008 Carlos Corbacho <carlos@strangeworlds.co.uk>
 
@@ -87,17 +87,7 @@ acer-wmi come with built-in wireless. However, should you feel so inclined to
 ever wish to remove the card, or swap it out at some point, please get in touch
 with me, as we may well be able to gain some data on wireless card detection.
 
-To read the status of the wireless radio (0=off, 1=on):
-cat /sys/devices/platform/acer-wmi/wireless
-
-To enable the wireless radio:
-echo 1 > /sys/devices/platform/acer-wmi/wireless
-
-To disable the wireless radio:
-echo 0 > /sys/devices/platform/acer-wmi/wireless
-
-To set the state of the wireless radio when loading acer-wmi, pass:
-wireless=X (where X is 0 or 1)
+The wireless radio is exposed through rfkill.
 
 Bluetooth
 *********
@@ -117,17 +107,7 @@ For the adventurously minded - if you want to buy an internal bluetooth
 module off the internet that is compatible with your laptop and fit it, then
 it will work just fine with acer-wmi.
 
-To read the status of the bluetooth module (0=off, 1=on):
-cat /sys/devices/platform/acer-wmi/wireless
-
-To enable the bluetooth module:
-echo 1 > /sys/devices/platform/acer-wmi/bluetooth
-
-To disable the bluetooth module:
-echo 0 > /sys/devices/platform/acer-wmi/bluetooth
-
-To set the state of the bluetooth module when loading acer-wmi, pass:
-bluetooth=X (where X is 0 or 1)
+Bluetooth is exposed through rfkill.
 
 3G
 **
index d9f50a19fa0c48185968e875aa2c9163bae3e6fa..089f6138fcd94249a6444ca3a932a50c263098e1 100644 (file)
@@ -50,10 +50,12 @@ Connecting a function (probe) to a marker is done by providing a probe (function
 to call) for the specific marker through marker_probe_register() and can be
 activated by calling marker_arm(). Marker deactivation can be done by calling
 marker_disarm() as many times as marker_arm() has been called. Removing a probe
-is done through marker_probe_unregister(); it will disarm the probe and make
-sure there is no caller left using the probe when it returns. Probe removal is
-preempt-safe because preemption is disabled around the probe call. See the
-"Probe example" section below for a sample probe module.
+is done through marker_probe_unregister(); it will disarm the probe.
+marker_synchronize_unregister() must be called before the end of the module exit
+function to make sure there is no caller left using the probe. This, and the
+fact that preemption is disabled around the probe call, make sure that probe
+removal and module unload are safe. See the "Probe example" section below for a
+sample probe module.
 
 The marker mechanism supports inserting multiple instances of the same marker.
 Markers can be put in inline functions, inlined static functions, and
index de4063cb4fdc0ad6abea29d766cae78616837311..02ea9a971b8e5a7b0b33ebcf7e8f56be7c36ac1c 100644 (file)
@@ -1917,6 +1917,8 @@ platforms are moved over to use the flattened-device-tree model.
                        inverse clock polarity (CPOL) mode
     - spi-cpha        - (optional) Empty property indicating device requires
                        shifted clock phase (CPHA) mode
+    - spi-cs-high     - (optional) Empty property indicating device requires
+                       chip select active high
 
     SPI example for an MPC5200 SPI bus:
                spi@f00 {
index 74ae6f1cd2d6e3cdb313295f9d0fc55124583ec2..81a917ef96e9afbeb609fd6984f8f0eaa1b316d2 100644 (file)
@@ -2,13 +2,13 @@
 
 Required properties:
 
- - device_type : Should be "board-control"
+ - compatible : Should be "fsl,<board>-bcsr"
  - reg : Offset and length of the register set for the device
 
 Example:
 
        bcsr@f8000000 {
-               device_type = "board-control";
+               compatible = "fsl,mpc8360mds-bcsr";
                reg = <f8000000 8000>;
        };
 
index 49378a9f2b5f276c4a050e76b0898c25a74303e0..10a0263ebb3f01e832c7827cc75d7fe54b341a6f 100644 (file)
@@ -95,8 +95,9 @@ On all -  write a character to /proc/sysrq-trigger.  e.g.:
 
 'p'     - Will dump the current registers and flags to your console.
 
-'q'     - Will dump a list of all running hrtimers.
-         WARNING: Does not cover any other timers
+'q'     - Will dump per CPU lists of all armed hrtimers (but NOT regular
+          timer_list timers) and detailed information about all
+          clockevent devices.
 
 'r'     - Turns off keyboard raw mode and sets it to XLATE.
 
diff --git a/Documentation/tracepoints.txt b/Documentation/tracepoints.txt
new file mode 100644 (file)
index 0000000..5d354e1
--- /dev/null
@@ -0,0 +1,101 @@
+                    Using the Linux Kernel Tracepoints
+
+                           Mathieu Desnoyers
+
+
+This document introduces Linux Kernel Tracepoints and their use. It provides
+examples of how to insert tracepoints in the kernel and connect probe functions
+to them and provides some examples of probe functions.
+
+
+* Purpose of tracepoints
+
+A tracepoint placed in code provides a hook to call a function (probe) that you
+can provide at runtime. A tracepoint can be "on" (a probe is connected to it) or
+"off" (no probe is attached). When a tracepoint is "off" it has no effect,
+except for adding a tiny time penalty (checking a condition for a branch) and
+space penalty (adding a few bytes for the function call at the end of the
+instrumented function and adds a data structure in a separate section).  When a
+tracepoint is "on", the function you provide is called each time the tracepoint
+is executed, in the execution context of the caller. When the function provided
+ends its execution, it returns to the caller (continuing from the tracepoint
+site).
+
+You can put tracepoints at important locations in the code. They are
+lightweight hooks that can pass an arbitrary number of parameters,
+which prototypes are described in a tracepoint declaration placed in a header
+file.
+
+They can be used for tracing and performance accounting.
+
+
+* Usage
+
+Two elements are required for tracepoints :
+
+- A tracepoint definition, placed in a header file.
+- The tracepoint statement, in C code.
+
+In order to use tracepoints, you should include linux/tracepoint.h.
+
+In include/trace/subsys.h :
+
+#include <linux/tracepoint.h>
+
+DEFINE_TRACE(subsys_eventname,
+       TPPTOTO(int firstarg, struct task_struct *p),
+       TPARGS(firstarg, p));
+
+In subsys/file.c (where the tracing statement must be added) :
+
+#include <trace/subsys.h>
+
+void somefct(void)
+{
+       ...
+       trace_subsys_eventname(arg, task);
+       ...
+}
+
+Where :
+- subsys_eventname is an identifier unique to your event
+    - subsys is the name of your subsystem.
+    - eventname is the name of the event to trace.
+- TPPTOTO(int firstarg, struct task_struct *p) is the prototype of the function
+  called by this tracepoint.
+- TPARGS(firstarg, p) are the parameters names, same as found in the prototype.
+
+Connecting a function (probe) to a tracepoint is done by providing a probe
+(function to call) for the specific tracepoint through
+register_trace_subsys_eventname().  Removing a probe is done through
+unregister_trace_subsys_eventname(); it will remove the probe sure there is no
+caller left using the probe when it returns. Probe removal is preempt-safe
+because preemption is disabled around the probe call. See the "Probe example"
+section below for a sample probe module.
+
+The tracepoint mechanism supports inserting multiple instances of the same
+tracepoint, but a single definition must be made of a given tracepoint name over
+all the kernel to make sure no type conflict will occur. Name mangling of the
+tracepoints is done using the prototypes to make sure typing is correct.
+Verification of probe type correctness is done at the registration site by the
+compiler. Tracepoints can be put in inline functions, inlined static functions,
+and unrolled loops as well as regular functions.
+
+The naming scheme "subsys_event" is suggested here as a convention intended
+to limit collisions. Tracepoint names are global to the kernel: they are
+considered as being the same whether they are in the core kernel image or in
+modules.
+
+
+* Probe / tracepoint example
+
+See the example provided in samples/tracepoints/src
+
+Compile them with your kernel.
+
+Run, as root :
+modprobe tracepoint-example (insmod order is not important)
+modprobe tracepoint-probe-example
+cat /proc/tracepoint-example (returns an expected error)
+rmmod tracepoint-example tracepoint-probe-example
+dmesg
index a4afb560a45bfa9c7429f18d54d0f8b4c194b116..5bbbe2096223f69bc1f0d7007f6d07a3385e4fd4 100644 (file)
@@ -36,7 +36,7 @@ $ mount -t debugfs debugfs /debug
 $ echo mmiotrace > /debug/tracing/current_tracer
 $ cat /debug/tracing/trace_pipe > mydump.txt &
 Start X or whatever.
-$ echo "X is up" > /debug/tracing/marker
+$ echo "X is up" > /debug/tracing/trace_marker
 $ echo none > /debug/tracing/current_tracer
 Check for lost events.
 
@@ -59,9 +59,8 @@ The 'cat' process should stay running (sleeping) in the background.
 Load the driver you want to trace and use it. Mmiotrace will only catch MMIO
 accesses to areas that are ioremapped while mmiotrace is active.
 
-[Unimplemented feature:]
 During tracing you can place comments (markers) into the trace by
-$ echo "X is up" > /debug/tracing/marker
+$ echo "X is up" > /debug/tracing/trace_marker
 This makes it easier to see which part of the (huge) trace corresponds to
 which action. It is recommended to place descriptive markers about what you
 do.
diff --git a/Documentation/usb/WUSB-Design-overview.txt b/Documentation/usb/WUSB-Design-overview.txt
new file mode 100644 (file)
index 0000000..4c3d62c
--- /dev/null
@@ -0,0 +1,448 @@
+
+Linux UWB + Wireless USB + WiNET
+
+   (C) 2005-2006 Intel Corporation
+   Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License version
+   2 as published by the Free Software Foundation.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+
+Please visit http://bughost.org/thewiki/Design-overview.txt-1.8 for
+updated content.
+
+    * Design-overview.txt-1.8
+
+This code implements a Ultra Wide Band stack for Linux, as well as
+drivers for the the USB based UWB radio controllers defined in the
+Wireless USB 1.0 specification (including Wireless USB host controller
+and an Intel WiNET controller).
+
+   1. Introduction
+         1. HWA: Host Wire adapters, your Wireless USB dongle
+
+         2. DWA: Device Wired Adaptor, a Wireless USB hub for wired
+            devices
+         3. WHCI: Wireless Host Controller Interface, the PCI WUSB host
+            adapter
+   2. The UWB stack
+         1. Devices and hosts: the basic structure
+
+         2. Host Controller life cycle
+
+         3. On the air: beacons and enumerating the radio neighborhood
+
+         4. Device lists
+         5. Bandwidth allocation
+
+   3. Wireless USB Host Controller drivers
+
+   4. Glossary
+
+
+    Introduction
+
+UWB is a wide-band communication protocol that is to serve also as the
+low-level protocol for others (much like TCP sits on IP). Currently
+these others are Wireless USB and TCP/IP, but seems Bluetooth and
+Firewire/1394 are coming along.
+
+UWB uses a band from roughly 3 to 10 GHz, transmitting at a max of
+~-41dB (or 0.074 uW/MHz--geography specific data is still being
+negotiated w/ regulators, so watch for changes). That band is divided in
+a bunch of ~1.5 GHz wide channels (or band groups) composed of three
+subbands/subchannels (528 MHz each). Each channel is independent of each
+other, so you could consider them different "busses". Initially this
+driver considers them all a single one.
+
+Radio time is divided in 65536 us long /superframes/, each one divided
+in 256 256us long /MASs/ (Media Allocation Slots), which are the basic
+time/media allocation units for transferring data. At the beginning of
+each superframe there is a Beacon Period (BP), where every device
+transmit its beacon on a single MAS. The length of the BP depends on how
+many devices are present and the length of their beacons.
+
+Devices have a MAC (fixed, 48 bit address) and a device (changeable, 16
+bit address) and send periodic beacons to advertise themselves and pass
+info on what they are and do. They advertise their capabilities and a
+bunch of other stuff.
+
+The different logical parts of this driver are:
+
+    *
+
+      *UWB*: the Ultra-Wide-Band stack -- manages the radio and
+      associated spectrum to allow for devices sharing it. Allows to
+      control bandwidth assingment, beaconing, scanning, etc
+
+    *
+
+      *WUSB*: the layer that sits on top of UWB to provide Wireless USB.
+      The Wireless USB spec defines means to control a UWB radio and to
+      do the actual WUSB.
+
+
+      HWA: Host Wire adapters, your Wireless USB dongle
+
+WUSB also defines a device called a Host Wire Adaptor (HWA), which in
+mere terms is a USB dongle that enables your PC to have UWB and Wireless
+USB. The Wireless USB Host Controller in a HWA looks to the host like a
+[Wireless] USB controller connected via USB (!)
+
+The HWA itself is broken in two or three main interfaces:
+
+    *
+
+      *RC*: Radio control -- this implements an interface to the
+      Ultra-Wide-Band radio controller. The driver for this implements a
+      USB-based UWB Radio Controller to the UWB stack.
+
+    *
+
+      *HC*: the wireless USB host controller. It looks like a USB host
+      whose root port is the radio and the WUSB devices connect to it.
+      To the system it looks like a separate USB host. The driver (will)
+      implement a USB host controller (similar to UHCI, OHCI or EHCI)
+      for which the root hub is the radio...To reiterate: it is a USB
+      controller that is connected via USB instead of PCI.
+
+    *
+
+      *WINET*: some HW provide a WiNET interface (IP over UWB). This
+      package provides a driver for it (it looks like a network
+      interface, winetX). The driver detects when there is a link up for
+      their type and kick into gear.
+
+
+      DWA: Device Wired Adaptor, a Wireless USB hub for wired devices
+
+These are the complement to HWAs. They are a USB host for connecting
+wired devices, but it is connected to your PC connected via Wireless
+USB. To the system it looks like yet another USB host. To the untrained
+eye, it looks like a hub that connects upstream wirelessly.
+
+We still offer no support for this; however, it should share a lot of
+code with the HWA-RC driver; there is a bunch of factorization work that
+has been done to support that in upcoming releases.
+
+
+      WHCI: Wireless Host Controller Interface, the PCI WUSB host adapter
+
+This is your usual PCI device that implements WHCI. Similar in concept
+to EHCI, it allows your wireless USB devices (including DWAs) to connect
+to your host via a PCI interface. As in the case of the HWA, it has a
+Radio Control interface and the WUSB Host Controller interface per se.
+
+There is still no driver support for this, but will be in upcoming
+releases.
+
+
+    The UWB stack
+
+The main mission of the UWB stack is to keep a tally of which devices
+are in radio proximity to allow drivers to connect to them. As well, it
+provides an API for controlling the local radio controllers (RCs from
+now on), such as to start/stop beaconing, scan, allocate bandwidth, etc.
+
+
+      Devices and hosts: the basic structure
+
+The main building block here is the UWB device (struct uwb_dev). For
+each device that pops up in radio presence (ie: the UWB host receives a
+beacon from it) you get a struct uwb_dev that will show up in
+/sys/class/uwb and in /sys/bus/uwb/devices.
+
+For each RC that is detected, a new struct uwb_rc is created. In turn, a
+RC is also a device, so they also show in /sys/class/uwb and
+/sys/bus/uwb/devices, but at the same time, only radio controllers show
+up in /sys/class/uwb_rc.
+
+    *
+
+      [*] The reason for RCs being also devices is that not only we can
+      see them while enumerating the system device tree, but also on the
+      radio (their beacons and stuff), so the handling has to be
+      likewise to that of a device.
+
+Each RC driver is implemented by a separate driver that plugs into the
+interface that the UWB stack provides through a struct uwb_rc_ops. The
+spec creators have been nice enough to make the message format the same
+for HWA and WHCI RCs, so the driver is really a very thin transport that
+moves the requests from the UWB API to the device [/uwb_rc_ops->cmd()/]
+and sends the replies and notifications back to the API
+[/uwb_rc_neh_grok()/]. Notifications are handled to the UWB daemon, that
+is chartered, among other things, to keep the tab of how the UWB radio
+neighborhood looks, creating and destroying devices as they show up or
+dissapear.
+
+Command execution is very simple: a command block is sent and a event
+block or reply is expected back. For sending/receiving command/events, a
+handle called /neh/ (Notification/Event Handle) is opened with
+/uwb_rc_neh_open()/.
+
+The HWA-RC (USB dongle) driver (drivers/uwb/hwa-rc.c) does this job for
+the USB connected HWA. Eventually, drivers/whci-rc.c will do the same
+for the PCI connected WHCI controller.
+
+
+      Host Controller life cycle
+
+So let's say we connect a dongle to the system: it is detected and
+firmware uploaded if needed [for Intel's i1480
+/drivers/uwb/ptc/usb.c:ptc_usb_probe()/] and then it is reenumerated.
+Now we have a real HWA device connected and
+/drivers/uwb/hwa-rc.c:hwarc_probe()/ picks it up, that will set up the
+Wire-Adaptor environment and then suck it into the UWB stack's vision of
+the world [/drivers/uwb/lc-rc.c:uwb_rc_add()/].
+
+    *
+
+      [*] The stack should put a new RC to scan for devices
+      [/uwb_rc_scan()/] so it finds what's available around and tries to
+      connect to them, but this is policy stuff and should be driven
+      from user space. As of now, the operator is expected to do it
+      manually; see the release notes for documentation on the procedure.
+
+When a dongle is disconnected, /drivers/uwb/hwa-rc.c:hwarc_disconnect()/
+takes time of tearing everything down safely (or not...).
+
+
+      On the air: beacons and enumerating the radio neighborhood
+
+So assuming we have devices and we have agreed for a channel to connect
+on (let's say 9), we put the new RC to beacon:
+
+    *
+
+            $ echo 9 0 > /sys/class/uwb_rc/uwb0/beacon
+
+Now it is visible. If there were other devices in the same radio channel
+and beacon group (that's what the zero is for), the dongle's radio
+control interface will send beacon notifications on its
+notification/event endpoint (NEEP). The beacon notifications are part of
+the event stream that is funneled into the API with
+/drivers/uwb/neh.c:uwb_rc_neh_grok()/ and delivered to the UWBD, the UWB
+daemon through a notification list.
+
+UWBD wakes up and scans the event list; finds a beacon and adds it to
+the BEACON CACHE (/uwb_beca/). If he receives a number of beacons from
+the same device, he considers it to be 'onair' and creates a new device
+[/drivers/uwb/lc-dev.c:uwbd_dev_onair()/]. Similarly, when no beacons
+are received in some time, the device is considered gone and wiped out
+[uwbd calls periodically /uwb/beacon.c:uwb_beca_purge()/ that will purge
+the beacon cache of dead devices].
+
+
+      Device lists
+
+All UWB devices are kept in the list of the struct bus_type uwb_bus.
+
+
+      Bandwidth allocation
+
+The UWB stack maintains a local copy of DRP availability through
+processing of incoming *DRP Availability Change* notifications. This
+local copy is currently used to present the current bandwidth
+availability to the user through the sysfs file
+/sys/class/uwb_rc/uwbx/bw_avail. In the future the bandwidth
+availability information will be used by the bandwidth reservation
+routines.
+
+The bandwidth reservation routines are in progress and are thus not
+present in the current release. When completed they will enable a user
+to initiate DRP reservation requests through interaction with sysfs. DRP
+reservation requests from remote UWB devices will also be handled. The
+bandwidth management done by the UWB stack will include callbacks to the
+higher layers will enable the higher layers to use the reservations upon
+completion. [Note: The bandwidth reservation work is in progress and
+subject to change.]
+
+
+    Wireless USB Host Controller drivers
+
+*WARNING* This section needs a lot of work!
+
+As explained above, there are three different types of HCs in the WUSB
+world: HWA-HC, DWA-HC and WHCI-HC.
+
+HWA-HC and DWA-HC share that they are Wire-Adapters (USB or WUSB
+connected controllers), and their transfer management system is almost
+identical. So is their notification delivery system.
+
+HWA-HC and WHCI-HC share that they are both WUSB host controllers, so
+they have to deal with WUSB device life cycle and maintenance, wireless
+root-hub
+
+HWA exposes a Host Controller interface (HWA-HC 0xe0/02/02). This has
+three endpoints (Notifications, Data Transfer In and Data Transfer
+Out--known as NEP, DTI and DTO in the code).
+
+We reserve UWB bandwidth for our Wireless USB Cluster, create a Cluster
+ID and tell the HC to use all that. Then we start it. This means the HC
+starts sending MMCs.
+
+    *
+
+      The MMCs are blocks of data defined somewhere in the WUSB1.0 spec
+      that define a stream in the UWB channel time allocated for sending
+      WUSB IEs (host to device commands/notifications) and Device
+      Notifications (device initiated to host). Each host defines a
+      unique Wireless USB cluster through MMCs. Devices can connect to a
+      single cluster at the time. The IEs are Information Elements, and
+      among them are the bandwidth allocations that tell each device
+      when can they transmit or receive.
+
+Now it all depends on external stimuli.
+
+*New device connection*
+
+A new device pops up, it scans the radio looking for MMCs that give out
+the existence of Wireless USB channels. Once one (or more) are found,
+selects which one to connect to. Sends a /DN_Connect/ (device
+notification connect) during the DNTS (Device Notification Time
+Slot--announced in the MMCs
+
+HC picks the /DN_Connect/ out (nep module sends to notif.c for delivery
+into /devconnect/). This process starts the authentication process for
+the device. First we allocate a /fake port/ and assign an
+unauthenticated address (128 to 255--what we really do is
+0x80 | fake_port_idx). We fiddle with the fake port status and /khubd/
+sees a new connection, so he moves on to enable the fake port with a reset.
+
+So now we are in the reset path -- we know we have a non-yet enumerated
+device with an unauthorized address; we ask user space to authenticate
+(FIXME: not yet done, similar to bluetooth pairing), then we do the key
+exchange (FIXME: not yet done) and issue a /set address 0/ to bring the
+device to the default state. Device is authenticated.
+
+From here, the USB stack takes control through the usb_hcd ops. khubd
+has seen the port status changes, as we have been toggling them. It will
+start enumerating and doing transfers through usb_hcd->urb_enqueue() to
+read descriptors and move our data.
+
+*Device life cycle and keep alives*
+
+Everytime there is a succesful transfer to/from a device, we update a
+per-device activity timestamp. If not, every now and then we check and
+if the activity timestamp gets old, we ping the device by sending it a
+Keep Alive IE; it responds with a /DN_Alive/ pong during the DNTS (this
+arrives to us as a notification through
+devconnect.c:wusb_handle_dn_alive(). If a device times out, we
+disconnect it from the system (cleaning up internal information and
+toggling the bits in the fake hub port, which kicks khubd into removing
+the rest of the stuff).
+
+This is done through devconnect:__wusb_check_devs(), which will scan the
+device list looking for whom needs refreshing.
+
+If the device wants to disconnect, it will either die (ugly) or send a
+/DN_Disconnect/ that will prompt a disconnection from the system.
+
+*Sending and receiving data*
+
+Data is sent and received through /Remote Pipes/ (rpipes). An rpipe is
+/aimed/ at an endpoint in a WUSB device. This is the same for HWAs and
+DWAs.
+
+Each HC has a number of rpipes and buffers that can be assigned to them;
+when doing a data transfer (xfer), first the rpipe has to be aimed and
+prepared (buffers assigned), then we can start queueing requests for
+data in or out.
+
+Data buffers have to be segmented out before sending--so we send first a
+header (segment request) and then if there is any data, a data buffer
+immediately after to the DTI interface (yep, even the request). If our
+buffer is bigger than the max segment size, then we just do multiple
+requests.
+
+[This sucks, because doing USB scatter gatter in Linux is resource
+intensive, if any...not that the current approach is not. It just has to
+be cleaned up a lot :)].
+
+If reading, we don't send data buffers, just the segment headers saying
+we want to read segments.
+
+When the xfer is executed, we receive a notification that says data is
+ready in the DTI endpoint (handled through
+xfer.c:wa_handle_notif_xfer()). In there we read from the DTI endpoint a
+descriptor that gives us the status of the transfer, its identification
+(given when we issued it) and the segment number. If it was a data read,
+we issue another URB to read into the destination buffer the chunk of
+data coming out of the remote endpoint. Done, wait for the next guy. The
+callbacks for the URBs issued from here are the ones that will declare
+the xfer complete at some point and call it's callback.
+
+Seems simple, but the implementation is not trivial.
+
+    *
+
+      *WARNING* Old!!
+
+The main xfer descriptor, wa_xfer (equivalent to a URB) contains an
+array of segments, tallys on segments and buffers and callback
+information. Buried in there is a lot of URBs for executing the segments
+and buffer transfers.
+
+For OUT xfers, there is an array of segments, one URB for each, another
+one of buffer URB. When submitting, we submit URBs for segment request
+1, buffer 1, segment 2, buffer 2...etc. Then we wait on the DTI for xfer
+result data; when all the segments are complete, we call the callback to
+finalize the transfer.
+
+For IN xfers, we only issue URBs for the segments we want to read and
+then wait for the xfer result data.
+
+*URB mapping into xfers*
+
+This is done by hwahc_op_urb_[en|de]queue(). In enqueue() we aim an
+rpipe to the endpoint where we have to transmit, create a transfer
+context (wa_xfer) and submit it. When the xfer is done, our callback is
+called and we assign the status bits and release the xfer resources.
+
+In dequeue() we are basically cancelling/aborting the transfer. We issue
+a xfer abort request to the HC, cancell all the URBs we had submitted
+and not yet done and when all that is done, the xfer callback will be
+called--this will call the URB callback.
+
+
+    Glossary
+
+*DWA* -- Device Wire Adapter
+
+USB host, wired for downstream devices, upstream connects wirelessly
+with Wireless USB.
+
+*EVENT* -- Response to a command on the NEEP
+
+*HWA* -- Host Wire Adapter / USB dongle for UWB and Wireless USB
+
+*NEH* -- Notification/Event Handle
+
+Handle/file descriptor for receiving notifications or events. The WA
+code requires you to get one of this to listen for notifications or
+events on the NEEP.
+
+*NEEP* -- Notification/Event EndPoint
+
+Stuff related to the management of the first endpoint of a HWA USB
+dongle that is used to deliver an stream of events and notifications to
+the host.
+
+*NOTIFICATION* -- Message coming in the NEEP as response to something.
+
+*RC* -- Radio Control
+
+Design-overview.txt-1.8 (last edited 2006-11-04 12:22:24 by
+InakyPerezGonzalez)
+
diff --git a/Documentation/usb/wusb-cbaf b/Documentation/usb/wusb-cbaf
new file mode 100644 (file)
index 0000000..2e78b70
--- /dev/null
@@ -0,0 +1,139 @@
+#! /bin/bash
+#
+
+set -e
+
+progname=$(basename $0)
+function help
+{
+    cat <<EOF
+Usage: $progname COMMAND DEVICEs [ARGS]
+
+Command for manipulating the pairing/authentication credentials of a
+Wireless USB device that supports wired-mode Cable-Based-Association.
+
+Works in conjunction with the wusb-cba.ko driver from http://linuxuwb.org.
+
+
+DEVICE
+
+ sysfs path to the device to authenticate; for example, both this
+ guys are the same:
+
+ /sys/devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4.4/1-4.4:1.1
+ /sys/bus/usb/drivers/wusb-cbaf/1-4.4:1.1
+
+COMMAND/ARGS are
+
+ start
+
+   Start a WUSB host controller (by setting up a CHID)
+
+ set-chid DEVICE HOST-CHID HOST-BANDGROUP HOST-NAME
+
+   Sets host information in the device; after this you can call the
+   get-cdid to see how does this device report itself to us.
+
+ get-cdid DEVICE
+
+   Get the device ID associated to the HOST-CHDI we sent with
+   'set-chid'. We might not know about it.
+
+ set-cc DEVICE
+
+   If we allow the device to connect, set a random new CDID and CK
+   (connection key). Device saves them for the next time it wants to
+   connect wireless. We save them for that next time also so we can
+   authenticate the device (when we see the CDID he uses to id
+   itself) and the CK to crypto talk to it.
+
+CHID is always 16 hex bytes in 'XX YY ZZ...' form
+BANDGROUP is almost always 0001
+
+Examples:
+
+  You can default most arguments to '' to get a sane value:
+
+  $ $progname set-chid '' '' '' "My host name"
+
+  A full sequence:
+
+  $ $progname set-chid '' '' '' "My host name"
+  $ $progname get-cdid ''
+  $ $progname set-cc ''
+
+EOF
+}
+
+
+# Defaults
+# FIXME: CHID should come from a database :), band group from the host
+host_CHID="00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff"
+host_band_group="0001"
+host_name=$(hostname)
+
+devs="$(echo /sys/bus/usb/drivers/wusb-cbaf/[0-9]*)"
+hdevs="$(for h in /sys/class/uwb_rc/*/wusbhc; do readlink -f $h; done)"
+
+result=0
+case $1 in
+    start)
+        for dev in ${2:-$hdevs}
+          do
+          uwb_rc=$(readlink -f $dev/uwb_rc)
+          if cat $uwb_rc/beacon | grep -q -- "-1"
+              then
+              echo 13 0 > $uwb_rc/beacon
+              echo I: started beaconing on ch 13 on $(basename $uwb_rc) >&2
+          fi
+          echo $host_CHID > $dev/wusb_chid
+          echo I: started host $(basename $dev) >&2
+        done
+        ;;
+    stop)
+        for dev in ${2:-$hdevs}
+          do
+          echo 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > $dev/wusb_chid
+          echo I: stopped host $(basename $dev) >&2
+          uwb_rc=$(readlink -f $dev/uwb_rc)
+          echo -1 | cat > $uwb_rc/beacon
+          echo I: stopped beaconing on $(basename $uwb_rc) >&2
+        done
+        ;;
+    set-chid)
+        shift
+        for dev in ${2:-$devs}; do
+            echo "${4:-$host_name}" > $dev/wusb_host_name
+            echo "${3:-$host_band_group}" > $dev/wusb_host_band_groups
+            echo ${2:-$host_CHID} > $dev/wusb_chid
+        done
+        ;;
+    get-cdid)
+        for dev in ${2:-$devs}
+          do
+          cat $dev/wusb_cdid
+        done
+        ;;
+    set-cc)
+        for dev in ${2:-$devs}; do
+            shift
+            CDID="$(head --bytes=16 /dev/urandom  | od -tx1 -An)"
+            CK="$(head --bytes=16 /dev/urandom  | od -tx1 -An)"
+            echo "$CDID" > $dev/wusb_cdid
+            echo "$CK" > $dev/wusb_ck
+
+            echo I: CC set >&2
+            echo "CHID: $(cat $dev/wusb_chid)"
+            echo "CDID:$CDID"
+            echo "CK:  $CK"
+        done
+        ;;
+    help|h|--help|-h)
+        help
+        ;;
+    *)
+        echo "E: Unknown usage" 1>&2
+        help 1>&2
+        result=1
+esac
+exit $result
index 355c192d699779f773259ddd647b64d574021cfe..16202c8ac68f06bf2dfcb387aa2ee91c5e9bc4f6 100644 (file)
@@ -378,8 +378,9 @@ T:  git://git.kernel.org/pub/scm/linux/kernel/git/joro/linux-2.6-iommu.git
 S:     Supported
 
 AMD MICROCODE UPDATE SUPPORT
-P:      Peter Oruba
-M:      peter.oruba@amd.com
+P:      Andreas Herrmann
+M:      andeas.herrmann3@amd.com
+L:      amd64-microcode@amd64.org
 S:      Supported
 
 AMS (Apple Motion Sensor) DRIVER
@@ -1053,6 +1054,12 @@ L:       cbe-oss-dev@ozlabs.org
 W:     http://www.ibm.com/developerworks/power/cell/
 S:     Supported
 
+CERTIFIED WIRELESS USB (WUSB) SUBSYSTEM:
+P:     David Vrabel
+M:     david.vrabel@csr.com
+L:     linux-usb@vger.kernel.org
+S:     Supported
+
 CFAG12864B LCD DRIVER
 P:     Miguel Ojeda Sandonis
 M:     miguel.ojeda.sandonis@gmail.com
@@ -1198,7 +1205,7 @@ S:        Maintained
 
 CPU FREQUENCY DRIVERS
 P:     Dave Jones
-M:     davej@codemonkey.org.uk
+M:     davej@redhat.com
 L:     cpufreq@vger.kernel.org
 W:     http://www.codemonkey.org.uk/projects/cpufreq/
 T:     git kernel.org/pub/scm/linux/kernel/git/davej/cpufreq.git
@@ -1427,8 +1434,8 @@ M:        rdunlap@xenotime.net
 S:     Maintained
 
 DOCKING STATION DRIVER
-P:     Kristen Carlson Accardi
-M:     kristen.c.accardi@intel.com
+P:     Shaohua Li
+M:     shaohua.li@intel.com
 L:     linux-acpi@vger.kernel.org
 S:     Supported
 
@@ -2103,6 +2110,12 @@ L:       linux-ide@vger.kernel.org
 L:     linux-scsi@vger.kernel.org
 S:     Orphan
 
+IDLE-I7300
+P:     Andy Henroid
+M:     andrew.d.henroid@intel.com
+L:     linux-pm@lists.linux-foundation.org
+S:     Supported
+
 IEEE 1394 SUBSYSTEM (drivers/ieee1394)
 P:     Ben Collins
 M:     ben.collins@ubuntu.com
@@ -2176,6 +2189,13 @@ M:       maciej.sosnowski@intel.com
 L:     linux-kernel@vger.kernel.org
 S:     Supported
 
+INTEL IOMMU (VT-d)
+P:     David Woodhouse
+M:     dwmw2@infradead.org
+L:     iommu@lists.linux-foundation.org
+T:     git://git.infradead.org/iommu-2.6.git
+S:     Supported
+
 INTEL IOP-ADMA DMA DRIVER
 P:     Dan Williams
 M:     dan.j.williams@intel.com
@@ -2928,9 +2948,9 @@ S:        Maintained
 
 NETEFFECT IWARP RNIC DRIVER (IW_NES)
 P:     Faisal Latif
-M:     flatif@neteffect.com
+M:     faisal.latif@intel.com
 P:     Chien Tung
-M:     ctung@neteffect.com
+M:     chien.tin.tung@intel.com
 L:     general@lists.openfabrics.org
 W:     http://www.neteffect.com
 S:     Supported
@@ -3173,6 +3193,11 @@ M:       olof@lixom.net
 L:     i2c@lm-sensors.org
 S:     Maintained
 
+PANASONIC LAPTOP ACPI EXTRAS DRIVER
+P:     Harald Welte
+M:     laforge@gnumonks.org
+S:     Maintained
+
 PANASONIC MN10300/AM33 PORT
 P:     David Howells
 M:     dhowells@redhat.com
@@ -3244,11 +3269,6 @@ L:       linux-pci@vger.kernel.org
 T:     git kernel.org:/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git
 S:     Supported
 
-PCI HOTPLUG CORE
-P:     Kristen Carlson Accardi
-M:     kristen.c.accardi@intel.com
-S:     Supported
-
 PCIE HOTPLUG DRIVER
 P:     Kristen Carlson Accardi
 M:     kristen.c.accardi@intel.com
@@ -4191,6 +4211,12 @@ L:       sparclinux@vger.kernel.org
 T:     git kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6.git
 S:     Maintained
 
+ULTRA-WIDEBAND (UWB) SUBSYSTEM:
+P:     David Vrabel
+M:     david.vrabel@csr.com
+L:     linux-usb@vger.kernel.org
+S:     Supported
+
 UNIFORM CDROM DRIVER
 P:     Jens Axboe
 M:     axboe@kernel.dk
@@ -4616,6 +4642,11 @@ M:       zaga@fly.cc.fer.hr
 L:     linux-scsi@vger.kernel.org
 S:     Maintained
 
+WIMEDIA LLC PROTOCOL (WLP) SUBSYSTEM
+P:     David Vrabel
+M:     david.vrabel@csr.com
+S:     Maintained
+
 WISTRON LAPTOP BUTTON DRIVER
 P:     Miloslav Trmac
 M:     mitr@volny.cz
index 16e3fbb968a8966bc58570ca117349631e81f2d7..f6703f1cd9c717bfaccb09f34a745ee4fd306b98 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -437,7 +437,7 @@ ifeq ($(config-targets),1)
 # KBUILD_DEFCONFIG may point out an alternative default configuration
 # used for 'make defconfig'
 include $(srctree)/arch/$(SRCARCH)/Makefile
-export KBUILD_DEFCONFIG
+export KBUILD_DEFCONFIG KBUILD_KCONFIG
 
 config %config: scripts_basic outputmakefile FORCE
        $(Q)mkdir -p include/linux include/config
index 8509dad312044ede7039ef35846b24ffe49a6582..18a3ea1aac51376882d0bd8cb50503b2d0442ee3 100644 (file)
@@ -165,14 +165,11 @@ osf_getdirentries(unsigned int fd, struct osf_dirent __user *dirent,
        buf.error = 0;
 
        error = vfs_readdir(file, osf_filldir, &buf);
-       if (error < 0)
-               goto out_putf;
-
-       error = buf.error;
+       if (error >= 0)
+               error = buf.error;
        if (count != buf.count)
                error = count - buf.count;
 
- out_putf:
        fput(file);
  out:
        return error;
@@ -986,10 +983,12 @@ asmlinkage int
 osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp,
           struct timeval32 __user *tvp)
 {
-       s64 timeout = MAX_SCHEDULE_TIMEOUT;
+       struct timespec end_time, *to = NULL;
        if (tvp) {
                time_t sec, usec;
 
+               to = &end_time;
+
                if (!access_ok(VERIFY_READ, tvp, sizeof(*tvp))
                    || __get_user(sec, &tvp->tv_sec)
                    || __get_user(usec, &tvp->tv_usec)) {
@@ -999,14 +998,13 @@ osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp,
                if (sec < 0 || usec < 0)
                        return -EINVAL;
 
-               if ((unsigned long) sec < MAX_SELECT_SECONDS) {
-                       timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
-                       timeout += sec * (unsigned long) HZ;
-               }
+               if (poll_select_set_timeout(to, sec, usec * NSEC_PER_USEC))
+                       return -EINVAL;         
+
        }
 
        /* OSF does not copy back the remaining time.  */
-       return core_sys_select(n, inp, outp, exp, &timeout);
+       return core_sys_select(n, inp, outp, exp, to);
 }
 
 struct rusage32 {
index 99a7f19da13aae935ae8b25ca9a590e8d5e02272..a4555f497639fa0c68e7da3e0284ce221005cee9 100644 (file)
@@ -47,7 +47,7 @@ typedef struct irq_swizzle_struct
 
 static irq_swizzle_t *sable_lynx_irq_swizzle;
 
-static void sable_lynx_init_irq(int nr_irqs);
+static void sable_lynx_init_irq(int nr_of_irqs);
 
 #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SABLE)
 
@@ -530,11 +530,11 @@ sable_lynx_srm_device_interrupt(unsigned long vector)
 }
 
 static void __init
-sable_lynx_init_irq(int nr_irqs)
+sable_lynx_init_irq(int nr_of_irqs)
 {
        long i;
 
-       for (i = 0; i < nr_irqs; ++i) {
+       for (i = 0; i < nr_of_irqs; ++i) {
                irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
                irq_desc[i].chip = &sable_lynx_irq_type;
        }
index 7c3d5ec6ec676d579f027b5caaddcafbb8584e3e..bd8ac533a504d96521507df11795d9e0cd032118 100644 (file)
@@ -106,7 +106,7 @@ op_axp_stop(void)
 }
 
 static int
-op_axp_create_files(struct super_block * sb, struct dentry * root)
+op_axp_create_files(struct super_block *sb, struct dentry *root)
 {
        int i;
 
index df39d20f7425ad9c41679a566ae212f924a222ff..5021db2217eddfbecd628aba53ca44f6fb62ade9 100644 (file)
@@ -356,7 +356,7 @@ config ARCH_IXP4XX
        select GENERIC_GPIO
        select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
-       select ZONE_DMA if PCI
+       select DMABOUNCE if PCI
        help
          Support for Intel's IXP4XX (XScale) family of processors.
 
@@ -540,16 +540,15 @@ config ARCH_OMAP
        help
          Support for TI's OMAP platform (OMAP1 and OMAP2).
 
-config ARCH_MSM7X00A
-       bool "Qualcomm MSM7X00A"
+config ARCH_MSM
+       bool "Qualcomm MSM"
        select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        help
-         Support for Qualcomm MSM7X00A based systems.  This runs on the ARM11
-         apps processor of the MSM7X00A and depends on a shared memory
+         Support for Qualcomm MSM7K based systems.  This runs on the ARM11
+         apps processor of the MSM7K and depends on a shared memory
          interface to the ARM9 modem processor which runs the baseband stack
          and controls some vital subsystems (clock and power control, etc).
-         <http://www.cdmatech.com/products/msm7200_chipset_solution.jsp>
 
 endchoice
 
@@ -1256,6 +1255,8 @@ source "drivers/hid/Kconfig"
 
 source "drivers/usb/Kconfig"
 
+source "drivers/uwb/Kconfig"
+
 source "drivers/mmc/Kconfig"
 
 source "drivers/memstick/Kconfig"
index 7d5121260fda0370fe85303120544af07689cf79..bd6e28115ebb36284050b290ea1d8800fbec3763 100644 (file)
@@ -141,7 +141,7 @@ endif
  machine-$(CONFIG_ARCH_MX3)       := mx3
  machine-$(CONFIG_ARCH_ORION5X)           := orion5x
     plat-$(CONFIG_PLAT_ORION)     := orion
- machine-$(CONFIG_ARCH_MSM7X00A)   := msm
+ machine-$(CONFIG_ARCH_MSM)       := msm
  machine-$(CONFIG_ARCH_LOKI)       := loki
  machine-$(CONFIG_ARCH_MV78XX0)    := mv78xx0
 
index 2e32acca02fbb83374c74f67e1fba340cfaa9a2c..86b5e6982660da255a13148a9392dc4d73def0b4 100644 (file)
@@ -13,10 +13,10 @@ config ICST307
 config SA1111
        bool
        select DMABOUNCE if !ARCH_PXA
-       select ZONE_DMA if !ARCH_PXA
 
 config DMABOUNCE
        bool
+       select ZONE_DMA
 
 config TIMER_ACORN
        bool
index fb86f248aab84c2aa73f5d8c383f745c2d5e3e15..47ccec95f3e867ce5141f7e0db7bdb7f2e57667d 100644 (file)
@@ -581,6 +581,7 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
                goto out;
        }
 
+#ifdef CONFIG_DMABOUNCE
        /*
         * If the parent device has a DMA mask associated with it,
         * propagate it down to the children.
@@ -598,6 +599,7 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
                        }
                }
        }
+#endif
 
 out:
        return ret;
@@ -937,7 +939,7 @@ static int sa1111_resume(struct platform_device *dev)
 #define sa1111_resume  NULL
 #endif
 
-static int sa1111_probe(struct platform_device *pdev)
+static int __devinit sa1111_probe(struct platform_device *pdev)
 {
        struct resource *mem;
        int irq;
index 9b8748a8d9ddaa9ee9808262e54ae0b67ea1d8b0..f3af0b593eb08ab5149acca798ca53acbb8b2c47 100644 (file)
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Mon Nov 28 10:30:09 2005
+# Linux kernel version: 2.6.27
+# Mon Oct 20 10:12:23 2008
 #
 CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_MMU=y
-CONFIG_UID16=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=m
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
-
-#
-# Block layer
-#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -79,50 +119,97 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
 
 #
 # System Type
 #
+# 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_CLPS7500 is not set
 # CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
 # CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
 CONFIG_ARCH_PXA=y
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_REALVIEW is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_MSM7X00A is not set
 
 #
-# Intel PXA2xx Implementations
+# Intel PXA2xx/PXA3xx Implementations
 #
+# CONFIG_ARCH_GUMSTIX is not set
 # CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_LOGICPD_PXA270 is not set
 # CONFIG_MACH_MAINSTONE is not set
+# CONFIG_MACH_MP900C is not set
 # CONFIG_ARCH_PXA_IDP is not set
 CONFIG_PXA_SHARPSL=y
-CONFIG_PXA_SHARPSL_25x=y
-# CONFIG_PXA_SHARPSL_27x is not set
 CONFIG_MACH_POODLE=y
 CONFIG_MACH_CORGI=y
 CONFIG_MACH_SHEPHERD=y
 CONFIG_MACH_HUSKY=y
+# CONFIG_MACH_AKITA is not set
+# CONFIG_MACH_SPITZ is not set
+# CONFIG_MACH_BORZOI is not set
 CONFIG_MACH_TOSA=y
+# CONFIG_ARCH_VIPER is not set
+# CONFIG_ARCH_PXA_ESERIES is not set
+# CONFIG_TRIZEPS_PXA is not set
+# CONFIG_MACH_EM_X270 is not set
+# CONFIG_MACH_COLIBRI is not set
+# CONFIG_MACH_ZYLONITE is not set
+# CONFIG_MACH_LITTLETON is not set
+# CONFIG_MACH_TAVOREVB is not set
+# CONFIG_MACH_SAAR is not set
+# CONFIG_MACH_ARMCORE is not set
+# CONFIG_MACH_CM_X300 is not set
+# CONFIG_MACH_MAGICIAN is not set
+# CONFIG_MACH_MIOA701 is not set
+# CONFIG_MACH_PCM027 is not set
+# CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_PXA_EZX is not set
 CONFIG_PXA25x=y
 CONFIG_PXA_SHARP_C7xx=y
 CONFIG_PXA_SSP=y
+# CONFIG_PXA_PWM is not set
+# CONFIG_TOSA_BT is not set
+CONFIG_PXA_HAVE_BOARD_IRQS=y
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
 
 #
 # Processor Type
@@ -131,25 +218,30 @@ CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_PABRT_NOIFAR=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
 
 #
 # Processor Features
 #
 CONFIG_ARM_THUMB=y
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
+# CONFIG_IWMMXT is not set
 CONFIG_XSCALE_PMU=y
+CONFIG_SHARP_LOCOMO=y
 CONFIG_SHARP_PARAM=y
+CONFIG_SHARPSL_PM=y
 CONFIG_SHARP_SCOOP=y
 
 #
 # Bus support
 #
-CONFIG_ISA_DMA_API=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCCARD=y
 # CONFIG_PCMCIA_DEBUG is not set
 CONFIG_PCMCIA=y
@@ -164,16 +256,32 @@ CONFIG_PCMCIA_PXA2XX=y
 #
 # Kernel Features
 #
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
 CONFIG_PREEMPT=y
-# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -183,6 +291,13 @@ CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2   debug"
 # CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
 
 #
 # Floating point emulation
@@ -199,6 +314,7 @@ CONFIG_FPE_NWFPE=y
 # Userspace binary formats
 #
 CONFIG_BINFMT_ELF=y
+CONFIG_HAVE_AOUT=y
 CONFIG_BINFMT_AOUT=m
 CONFIG_BINFMT_MISC=m
 # CONFIG_ARTHUR is not set
@@ -207,12 +323,12 @@ CONFIG_BINFMT_MISC=m
 # Power management options
 #
 CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
-CONFIG_APM=y
-
-#
-# Networking
-#
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_APM_EMULATION=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
 #
@@ -223,6 +339,10 @@ CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -236,140 +356,131 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
 CONFIG_IPV6=m
 # CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=m
 CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
 CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
 
 #
 # Core Netfilter Configuration
 #
-# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_IP_VS is not set
 
 #
 # IP: Netfilter Configuration
 #
-CONFIG_IP_NF_CONNTRACK=m
-# CONFIG_IP_NF_CT_ACCT is not set
-# CONFIG_IP_NF_CONNTRACK_MARK is not set
-# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
-CONFIG_IP_NF_CT_PROTO_SCTP=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_NETBIOS_NS is not set
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-# CONFIG_IP_NF_PPTP is not set
+# CONFIG_NF_DEFRAG_IPV4 is not set
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+# CONFIG_IP_NF_MATCH_AH is not set
 CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
 CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_REALM=m
-CONFIG_IP_NF_MATCH_SCTP=m
-# CONFIG_IP_NF_MATCH_DCCP is not set
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
-# CONFIG_IP_NF_MATCH_STRING is not set
 CONFIG_IP_NF_FILTER=m
 # CONFIG_IP_NF_TARGET_REJECT is not set
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-# CONFIG_IP_NF_TARGET_NFQUEUE is not set
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-# CONFIG_IP_NF_TARGET_MASQUERADE is not set
-# CONFIG_IP_NF_TARGET_REDIRECT is not set
-# CONFIG_IP_NF_TARGET_NETMAP is not set
-# CONFIG_IP_NF_TARGET_SAME is not set
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
 CONFIG_IP_NF_MANGLE=m
-# CONFIG_IP_NF_TARGET_TOS is not set
 # CONFIG_IP_NF_TARGET_ECN is not set
-# CONFIG_IP_NF_TARGET_DSCP is not set
-# CONFIG_IP_NF_TARGET_MARK is not set
-# CONFIG_IP_NF_TARGET_CLASSIFY is not set
 # CONFIG_IP_NF_TARGET_TTL is not set
 CONFIG_IP_NF_RAW=m
-# CONFIG_IP_NF_TARGET_NOTRACK is not set
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 
 #
-# IPv6: Netfilter Configuration (EXPERIMENTAL)
+# IPv6: Netfilter Configuration
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
-CONFIG_IP6_NF_MATCH_RT=m
-CONFIG_IP6_NF_MATCH_OPTS=m
+# CONFIG_IP6_NF_MATCH_AH is not set
+CONFIG_IP6_NF_MATCH_EUI64=m
 CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_HL=m
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
-CONFIG_IP6_NF_MATCH_OWNER=m
-CONFIG_IP6_NF_MATCH_MARK=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_AHESP=m
-CONFIG_IP6_NF_MATCH_LENGTH=m
-CONFIG_IP6_NF_MATCH_EUI64=m
-CONFIG_IP6_NF_FILTER=m
+# CONFIG_IP6_NF_MATCH_MH is not set
+CONFIG_IP6_NF_MATCH_RT=m
 # CONFIG_IP6_NF_TARGET_LOG is not set
+CONFIG_IP6_NF_FILTER=m
 # CONFIG_IP6_NF_TARGET_REJECT is not set
-# CONFIG_IP6_NF_TARGET_NFQUEUE is not set
 CONFIG_IP6_NF_MANGLE=m
-# CONFIG_IP6_NF_TARGET_MARK is not set
 # CONFIG_IP6_NF_TARGET_HL is not set
 CONFIG_IP6_NF_RAW=m
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -377,21 +488,16 @@ CONFIG_IP6_NF_RAW=m
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
 # CONFIG_NET_SCHED is not set
-CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 CONFIG_IRDA=m
 
 #
@@ -421,27 +527,17 @@ CONFIG_IRCOMM=m
 #
 # Dongle support
 #
-
-#
-# Old SIR device drivers
-#
-# CONFIG_IRPORT_SIR is not set
-
-#
-# Old Serial dongle support
-#
+# 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_NSC_FIR is not set
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-# CONFIG_VIA_FIR is not set
 CONFIG_PXA_FICP=m
+# CONFIG_MCS_FIR is not set
 CONFIG_BT=m
 CONFIG_BT_L2CAP=m
 CONFIG_BT_SCO=m
@@ -457,9 +553,12 @@ CONFIG_BT_HIDP=m
 #
 CONFIG_BT_HCIUSB=m
 # CONFIG_BT_HCIUSB_SCO is not set
+# CONFIG_BT_HCIBTUSB is not set
+# CONFIG_BT_HCIBTSDIO is not set
 CONFIG_BT_HCIUART=m
 CONFIG_BT_HCIUART_H4=y
 CONFIG_BT_HCIUART_BCSP=y
+# CONFIG_BT_HCIUART_LL is not set
 CONFIG_BT_HCIBCM203X=m
 CONFIG_BT_HCIBPA10X=m
 CONFIG_BT_HCIBFUSB=m
@@ -468,11 +567,20 @@ CONFIG_BT_HCIBT3C=m
 CONFIG_BT_HCIBLUECARD=m
 CONFIG_BT_HCIBTUART=m
 CONFIG_BT_HCIVHCI=m
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 # CONFIG_IEEE80211_CRYPT_CCMP is not set
 # CONFIG_IEEE80211_CRYPT_TKIP is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -481,19 +589,16 @@ CONFIG_IEEE80211_CRYPT_WEP=m
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_DEBUG_DRIVER is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
@@ -501,16 +606,20 @@ CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_AFS_PARTS is not set
+# 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
@@ -535,16 +644,18 @@ CONFIG_MTD_ROM=y
 # Mapping drivers for chip access
 #
 CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
 CONFIG_MTD_SHARP_SL=y
 # 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_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
 # CONFIG_MTD_BLOCK2MTD is not set
 
 #
@@ -553,78 +664,66 @@ CONFIG_MTD_SHARP_SL=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_VERIFY_WRITE=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
 # CONFIG_MTD_NAND_H1900 is not set
 CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 CONFIG_MTD_NAND_SHARPSL=y
 # CONFIG_MTD_NAND_NANDSIM is not set
-
-#
-# OneNAND Flash Device Drivers
-#
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
 # CONFIG_MTD_ONENAND is not set
 
 #
-# Parallel port support
+# UBI - Unsorted block images
 #
+# CONFIG_MTD_UBI is not set
 # CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 # CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
 
 #
-# Please see Documentation/ide.txt for help/info on IDE drives
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
 CONFIG_BLK_DEV_IDECS=y
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
 
 #
 # IDE chipset support/bugfixes
 #
-CONFIG_IDE_GENERIC=y
-# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
 # CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -644,121 +743,76 @@ CONFIG_CHR_DEV_SG=m
 CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
 
 #
-# SCSI Transport Attributes
+# 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_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_DEBUG is not set
-
-#
-# PCMCIA SCSI adapter support
-#
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-# CONFIG_PCMCIA_SYM53C500 is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-
-#
-# PHY device support
-#
+# CONFIG_VETH is not set
 # CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=m
+# CONFIG_AX88796 is not set
 # CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
 
 #
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-# CONFIG_PCMCIA_WAVELAN is not set
-# CONFIG_PCMCIA_NETWAVE is not set
-
-#
-# Wireless 802.11 Frequency Hopping cards support
+# Wireless LAN
 #
-# CONFIG_PCMCIA_RAYCS is not set
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
 
 #
-# Wireless 802.11b ISA/PCI cards support
-#
-CONFIG_HERMES=m
-# CONFIG_ATMEL is not set
-
-#
-# Wireless 802.11b Pcmcia/Cardbus cards support
-#
-CONFIG_PCMCIA_HERMES=m
-CONFIG_PCMCIA_SPECTRUM=m
-# CONFIG_AIRO_CS is not set
-# CONFIG_PCMCIA_WL3501 is not set
-CONFIG_HOSTAP=m
-CONFIG_HOSTAP_FIRMWARE=y
-CONFIG_HOSTAP_CS=m
-CONFIG_NET_WIRELESS=y
-
-#
-# PCMCIA network device support
+# USB Network Adapters
 #
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+# CONFIG_USB_NET_DM9601 is not set
+# CONFIG_USB_NET_SMSC95XX is not set
+# CONFIG_USB_NET_GL620A is not set
+CONFIG_USB_NET_NET1080=m
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_MCS7830 is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+CONFIG_USB_NET_ZAURUS=m
 CONFIG_NET_PCMCIA=y
 # CONFIG_PCMCIA_3C589 is not set
 # CONFIG_PCMCIA_3C574 is not set
@@ -768,10 +822,6 @@ CONFIG_PCMCIA_PCNET=m
 # CONFIG_PCMCIA_SMC91C92 is not set
 # CONFIG_PCMCIA_XIRC2PS is not set
 # CONFIG_PCMCIA_AXNET is not set
-
-#
-# Wan interfaces
-#
 # CONFIG_WAN is not set
 CONFIG_PPP=m
 # CONFIG_PPP_MULTILINK is not set
@@ -782,30 +832,29 @@ CONFIG_PPP_ASYNC=m
 CONFIG_PPP_BSDCOMP=m
 # CONFIG_PPP_MPPE is not set
 # CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
 # CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
+CONFIG_SLHC=m
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
 # CONFIG_ISDN 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_TSDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
+# CONFIG_INPUT_APMPOWER is not set
 
 #
 # Input Device Drivers
@@ -814,19 +863,39 @@ CONFIG_INPUT_KEYBOARD=y
 # CONFIG_KEYBOARD_ATKBD is not set
 # CONFIG_KEYBOARD_SUNKBD is not set
 # CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_LOCOMO is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_KEYBOARD_CORGI=y
 CONFIG_KEYBOARD_SPITZ=y
+CONFIG_KEYBOARD_TOSA=y
+# CONFIG_KEYBOARD_TOSA_USE_EXT_KEYCODES is not set
+# CONFIG_KEYBOARD_GPIO 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_CORGI=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+# CONFIG_TOUCHSCREEN_CORGI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
 # CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_TOUCHSCREEN_ELO 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_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=m
 
 #
@@ -839,8 +908,11 @@ CONFIG_INPUT_UINPUT=m
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -849,6 +921,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=m
 CONFIG_SERIAL_8250_CS=m
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -860,97 +933,130 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=m
 # CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 
-#
-# Ftape, the floppy tape device driver
-#
-
 #
 # PCMCIA character devices
 #
 # CONFIG_SYNCLINK_CS is not set
 # CONFIG_CARDMAN_4000 is not set
 # CONFIG_CARDMAN_4040 is not set
+# CONFIG_IPWIRELESS is not set
 # CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
 CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
 # CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
 
 #
-# I2C Algorithms
+# I2C Hardware Bus support
 #
-CONFIG_I2C_ALGOBIT=y
-# 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_GPIO is not set
+# CONFIG_I2C_OCORES is not set
 CONFIG_I2C_PXA=y
 # CONFIG_I2C_PXA_SLAVE 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
-# CONFIG_I2C_PCA_ISA is not set
 
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_TPS65010 is not set
 # CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_RTC_X1205_I2C 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
 
 #
-# Hardware Monitoring support
+# SPI Master Controller Drivers
 #
+# CONFIG_SPI_BITBANG is not set
+CONFIG_SPI_PXA2XX=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
 # CONFIG_SENSORS_GL518SM is not set
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -960,70 +1066,193 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+CONFIG_SENSORS_MAX1111=y
 # 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_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_VT1211 is not set
 # CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
 # CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
 # CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
 
 #
-# Misc devices
+# Sonics Silicon Backplane
 #
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
-# Multimedia Capabilities Port drivers
+# Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_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_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
 
 #
 # Multimedia devices
 #
-CONFIG_VIDEO_DEV=m
-
-#
-# Video For Linux
-#
 
 #
-# Video Adapters
+# Multimedia core support
 #
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L2_COMMON=m
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=m
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=m
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=m
+CONFIG_MEDIA_TUNER_TDA8290=m
+CONFIG_MEDIA_TUNER_TDA9887=m
+CONFIG_MEDIA_TUNER_TEA5761=m
+CONFIG_MEDIA_TUNER_TEA5767=m
+CONFIG_MEDIA_TUNER_MT20XX=m
+CONFIG_MEDIA_TUNER_XC2028=m
+CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_VIDEO_V4L2=m
+CONFIG_VIDEO_V4L1=m
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+# CONFIG_VIDEO_VIVI is not set
 # CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
 # CONFIG_VIDEO_SAA5246A is not set
 # CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
+# CONFIG_SOC_CAMERA is not set
+CONFIG_V4L_USB_DRIVERS=y
+# CONFIG_USB_VIDEO_CLASS is not set
+CONFIG_USB_GSPCA=m
+# CONFIG_USB_M5602 is not set
+# CONFIG_USB_GSPCA_CONEX is not set
+# CONFIG_USB_GSPCA_ETOMS is not set
+# CONFIG_USB_GSPCA_FINEPIX is not set
+# CONFIG_USB_GSPCA_MARS is not set
+# CONFIG_USB_GSPCA_OV519 is not set
+# CONFIG_USB_GSPCA_PAC207 is not set
+# CONFIG_USB_GSPCA_PAC7311 is not set
+# CONFIG_USB_GSPCA_SONIXB is not set
+# CONFIG_USB_GSPCA_SONIXJ is not set
+# CONFIG_USB_GSPCA_SPCA500 is not set
+# CONFIG_USB_GSPCA_SPCA501 is not set
+# CONFIG_USB_GSPCA_SPCA505 is not set
+# CONFIG_USB_GSPCA_SPCA506 is not set
+# CONFIG_USB_GSPCA_SPCA508 is not set
+# CONFIG_USB_GSPCA_SPCA561 is not set
+# CONFIG_USB_GSPCA_STK014 is not set
+# CONFIG_USB_GSPCA_SUNPLUS is not set
+# CONFIG_USB_GSPCA_T613 is not set
+# CONFIG_USB_GSPCA_TV8532 is not set
+# CONFIG_USB_GSPCA_VC032X is not set
+# CONFIG_USB_GSPCA_ZC3XX is not set
+# CONFIG_VIDEO_PVRUSB2 is not set
 # CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_USBVISION is not set
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
 # CONFIG_VIDEO_OVCAMCHIP is not set
-# CONFIG_VIDEO_AUDIO_DECODER is not set
-# CONFIG_VIDEO_DECODER is not set
-
-#
-# Radio Adapters
-#
-# CONFIG_RADIO_MAESTRO is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+# CONFIG_USB_ZC0301 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_ZR364XX is not set
+# CONFIG_USB_STKWEBCAM is not set
+# CONFIG_USB_S2255 is not set
+CONFIG_RADIO_ADAPTERS=y
+CONFIG_USB_DSBR=m
+# CONFIG_USB_SI470X is not set
+# CONFIG_USB_MR800 is not set
+# CONFIG_DAB 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_S1D13XXX is not set
 # CONFIG_FB_PXA is not set
+# CONFIG_FB_MBX is not set
 CONFIG_FB_W100=y
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_CORGI=y
+# 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_LOCOMO=y
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
 
 #
 # Console display driver support
@@ -1031,6 +1260,7 @@ CONFIG_FB_W100=y
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
 # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 CONFIG_FONTS=y
 CONFIG_FONT_8x8=y
@@ -1043,93 +1273,95 @@ CONFIG_FONT_8x16=y
 # CONFIG_FONT_SUN8x16 is not set
 # CONFIG_FONT_SUN12x22 is not set
 # CONFIG_FONT_10x18 is not set
-
-#
-# Logo configuration
-#
 # CONFIG_LOGO is not set
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_DEVICE=y
-# CONFIG_LCD_CLASS_DEVICE is not set
-CONFIG_BACKLIGHT_CORGI=y
-
-#
-# Sound
-#
 CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+# CONFIG_SND is not set
+CONFIG_SOUND_PRIME=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
 
 #
-# Advanced Linux Sound Architecture
+# USB Input Devices
 #
-# CONFIG_SND is not set
+CONFIG_USB_HID=m
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
 
 #
-# Open Sound System
+# USB HID Boot Protocol drivers
 #
-CONFIG_SOUND_PRIME=y
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-CONFIG_SOUND_OSS=y
-# CONFIG_SOUND_TRACEINIT is not set
-# CONFIG_SOUND_DMAP is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_ADLIB is not set
-# CONFIG_SOUND_ACI_MIXER is not set
-# CONFIG_SOUND_CS4232 is not set
-# CONFIG_SOUND_SSCAPE is not set
-# CONFIG_SOUND_GUS is not set
-# CONFIG_SOUND_VMIDI is not set
-# CONFIG_SOUND_TRIX is not set
-# CONFIG_SOUND_MSS is not set
-# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_NM256 is not set
-# CONFIG_SOUND_MAD16 is not set
-# CONFIG_SOUND_PAS is not set
-# CONFIG_SOUND_PSS is not set
-# CONFIG_SOUND_SB is not set
-# CONFIG_SOUND_AWE32_SYNTH is not set
-# CONFIG_SOUND_WAVEFRONT is not set
-# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_OPL3SA2 is not set
-# CONFIG_SOUND_UART6850 is not set
-# CONFIG_SOUND_AEDSP16 is not set
-# CONFIG_SOUND_TVMIXER is not set
-# CONFIG_SOUND_AD1980 is not set
-
-#
-# USB support
+CONFIG_USB_KBD=m
+CONFIG_USB_MOUSE=m
+
 #
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=m
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_BRIGHT=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_DELL=m
+CONFIG_HID_EZKEY=m
+CONFIG_HID_GYRATION=m
+CONFIG_HID_LOGITECH=m
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+CONFIG_HID_PANTHERLORD=m
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+CONFIG_THRUSTMASTER_FF=m
+CONFIG_ZEROPLUS_FF=m
+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=m
 # CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
 
 #
 # Miscellaneous USB options
 #
 CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
+CONFIG_USB_DEVICE_CLASS=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
 
 #
 # USB Host Controller Drivers
 #
+# CONFIG_USB_C67X00_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_SL811_HCD=m
 CONFIG_USB_SL811_CS=m
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
 # USB Device Class drivers
 #
-# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
 CONFIG_USB_ACM=m
 CONFIG_USB_PRINTER=m
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -1148,33 +1380,11 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
-
-#
-# USB Input Devices
-#
-CONFIG_USB_HID=m
-CONFIG_USB_HIDINPUT=y
-# CONFIG_HID_FF is not set
-# CONFIG_USB_HIDDEV is not set
-
-#
-# USB HID Boot Protocol drivers
-#
-CONFIG_USB_KBD=m
-CONFIG_USB_MOUSE=m
-CONFIG_USB_AIPTEK=m
-CONFIG_USB_WACOM=m
-# CONFIG_USB_ACECAD is not set
-CONFIG_USB_KBTAB=m
-CONFIG_USB_POWERMATE=m
-CONFIG_USB_MTOUCH=m
-# CONFIG_USB_ITMTOUCH is not set
-CONFIG_USB_EGALAX=m
-# CONFIG_USB_YEALINK is not set
-CONFIG_USB_XPAD=m
-CONFIG_USB_ATI_REMOTE=m
-# CONFIG_USB_KEYSPAN_REMOTE is not set
-# CONFIG_USB_APPLETOUCH 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
@@ -1182,57 +1392,23 @@ CONFIG_USB_ATI_REMOTE=m
 CONFIG_USB_MDC800=m
 CONFIG_USB_MICROTEK=m
 
-#
-# USB Multimedia devices
-#
-CONFIG_USB_DABUSB=m
-CONFIG_USB_VICAM=m
-CONFIG_USB_DSBR=m
-CONFIG_USB_IBMCAM=m
-CONFIG_USB_KONICAWC=m
-CONFIG_USB_OV511=m
-CONFIG_USB_SE401=m
-CONFIG_USB_SN9C102=m
-CONFIG_USB_STV680=m
-# CONFIG_USB_PWC is not set
-
-#
-# USB Network Adapters
-#
-CONFIG_USB_CATC=m
-CONFIG_USB_KAWETH=m
-CONFIG_USB_PEGASUS=m
-CONFIG_USB_RTL8150=m
-CONFIG_USB_USBNET=m
-CONFIG_USB_NET_AX8817X=m
-CONFIG_USB_NET_CDCETHER=m
-# CONFIG_USB_NET_GL620A is not set
-CONFIG_USB_NET_NET1080=m
-# CONFIG_USB_NET_PLUSB is not set
-# CONFIG_USB_NET_RNDIS_HOST is not set
-# CONFIG_USB_NET_CDC_SUBSET is not set
-CONFIG_USB_NET_ZAURUS=m
-# CONFIG_USB_ZD1201 is not set
-CONFIG_USB_MON=y
-
 #
 # USB port drivers
 #
-
-#
-# USB Serial Converter support
-#
 CONFIG_USB_SERIAL=m
+CONFIG_USB_EZUSB=y
 CONFIG_USB_SERIAL_GENERIC=y
-# CONFIG_USB_SERIAL_AIRPRIME is not set
-# CONFIG_USB_SERIAL_ANYDATA is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
 CONFIG_USB_SERIAL_BELKIN=m
+# CONFIG_USB_SERIAL_CH341 is not set
 # CONFIG_USB_SERIAL_WHITEHEAT is not set
 CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
 # CONFIG_USB_SERIAL_CP2101 is not set
 CONFIG_USB_SERIAL_CYPRESS_M8=m
 CONFIG_USB_SERIAL_EMPEG=m
 CONFIG_USB_SERIAL_FTDI_SIO=m
+# CONFIG_USB_SERIAL_FUNSOFT is not set
 CONFIG_USB_SERIAL_VISOR=m
 CONFIG_USB_SERIAL_IPAQ=m
 CONFIG_USB_SERIAL_IR=m
@@ -1240,6 +1416,7 @@ CONFIG_USB_SERIAL_EDGEPORT=m
 CONFIG_USB_SERIAL_EDGEPORT_TI=m
 CONFIG_USB_SERIAL_GARMIN=m
 CONFIG_USB_SERIAL_IPW=m
+# CONFIG_USB_SERIAL_IUU is not set
 CONFIG_USB_SERIAL_KEYSPAN_PDA=m
 CONFIG_USB_SERIAL_KEYSPAN=m
 # CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
@@ -1257,50 +1434,68 @@ CONFIG_USB_SERIAL_KEYSPAN=m
 CONFIG_USB_SERIAL_KLSI=m
 CONFIG_USB_SERIAL_KOBIL_SCT=m
 CONFIG_USB_SERIAL_MCT_U232=m
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
 # CONFIG_USB_SERIAL_HP4X is not set
 CONFIG_USB_SERIAL_SAFE=m
 # CONFIG_USB_SERIAL_SAFE_PADDED is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
 CONFIG_USB_SERIAL_TI=m
 CONFIG_USB_SERIAL_CYBERJACK=m
 CONFIG_USB_SERIAL_XIRCOM=m
+# CONFIG_USB_SERIAL_OPTION is not set
 CONFIG_USB_SERIAL_OMNINET=m
-CONFIG_USB_EZUSB=y
+# CONFIG_USB_SERIAL_DEBUG is not set
 
 #
 # USB Miscellaneous drivers
 #
 CONFIG_USB_EMI62=m
 CONFIG_USB_EMI26=m
-CONFIG_USB_AUERSWALD=m
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
 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=m
-CONFIG_USB_PHIDGETKIT=m
-CONFIG_USB_PHIDGETSERVO=m
+# CONFIG_USB_PHIDGET is not set
 CONFIG_USB_IDMOUSE=m
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY 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
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
-#
+# 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
+CONFIG_USB_GADGET_VBUS_DRAW=2
 CONFIG_USB_GADGET_SELECTED=y
-# CONFIG_USB_GADGET_NET2280 is not set
-CONFIG_USB_GADGET_PXA2XX=y
-CONFIG_USB_PXA2XX=y
-# CONFIG_USB_PXA2XX_SMALL is not set
-# CONFIG_USB_GADGET_GOKU is not set
+# 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=y
+CONFIG_USB_PXA25X=y
+# CONFIG_USB_PXA25X_SMALL is not set
+# CONFIG_USB_GADGET_PXA27X 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_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
 # CONFIG_USB_GADGET_DUMMY_HCD is not set
 # CONFIG_USB_GADGET_DUALSPEED is not set
 CONFIG_USB_ZERO=m
@@ -1310,15 +1505,42 @@ CONFIG_USB_GADGETFS=m
 CONFIG_USB_FILE_STORAGE=m
 # CONFIG_USB_FILE_STORAGE_TEST is not set
 CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
 
 #
-# MMC/SD Card support
+# MMC/SD/SDIO Card Drivers
 #
-CONFIG_MMC=y
-# CONFIG_MMC_DEBUG is not set
 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_PXA=y
-# CONFIG_MMC_WBSD is not set
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+
+#
+# Voltage and Current regulators
+#
+# CONFIG_REGULATOR is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_UIO is not set
 
 #
 # File systems
@@ -1327,16 +1549,17 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD 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_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
@@ -1361,11 +1584,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=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_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1377,39 +1602,42 @@ CONFIG_RAMFS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
 CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
 CONFIG_JFFS2_COMPRESSION_OPTIONS=y
 CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 CONFIG_JFFS2_RUBIN=y
 # CONFIG_JFFS2_CMODE_NONE is not set
 CONFIG_JFFS2_CMODE_PRIORITY=y
 # CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
 CONFIG_CRAMFS=m
 # 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
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
-# CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
 CONFIG_SUNRPC_GSS=m
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=m
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1419,7 +1647,6 @@ CONFIG_SMB_NLS_REMOTE="cp437"
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -1439,11 +1666,9 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
-
-#
-# Native Language Support
-#
+# CONFIG_SYSV68_PARTITION is not set
 CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="cp437"
 CONFIG_NLS_CODEPAGE_437=y
@@ -1484,35 +1709,71 @@ CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=y
-
-#
-# Profiling support
-#
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
+# CONFIG_DLM is not set
 
 #
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
-CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
 # CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
 CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
 # CONFIG_DEBUG_USER is not set
 CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_DEBUG_LL=y
 # CONFIG_DEBUG_ICEDCC is not set
 
@@ -1521,46 +1782,113 @@ CONFIG_DEBUG_LL=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
 
 #
-# Cryptographic options
+# Crypto core or helper
 #
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_GF128MUL is not set
 CONFIG_CRYPTO_NULL=m
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=m
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
 # CONFIG_CRYPTO_TGR192 is not set
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
 CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+# CONFIG_CRYPTO_CAMELLIA is not set
 CONFIG_CRYPTO_CAST5=m
 CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
 CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
 CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_TEST=m
+# CONFIG_CRYPTO_LZO is not set
 
 #
-# Hardware crypto devices
+# Random Number Generation
 #
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=y
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index ae4c5e62086ac454b7e4e140ec66f0acc74dcfbf..3b4ecf2a90ddd0328e08a44ce018243b1ac665f4 100644 (file)
@@ -133,7 +133,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
-CONFIG_ARCH_MSM7X00A=y
+CONFIG_ARCH_MSM=y
 
 #
 # Boot options
index 7d59fb1f1ceaa523bfc3433b6d1498d9d67b0e94..4df5b4db2aa0663f698c4cae844ecf3c1940ca3e 100644 (file)
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Mon Nov 28 10:26:52 2005
+# Linux kernel version: 2.6.27
+# Mon Oct 20 10:25:37 2008
 #
 CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_MMU=y
-CONFIG_UID16=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=m
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
-
-#
-# Block layer
-#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -79,49 +119,95 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
 
 #
 # System Type
 #
+# 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_CLPS7500 is not set
 # CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
 # CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
 CONFIG_ARCH_PXA=y
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_REALVIEW is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_MSM7X00A is not set
 
 #
-# Intel PXA2xx Implementations
+# Intel PXA2xx/PXA3xx Implementations
 #
+# CONFIG_ARCH_GUMSTIX is not set
 # CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_LOGICPD_PXA270 is not set
 # CONFIG_MACH_MAINSTONE is not set
+# CONFIG_MACH_MP900C is not set
 # CONFIG_ARCH_PXA_IDP is not set
 CONFIG_PXA_SHARPSL=y
-# CONFIG_PXA_SHARPSL_25x is not set
-CONFIG_PXA_SHARPSL_27x=y
+# CONFIG_MACH_POODLE is not set
+# CONFIG_MACH_CORGI is not set
+# CONFIG_MACH_SHEPHERD is not set
+# CONFIG_MACH_HUSKY is not set
 CONFIG_MACH_AKITA=y
 CONFIG_MACH_SPITZ=y
 CONFIG_MACH_BORZOI=y
+# CONFIG_MACH_TOSA is not set
+# CONFIG_ARCH_VIPER is not set
+# CONFIG_ARCH_PXA_ESERIES is not set
+# CONFIG_TRIZEPS_PXA is not set
+# CONFIG_MACH_EM_X270 is not set
+# CONFIG_MACH_COLIBRI is not set
+# CONFIG_MACH_ZYLONITE is not set
+# CONFIG_MACH_LITTLETON is not set
+# CONFIG_MACH_TAVOREVB is not set
+# CONFIG_MACH_SAAR is not set
+# CONFIG_MACH_ARMCORE is not set
+# CONFIG_MACH_CM_X300 is not set
+# CONFIG_MACH_MAGICIAN is not set
+# CONFIG_MACH_MIOA701 is not set
+# CONFIG_MACH_PCM027 is not set
+# CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_PXA_EZX is not set
 CONFIG_PXA27x=y
-CONFIG_IWMMXT=y
 CONFIG_PXA_SHARP_Cxx00=y
 CONFIG_PXA_SSP=y
+# CONFIG_PXA_PWM is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
 
 #
 # Processor Type
@@ -130,25 +216,29 @@ CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_PABRT_NOIFAR=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
 
 #
 # Processor Features
 #
 CONFIG_ARM_THUMB=y
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
+CONFIG_IWMMXT=y
 CONFIG_XSCALE_PMU=y
 CONFIG_SHARP_PARAM=y
+CONFIG_SHARPSL_PM=y
 CONFIG_SHARP_SCOOP=y
 
 #
 # Bus support
 #
-CONFIG_ISA_DMA_API=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCCARD=y
 # CONFIG_PCMCIA_DEBUG is not set
 CONFIG_PCMCIA=y
@@ -163,16 +253,32 @@ CONFIG_PCMCIA_PXA2XX=y
 #
 # Kernel Features
 #
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
 CONFIG_PREEMPT=y
-# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -182,6 +288,13 @@ CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2   debug"
 # CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
 
 #
 # Floating point emulation
@@ -198,6 +311,7 @@ CONFIG_FPE_NWFPE=y
 # Userspace binary formats
 #
 CONFIG_BINFMT_ELF=y
+CONFIG_HAVE_AOUT=y
 CONFIG_BINFMT_AOUT=m
 CONFIG_BINFMT_MISC=m
 # CONFIG_ARTHUR is not set
@@ -206,12 +320,12 @@ CONFIG_BINFMT_MISC=m
 # Power management options
 #
 CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
-CONFIG_APM=y
-
-#
-# Networking
-#
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_APM_EMULATION=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
 #
@@ -222,6 +336,10 @@ CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -235,140 +353,131 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
 CONFIG_IPV6=m
 # CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=m
 CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
 CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
 
 #
 # Core Netfilter Configuration
 #
-# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_IP_VS is not set
 
 #
 # IP: Netfilter Configuration
 #
-CONFIG_IP_NF_CONNTRACK=m
-# CONFIG_IP_NF_CT_ACCT is not set
-# CONFIG_IP_NF_CONNTRACK_MARK is not set
-# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
-CONFIG_IP_NF_CT_PROTO_SCTP=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_NETBIOS_NS is not set
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-# CONFIG_IP_NF_PPTP is not set
+# CONFIG_NF_DEFRAG_IPV4 is not set
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+# CONFIG_IP_NF_MATCH_AH is not set
 CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
 CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_REALM=m
-CONFIG_IP_NF_MATCH_SCTP=m
-# CONFIG_IP_NF_MATCH_DCCP is not set
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
-# CONFIG_IP_NF_MATCH_STRING is not set
 CONFIG_IP_NF_FILTER=m
 # CONFIG_IP_NF_TARGET_REJECT is not set
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-# CONFIG_IP_NF_TARGET_NFQUEUE is not set
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-# CONFIG_IP_NF_TARGET_MASQUERADE is not set
-# CONFIG_IP_NF_TARGET_REDIRECT is not set
-# CONFIG_IP_NF_TARGET_NETMAP is not set
-# CONFIG_IP_NF_TARGET_SAME is not set
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
 CONFIG_IP_NF_MANGLE=m
-# CONFIG_IP_NF_TARGET_TOS is not set
 # CONFIG_IP_NF_TARGET_ECN is not set
-# CONFIG_IP_NF_TARGET_DSCP is not set
-# CONFIG_IP_NF_TARGET_MARK is not set
-# CONFIG_IP_NF_TARGET_CLASSIFY is not set
 # CONFIG_IP_NF_TARGET_TTL is not set
 CONFIG_IP_NF_RAW=m
-# CONFIG_IP_NF_TARGET_NOTRACK is not set
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 
 #
-# IPv6: Netfilter Configuration (EXPERIMENTAL)
+# IPv6: Netfilter Configuration
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
-CONFIG_IP6_NF_MATCH_RT=m
-CONFIG_IP6_NF_MATCH_OPTS=m
+# CONFIG_IP6_NF_MATCH_AH is not set
+CONFIG_IP6_NF_MATCH_EUI64=m
 CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_HL=m
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
-CONFIG_IP6_NF_MATCH_OWNER=m
-CONFIG_IP6_NF_MATCH_MARK=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_AHESP=m
-CONFIG_IP6_NF_MATCH_LENGTH=m
-CONFIG_IP6_NF_MATCH_EUI64=m
-CONFIG_IP6_NF_FILTER=m
+# CONFIG_IP6_NF_MATCH_MH is not set
+CONFIG_IP6_NF_MATCH_RT=m
 # CONFIG_IP6_NF_TARGET_LOG is not set
+CONFIG_IP6_NF_FILTER=m
 # CONFIG_IP6_NF_TARGET_REJECT is not set
-# CONFIG_IP6_NF_TARGET_NFQUEUE is not set
 CONFIG_IP6_NF_MANGLE=m
-# CONFIG_IP6_NF_TARGET_MARK is not set
 # CONFIG_IP6_NF_TARGET_HL is not set
 CONFIG_IP6_NF_RAW=m
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -376,21 +485,16 @@ CONFIG_IP6_NF_RAW=m
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
 # CONFIG_NET_SCHED is not set
-CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 CONFIG_IRDA=m
 
 #
@@ -420,27 +524,17 @@ CONFIG_IRCOMM=m
 #
 # Dongle support
 #
-
-#
-# Old SIR device drivers
-#
-# CONFIG_IRPORT_SIR is not set
-
-#
-# Old Serial dongle support
-#
+# 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_NSC_FIR is not set
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-# CONFIG_VIA_FIR is not set
 CONFIG_PXA_FICP=m
+# CONFIG_MCS_FIR is not set
 CONFIG_BT=m
 CONFIG_BT_L2CAP=m
 CONFIG_BT_SCO=m
@@ -456,9 +550,12 @@ CONFIG_BT_HIDP=m
 #
 CONFIG_BT_HCIUSB=m
 # CONFIG_BT_HCIUSB_SCO is not set
+# CONFIG_BT_HCIBTUSB is not set
+# CONFIG_BT_HCIBTSDIO is not set
 CONFIG_BT_HCIUART=m
 CONFIG_BT_HCIUART_H4=y
 CONFIG_BT_HCIUART_BCSP=y
+# CONFIG_BT_HCIUART_LL is not set
 CONFIG_BT_HCIBCM203X=m
 CONFIG_BT_HCIBPA10X=m
 CONFIG_BT_HCIBFUSB=m
@@ -467,11 +564,20 @@ CONFIG_BT_HCIBT3C=m
 CONFIG_BT_HCIBLUECARD=m
 CONFIG_BT_HCIBTUART=m
 CONFIG_BT_HCIVHCI=m
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 # CONFIG_IEEE80211_CRYPT_CCMP is not set
 # CONFIG_IEEE80211_CRYPT_TKIP is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -480,19 +586,16 @@ CONFIG_IEEE80211_CRYPT_WEP=m
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_DEBUG_DRIVER is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
@@ -500,16 +603,20 @@ CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_AFS_PARTS is not set
+# 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
@@ -534,16 +641,18 @@ CONFIG_MTD_ROM=y
 # Mapping drivers for chip access
 #
 CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
 CONFIG_MTD_SHARP_SL=y
 # 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_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
 # CONFIG_MTD_BLOCK2MTD is not set
 
 #
@@ -552,78 +661,66 @@ CONFIG_MTD_SHARP_SL=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_VERIFY_WRITE=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
 # CONFIG_MTD_NAND_H1900 is not set
 CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 CONFIG_MTD_NAND_SHARPSL=y
 # CONFIG_MTD_NAND_NANDSIM is not set
-
-#
-# OneNAND Flash Device Drivers
-#
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
 # CONFIG_MTD_ONENAND is not set
 
 #
-# Parallel port support
+# UBI - Unsorted block images
 #
+# CONFIG_MTD_UBI is not set
 # CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 # CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
 
 #
-# Please see Documentation/ide.txt for help/info on IDE drives
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
 CONFIG_BLK_DEV_IDECS=y
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
 
 #
 # IDE chipset support/bugfixes
 #
-CONFIG_IDE_GENERIC=y
-# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
 # CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -643,121 +740,76 @@ CONFIG_CHR_DEV_SG=m
 CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
 
 #
-# SCSI Transport Attributes
+# 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_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_DEBUG is not set
-
-#
-# PCMCIA SCSI adapter support
-#
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-# CONFIG_PCMCIA_SYM53C500 is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-
-#
-# PHY device support
-#
+# CONFIG_VETH is not set
 # CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=m
+# CONFIG_AX88796 is not set
 # CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
 
 #
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
+# Wireless LAN
 #
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
 
 #
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-# CONFIG_PCMCIA_WAVELAN is not set
-# CONFIG_PCMCIA_NETWAVE is not set
-
-#
-# Wireless 802.11 Frequency Hopping cards support
-#
-# CONFIG_PCMCIA_RAYCS is not set
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-CONFIG_HERMES=m
-# CONFIG_ATMEL is not set
-
-#
-# Wireless 802.11b Pcmcia/Cardbus cards support
-#
-CONFIG_PCMCIA_HERMES=m
-CONFIG_PCMCIA_SPECTRUM=m
-# CONFIG_AIRO_CS is not set
-# CONFIG_PCMCIA_WL3501 is not set
-CONFIG_HOSTAP=m
-CONFIG_HOSTAP_FIRMWARE=y
-CONFIG_HOSTAP_CS=m
-CONFIG_NET_WIRELESS=y
-
-#
-# PCMCIA network device support
+# USB Network Adapters
 #
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+# CONFIG_USB_NET_DM9601 is not set
+# CONFIG_USB_NET_SMSC95XX is not set
+# CONFIG_USB_NET_GL620A is not set
+CONFIG_USB_NET_NET1080=m
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_MCS7830 is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+CONFIG_USB_NET_ZAURUS=m
 CONFIG_NET_PCMCIA=y
 # CONFIG_PCMCIA_3C589 is not set
 # CONFIG_PCMCIA_3C574 is not set
@@ -767,10 +819,6 @@ CONFIG_PCMCIA_PCNET=m
 # CONFIG_PCMCIA_SMC91C92 is not set
 # CONFIG_PCMCIA_XIRC2PS is not set
 # CONFIG_PCMCIA_AXNET is not set
-
-#
-# Wan interfaces
-#
 # CONFIG_WAN is not set
 CONFIG_PPP=m
 # CONFIG_PPP_MULTILINK is not set
@@ -781,31 +829,29 @@ CONFIG_PPP_ASYNC=m
 CONFIG_PPP_BSDCOMP=m
 # CONFIG_PPP_MPPE is not set
 # CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
 # CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
+CONFIG_SLHC=m
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
 # CONFIG_ISDN 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_TSDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
-# CONFIG_INPUT_POWER is not set
+# CONFIG_INPUT_APMPOWER is not set
 
 #
 # Input Device Drivers
@@ -816,17 +862,35 @@ CONFIG_INPUT_KEYBOARD=y
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 # CONFIG_KEYBOARD_CORGI is not set
 CONFIG_KEYBOARD_SPITZ=y
+# CONFIG_KEYBOARD_PXA27x is not set
+# CONFIG_KEYBOARD_GPIO 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_CORGI=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+# CONFIG_TOUCHSCREEN_CORGI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
 # CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_TOUCHSCREEN_ELO 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_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=m
 
 #
@@ -839,8 +903,11 @@ CONFIG_INPUT_UINPUT=m
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -849,6 +916,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=m
 CONFIG_SERIAL_8250_CS=m
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -860,101 +928,253 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=m
 # CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 
-#
-# Ftape, the floppy tape device driver
-#
-
 #
 # PCMCIA character devices
 #
 # CONFIG_SYNCLINK_CS is not set
 # CONFIG_CARDMAN_4000 is not set
 # CONFIG_CARDMAN_4040 is not set
+# CONFIG_IPWIRELESS is not set
 # CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
 CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
 # CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
 
 #
-# I2C Algorithms
+# I2C Hardware Bus support
 #
-# 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_GPIO is not set
+# CONFIG_I2C_OCORES is not set
 CONFIG_I2C_PXA=y
 # CONFIG_I2C_PXA_SLAVE 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
-# CONFIG_I2C_PCA_ISA is not set
 
 #
-# Hardware Monitoring support
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+CONFIG_SPI_PXA2XX=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
 #
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+CONFIG_SENSORS_MAX1111=y
+# 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_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_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
 
 #
-# Misc devices
+# Sonics Silicon Backplane
 #
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
-# Multimedia Capabilities Port drivers
+# Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_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_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C 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
 
 #
-# Digital Video Broadcasting Devices
+# Multimedia drivers
 #
-# CONFIG_DVB is not set
+# CONFIG_DAB 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_S1D13XXX is not set
 CONFIG_FB_PXA=y
+# CONFIG_FB_PXA_SMARTPANEL is not set
 # CONFIG_FB_PXA_PARAMETERS is not set
+# CONFIG_FB_MBX is not set
 # CONFIG_FB_W100 is not set
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_CORGI=y
+# 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
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
 
 #
 # Console display driver support
@@ -962,6 +1182,7 @@ CONFIG_FB_PXA=y
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
 CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
 CONFIG_FONTS=y
 CONFIG_FONT_8x8=y
@@ -974,55 +1195,96 @@ CONFIG_FONT_8x16=y
 # CONFIG_FONT_SUN8x16 is not set
 # CONFIG_FONT_SUN12x22 is not set
 # CONFIG_FONT_10x18 is not set
+# CONFIG_LOGO is not set
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
 
 #
-# Logo configuration
+# USB Input Devices
 #
-# CONFIG_LOGO is not set
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_DEVICE=y
-CONFIG_LCD_CLASS_DEVICE=y
-CONFIG_LCD_DEVICE=y
-CONFIG_BACKLIGHT_CORGI=y
+CONFIG_USB_HID=m
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
 
 #
-# Sound
+# USB HID Boot Protocol drivers
 #
-# CONFIG_SOUND is not set
+CONFIG_USB_KBD=m
+CONFIG_USB_MOUSE=m
 
 #
-# USB support
-#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=m
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_BRIGHT=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_DELL=m
+CONFIG_HID_EZKEY=m
+CONFIG_HID_GYRATION=m
+CONFIG_HID_LOGITECH=m
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+CONFIG_HID_PANTHERLORD=m
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+CONFIG_THRUSTMASTER_FF=m
+CONFIG_ZEROPLUS_FF=m
+CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 CONFIG_USB=m
 # CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
 
 #
 # Miscellaneous USB options
 #
 CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
+CONFIG_USB_DEVICE_CLASS=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
 
 #
 # USB Host Controller Drivers
 #
+# CONFIG_USB_C67X00_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=m
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_SL811_HCD=m
 CONFIG_USB_SL811_CS=m
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
 # USB Device Class drivers
 #
 CONFIG_USB_ACM=m
 CONFIG_USB_PRINTER=m
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -1041,33 +1303,11 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
-
-#
-# USB Input Devices
-#
-CONFIG_USB_HID=m
-CONFIG_USB_HIDINPUT=y
-# CONFIG_HID_FF is not set
-# CONFIG_USB_HIDDEV is not set
-
-#
-# USB HID Boot Protocol drivers
-#
-CONFIG_USB_KBD=m
-CONFIG_USB_MOUSE=m
-CONFIG_USB_AIPTEK=m
-CONFIG_USB_WACOM=m
-# CONFIG_USB_ACECAD is not set
-CONFIG_USB_KBTAB=m
-CONFIG_USB_POWERMATE=m
-CONFIG_USB_MTOUCH=m
-# CONFIG_USB_ITMTOUCH is not set
-CONFIG_USB_EGALAX=m
-# CONFIG_USB_YEALINK is not set
-CONFIG_USB_XPAD=m
-CONFIG_USB_ATI_REMOTE=m
-# CONFIG_USB_KEYSPAN_REMOTE is not set
-# CONFIG_USB_APPLETOUCH 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
@@ -1075,52 +1315,23 @@ CONFIG_USB_ATI_REMOTE=m
 CONFIG_USB_MDC800=m
 CONFIG_USB_MICROTEK=m
 
-#
-# USB Multimedia devices
-#
-CONFIG_USB_DABUSB=m
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network Adapters
-#
-CONFIG_USB_CATC=m
-CONFIG_USB_KAWETH=m
-CONFIG_USB_PEGASUS=m
-CONFIG_USB_RTL8150=m
-CONFIG_USB_USBNET=m
-CONFIG_USB_NET_AX8817X=m
-CONFIG_USB_NET_CDCETHER=m
-# CONFIG_USB_NET_GL620A is not set
-CONFIG_USB_NET_NET1080=m
-# CONFIG_USB_NET_PLUSB is not set
-# CONFIG_USB_NET_RNDIS_HOST is not set
-# CONFIG_USB_NET_CDC_SUBSET is not set
-CONFIG_USB_NET_ZAURUS=m
-# CONFIG_USB_ZD1201 is not set
-CONFIG_USB_MON=y
-
 #
 # USB port drivers
 #
-
-#
-# USB Serial Converter support
-#
 CONFIG_USB_SERIAL=m
+CONFIG_USB_EZUSB=y
 CONFIG_USB_SERIAL_GENERIC=y
-# CONFIG_USB_SERIAL_AIRPRIME is not set
-# CONFIG_USB_SERIAL_ANYDATA is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
 CONFIG_USB_SERIAL_BELKIN=m
+# CONFIG_USB_SERIAL_CH341 is not set
 # CONFIG_USB_SERIAL_WHITEHEAT is not set
 CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
 # CONFIG_USB_SERIAL_CP2101 is not set
 CONFIG_USB_SERIAL_CYPRESS_M8=m
 CONFIG_USB_SERIAL_EMPEG=m
 CONFIG_USB_SERIAL_FTDI_SIO=m
+# CONFIG_USB_SERIAL_FUNSOFT is not set
 CONFIG_USB_SERIAL_VISOR=m
 CONFIG_USB_SERIAL_IPAQ=m
 CONFIG_USB_SERIAL_IR=m
@@ -1128,6 +1339,7 @@ CONFIG_USB_SERIAL_EDGEPORT=m
 CONFIG_USB_SERIAL_EDGEPORT_TI=m
 CONFIG_USB_SERIAL_GARMIN=m
 CONFIG_USB_SERIAL_IPW=m
+# CONFIG_USB_SERIAL_IUU is not set
 CONFIG_USB_SERIAL_KEYSPAN_PDA=m
 CONFIG_USB_SERIAL_KEYSPAN=m
 # CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
@@ -1145,49 +1357,66 @@ CONFIG_USB_SERIAL_KEYSPAN=m
 CONFIG_USB_SERIAL_KLSI=m
 CONFIG_USB_SERIAL_KOBIL_SCT=m
 CONFIG_USB_SERIAL_MCT_U232=m
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
 # CONFIG_USB_SERIAL_HP4X is not set
 CONFIG_USB_SERIAL_SAFE=m
 # CONFIG_USB_SERIAL_SAFE_PADDED is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
 CONFIG_USB_SERIAL_TI=m
 CONFIG_USB_SERIAL_CYBERJACK=m
 CONFIG_USB_SERIAL_XIRCOM=m
 # CONFIG_USB_SERIAL_OPTION is not set
 CONFIG_USB_SERIAL_OMNINET=m
-CONFIG_USB_EZUSB=y
+# CONFIG_USB_SERIAL_DEBUG is not set
 
 #
 # USB Miscellaneous drivers
 #
 CONFIG_USB_EMI62=m
 CONFIG_USB_EMI26=m
-CONFIG_USB_AUERSWALD=m
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
 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=m
-CONFIG_USB_PHIDGETKIT=m
-CONFIG_USB_PHIDGETSERVO=m
+# CONFIG_USB_PHIDGET is not set
 CONFIG_USB_IDMOUSE=m
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY 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
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
-#
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
 CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG is not set
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
 CONFIG_USB_GADGET_SELECTED=y
-# CONFIG_USB_GADGET_NET2280 is not set
-# CONFIG_USB_GADGET_PXA2XX is not set
-# CONFIG_USB_GADGET_GOKU is not set
+# 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_PXA27X 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_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
 CONFIG_USB_GADGET_DUMMY_HCD=y
 CONFIG_USB_DUMMY_HCD=m
 CONFIG_USB_GADGET_DUALSPEED=y
@@ -1198,15 +1427,42 @@ CONFIG_USB_GADGETFS=m
 CONFIG_USB_FILE_STORAGE=m
 # CONFIG_USB_FILE_STORAGE_TEST is not set
 CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
 
 #
-# MMC/SD Card support
+# MMC/SD/SDIO Card Drivers
 #
-CONFIG_MMC=y
-# CONFIG_MMC_DEBUG is not set
 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_PXA=y
-# CONFIG_MMC_WBSD is not set
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+
+#
+# Voltage and Current regulators
+#
+# CONFIG_REGULATOR is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_UIO is not set
 
 #
 # File systems
@@ -1218,18 +1474,19 @@ CONFIG_EXT2_FS_SECURITY=y
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
 CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
@@ -1254,11 +1511,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=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_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1270,39 +1529,42 @@ CONFIG_RAMFS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
 CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
 CONFIG_JFFS2_COMPRESSION_OPTIONS=y
 CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 CONFIG_JFFS2_RUBIN=y
 # CONFIG_JFFS2_CMODE_NONE is not set
 CONFIG_JFFS2_CMODE_PRIORITY=y
 # CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
 CONFIG_CRAMFS=m
 # 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
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
-# CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
 CONFIG_SUNRPC_GSS=m
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=m
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1312,7 +1574,6 @@ CONFIG_SMB_NLS_REMOTE="cp437"
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -1332,11 +1593,9 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
-
-#
-# Native Language Support
-#
+# CONFIG_SYSV68_PARTITION is not set
 CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="cp437"
 CONFIG_NLS_CODEPAGE_437=y
@@ -1377,35 +1636,71 @@ CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=y
-
-#
-# Profiling support
-#
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
+# CONFIG_DLM is not set
 
 #
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
-CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
 # CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
 CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
 # CONFIG_DEBUG_USER is not set
 CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_DEBUG_LL=y
 # CONFIG_DEBUG_ICEDCC is not set
 
@@ -1414,46 +1709,113 @@ CONFIG_DEBUG_LL=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
 
 #
-# Cryptographic options
+# Crypto core or helper
 #
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_GF128MUL is not set
 CONFIG_CRYPTO_NULL=m
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=m
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
 # CONFIG_CRYPTO_TGR192 is not set
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
 CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+# CONFIG_CRYPTO_CAMELLIA is not set
 CONFIG_CRYPTO_CAST5=m
 CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
 CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
 CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_TEST=m
+# CONFIG_CRYPTO_LZO is not set
 
 #
-# Hardware crypto devices
+# Random Number Generation
 #
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=y
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index 8b7a431a8bfc6c2ac26586843eed1d7c3d4e1e5f..9033d147f052933bf38bd195ba9cadfd310824d1 100644 (file)
@@ -147,6 +147,7 @@ CONFIG_ARCH_PXA=y
 # CONFIG_MACH_MAINSTONE is not set
 # CONFIG_ARCH_PXA_IDP is not set
 # CONFIG_PXA_SHARPSL is not set
+CONFIG_TRIZEPS_PXA=y
 CONFIG_MACH_TRIZEPS4=y
 CONFIG_MACH_TRIZEPS4_CONXS=y
 # CONFIG_MACH_TRIZEPS4_ANY is not set
index 5001390be9582fc1c937aa562671c23cd403f957..d3f0a9eee9f65a94b8b7804c162f65160496b485 100644 (file)
                        __res = __m;                                    \
                        asm (   "umlal  %Q0, %R0, %Q1, %Q2\n\t"         \
                                "mov    %Q0, #0"                        \
-                               : "+r" (__res)                          \
+                               : "+&r" (__res)                         \
                                : "r" (__m), "r" (__n)                  \
                                : "cc" );                               \
                } else {                                                \
                                "umlal  %R0, %Q0, %Q1, %R2\n\t"         \
                                "mov    %R0, #0\n\t"                    \
                                "umlal  %Q0, %R0, %R1, %R2"             \
-                               : "+r" (__res)                          \
+                               : "+&r" (__res)                         \
                                : "r" (__m), "r" (__n)                  \
                                : "cc" );                               \
                } else {                                                \
                                "adds   %Q0, %1, %Q0\n\t"               \
                                "adc    %R0, %R0, #0\n\t"               \
                                "umlal  %Q0, %R0, %R2, %R3"             \
-                               : "+r" (__res), "+r" (__z)              \
+                               : "+&r" (__res), "+&r" (__z)            \
                                : "r" (__m), "r" (__n)                  \
                                : "cc" );                               \
                }                                                       \
index 7e5ebb5bdd17c8e43fb2f25ccf93e5e824e17c3e..9b0447c3d59b15443539c44eb1cb3a23dedd3a3b 100644 (file)
@@ -404,6 +404,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
                }
 
                pin = bank->chipbase;
+               gpio = &irq_desc[pin];
 
                while (isr) {
                        if (isr & 1) {
index 71c2fa70c8e8be28a43937481b08efb8b0550c62..98ec30c97bbe9d115994ca20cfca0cc82a614473 100644 (file)
@@ -89,6 +89,8 @@
  *     node 3:  0xd8000000 - 0xdfffffff
  */
 #define NODE_MEM_SIZE_BITS     24
+#define SECTION_SIZE_BITS      24
+#define MAX_PHYSMEM_BITS       32
 
 #endif
 
index 49213d9d7cad5c6538f4999de573fe2d50e2b82d..d6d52527589dc7c6ad1f45053b8f2a08e7d3dfc6 100644 (file)
@@ -41,7 +41,7 @@ static inline unsigned long iop13xx_core_freq(void)
                return 1200000000;
        default:
                printk("%s: warning unknown frequency, defaulting to 800Mhz\n",
-                       __FUNCTION__);
+                       __func__);
        }
 
        return 800000000;
@@ -60,7 +60,7 @@ static inline unsigned long iop13xx_xsi_bus_ratio(void)
                return 4;
        default:
                printk("%s: warning unknown ratio, defaulting to 2\n",
-                       __FUNCTION__);
+                       __func__);
        }
 
        return 2;
index b0653a87159a89b36b67da7674b8163e80439f0e..30451300751beb360ca41cf6e6f46814db1215f9 100644 (file)
@@ -143,7 +143,7 @@ static struct irq_chip ixdp2x00_cpld_irq_chip = {
        .unmask = ixdp2x00_irq_unmask
 };
 
-void __init ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long *mask_reg, unsigned long nr_irqs)
+void __init ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long *mask_reg, unsigned long nr_of_irqs)
 {
        unsigned int irq;
 
@@ -154,7 +154,7 @@ void __init ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigne
 
        board_irq_stat = stat_reg;
        board_irq_mask = mask_reg;
-       board_irq_count = nr_irqs;
+       board_irq_count = nr_of_irqs;
 
        *board_irq_mask = 0xffffffff;
 
index db8b5fe06c0de1a53582b83c256a838ba6490d8b..2c5a02b8520e4b4a79c8f38ce6e01e7836de441a 100644 (file)
@@ -167,11 +167,6 @@ config MACH_GTWX5715
 
 comment "IXP4xx Options"
 
-config DMABOUNCE
-       bool
-       default y
-       depends on PCI
-
 config IXP4XX_INDIRECT_PCI
        bool "Use indirect PCI memory access"
        depends on PCI
index e14bf40bfb0755990a4b2b8e6663e7eae4e3d49e..b96c55dad343be40001a700be7c8c48833e6d78c 100644 (file)
@@ -2,4 +2,4 @@ obj-y                           += common.o addr-map.o irq.o pcie.o
 
 obj-$(CONFIG_MACH_DB88F6281_BP)                += db88f6281-bp-setup.o
 obj-$(CONFIG_MACH_RD88F6192_NAS)       += rd88f6192-nas-setup.o
-obj-$(CONFIG_MACH_RD88F6192_NAS)       += rd88f6281-setup.o
+obj-$(CONFIG_MACH_RD88F6281)           += rd88f6281-setup.o
index 85cad05d8c5bf3bc613b9feaa4ac0c0177f3a358..0bb1fbd84ccb9f561cbb6cb6ebc14cdc485f6784 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/mv643xx_eth.h>
 #include <linux/ata_platform.h>
 #include <linux/spi/orion_spi.h>
+#include <net/dsa.h>
 #include <asm/page.h>
 #include <asm/timex.h>
 #include <asm/mach/map.h>
@@ -151,6 +152,40 @@ void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
 }
 
 
+/*****************************************************************************
+ * Ethernet switch
+ ****************************************************************************/
+static struct resource kirkwood_switch_resources[] = {
+       {
+               .start  = 0,
+               .end    = 0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device kirkwood_switch_device = {
+       .name           = "dsa",
+       .id             = 0,
+       .num_resources  = 0,
+       .resource       = kirkwood_switch_resources,
+};
+
+void __init kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq)
+{
+       if (irq != NO_IRQ) {
+               kirkwood_switch_resources[0].start = irq;
+               kirkwood_switch_resources[0].end = irq;
+               kirkwood_switch_device.num_resources = 1;
+       }
+
+       d->mii_bus = &kirkwood_ge00_shared.dev;
+       d->netdev = &kirkwood_ge00.dev;
+       kirkwood_switch_device.dev.platform_data = d;
+
+       platform_device_register(&kirkwood_switch_device);
+}
+
+
 /*****************************************************************************
  * SoC RTC
  ****************************************************************************/
index 8fa0f6a2763526bf613033eb08a5dfeb6e0b33e1..5774632a67e34ac746307c8d749ab6355c71ef63 100644 (file)
@@ -11,6 +11,7 @@
 #ifndef __ARCH_KIRKWOOD_COMMON_H
 #define __ARCH_KIRKWOOD_COMMON_H
 
+struct dsa_platform_data;
 struct mv643xx_eth_platform_data;
 struct mv_sata_platform_data;
 
@@ -29,6 +30,7 @@ void kirkwood_pcie_id(u32 *dev, u32 *rev);
 
 void kirkwood_ehci_init(void);
 void kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data);
+void kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq);
 void kirkwood_pcie_init(void);
 void kirkwood_rtc_init(void);
 void kirkwood_sata_init(struct mv_sata_platform_data *sata_data);
index f785093e433f4f3f8d8feeb460691980a5413e50..175054abd630d59cbae7e4698adaba474adaf250 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/ata_platform.h>
 #include <linux/mv643xx_eth.h>
 #include <linux/ethtool.h>
+#include <net/dsa.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
@@ -74,6 +75,15 @@ static struct mv643xx_eth_platform_data rd88f6281_ge00_data = {
        .duplex         = DUPLEX_FULL,
 };
 
+static struct dsa_platform_data rd88f6281_switch_data = {
+       .port_names[0]  = "lan1",
+       .port_names[1]  = "lan2",
+       .port_names[2]  = "lan3",
+       .port_names[3]  = "lan4",
+       .port_names[4]  = "wan",
+       .port_names[5]  = "cpu",
+};
+
 static struct mv_sata_platform_data rd88f6281_sata_data = {
        .n_ports        = 2,
 };
@@ -87,6 +97,7 @@ static void __init rd88f6281_init(void)
 
        kirkwood_ehci_init();
        kirkwood_ge00_init(&rd88f6281_ge00_data);
+       kirkwood_ge00_switch_init(&rd88f6281_switch_data, NO_IRQ);
        kirkwood_rtc_init();
        kirkwood_sata_init(&rd88f6281_sata_data);
        kirkwood_uart0_init();
index 3553babbbf0541653a899ee3b18317736a01ba79..d140abca690afdee1a0c78a0a288ec545312f3f2 100644 (file)
@@ -1,18 +1,13 @@
-if ARCH_MSM7X00A
+if ARCH_MSM
 
-comment "MSM7X00A Board Type"
-       depends on ARCH_MSM7X00A
+comment "MSM Board Type"
+       depends on ARCH_MSM
 
 config MACH_HALIBUT
-       depends on ARCH_MSM7X00A
+       depends on ARCH_MSM
        default y
-       bool "Halibut Board (QCT SURF7200A)"
+       bool "Halibut Board (QCT SURF7201A)"
        help
-         Support for the Qualcomm SURF7200A eval board.
-
-config MSM7X00A_IDLE
-       depends on ARCH_MSM7X00A
-       default y
-       bool "Idle Support for MSM7X00A"
+         Support for the Qualcomm SURF7201A eval board.
 
 endif
index d12f2365585096d2d8ee3ffe04652a13d66318ca..1aa47001aa3b065b1b0d4f3a5387a0447bda5cb0 100644 (file)
@@ -1,7 +1,8 @@
 obj-y += io.o idle.o irq.o timer.o dma.o
-
-# Common code for board init
-obj-y += common.o
+obj-y += devices.o
+obj-y += proc_comm.o
+obj-y += vreg.o
+obj-y += clock.o clock-7x01a.o
 
 obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o
 
index a24259133e070258de7aa83236159d681fc4e276..c2a96e3965a6ccfab9bb15e6e2fd0cf8ef0b3fe0 100644 (file)
@@ -33,6 +33,8 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 
+#include "devices.h"
+
 static struct resource smc91x_resources[] = {
        [0] = {
                .start  = 0x9C004300,
@@ -53,31 +55,12 @@ static struct platform_device smc91x_device = {
        .resource       = smc91x_resources,
 };
 
-static void mddi0_panel_power(int on)
-{
-}
-
-static struct msm_mddi_platform_data msm_mddi0_pdata = {
-       .panel_power    = mddi0_panel_power,
-       .has_vsync_irq  = 0,
-};
-
-static struct platform_device msm_mddi0_device = {
-       .name   = "msm_mddi",
-       .id     = 0,
-       .dev    = {
-               .platform_data = &msm_mddi0_pdata
-       },
-};
-
-static struct platform_device msm_serial0_device = {
-       .name   = "msm_serial",
-       .id     = 0,
-};
-
 static struct platform_device *devices[] __initdata = {
-       &msm_serial0_device,
-       &msm_mddi0_device,
+       &msm_device_uart3,
+       &msm_device_smd,
+       &msm_device_nand,
+       &msm_device_hsusb,
+       &msm_device_i2c,
        &smc91x_device,
 };
 
@@ -91,20 +74,15 @@ static void __init halibut_init_irq(void)
 static void __init halibut_init(void)
 {
        platform_add_devices(devices, ARRAY_SIZE(devices));
-       msm_add_devices();
 }
 
 static void __init halibut_map_io(void)
 {
        msm_map_common_io();
+       msm_clock_init();
 }
 
 MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)")
-
-/* UART for LL DEBUG */
-       .phys_io        = MSM_UART1_PHYS,
-       .io_pg_offst    = ((MSM_UART1_BASE) >> 18) & 0xfffc,
-
        .boot_params    = 0x10000100,
        .map_io         = halibut_map_io,
        .init_irq       = halibut_init_irq,
diff --git a/arch/arm/mach-msm/clock-7x01a.c b/arch/arm/mach-msm/clock-7x01a.c
new file mode 100644 (file)
index 0000000..62230a3
--- /dev/null
@@ -0,0 +1,126 @@
+/* arch/arm/mach-msm/clock-7x01a.c
+ *
+ * Clock tables for MSM7X01A
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007 QUALCOMM Incorporated
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include "clock.h"
+#include "devices.h"
+
+/* clock IDs used by the modem processor */
+
+#define ACPU_CLK       0   /* Applications processor clock */
+#define ADM_CLK                1   /* Applications data mover clock */
+#define ADSP_CLK       2   /* ADSP clock */
+#define EBI1_CLK       3   /* External bus interface 1 clock */
+#define EBI2_CLK       4   /* External bus interface 2 clock */
+#define ECODEC_CLK     5   /* External CODEC clock */
+#define EMDH_CLK       6   /* External MDDI host clock */
+#define GP_CLK         7   /* General purpose clock */
+#define GRP_CLK                8   /* Graphics clock */
+#define I2C_CLK                9   /* I2C clock */
+#define ICODEC_RX_CLK  10  /* Internal CODEX RX clock */
+#define ICODEC_TX_CLK  11  /* Internal CODEX TX clock */
+#define IMEM_CLK       12  /* Internal graphics memory clock */
+#define MDC_CLK                13  /* MDDI client clock */
+#define MDP_CLK                14  /* Mobile display processor clock */
+#define PBUS_CLK       15  /* Peripheral bus clock */
+#define PCM_CLK                16  /* PCM clock */
+#define PMDH_CLK       17  /* Primary MDDI host clock */
+#define SDAC_CLK       18  /* Stereo DAC clock */
+#define SDC1_CLK       19  /* Secure Digital Card clocks */
+#define SDC1_PCLK      20
+#define SDC2_CLK       21
+#define SDC2_PCLK      22
+#define SDC3_CLK       23
+#define SDC3_PCLK      24
+#define SDC4_CLK       25
+#define SDC4_PCLK      26
+#define TSIF_CLK       27  /* Transport Stream Interface clocks */
+#define TSIF_REF_CLK   28
+#define TV_DAC_CLK     29  /* TV clocks */
+#define TV_ENC_CLK     30
+#define UART1_CLK      31  /* UART clocks */
+#define UART2_CLK      32
+#define UART3_CLK      33
+#define UART1DM_CLK    34
+#define UART2DM_CLK    35
+#define USB_HS_CLK     36  /* High speed USB core clock */
+#define USB_HS_PCLK    37  /* High speed USB pbus clock */
+#define USB_OTG_CLK    38  /* Full speed USB clock */
+#define VDC_CLK                39  /* Video controller clock */
+#define VFE_CLK                40  /* Camera / Video Front End clock */
+#define VFE_MDC_CLK    41  /* VFE MDDI client clock */
+
+#define NR_CLKS                42
+
+#define CLOCK(clk_name, clk_id, clk_dev, clk_flags) {  \
+       .name = clk_name, \
+       .id = clk_id, \
+       .flags = clk_flags, \
+       .dev = clk_dev, \
+       }
+
+#define OFF CLKFLAG_AUTO_OFF
+#define MINMAX CLKFLAG_USE_MIN_MAX_TO_SET
+
+struct clk msm_clocks[] = {
+       CLOCK("adm_clk",        ADM_CLK,        NULL, 0),
+       CLOCK("adsp_clk",       ADSP_CLK,       NULL, 0),
+       CLOCK("ebi1_clk",       EBI1_CLK,       NULL, 0),
+       CLOCK("ebi2_clk",       EBI2_CLK,       NULL, 0),
+       CLOCK("ecodec_clk",     ECODEC_CLK,     NULL, 0),
+       CLOCK("emdh_clk",       EMDH_CLK,       NULL, OFF),
+       CLOCK("gp_clk",         GP_CLK,         NULL, 0),
+       CLOCK("grp_clk",        GRP_CLK,        NULL, OFF),
+       CLOCK("i2c_clk",        I2C_CLK,        &msm_device_i2c.dev, 0),
+       CLOCK("icodec_rx_clk",  ICODEC_RX_CLK,  NULL, 0),
+       CLOCK("icodec_tx_clk",  ICODEC_TX_CLK,  NULL, 0),
+       CLOCK("imem_clk",       IMEM_CLK,       NULL, OFF),
+       CLOCK("mdc_clk",        MDC_CLK,        NULL, 0),
+       CLOCK("mdp_clk",        MDP_CLK,        NULL, OFF),
+       CLOCK("pbus_clk",       PBUS_CLK,       NULL, 0),
+       CLOCK("pcm_clk",        PCM_CLK,        NULL, 0),
+       CLOCK("pmdh_clk",       PMDH_CLK,       NULL, OFF | MINMAX),
+       CLOCK("sdac_clk",       SDAC_CLK,       NULL, OFF),
+       CLOCK("sdc_clk",        SDC1_CLK,       &msm_device_sdc1.dev, OFF),
+       CLOCK("sdc_pclk",       SDC1_PCLK,      &msm_device_sdc1.dev, OFF),
+       CLOCK("sdc_clk",        SDC2_CLK,       &msm_device_sdc2.dev, OFF),
+       CLOCK("sdc_pclk",       SDC2_PCLK,      &msm_device_sdc2.dev, OFF),
+       CLOCK("sdc_clk",        SDC3_CLK,       &msm_device_sdc3.dev, OFF),
+       CLOCK("sdc_pclk",       SDC3_PCLK,      &msm_device_sdc3.dev, OFF),
+       CLOCK("sdc_clk",        SDC4_CLK,       &msm_device_sdc4.dev, OFF),
+       CLOCK("sdc_pclk",       SDC4_PCLK,      &msm_device_sdc4.dev, OFF),
+       CLOCK("tsif_clk",       TSIF_CLK,       NULL, 0),
+       CLOCK("tsif_ref_clk",   TSIF_REF_CLK,   NULL, 0),
+       CLOCK("tv_dac_clk",     TV_DAC_CLK,     NULL, 0),
+       CLOCK("tv_enc_clk",     TV_ENC_CLK,     NULL, 0),
+       CLOCK("uart_clk",       UART1_CLK,      &msm_device_uart1.dev, OFF),
+       CLOCK("uart_clk",       UART2_CLK,      &msm_device_uart2.dev, 0),
+       CLOCK("uart_clk",       UART3_CLK,      &msm_device_uart3.dev, OFF),
+       CLOCK("uart1dm_clk",    UART1DM_CLK,    NULL, OFF),
+       CLOCK("uart2dm_clk",    UART2DM_CLK,    NULL, 0),
+       CLOCK("usb_hs_clk",     USB_HS_CLK,     &msm_device_hsusb.dev, OFF),
+       CLOCK("usb_hs_pclk",    USB_HS_PCLK,    &msm_device_hsusb.dev, OFF),
+       CLOCK("usb_otg_clk",    USB_OTG_CLK,    NULL, 0),
+       CLOCK("vdc_clk",        VDC_CLK,        NULL, OFF | MINMAX),
+       CLOCK("vfe_clk",        VFE_CLK,        NULL, OFF),
+       CLOCK("vfe_mdc_clk",    VFE_MDC_CLK,    NULL, OFF),
+};
+
+unsigned msm_num_clocks = ARRAY_SIZE(msm_clocks);
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
new file mode 100644 (file)
index 0000000..3b1ce36
--- /dev/null
@@ -0,0 +1,218 @@
+/* arch/arm/mach-msm/clock.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007 QUALCOMM Incorporated
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+
+#include "clock.h"
+#include "proc_comm.h"
+
+static DEFINE_MUTEX(clocks_mutex);
+static DEFINE_SPINLOCK(clocks_lock);
+static LIST_HEAD(clocks);
+
+/*
+ * glue for the proc_comm interface
+ */
+static inline int pc_clk_enable(unsigned id)
+{
+       return msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL);
+}
+
+static inline void pc_clk_disable(unsigned id)
+{
+       msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL);
+}
+
+static inline int pc_clk_set_rate(unsigned id, unsigned rate)
+{
+       return msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
+}
+
+static inline int pc_clk_set_min_rate(unsigned id, unsigned rate)
+{
+       return msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate);
+}
+
+static inline int pc_clk_set_max_rate(unsigned id, unsigned rate)
+{
+       return msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate);
+}
+
+static inline int pc_clk_set_flags(unsigned id, unsigned flags)
+{
+       return msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags);
+}
+
+static inline unsigned pc_clk_get_rate(unsigned id)
+{
+       if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL))
+               return 0;
+       else
+               return id;
+}
+
+static inline unsigned pc_clk_is_enabled(unsigned id)
+{
+       if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL))
+               return 0;
+       else
+               return id;
+}
+
+static inline int pc_pll_request(unsigned id, unsigned on)
+{
+       on = !!on;
+       return msm_proc_comm(PCOM_CLKCTL_RPC_PLL_REQUEST, &id, &on);
+}
+
+/*
+ * Standard clock functions defined in include/linux/clk.h
+ */
+struct clk *clk_get(struct device *dev, const char *id)
+{
+       struct clk *clk;
+
+       mutex_lock(&clocks_mutex);
+
+       list_for_each_entry(clk, &clocks, list)
+               if (!strcmp(id, clk->name) && clk->dev == dev)
+                       goto found_it;
+
+       list_for_each_entry(clk, &clocks, list)
+               if (!strcmp(id, clk->name) && clk->dev == NULL)
+                       goto found_it;
+
+       clk = ERR_PTR(-ENOENT);
+found_it:
+       mutex_unlock(&clocks_mutex);
+       return clk;
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
+
+int clk_enable(struct clk *clk)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&clocks_lock, flags);
+       clk->count++;
+       if (clk->count == 1)
+               pc_clk_enable(clk->id);
+       spin_unlock_irqrestore(&clocks_lock, flags);
+       return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&clocks_lock, flags);
+       BUG_ON(clk->count == 0);
+       clk->count--;
+       if (clk->count == 0)
+               pc_clk_disable(clk->id);
+       spin_unlock_irqrestore(&clocks_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+       return pc_clk_get_rate(clk->id);
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+       int ret;
+       if (clk->flags & CLKFLAG_USE_MIN_MAX_TO_SET) {
+               ret = pc_clk_set_max_rate(clk->id, rate);
+               if (ret)
+                       return ret;
+               return pc_clk_set_min_rate(clk->id, rate);
+       }
+       return pc_clk_set_rate(clk->id, rate);
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+       return -ENOSYS;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+       return ERR_PTR(-ENOSYS);
+}
+EXPORT_SYMBOL(clk_get_parent);
+
+int clk_set_flags(struct clk *clk, unsigned long flags)
+{
+       if (clk == NULL || IS_ERR(clk))
+               return -EINVAL;
+       return pc_clk_set_flags(clk->id, flags);
+}
+EXPORT_SYMBOL(clk_set_flags);
+
+
+void __init msm_clock_init(void)
+{
+       unsigned n;
+
+       spin_lock_init(&clocks_lock);
+       mutex_lock(&clocks_mutex);
+       for (n = 0; n < msm_num_clocks; n++)
+               list_add_tail(&msm_clocks[n].list, &clocks);
+       mutex_unlock(&clocks_mutex);
+}
+
+/* The bootloader and/or AMSS may have left various clocks enabled.
+ * Disable any clocks that belong to us (CLKFLAG_AUTO_OFF) but have
+ * not been explicitly enabled by a clk_enable() call.
+ */
+static int __init clock_late_init(void)
+{
+       unsigned long flags;
+       struct clk *clk;
+       unsigned count = 0;
+
+       mutex_lock(&clocks_mutex);
+       list_for_each_entry(clk, &clocks, list) {
+               if (clk->flags & CLKFLAG_AUTO_OFF) {
+                       spin_lock_irqsave(&clocks_lock, flags);
+                       if (!clk->count) {
+                               count++;
+                               pc_clk_disable(clk->id);
+                       }
+                       spin_unlock_irqrestore(&clocks_lock, flags);
+               }
+       }
+       mutex_unlock(&clocks_mutex);
+       pr_info("clock_late_init() disabled %d unused clocks\n", count);
+       return 0;
+}
+
+late_initcall(clock_late_init);
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
new file mode 100644 (file)
index 0000000..f875e15
--- /dev/null
@@ -0,0 +1,48 @@
+/* arch/arm/mach-msm/clock.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007 QUALCOMM Incorporated
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 __ARCH_ARM_MACH_MSM_CLOCK_H
+#define __ARCH_ARM_MACH_MSM_CLOCK_H
+
+#include <linux/list.h>
+
+#define CLKFLAG_INVERT                 0x00000001
+#define CLKFLAG_NOINVERT               0x00000002
+#define CLKFLAG_NONEST                 0x00000004
+#define CLKFLAG_NORESET                        0x00000008
+
+#define CLK_FIRST_AVAILABLE_FLAG       0x00000100
+#define CLKFLAG_USE_MIN_MAX_TO_SET     0x00000200
+#define CLKFLAG_AUTO_OFF               0x00000400
+
+struct clk {
+       uint32_t id;
+       uint32_t count;
+       uint32_t flags;
+       const char *name;
+       struct list_head list;
+       struct device *dev;
+};
+
+#define A11S_CLK_CNTL_ADDR             (MSM_CSR_BASE + 0x100)
+#define A11S_CLK_SEL_ADDR              (MSM_CSR_BASE + 0x104)
+#define A11S_VDD_SVS_PLEVEL_ADDR       (MSM_CSR_BASE + 0x124)
+
+extern struct clk msm_clocks[];
+extern unsigned msm_num_clocks;
+
+#endif
+
diff --git a/arch/arm/mach-msm/common.c b/arch/arm/mach-msm/common.c
deleted file mode 100644 (file)
index 604f8ad..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/* linux/arch/arm/mach-msm/common.c
- *
- * Common setup code for MSM7K Boards
- *
- * Copyright (C) 2007 Google, Inc.
- * Author: Brian Swetland <swetland@google.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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 <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <asm/mach/flash.h>
-
-#include <asm/setup.h>
-
-#include <linux/mtd/nand.h>
-#include <linux/mtd/partitions.h>
-
-#include <mach/msm_iomap.h>
-
-#include <mach/board.h>
-
-struct flash_platform_data msm_nand_data = {
-       .parts          = 0,
-       .nr_parts       = 0,
-};
-
-static struct resource msm_nand_resources[] = {
-       [0] = {
-               .start  = 7,
-               .end    = 7,
-               .flags  = IORESOURCE_DMA,
-       },
-};
-
-static struct platform_device msm_nand_device = {
-       .name           = "msm_nand",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(msm_nand_resources),
-       .resource       = msm_nand_resources,
-       .dev            = {
-               .platform_data  = &msm_nand_data,
-       },
-};
-
-static struct platform_device msm_smd_device = {
-       .name   = "msm_smd",
-       .id     = -1,
-};
-
-static struct resource msm_i2c_resources[] = {
-       {
-               .start  = MSM_I2C_BASE,
-               .end    = MSM_I2C_BASE + MSM_I2C_SIZE - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .start  = INT_PWB_I2C,
-               .end    = INT_PWB_I2C,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device msm_i2c_device = {
-       .name           = "msm_i2c",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(msm_i2c_resources),
-       .resource       = msm_i2c_resources,
-};
-
-static struct resource usb_resources[] = {
-       {
-               .start  = MSM_HSUSB_PHYS,
-               .end    = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .start  = INT_USB_HS,
-               .end    = INT_USB_HS,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device msm_hsusb_device = {
-       .name           = "msm_hsusb",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(usb_resources),
-       .resource       = usb_resources,
-       .dev            = {
-               .coherent_dma_mask      = 0xffffffff,
-       },
-};
-
-static struct platform_device *devices[] __initdata = {
-       &msm_nand_device,
-       &msm_smd_device,
-       &msm_i2c_device,
-       &msm_hsusb_device,
-};
-
-void __init msm_add_devices(void)
-{
-       platform_add_devices(devices, ARRAY_SIZE(devices));
-}
diff --git a/arch/arm/mach-msm/devices.c b/arch/arm/mach-msm/devices.c
new file mode 100644 (file)
index 0000000..f2a74b9
--- /dev/null
@@ -0,0 +1,267 @@
+/* linux/arch/arm/mach-msm/devices.c
+ *
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <mach/msm_iomap.h>
+#include "devices.h"
+
+#include <asm/mach/flash.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+static struct resource resources_uart1[] = {
+       {
+               .start  = INT_UART1,
+               .end    = INT_UART1,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = MSM_UART1_PHYS,
+               .end    = MSM_UART1_PHYS + MSM_UART1_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct resource resources_uart2[] = {
+       {
+               .start  = INT_UART2,
+               .end    = INT_UART2,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = MSM_UART2_PHYS,
+               .end    = MSM_UART2_PHYS + MSM_UART2_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct resource resources_uart3[] = {
+       {
+               .start  = INT_UART3,
+               .end    = INT_UART3,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = MSM_UART3_PHYS,
+               .end    = MSM_UART3_PHYS + MSM_UART3_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+struct platform_device msm_device_uart1 = {
+       .name   = "msm_serial",
+       .id     = 0,
+       .num_resources  = ARRAY_SIZE(resources_uart1),
+       .resource       = resources_uart1,
+};
+
+struct platform_device msm_device_uart2 = {
+       .name   = "msm_serial",
+       .id     = 1,
+       .num_resources  = ARRAY_SIZE(resources_uart2),
+       .resource       = resources_uart2,
+};
+
+struct platform_device msm_device_uart3 = {
+       .name   = "msm_serial",
+       .id     = 2,
+       .num_resources  = ARRAY_SIZE(resources_uart3),
+       .resource       = resources_uart3,
+};
+
+static struct resource resources_i2c[] = {
+       {
+               .start  = MSM_I2C_PHYS,
+               .end    = MSM_I2C_PHYS + MSM_I2C_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = INT_PWB_I2C,
+               .end    = INT_PWB_I2C,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device msm_device_i2c = {
+       .name           = "msm_i2c",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(resources_i2c),
+       .resource       = resources_i2c,
+};
+
+static struct resource resources_hsusb[] = {
+       {
+               .start  = MSM_HSUSB_PHYS,
+               .end    = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = INT_USB_HS,
+               .end    = INT_USB_HS,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device msm_device_hsusb = {
+       .name           = "msm_hsusb",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(resources_hsusb),
+       .resource       = resources_hsusb,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
+};
+
+struct flash_platform_data msm_nand_data = {
+       .parts          = NULL,
+       .nr_parts       = 0,
+};
+
+static struct resource resources_nand[] = {
+       [0] = {
+               .start  = 7,
+               .end    = 7,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device msm_device_nand = {
+       .name           = "msm_nand",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(resources_nand),
+       .resource       = resources_nand,
+       .dev            = {
+               .platform_data  = &msm_nand_data,
+       },
+};
+
+struct platform_device msm_device_smd = {
+       .name   = "msm_smd",
+       .id     = -1,
+};
+
+static struct resource resources_sdc1[] = {
+       {
+               .start  = MSM_SDC1_PHYS,
+               .end    = MSM_SDC1_PHYS + MSM_SDC1_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = INT_SDC1_0,
+               .end    = INT_SDC1_1,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = 8,
+               .end    = 8,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+static struct resource resources_sdc2[] = {
+       {
+               .start  = MSM_SDC2_PHYS,
+               .end    = MSM_SDC2_PHYS + MSM_SDC2_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = INT_SDC2_0,
+               .end    = INT_SDC2_1,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = 8,
+               .end    = 8,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+static struct resource resources_sdc3[] = {
+       {
+               .start  = MSM_SDC3_PHYS,
+               .end    = MSM_SDC3_PHYS + MSM_SDC3_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = INT_SDC3_0,
+               .end    = INT_SDC3_1,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = 8,
+               .end    = 8,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+static struct resource resources_sdc4[] = {
+       {
+               .start  = MSM_SDC4_PHYS,
+               .end    = MSM_SDC4_PHYS + MSM_SDC4_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = INT_SDC4_0,
+               .end    = INT_SDC4_1,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = 8,
+               .end    = 8,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device msm_device_sdc1 = {
+       .name           = "msm_sdcc",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(resources_sdc1),
+       .resource       = resources_sdc1,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
+};
+
+struct platform_device msm_device_sdc2 = {
+       .name           = "msm_sdcc",
+       .id             = 2,
+       .num_resources  = ARRAY_SIZE(resources_sdc2),
+       .resource       = resources_sdc2,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
+};
+
+struct platform_device msm_device_sdc3 = {
+       .name           = "msm_sdcc",
+       .id             = 3,
+       .num_resources  = ARRAY_SIZE(resources_sdc3),
+       .resource       = resources_sdc3,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
+};
+
+struct platform_device msm_device_sdc4 = {
+       .name           = "msm_sdcc",
+       .id             = 4,
+       .num_resources  = ARRAY_SIZE(resources_sdc4),
+       .resource       = resources_sdc4,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
+};
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
new file mode 100644 (file)
index 0000000..0744c4a
--- /dev/null
@@ -0,0 +1,36 @@
+/* linux/arch/arm/mach-msm/devices.h
+ *
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 __ARCH_ARM_MACH_MSM_DEVICES_H
+#define __ARCH_ARM_MACH_MSM_DEVICES_H
+
+extern struct platform_device msm_device_uart1;
+extern struct platform_device msm_device_uart2;
+extern struct platform_device msm_device_uart3;
+
+extern struct platform_device msm_device_sdc1;
+extern struct platform_device msm_device_sdc2;
+extern struct platform_device msm_device_sdc3;
+extern struct platform_device msm_device_sdc4;
+
+extern struct platform_device msm_device_hsusb;
+
+extern struct platform_device msm_device_i2c;
+
+extern struct platform_device msm_device_smd;
+
+extern struct platform_device msm_device_nand;
+
+#endif
index 0c8f252637e15a31486887c15dd28818829691eb..f5420f9585c59ec504dd85325c55e42141e50f96 100644 (file)
@@ -26,7 +26,7 @@ enum {
 };
 
 static DEFINE_SPINLOCK(msm_dmov_lock);
-static struct msm_dmov_cmd active_command;
+static unsigned int channel_active;
 static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
 static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
 unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS;
@@ -43,6 +43,11 @@ unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS;
 #define PRINT_FLOW(format, args...) \
        MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_FLOW, format, args);
 
+void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful)
+{
+       writel((graceful << 31), DMOV_FLUSH0(id));
+}
+
 void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
 {
        unsigned long irq_flags;
@@ -60,6 +65,9 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
 #endif
                PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n", id, status);
                list_add_tail(&cmd->list, &active_commands[id]);
+               if (!channel_active)
+                       enable_irq(INT_ADM_AARM);
+               channel_active |= 1U << id;
                writel(cmd->cmdptr, DMOV_CMD_PTR(id));
        } else {
                if (list_empty(&active_commands[id]))
@@ -76,21 +84,19 @@ struct msm_dmov_exec_cmdptr_cmd {
        struct completion complete;
        unsigned id;
        unsigned int result;
-       unsigned int flush[6];
+       struct msm_dmov_errdata err;
 };
 
-static void dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd, unsigned int result)
+static void
+dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd,
+                              unsigned int result,
+                              struct msm_dmov_errdata *err)
 {
        struct msm_dmov_exec_cmdptr_cmd *cmd = container_of(_cmd, struct msm_dmov_exec_cmdptr_cmd, dmov_cmd);
        cmd->result = result;
-       if (result != 0x80000002) {
-               cmd->flush[0] = readl(DMOV_FLUSH0(cmd->id));
-               cmd->flush[1] = readl(DMOV_FLUSH1(cmd->id));
-               cmd->flush[2] = readl(DMOV_FLUSH2(cmd->id));
-               cmd->flush[3] = readl(DMOV_FLUSH3(cmd->id));
-               cmd->flush[4] = readl(DMOV_FLUSH4(cmd->id));
-               cmd->flush[5] = readl(DMOV_FLUSH5(cmd->id));
-       }
+       if (result != 0x80000002 && err)
+               memcpy(&cmd->err, err, sizeof(struct msm_dmov_errdata));
+
        complete(&cmd->complete);
 }
 
@@ -111,7 +117,7 @@ int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr)
        if (cmd.result != 0x80000002) {
                PRINT_ERROR("dmov_exec_cmdptr(%d): ERROR, result: %x\n", id, cmd.result);
                PRINT_ERROR("dmov_exec_cmdptr(%d):  flush: %x %x %x %x\n",
-                       id, cmd.flush[0], cmd.flush[1], cmd.flush[2], cmd.flush[3]);
+                       id, cmd.err.flush[0], cmd.err.flush[1], cmd.err.flush[2], cmd.err.flush[3]);
                return -EIO;
        }
        PRINT_FLOW("dmov_exec_cmdptr(%d, %x) done\n", id, cmdptr);
@@ -159,25 +165,40 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
                                        "for %p, result %x\n", id, cmd, ch_result);
                                if (cmd) {
                                        list_del(&cmd->list);
-                                       cmd->complete_func(cmd, ch_result);
+                                       cmd->complete_func(cmd, ch_result, NULL);
                                }
                        }
                        if (ch_result & DMOV_RSLT_FLUSH) {
-                               unsigned int flush0 = readl(DMOV_FLUSH0(id));
+                               struct msm_dmov_errdata errdata;
+
+                               errdata.flush[0] = readl(DMOV_FLUSH0(id));
+                               errdata.flush[1] = readl(DMOV_FLUSH1(id));
+                               errdata.flush[2] = readl(DMOV_FLUSH2(id));
+                               errdata.flush[3] = readl(DMOV_FLUSH3(id));
+                               errdata.flush[4] = readl(DMOV_FLUSH4(id));
+                               errdata.flush[5] = readl(DMOV_FLUSH5(id));
                                PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
-                               PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, flush0);
+                               PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
                                if (cmd) {
                                        list_del(&cmd->list);
-                                       cmd->complete_func(cmd, ch_result);
+                                       cmd->complete_func(cmd, ch_result, &errdata);
                                }
                        }
                        if (ch_result & DMOV_RSLT_ERROR) {
-                               unsigned int flush0 = readl(DMOV_FLUSH0(id));
+                               struct msm_dmov_errdata errdata;
+
+                               errdata.flush[0] = readl(DMOV_FLUSH0(id));
+                               errdata.flush[1] = readl(DMOV_FLUSH1(id));
+                               errdata.flush[2] = readl(DMOV_FLUSH2(id));
+                               errdata.flush[3] = readl(DMOV_FLUSH3(id));
+                               errdata.flush[4] = readl(DMOV_FLUSH4(id));
+                               errdata.flush[5] = readl(DMOV_FLUSH5(id));
+
                                PRINT_ERROR("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
-                               PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, flush0);
+                               PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
                                if (cmd) {
                                        list_del(&cmd->list);
-                                       cmd->complete_func(cmd, ch_result);
+                                       cmd->complete_func(cmd, ch_result, &errdata);
                                }
                                /* this does not seem to work, once we get an error */
                                /* the datamover will no longer accept commands */
@@ -193,8 +214,14 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
                                writel(cmd->cmdptr, DMOV_CMD_PTR(id));
                        }
                } while (ch_status & DMOV_STATUS_RSLT_VALID);
+               if (list_empty(&active_commands[id]) && list_empty(&ready_commands[id]))
+                       channel_active &= ~(1U << id);
                PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
        }
+
+       if (!channel_active)
+               disable_irq(INT_ADM_AARM);
+
        spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
        return IRQ_HANDLED;
 }
@@ -202,12 +229,17 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
 static int __init msm_init_datamover(void)
 {
        int i;
+       int ret;
        for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
                INIT_LIST_HEAD(&ready_commands[i]);
                INIT_LIST_HEAD(&active_commands[i]);
                writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i));
        }
-       return request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL);
+       ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL);
+       if (ret)
+               return ret;
+       disable_irq(INT_ADM_AARM);
+       return 0;
 }
 
 arch_initcall(msm_init_datamover);
index a7639493c095391ff24da034be9f5b31bfc93855..264d62e519f3dedcd6f8024ccfb7c8f5d851737e 100644 (file)
@@ -33,5 +33,6 @@ void __init msm_add_devices(void);
 void __init msm_map_common_io(void);
 void __init msm_init_irq(void);
 void __init msm_init_gpio(void);
+void __init msm_clock_init(void);
 
 #endif
index 528eef4b605cdf1ee7c4b75899e6efc441f06744..1db3c97dbc49e4738d386396a5db3e6169cb7785 100644 (file)
        mrc     p15, 0, \rx, c1, c0
        tst     \rx, #1
        ldreq   \rx, =MSM_UART1_PHYS
-       ldrne   \rx, =MSM_UART1_BASE
+       movne   \rx, #0
        .endm
 
        .macro  senduart,rd,rx
-       str     \rd, [\rx, #0x0C]
+       teq     \rx, #0
+       strne   \rd, [\rx, #0x0C]
        .endm
 
        .macro  waituart,rd,rx
        @ wait for TX_READY
+       teq     \rx, #0
+       bne     2f
 1:     ldr     \rd, [\rx, #0x08]
        tst     \rd, #0x04
        beq     1b
+2:
        .endm
 
        .macro  busyuart,rd,rx
index ad1c87f86d10598080627c4553b3f265273c07f4..5ab5bdffab07334781b960661deebe041bab408b 100644 (file)
@@ -1,4 +1,4 @@
-/* arch/arm/mach-msm/include/mach/dma.h
+/* linux/include/asm-arm/arch-msm/dma.h
  *
  * Copyright (C) 2007 Google, Inc.
  *
 #include <linux/list.h>
 #include <mach/msm_iomap.h>
 
+struct msm_dmov_errdata {
+       uint32_t flush[6];
+};
+
 struct msm_dmov_cmd {
        struct list_head list;
        unsigned int cmdptr;
-       void (*complete_func)(struct msm_dmov_cmd *cmd, unsigned int result);
-/*     void (*user_result_func)(struct msm_dmov_cmd *cmd); */
+       void (*complete_func)(struct msm_dmov_cmd *cmd,
+                             unsigned int result,
+                             struct msm_dmov_errdata *err);
 };
 
 void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd);
-void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd);
+void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful);
 int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
-/* int msm_dmov_exec_cmd_etc(unsigned id, unsigned int cmdptr, int timeout, int interruptible); */
 
 
 
@@ -122,6 +126,16 @@ typedef struct {
        unsigned _reserved;
 } dmov_sg;
 
+/* Box mode */
+typedef struct {
+       uint32_t cmd;
+       uint32_t src_row_addr;
+       uint32_t dst_row_addr;
+       uint32_t src_dst_len;
+       uint32_t num_rows;
+       uint32_t row_offset;
+} dmov_box;
+
 /* bits for the cmd field of the above structures */
 
 #define CMD_LC      (1 << 31)  /* last command */
index e221f58ceea3997a0a90f0b52d997f89a0874acf..2f7b4c8620d95f257e6c845f541ce4a42a4abea7 100644 (file)
  *
  */
 
-#define MSM_VIC_BASE          0xE0000000
+#ifdef __ASSEMBLY__
+#define IOMEM(x)       x
+#else
+#define IOMEM(x)       ((void __force __iomem *)(x))
+#endif
+
+#define MSM_VIC_BASE          IOMEM(0xE0000000)
 #define MSM_VIC_PHYS          0xC0000000
 #define MSM_VIC_SIZE          SZ_4K
 
-#define MSM_CSR_BASE          0xE0001000
+#define MSM_CSR_BASE          IOMEM(0xE0001000)
 #define MSM_CSR_PHYS          0xC0100000
 #define MSM_CSR_SIZE          SZ_4K
 
 #define MSM_GPT_BASE          MSM_CSR_BASE
 #define MSM_GPT_SIZE          SZ_4K
 
-#define MSM_DMOV_BASE         0xE0002000
+#define MSM_DMOV_BASE         IOMEM(0xE0002000)
 #define MSM_DMOV_PHYS         0xA9700000
 #define MSM_DMOV_SIZE         SZ_4K
 
-#define MSM_UART1_BASE        0xE0003000
+#define MSM_GPIO1_BASE        IOMEM(0xE0003000)
+#define MSM_GPIO1_PHYS        0xA9200000
+#define MSM_GPIO1_SIZE        SZ_4K
+
+#define MSM_GPIO2_BASE        IOMEM(0xE0004000)
+#define MSM_GPIO2_PHYS        0xA9300000
+#define MSM_GPIO2_SIZE        SZ_4K
+
+#define MSM_CLK_CTL_BASE      IOMEM(0xE0005000)
+#define MSM_CLK_CTL_PHYS      0xA8600000
+#define MSM_CLK_CTL_SIZE      SZ_4K
+
+#define MSM_SHARED_RAM_BASE   IOMEM(0xE0100000)
+#define MSM_SHARED_RAM_PHYS   0x01F00000
+#define MSM_SHARED_RAM_SIZE   SZ_1M
+
 #define MSM_UART1_PHYS        0xA9A00000
 #define MSM_UART1_SIZE        SZ_4K
 
-#define MSM_UART2_BASE        0xE0004000
 #define MSM_UART2_PHYS        0xA9B00000
 #define MSM_UART2_SIZE        SZ_4K
 
-#define MSM_UART3_BASE        0xE0005000
 #define MSM_UART3_PHYS        0xA9C00000
 #define MSM_UART3_SIZE        SZ_4K
 
-#define MSM_I2C_BASE          0xE0006000
-#define MSM_I2C_PHYS          0xA9900000
-#define MSM_I2C_SIZE          SZ_4K
+#define MSM_SDC1_PHYS         0xA0400000
+#define MSM_SDC1_SIZE         SZ_4K
 
-#define MSM_GPIO1_BASE        0xE0007000
-#define MSM_GPIO1_PHYS        0xA9200000
-#define MSM_GPIO1_SIZE        SZ_4K
+#define MSM_SDC2_PHYS         0xA0500000
+#define MSM_SDC2_SIZE         SZ_4K
 
-#define MSM_GPIO2_BASE        0xE0008000
-#define MSM_GPIO2_PHYS        0xA9300000
-#define MSM_GPIO2_SIZE        SZ_4K
+#define MSM_SDC3_PHYS         0xA0600000
+#define MSM_SDC3_SIZE         SZ_4K
+
+#define MSM_SDC4_PHYS         0xA0700000
+#define MSM_SDC4_SIZE         SZ_4K
+
+#define MSM_I2C_PHYS          0xA9900000
+#define MSM_I2C_SIZE          SZ_4K
 
-#define MSM_HSUSB_BASE        0xE0009000
 #define MSM_HSUSB_PHYS        0xA0800000
 #define MSM_HSUSB_SIZE        SZ_4K
 
-#define MSM_CLK_CTL_BASE      0xE000A000
-#define MSM_CLK_CTL_PHYS      0xA8600000
-#define MSM_CLK_CTL_SIZE      SZ_4K
-
-#define MSM_PMDH_BASE         0xE000B000
 #define MSM_PMDH_PHYS         0xAA600000
 #define MSM_PMDH_SIZE         SZ_4K
 
-#define MSM_EMDH_BASE         0xE000C000
 #define MSM_EMDH_PHYS         0xAA700000
 #define MSM_EMDH_SIZE         SZ_4K
 
-#define MSM_MDP_BASE          0xE0010000
 #define MSM_MDP_PHYS          0xAA200000
 #define MSM_MDP_SIZE          0x000F0000
 
-#define MSM_SHARED_RAM_BASE   0xE0100000
-#define MSM_SHARED_RAM_PHYS   0x01F00000
-#define MSM_SHARED_RAM_SIZE   SZ_1M
+#define MSM_MDC_PHYS         0xAA500000
+#define MSM_MDC_SIZE         SZ_1M
+
+#define MSM_AD5_PHYS          0xAC000000
+#define MSM_AD5_SIZE          (SZ_1M*13)
+
 
 #endif
diff --git a/arch/arm/mach-msm/include/mach/vreg.h b/arch/arm/mach-msm/include/mach/vreg.h
new file mode 100644 (file)
index 0000000..9f9e25c
--- /dev/null
@@ -0,0 +1,29 @@
+/* linux/include/asm-arm/arch-msm/vreg.h
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 __ARCH_ARM_MACH_MSM_VREG_H
+#define __ARCH_ARM_MACH_MSM_VREG_H
+
+struct vreg;
+
+struct vreg *vreg_get(struct device *dev, const char *id);
+void vreg_put(struct vreg *vreg);
+
+int vreg_enable(struct vreg *vreg);
+void vreg_disable(struct vreg *vreg);
+int vreg_set_level(struct vreg *vreg, unsigned mv);
+
+#endif
index 7999e4ba8e200c4325f4df99d296262453aa1eaf..6e7692ff6f2cb1a7416a8b12c44d0aed0748f3ae 100644 (file)
@@ -28,7 +28,7 @@
 #include <mach/board.h>
 
 #define MSM_DEVICE(name) { \
-               .virtual = MSM_##name##_BASE, \
+               .virtual = (unsigned long) MSM_##name##_BASE, \
                .pfn = __phys_to_pfn(MSM_##name##_PHYS), \
                .length = MSM_##name##_SIZE, \
                .type = MT_DEVICE_NONSHARED, \
@@ -39,19 +39,11 @@ static struct map_desc msm_io_desc[] __initdata = {
        MSM_DEVICE(CSR),
        MSM_DEVICE(GPT),
        MSM_DEVICE(DMOV),
-       MSM_DEVICE(UART1),
-       MSM_DEVICE(UART2),
-       MSM_DEVICE(UART3),
-       MSM_DEVICE(I2C),
        MSM_DEVICE(GPIO1),
        MSM_DEVICE(GPIO2),
-       MSM_DEVICE(HSUSB),
        MSM_DEVICE(CLK_CTL),
-       MSM_DEVICE(PMDH),
-       MSM_DEVICE(EMDH),
-       MSM_DEVICE(MDP),
        {
-               .virtual =  MSM_SHARED_RAM_BASE,
+               .virtual =  (unsigned long) MSM_SHARED_RAM_BASE,
                .pfn =      __phys_to_pfn(MSM_SHARED_RAM_PHYS),
                .length =   MSM_SHARED_RAM_SIZE,
                .type =     MT_DEVICE,
index 04b8d182ff8aa72a33af684d79bc1f9ba7094f86..69ca0dd79bdfc65ed8bdbeff8d1535969f1bd5a8 100644 (file)
 
 static void msm_irq_ack(unsigned int irq)
 {
-       unsigned reg = VIC_INT_CLEAR0 + ((irq & 32) ? 4 : 0);
+       void __iomem *reg = VIC_INT_CLEAR0 + ((irq & 32) ? 4 : 0);
        irq = 1 << (irq & 31);
        writel(irq, reg);
 }
 
 static void msm_irq_mask(unsigned int irq)
 {
-       unsigned reg = VIC_INT_ENCLEAR0 + ((irq & 32) ? 4 : 0);
+       void __iomem *reg = VIC_INT_ENCLEAR0 + ((irq & 32) ? 4 : 0);
        writel(1 << (irq & 31), reg);
 }
 
 static void msm_irq_unmask(unsigned int irq)
 {
-       unsigned reg = VIC_INT_ENSET0 + ((irq & 32) ? 4 : 0);
+       void __iomem *reg = VIC_INT_ENSET0 + ((irq & 32) ? 4 : 0);
        writel(1 << (irq & 31), reg);
 }
 
@@ -90,8 +90,8 @@ static int msm_irq_set_wake(unsigned int irq, unsigned int on)
 
 static int msm_irq_set_type(unsigned int irq, unsigned int flow_type)
 {
-       unsigned treg = VIC_INT_TYPE0 + ((irq & 32) ? 4 : 0);
-       unsigned preg = VIC_INT_POLARITY0 + ((irq & 32) ? 4 : 0);
+       void __iomem *treg = VIC_INT_TYPE0 + ((irq & 32) ? 4 : 0);
+       void __iomem *preg = VIC_INT_POLARITY0 + ((irq & 32) ? 4 : 0);
        int b = 1 << (irq & 31);
 
        if (flow_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW))
diff --git a/arch/arm/mach-msm/proc_comm.c b/arch/arm/mach-msm/proc_comm.c
new file mode 100644 (file)
index 0000000..915ee70
--- /dev/null
@@ -0,0 +1,110 @@
+/* arch/arm/mach-msm/proc_comm.c
+ *
+ * Copyright (C) 2007-2008 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <mach/msm_iomap.h>
+#include <mach/system.h>
+
+#include "proc_comm.h"
+
+#define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4)
+
+static inline void notify_other_proc_comm(void)
+{
+       writel(1, MSM_A2M_INT(6));
+}
+
+#define APP_COMMAND 0x00
+#define APP_STATUS  0x04
+#define APP_DATA1   0x08
+#define APP_DATA2   0x0C
+
+#define MDM_COMMAND 0x10
+#define MDM_STATUS  0x14
+#define MDM_DATA1   0x18
+#define MDM_DATA2   0x1C
+
+static DEFINE_SPINLOCK(proc_comm_lock);
+
+/* The higher level SMD support will install this to
+ * provide a way to check for and handle modem restart.
+ */
+int (*msm_check_for_modem_crash)(void);
+
+/* Poll for a state change, checking for possible
+ * modem crashes along the way (so we don't wait
+ * forever while the ARM9 is blowing up).
+ *
+ * Return an error in the event of a modem crash and
+ * restart so the msm_proc_comm() routine can restart
+ * the operation from the beginning.
+ */
+static int proc_comm_wait_for(void __iomem *addr, unsigned value)
+{
+       for (;;) {
+               if (readl(addr) == value)
+                       return 0;
+
+               if (msm_check_for_modem_crash)
+                       if (msm_check_for_modem_crash())
+                               return -EAGAIN;
+       }
+}
+
+int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2)
+{
+       void __iomem *base = MSM_SHARED_RAM_BASE;
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&proc_comm_lock, flags);
+
+       for (;;) {
+               if (proc_comm_wait_for(base + MDM_STATUS, PCOM_READY))
+                       continue;
+
+               writel(cmd, base + APP_COMMAND);
+               writel(data1 ? *data1 : 0, base + APP_DATA1);
+               writel(data2 ? *data2 : 0, base + APP_DATA2);
+
+               notify_other_proc_comm();
+
+               if (proc_comm_wait_for(base + APP_COMMAND, PCOM_CMD_DONE))
+                       continue;
+
+               if (readl(base + APP_STATUS) != PCOM_CMD_FAIL) {
+                       if (data1)
+                               *data1 = readl(base + APP_DATA1);
+                       if (data2)
+                               *data2 = readl(base + APP_DATA2);
+                       ret = 0;
+               } else {
+                       ret = -EIO;
+               }
+               break;
+       }
+
+       writel(PCOM_CMD_IDLE, base + APP_COMMAND);
+
+       spin_unlock_irqrestore(&proc_comm_lock, flags);
+
+       return ret;
+}
+
+
diff --git a/arch/arm/mach-msm/proc_comm.h b/arch/arm/mach-msm/proc_comm.h
new file mode 100644 (file)
index 0000000..834760f
--- /dev/null
@@ -0,0 +1,165 @@
+/* arch/arm/mach-msm/proc_comm.h
+ *
+ * Copyright (c) 2007 QUALCOMM Incorporated
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 _ARCH_ARM_MACH_MSM_PROC_COMM_H_
+#define _ARCH_ARM_MACH_MSM_PROC_COMM_H_
+
+enum {
+       PCOM_CMD_IDLE = 0x0,
+       PCOM_CMD_DONE,
+       PCOM_RESET_APPS,
+       PCOM_RESET_CHIP,
+       PCOM_CONFIG_NAND_MPU,
+       PCOM_CONFIG_USB_CLKS,
+       PCOM_GET_POWER_ON_STATUS,
+       PCOM_GET_WAKE_UP_STATUS,
+       PCOM_GET_BATT_LEVEL,
+       PCOM_CHG_IS_CHARGING,
+       PCOM_POWER_DOWN,
+       PCOM_USB_PIN_CONFIG,
+       PCOM_USB_PIN_SEL,
+       PCOM_SET_RTC_ALARM,
+       PCOM_NV_READ,
+       PCOM_NV_WRITE,
+       PCOM_GET_UUID_HIGH,
+       PCOM_GET_UUID_LOW,
+       PCOM_GET_HW_ENTROPY,
+       PCOM_RPC_GPIO_TLMM_CONFIG_REMOTE,
+       PCOM_CLKCTL_RPC_ENABLE,
+       PCOM_CLKCTL_RPC_DISABLE,
+       PCOM_CLKCTL_RPC_RESET,
+       PCOM_CLKCTL_RPC_SET_FLAGS,
+       PCOM_CLKCTL_RPC_SET_RATE,
+       PCOM_CLKCTL_RPC_MIN_RATE,
+       PCOM_CLKCTL_RPC_MAX_RATE,
+       PCOM_CLKCTL_RPC_RATE,
+       PCOM_CLKCTL_RPC_PLL_REQUEST,
+       PCOM_CLKCTL_RPC_ENABLED,
+       PCOM_VREG_SWITCH,
+       PCOM_VREG_SET_LEVEL,
+       PCOM_GPIO_TLMM_CONFIG_GROUP,
+       PCOM_GPIO_TLMM_UNCONFIG_GROUP,
+       PCOM_NV_WRITE_BYTES_4_7,
+       PCOM_CONFIG_DISP,
+       PCOM_GET_FTM_BOOT_COUNT,
+       PCOM_RPC_GPIO_TLMM_CONFIG_EX,
+       PCOM_PM_MPP_CONFIG,
+       PCOM_GPIO_IN,
+       PCOM_GPIO_OUT,
+       PCOM_RESET_MODEM,
+       PCOM_RESET_CHIP_IMM,
+       PCOM_PM_VID_EN,
+       PCOM_VREG_PULLDOWN,
+       PCOM_NUM_CMDS,
+};
+
+enum {
+        PCOM_INVALID_STATUS = 0x0,
+        PCOM_READY,
+        PCOM_CMD_RUNNING,
+        PCOM_CMD_SUCCESS,
+        PCOM_CMD_FAIL,
+};
+
+/* List of VREGs that support the Pull Down Resistor setting. */
+enum {
+       PM_VREG_PDOWN_MSMA_ID,
+       PM_VREG_PDOWN_MSMP_ID,
+       PM_VREG_PDOWN_MSME1_ID, /* Not supported in Panoramix */
+       PM_VREG_PDOWN_MSMC1_ID, /* Not supported in PM6620 */
+       PM_VREG_PDOWN_MSMC2_ID, /* Supported in PM7500 only */
+       PM_VREG_PDOWN_GP3_ID,   /* Supported in PM7500 only */
+       PM_VREG_PDOWN_MSME2_ID, /* Supported in PM7500 and Panoramix only */
+       PM_VREG_PDOWN_GP4_ID,   /* Supported in PM7500 only */
+       PM_VREG_PDOWN_GP1_ID,   /* Supported in PM7500 only */
+       PM_VREG_PDOWN_TCXO_ID,
+       PM_VREG_PDOWN_PA_ID,
+       PM_VREG_PDOWN_RFTX_ID,
+       PM_VREG_PDOWN_RFRX1_ID,
+       PM_VREG_PDOWN_RFRX2_ID,
+       PM_VREG_PDOWN_SYNT_ID,
+       PM_VREG_PDOWN_WLAN_ID,
+       PM_VREG_PDOWN_USB_ID,
+       PM_VREG_PDOWN_MMC_ID,
+       PM_VREG_PDOWN_RUIM_ID,
+       PM_VREG_PDOWN_MSMC0_ID, /* Supported in PM6610 only */
+       PM_VREG_PDOWN_GP2_ID,   /* Supported in PM7500 only */
+       PM_VREG_PDOWN_GP5_ID,   /* Supported in PM7500 only */
+       PM_VREG_PDOWN_GP6_ID,   /* Supported in PM7500 only */
+       PM_VREG_PDOWN_RF_ID,
+       PM_VREG_PDOWN_RF_VCO_ID,
+       PM_VREG_PDOWN_MPLL_ID,
+       PM_VREG_PDOWN_S2_ID,
+       PM_VREG_PDOWN_S3_ID,
+       PM_VREG_PDOWN_RFUBM_ID,
+
+       /* new for HAN */
+       PM_VREG_PDOWN_RF1_ID,
+       PM_VREG_PDOWN_RF2_ID,
+       PM_VREG_PDOWN_RFA_ID,
+       PM_VREG_PDOWN_CDC2_ID,
+       PM_VREG_PDOWN_RFTX2_ID,
+       PM_VREG_PDOWN_USIM_ID,
+       PM_VREG_PDOWN_USB2P6_ID,
+       PM_VREG_PDOWN_USB3P3_ID,
+       PM_VREG_PDOWN_INVALID_ID,
+
+       /* backward compatible enums only */
+       PM_VREG_PDOWN_CAM_ID = PM_VREG_PDOWN_GP1_ID,
+       PM_VREG_PDOWN_MDDI_ID = PM_VREG_PDOWN_GP2_ID,
+       PM_VREG_PDOWN_RUIM2_ID = PM_VREG_PDOWN_GP3_ID,
+       PM_VREG_PDOWN_AUX_ID = PM_VREG_PDOWN_GP4_ID,
+       PM_VREG_PDOWN_AUX2_ID = PM_VREG_PDOWN_GP5_ID,
+       PM_VREG_PDOWN_BT_ID = PM_VREG_PDOWN_GP6_ID,
+
+       PM_VREG_PDOWN_MSME_ID = PM_VREG_PDOWN_MSME1_ID,
+       PM_VREG_PDOWN_MSMC_ID = PM_VREG_PDOWN_MSMC1_ID,
+       PM_VREG_PDOWN_RFA1_ID = PM_VREG_PDOWN_RFRX2_ID,
+       PM_VREG_PDOWN_RFA2_ID = PM_VREG_PDOWN_RFTX2_ID,
+       PM_VREG_PDOWN_XO_ID = PM_VREG_PDOWN_TCXO_ID
+};
+
+/* gpio info for PCOM_RPC_GPIO_TLMM_CONFIG_EX */
+
+#define GPIO_ENABLE    0
+#define GPIO_DISABLE   1
+
+#define GPIO_INPUT     0
+#define GPIO_OUTPUT    1
+
+#define GPIO_NO_PULL   0
+#define GPIO_PULL_DOWN 1
+#define GPIO_KEEPER    2
+#define GPIO_PULL_UP   3
+
+#define GPIO_2MA       0
+#define GPIO_4MA       1
+#define GPIO_6MA       2
+#define GPIO_8MA       3
+#define GPIO_10MA      4
+#define GPIO_12MA      5
+#define GPIO_14MA      6
+#define GPIO_16MA      7
+
+#define PCOM_GPIO_CFG(gpio, func, dir, pull, drvstr) \
+               ((((gpio) & 0x3FF) << 4)        | \
+               ((func) & 0xf)                  | \
+               (((dir) & 0x1) << 14)           | \
+               (((pull) & 0x3) << 15)          | \
+               (((drvstr) & 0xF) << 17))
+
+int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2);
+
+#endif
index 2bffe9b7e9fe4e726b1b2814675390a03de4629c..345a14cb73c38debc9e6bf55caac2b56700dea1c 100644 (file)
@@ -45,7 +45,7 @@ struct msm_clock {
        struct clock_event_device   clockevent;
        struct clocksource          clocksource;
        struct irqaction            irq;
-       uint32_t                    regbase;
+       void __iomem                *regbase;
        uint32_t                    freq;
        uint32_t                    shift;
 };
diff --git a/arch/arm/mach-msm/vreg.c b/arch/arm/mach-msm/vreg.c
new file mode 100644 (file)
index 0000000..fcb0b9f
--- /dev/null
@@ -0,0 +1,143 @@
+/* arch/arm/mach-msm/vreg.c
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/debugfs.h>
+#include <mach/vreg.h>
+
+#include "proc_comm.h"
+
+struct vreg {
+       const char *name;
+       unsigned id;
+};
+
+#define VREG(_name, _id) { .name = _name, .id = _id, }
+
+static struct vreg vregs[] = {
+       VREG("msma",    0),
+       VREG("msmp",    1),
+       VREG("msme1",   2),
+       VREG("msmc1",   3),
+       VREG("msmc2",   4),
+       VREG("gp3",     5),
+       VREG("msme2",   6),
+       VREG("gp4",     7),
+       VREG("gp1",     8),
+       VREG("tcxo",    9),
+       VREG("pa",      10),
+       VREG("rftx",    11),
+       VREG("rfrx1",   12),
+       VREG("rfrx2",   13),
+       VREG("synt",    14),
+       VREG("wlan",    15),
+       VREG("usb",     16),
+       VREG("boost",   17),
+       VREG("mmc",     18),
+       VREG("ruim",    19),
+       VREG("msmc0",   20),
+       VREG("gp2",     21),
+       VREG("gp5",     22),
+       VREG("gp6",     23),
+       VREG("rf",      24),
+       VREG("rf_vco",  26),
+       VREG("mpll",    27),
+       VREG("s2",      28),
+       VREG("s3",      29),
+       VREG("rfubm",   30),
+       VREG("ncp",     31),
+};
+
+struct vreg *vreg_get(struct device *dev, const char *id)
+{
+       int n;
+       for (n = 0; n < ARRAY_SIZE(vregs); n++) {
+               if (!strcmp(vregs[n].name, id))
+                       return vregs + n;
+       }
+       return 0;
+}
+
+void vreg_put(struct vreg *vreg)
+{
+}
+
+int vreg_enable(struct vreg *vreg)
+{
+       unsigned id = vreg->id;
+       unsigned enable = 1;
+       return msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+}
+
+void vreg_disable(struct vreg *vreg)
+{
+       unsigned id = vreg->id;
+       unsigned enable = 0;
+       msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+}
+
+int vreg_set_level(struct vreg *vreg, unsigned mv)
+{
+       unsigned id = vreg->id;
+       return msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv);
+}
+
+#if defined(CONFIG_DEBUG_FS)
+
+static int vreg_debug_set(void *data, u64 val)
+{
+       struct vreg *vreg = data;
+       switch (val) {
+       case 0:
+               vreg_disable(vreg);
+               break;
+       case 1:
+               vreg_enable(vreg);
+               break;
+       default:
+               vreg_set_level(vreg, val);
+               break;
+       }
+       return 0;
+}
+
+static int vreg_debug_get(void *data, u64 *val)
+{
+       return -ENOSYS;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(vreg_fops, vreg_debug_get, vreg_debug_set, "%llu\n");
+
+static int __init vreg_debug_init(void)
+{
+       struct dentry *dent;
+       int n;
+
+       dent = debugfs_create_dir("vreg", 0);
+       if (IS_ERR(dent))
+               return 0;
+
+       for (n = 0; n < ARRAY_SIZE(vregs); n++)
+               (void) debugfs_create_file(vregs[n].name, 0644,
+                                          dent, vregs + n, &vreg_fops);
+
+       return 0;
+}
+
+device_initcall(vreg_debug_init);
+#endif
index 49f434c39eb76e539f46e81be52d9735f7ca5145..2e285bbb7bbd1ebb3368a0de746a524f7ca944fc 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/platform_device.h>
 #include <linux/ata_platform.h>
 #include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
 #include <mach/mv78xx0.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -28,10 +29,14 @@ static struct mv643xx_eth_platform_data db78x00_ge01_data = {
 
 static struct mv643xx_eth_platform_data db78x00_ge10_data = {
        .phy_addr       = MV643XX_ETH_PHY_NONE,
+       .speed          = SPEED_1000,
+       .duplex         = DUPLEX_FULL,
 };
 
 static struct mv643xx_eth_platform_data db78x00_ge11_data = {
        .phy_addr       = MV643XX_ETH_PHY_NONE,
+       .speed          = SPEED_1000,
+       .duplex         = DUPLEX_FULL,
 };
 
 static struct mv_sata_platform_data db78x00_sata_data = {
index d354e0fe4477ad450668b16e462258e26b2b4853..c40fc378a251244bce6e6c0ad9f0e177c7326a75 100644 (file)
@@ -119,7 +119,7 @@ static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
 
 void __init omap_init_irq(void)
 {
-       unsigned long nr_irqs = 0;
+       unsigned long nr_of_irqs = 0;
        unsigned int nr_banks = 0;
        int i;
 
@@ -133,14 +133,14 @@ void __init omap_init_irq(void)
 
                omap_irq_bank_init_one(bank);
 
-               nr_irqs += bank->nr_irqs;
+               nr_of_irqs += bank->nr_irqs;
                nr_banks++;
        }
 
        printk(KERN_INFO "Total of %ld interrupts on %d active controller%s\n",
-              nr_irqs, nr_banks, nr_banks > 1 ? "s" : "");
+              nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : "");
 
-       for (i = 0; i < nr_irqs; i++) {
+       for (i = 0; i < nr_of_irqs; i++) {
                set_irq_chip(i, &omap_irq_chip);
                set_irq_handler(i, handle_level_irq);
                set_irq_flags(i, IRQF_VALID);
index 9625ef5975d0a3c09cb3a01fe173c542f04cd0db..437065c25c9cdf4c6a902576c32ae15d3d3bdc20 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/mv643xx_i2c.h>
 #include <linux/ata_platform.h>
 #include <linux/spi/orion_spi.h>
+#include <net/dsa.h>
 #include <asm/page.h>
 #include <asm/setup.h>
 #include <asm/timex.h>
@@ -197,6 +198,40 @@ void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
 }
 
 
+/*****************************************************************************
+ * Ethernet switch
+ ****************************************************************************/
+static struct resource orion5x_switch_resources[] = {
+       {
+               .start  = 0,
+               .end    = 0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device orion5x_switch_device = {
+       .name           = "dsa",
+       .id             = 0,
+       .num_resources  = 0,
+       .resource       = orion5x_switch_resources,
+};
+
+void __init orion5x_eth_switch_init(struct dsa_platform_data *d, int irq)
+{
+       if (irq != NO_IRQ) {
+               orion5x_switch_resources[0].start = irq;
+               orion5x_switch_resources[0].end = irq;
+               orion5x_switch_device.num_resources = 1;
+       }
+
+       d->mii_bus = &orion5x_eth_shared.dev;
+       d->netdev = &orion5x_eth.dev;
+       orion5x_switch_device.dev.platform_data = d;
+
+       platform_device_register(&orion5x_switch_device);
+}
+
+
 /*****************************************************************************
  * I2C
  ****************************************************************************/
@@ -275,7 +310,8 @@ void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data)
  * SPI
  ****************************************************************************/
 static struct orion_spi_info orion5x_spi_plat_data = {
-       .tclk           = 0,
+       .tclk                   = 0,
+       .enable_clock_fix       = 1,
 };
 
 static struct resource orion5x_spi_resources[] = {
index 1f8b2da676a5e86187cb8b6dcd92a5d278d83f26..a000c7c6ee96191ec7592055492f588b22bdfcd4 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __ARCH_ORION5X_COMMON_H
 #define __ARCH_ORION5X_COMMON_H
 
+struct dsa_platform_data;
 struct mv643xx_eth_platform_data;
 struct mv_sata_platform_data;
 
@@ -29,6 +30,7 @@ void orion5x_setup_pcie_wa_win(u32 base, u32 size);
 void orion5x_ehci0_init(void);
 void orion5x_ehci1_init(void);
 void orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data);
+void orion5x_eth_switch_init(struct dsa_platform_data *d, int irq);
 void orion5x_i2c_init(void);
 void orion5x_sata_init(struct mv_sata_platform_data *sata_data);
 void orion5x_spi_init(void);
index 500cdadaf09c8e160f566b37a1fb785e39437cce..15f53235ee302dbff7c9615fbc746c250982105b 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/mtd/physmap.h>
 #include <linux/mv643xx_eth.h>
 #include <linux/ethtool.h>
+#include <net/dsa.h>
 #include <asm/mach-types.h>
 #include <asm/gpio.h>
 #include <asm/leds.h>
@@ -93,6 +94,15 @@ static struct mv643xx_eth_platform_data rd88f5181l_fxo_eth_data = {
        .duplex         = DUPLEX_FULL,
 };
 
+static struct dsa_platform_data rd88f5181l_fxo_switch_data = {
+       .port_names[0]  = "lan2",
+       .port_names[1]  = "lan1",
+       .port_names[2]  = "wan",
+       .port_names[3]  = "cpu",
+       .port_names[5]  = "lan4",
+       .port_names[7]  = "lan3",
+};
+
 static void __init rd88f5181l_fxo_init(void)
 {
        /*
@@ -107,6 +117,7 @@ static void __init rd88f5181l_fxo_init(void)
         */
        orion5x_ehci0_init();
        orion5x_eth_init(&rd88f5181l_fxo_eth_data);
+       orion5x_eth_switch_init(&rd88f5181l_fxo_switch_data, NO_IRQ);
        orion5x_uart0_init();
 
        orion5x_setup_dev_boot_win(RD88F5181L_FXO_NOR_BOOT_BASE,
index ebde8141649935058d7a701b485e7a6b412cccd7..8ad3934399d4fab8680fd0cc994305f4363925ee 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/mv643xx_eth.h>
 #include <linux/ethtool.h>
 #include <linux/i2c.h>
+#include <net/dsa.h>
 #include <asm/mach-types.h>
 #include <asm/gpio.h>
 #include <asm/leds.h>
@@ -94,6 +95,15 @@ static struct mv643xx_eth_platform_data rd88f5181l_ge_eth_data = {
        .duplex         = DUPLEX_FULL,
 };
 
+static struct dsa_platform_data rd88f5181l_ge_switch_data = {
+       .port_names[0]  = "lan2",
+       .port_names[1]  = "lan1",
+       .port_names[2]  = "wan",
+       .port_names[3]  = "cpu",
+       .port_names[5]  = "lan4",
+       .port_names[7]  = "lan3",
+};
+
 static struct i2c_board_info __initdata rd88f5181l_ge_i2c_rtc = {
        I2C_BOARD_INFO("ds1338", 0x68),
 };
@@ -112,6 +122,7 @@ static void __init rd88f5181l_ge_init(void)
         */
        orion5x_ehci0_init();
        orion5x_eth_init(&rd88f5181l_ge_eth_data);
+       orion5x_eth_switch_init(&rd88f5181l_ge_switch_data, gpio_to_irq(8));
        orion5x_i2c_init();
        orion5x_uart0_init();
 
index 40e049539091ba7d4f01ce06297d896bf262e78a..262e25e4dace484fa826ddf60f8f226f1bf0bef6 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/spi/orion_spi.h>
 #include <linux/spi/flash.h>
 #include <linux/ethtool.h>
+#include <net/dsa.h>
 #include <asm/mach-types.h>
 #include <asm/gpio.h>
 #include <asm/leds.h>
@@ -34,6 +35,15 @@ static struct mv643xx_eth_platform_data rd88f6183ap_ge_eth_data = {
        .duplex         = DUPLEX_FULL,
 };
 
+static struct dsa_platform_data rd88f6183ap_ge_switch_data = {
+       .port_names[0]  = "lan1",
+       .port_names[1]  = "lan2",
+       .port_names[2]  = "lan3",
+       .port_names[3]  = "lan4",
+       .port_names[4]  = "wan",
+       .port_names[5]  = "cpu",
+};
+
 static struct mtd_partition rd88f6183ap_ge_partitions[] = {
        {
                .name   = "kernel",
@@ -79,6 +89,7 @@ static void __init rd88f6183ap_ge_init(void)
         */
        orion5x_ehci0_init();
        orion5x_eth_init(&rd88f6183ap_ge_eth_data);
+       orion5x_eth_switch_init(&rd88f6183ap_ge_switch_data, gpio_to_irq(3));
        spi_register_board_info(rd88f6183ap_ge_spi_slave_info,
                                ARRAY_SIZE(rd88f6183ap_ge_spi_slave_info));
        orion5x_spi_init();
index 9a4fd5256462e8686b81643e47fe9c8987165f10..cc8f8920086505fb963efc6c232f617ed1082855 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/mtd/physmap.h>
 #include <linux/mv643xx_eth.h>
 #include <linux/ethtool.h>
+#include <net/dsa.h>
 #include <asm/mach-types.h>
 #include <asm/gpio.h>
 #include <asm/mach/arch.h>
@@ -105,6 +106,15 @@ static struct mv643xx_eth_platform_data wrt350n_v2_eth_data = {
        .duplex         = DUPLEX_FULL,
 };
 
+static struct dsa_platform_data wrt350n_v2_switch_data = {
+       .port_names[0]  = "lan2",
+       .port_names[1]  = "lan1",
+       .port_names[2]  = "wan",
+       .port_names[3]  = "cpu",
+       .port_names[5]  = "lan3",
+       .port_names[7]  = "lan4",
+};
+
 static void __init wrt350n_v2_init(void)
 {
        /*
@@ -119,6 +129,7 @@ static void __init wrt350n_v2_init(void)
         */
        orion5x_ehci0_init();
        orion5x_eth_init(&wrt350n_v2_eth_data);
+       orion5x_eth_switch_init(&wrt350n_v2_switch_data, NO_IRQ);
        orion5x_uart0_init();
 
        orion5x_setup_dev_boot_win(WRT350N_V2_NOR_BOOT_BASE,
index f27f6b3d6e6f61be1b350c883dcd09cc383501a8..a062235e83a8b4c3b272c3d7af016d85dcd8b2ba 100644 (file)
@@ -71,6 +71,14 @@ config PXA_SHARPSL
          SL-C3000 (Spitz), SL-C3100 (Borzoi) or SL-C6000x (Tosa)
          handheld computer.
 
+config CORGI_SSP_DEPRECATED
+       bool
+       select PXA_SSP
+       help
+         This option will include corgi_ssp.c and corgi_lcd.c
+         that corgi_ts.c and other legacy drivers (corgi_bl.c
+         and sharpsl_pm.c) may depend on.
+
 config MACH_POODLE
        bool "Enable Sharp SL-5600 (Poodle) Support"
        depends on PXA_SHARPSL
@@ -257,7 +265,6 @@ config MACH_ARMCORE
        bool "CompuLab CM-X255/CM-X270 modules"
        select PXA27x
        select IWMMXT
-       select ZONE_DMA if PCI
        select PXA25x
        select PXA_SSP
 
index d31c9979cfa35f34aef2e1afcf81723c7e506924..d64c68b232e3ff8265b9c52df59863b2423004b0 100644 (file)
@@ -37,6 +37,7 @@ obj-$(CONFIG_MACH_TRIZEPS4)   += trizeps4.o
 obj-$(CONFIG_MACH_COLIBRI)     += colibri.o
 obj-$(CONFIG_PXA_SHARP_C7xx)   += corgi.o sharpsl_pm.o corgi_pm.o
 obj-$(CONFIG_PXA_SHARP_Cxx00)  += spitz.o sharpsl_pm.o spitz_pm.o
+obj-$(CONFIG_CORGI_SSP_DEPRECATED)     += corgi_ssp.o corgi_lcd.o
 obj-$(CONFIG_MACH_POODLE)      += poodle.o
 obj-$(CONFIG_MACH_PCM027)      += pcm027.o
 obj-$(CONFIG_MACH_PCM990_BASEBOARD)    += pcm990-baseboard.o
diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c
new file mode 100644 (file)
index 0000000..411607b
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * linux/arch/arm/mach-pxa/corgi_lcd.c
+ *
+ * Corgi/Spitz LCD Specific Code
+ *
+ * Copyright (C) 2005 Richard Purdie
+ *
+ * Connectivity:
+ *   Corgi - LCD to ATI Imageon w100 (Wallaby)
+ *   Spitz - LCD to PXA Framebuffer
+ *
+ * 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/delay.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <mach/corgi.h>
+#include <mach/hardware.h>
+#include <mach/pxa-regs.h>
+#include <mach/sharpsl.h>
+#include <mach/spitz.h>
+#include <asm/hardware/scoop.h>
+#include <asm/mach/sharpsl_param.h>
+#include "generic.h"
+
+/* Register Addresses */
+#define RESCTL_ADRS     0x00
+#define PHACTRL_ADRS    0x01
+#define DUTYCTRL_ADRS   0x02
+#define POWERREG0_ADRS  0x03
+#define POWERREG1_ADRS  0x04
+#define GPOR3_ADRS      0x05
+#define PICTRL_ADRS     0x06
+#define POLCTRL_ADRS    0x07
+
+/* Register Bit Definitions */
+#define RESCTL_QVGA     0x01
+#define RESCTL_VGA      0x00
+
+#define POWER1_VW_ON    0x01  /* VW Supply FET ON */
+#define POWER1_GVSS_ON  0x02  /* GVSS(-8V) Power Supply ON */
+#define POWER1_VDD_ON   0x04  /* VDD(8V),SVSS(-4V) Power Supply ON */
+
+#define POWER1_VW_OFF   0x00  /* VW Supply FET OFF */
+#define POWER1_GVSS_OFF 0x00  /* GVSS(-8V) Power Supply OFF */
+#define POWER1_VDD_OFF  0x00  /* VDD(8V),SVSS(-4V) Power Supply OFF */
+
+#define POWER0_COM_DCLK 0x01  /* COM Voltage DC Bias DAC Serial Data Clock */
+#define POWER0_COM_DOUT 0x02  /* COM Voltage DC Bias DAC Serial Data Out */
+#define POWER0_DAC_ON   0x04  /* DAC Power Supply ON */
+#define POWER0_COM_ON   0x08  /* COM Power Supply ON */
+#define POWER0_VCC5_ON  0x10  /* VCC5 Power Supply ON */
+
+#define POWER0_DAC_OFF  0x00  /* DAC Power Supply OFF */
+#define POWER0_COM_OFF  0x00  /* COM Power Supply OFF */
+#define POWER0_VCC5_OFF 0x00  /* VCC5 Power Supply OFF */
+
+#define PICTRL_INIT_STATE      0x01
+#define PICTRL_INIOFF          0x02
+#define PICTRL_POWER_DOWN      0x04
+#define PICTRL_COM_SIGNAL_OFF  0x08
+#define PICTRL_DAC_SIGNAL_OFF  0x10
+
+#define POLCTRL_SYNC_POL_FALL  0x01
+#define POLCTRL_EN_POL_FALL    0x02
+#define POLCTRL_DATA_POL_FALL  0x04
+#define POLCTRL_SYNC_ACT_H     0x08
+#define POLCTRL_EN_ACT_L       0x10
+
+#define POLCTRL_SYNC_POL_RISE  0x00
+#define POLCTRL_EN_POL_RISE    0x00
+#define POLCTRL_DATA_POL_RISE  0x00
+#define POLCTRL_SYNC_ACT_L     0x00
+#define POLCTRL_EN_ACT_H       0x00
+
+#define PHACTRL_PHASE_MANUAL   0x01
+#define DEFAULT_PHAD_QVGA     (9)
+#define DEFAULT_COMADJ        (125)
+
+/*
+ * This is only a psuedo I2C interface. We can't use the standard kernel
+ * routines as the interface is write only. We just assume the data is acked...
+ */
+static void lcdtg_ssp_i2c_send(u8 data)
+{
+       corgi_ssp_lcdtg_send(POWERREG0_ADRS, data);
+       udelay(10);
+}
+
+static void lcdtg_i2c_send_bit(u8 data)
+{
+       lcdtg_ssp_i2c_send(data);
+       lcdtg_ssp_i2c_send(data | POWER0_COM_DCLK);
+       lcdtg_ssp_i2c_send(data);
+}
+
+static void lcdtg_i2c_send_start(u8 base)
+{
+       lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
+       lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
+       lcdtg_ssp_i2c_send(base);
+}
+
+static void lcdtg_i2c_send_stop(u8 base)
+{
+       lcdtg_ssp_i2c_send(base);
+       lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
+       lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
+}
+
+static void lcdtg_i2c_send_byte(u8 base, u8 data)
+{
+       int i;
+       for (i = 0; i < 8; i++) {
+               if (data & 0x80)
+                       lcdtg_i2c_send_bit(base | POWER0_COM_DOUT);
+               else
+                       lcdtg_i2c_send_bit(base);
+               data <<= 1;
+       }
+}
+
+static void lcdtg_i2c_wait_ack(u8 base)
+{
+       lcdtg_i2c_send_bit(base);
+}
+
+static void lcdtg_set_common_voltage(u8 base_data, u8 data)
+{
+       /* Set Common Voltage to M62332FP via I2C */
+       lcdtg_i2c_send_start(base_data);
+       lcdtg_i2c_send_byte(base_data, 0x9c);
+       lcdtg_i2c_wait_ack(base_data);
+       lcdtg_i2c_send_byte(base_data, 0x00);
+       lcdtg_i2c_wait_ack(base_data);
+       lcdtg_i2c_send_byte(base_data, data);
+       lcdtg_i2c_wait_ack(base_data);
+       lcdtg_i2c_send_stop(base_data);
+}
+
+/* Set Phase Adjust */
+static void lcdtg_set_phadadj(int mode)
+{
+       int adj;
+       switch(mode) {
+               case 480:
+               case 640:
+                       /* Setting for VGA */
+                       adj = sharpsl_param.phadadj;
+                       if (adj < 0) {
+                               adj = PHACTRL_PHASE_MANUAL;
+                       } else {
+                               adj = ((adj & 0x0f) << 1) | PHACTRL_PHASE_MANUAL;
+                       }
+                       break;
+               case 240:
+               case 320:
+               default:
+                       /* Setting for QVGA */
+                       adj = (DEFAULT_PHAD_QVGA << 1) | PHACTRL_PHASE_MANUAL;
+                       break;
+       }
+
+       corgi_ssp_lcdtg_send(PHACTRL_ADRS, adj);
+}
+
+static int lcd_inited;
+
+void corgi_lcdtg_hw_init(int mode)
+{
+       if (!lcd_inited) {
+               int comadj;
+
+               /* Initialize Internal Logic & Port */
+               corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_POWER_DOWN | PICTRL_INIOFF | PICTRL_INIT_STATE
+                               | PICTRL_COM_SIGNAL_OFF | PICTRL_DAC_SIGNAL_OFF);
+
+               corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_OFF
+                               | POWER0_COM_OFF | POWER0_VCC5_OFF);
+
+               corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
+
+               /* VDD(+8V), SVSS(-4V) ON */
+               corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
+               mdelay(3);
+
+               /* DAC ON */
+               corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON
+                               | POWER0_COM_OFF | POWER0_VCC5_OFF);
+
+               /* INIB = H, INI = L  */
+               /* PICTL[0] = H , PICTL[1] = PICTL[2] = PICTL[4] = L */
+               corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF);
+
+               /* Set Common Voltage */
+               comadj = sharpsl_param.comadj;
+               if (comadj < 0)
+                       comadj = DEFAULT_COMADJ;
+               lcdtg_set_common_voltage((POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF), comadj);
+
+               /* VCC5 ON, DAC ON */
+               corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON |
+                               POWER0_COM_OFF | POWER0_VCC5_ON);
+
+               /* GVSS(-8V) ON, VDD ON */
+               corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
+               mdelay(2);
+
+               /* COM SIGNAL ON (PICTL[3] = L) */
+               corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIT_STATE);
+
+               /* COM ON, DAC ON, VCC5_ON */
+               corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON
+                               | POWER0_COM_ON | POWER0_VCC5_ON);
+
+               /* VW ON, GVSS ON, VDD ON */
+               corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_ON | POWER1_GVSS_ON | POWER1_VDD_ON);
+
+               /* Signals output enable */
+               corgi_ssp_lcdtg_send(PICTRL_ADRS, 0);
+
+               /* Set Phase Adjust */
+               lcdtg_set_phadadj(mode);
+
+               /* Initialize for Input Signals from ATI */
+               corgi_ssp_lcdtg_send(POLCTRL_ADRS, POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE
+                               | POLCTRL_DATA_POL_RISE | POLCTRL_SYNC_ACT_L | POLCTRL_EN_ACT_H);
+               udelay(1000);
+
+               lcd_inited=1;
+       } else {
+               lcdtg_set_phadadj(mode);
+       }
+
+       switch(mode) {
+               case 480:
+               case 640:
+                       /* Set Lcd Resolution (VGA) */
+                       corgi_ssp_lcdtg_send(RESCTL_ADRS, RESCTL_VGA);
+                       break;
+               case 240:
+               case 320:
+               default:
+                       /* Set Lcd Resolution (QVGA) */
+                       corgi_ssp_lcdtg_send(RESCTL_ADRS, RESCTL_QVGA);
+                       break;
+       }
+}
+
+void corgi_lcdtg_suspend(void)
+{
+       /* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */
+       mdelay(34);
+
+       /* (1)VW OFF */
+       corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
+
+       /* (2)COM OFF */
+       corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_COM_SIGNAL_OFF);
+       corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON);
+
+       /* (3)Set Common Voltage Bias 0V */
+       lcdtg_set_common_voltage(POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON, 0);
+
+       /* (4)GVSS OFF */
+       corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
+
+       /* (5)VCC5 OFF */
+       corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF);
+
+       /* (6)Set PDWN, INIOFF, DACOFF */
+       corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF |
+                       PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF);
+
+       /* (7)DAC OFF */
+       corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF);
+
+       /* (8)VDD OFF */
+       corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
+
+       lcd_inited = 0;
+}
+
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
new file mode 100644 (file)
index 0000000..8e2f221
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+ *  SSP control code for Sharp Corgi devices
+ *
+ *  Copyright (c) 2004-2005 Richard Purdie
+ *
+ *  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/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>
+#include <asm/mach-types.h>
+
+#include <mach/ssp.h>
+#include <mach/pxa-regs.h>
+#include <mach/pxa2xx-gpio.h>
+#include <mach/regs-ssp.h>
+#include "sharpsl.h"
+
+static DEFINE_SPINLOCK(corgi_ssp_lock);
+static struct ssp_dev corgi_ssp_dev;
+static struct ssp_state corgi_ssp_state;
+static struct corgissp_machinfo *ssp_machinfo;
+
+/*
+ * There are three devices connected to the SSP interface:
+ *   1. A touchscreen controller (TI ADS7846 compatible)
+ *   2. An LCD controller (with some Backlight functionality)
+ *   3. A battery monitoring IC (Maxim MAX1111)
+ *
+ * Each device uses a different speed/mode of communication.
+ *
+ * The touchscreen is very sensitive and the most frequently used
+ * so the port is left configured for this.
+ *
+ * Devices are selected using Chip Selects on GPIOs.
+ */
+
+/*
+ *  ADS7846 Routines
+ */
+unsigned long corgi_ssp_ads7846_putget(ulong data)
+{
+       unsigned long flag;
+       u32 ret = 0;
+
+       spin_lock_irqsave(&corgi_ssp_lock, flag);
+       if (ssp_machinfo->cs_ads7846 >= 0)
+               GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
+
+       ssp_write_word(&corgi_ssp_dev,data);
+       ssp_read_word(&corgi_ssp_dev, &ret);
+
+       if (ssp_machinfo->cs_ads7846 >= 0)
+               GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
+       spin_unlock_irqrestore(&corgi_ssp_lock, flag);
+
+       return ret;
+}
+
+/*
+ * NOTE: These functions should always be called in interrupt context
+ * and use the _lock and _unlock functions. They are very time sensitive.
+ */
+void corgi_ssp_ads7846_lock(void)
+{
+       spin_lock(&corgi_ssp_lock);
+       if (ssp_machinfo->cs_ads7846 >= 0)
+               GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
+}
+
+void corgi_ssp_ads7846_unlock(void)
+{
+       if (ssp_machinfo->cs_ads7846 >= 0)
+               GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
+       spin_unlock(&corgi_ssp_lock);
+}
+
+void corgi_ssp_ads7846_put(ulong data)
+{
+       ssp_write_word(&corgi_ssp_dev,data);
+}
+
+unsigned long corgi_ssp_ads7846_get(void)
+{
+       u32 ret = 0;
+       ssp_read_word(&corgi_ssp_dev, &ret);
+       return ret;
+}
+
+EXPORT_SYMBOL(corgi_ssp_ads7846_putget);
+EXPORT_SYMBOL(corgi_ssp_ads7846_lock);
+EXPORT_SYMBOL(corgi_ssp_ads7846_unlock);
+EXPORT_SYMBOL(corgi_ssp_ads7846_put);
+EXPORT_SYMBOL(corgi_ssp_ads7846_get);
+
+
+/*
+ *  LCD/Backlight Routines
+ */
+unsigned long corgi_ssp_dac_put(ulong data)
+{
+       unsigned long flag, sscr1 = SSCR1_SPH;
+       u32 tmp;
+
+       spin_lock_irqsave(&corgi_ssp_lock, flag);
+
+       if (machine_is_spitz() || machine_is_akita() || machine_is_borzoi())
+               sscr1 = 0;
+
+       ssp_disable(&corgi_ssp_dev);
+       ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), sscr1, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_lcdcon));
+       ssp_enable(&corgi_ssp_dev);
+
+       if (ssp_machinfo->cs_lcdcon >= 0)
+               GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
+       ssp_write_word(&corgi_ssp_dev,data);
+       /* Read null data back from device to prevent SSP overflow */
+       ssp_read_word(&corgi_ssp_dev, &tmp);
+       if (ssp_machinfo->cs_lcdcon >= 0)
+               GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
+
+       ssp_disable(&corgi_ssp_dev);
+       ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
+       ssp_enable(&corgi_ssp_dev);
+
+       spin_unlock_irqrestore(&corgi_ssp_lock, flag);
+
+       return 0;
+}
+
+void corgi_ssp_lcdtg_send(u8 adrs, u8 data)
+{
+       corgi_ssp_dac_put(((adrs & 0x07) << 5) | (data & 0x1f));
+}
+
+void corgi_ssp_blduty_set(int duty)
+{
+       corgi_ssp_lcdtg_send(0x02,duty);
+}
+
+EXPORT_SYMBOL(corgi_ssp_lcdtg_send);
+EXPORT_SYMBOL(corgi_ssp_blduty_set);
+
+/*
+ *  Max1111 Routines
+ */
+int corgi_ssp_max1111_get(ulong data)
+{
+       unsigned long flag;
+       long voltage = 0, voltage1 = 0, voltage2 = 0;
+
+       spin_lock_irqsave(&corgi_ssp_lock, flag);
+       if (ssp_machinfo->cs_max1111 >= 0)
+               GPCR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
+       ssp_disable(&corgi_ssp_dev);
+       ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_max1111));
+       ssp_enable(&corgi_ssp_dev);
+
+       udelay(1);
+
+       /* TB1/RB1 */
+       ssp_write_word(&corgi_ssp_dev,data);
+       ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1); /* null read */
+
+       /* TB12/RB2 */
+       ssp_write_word(&corgi_ssp_dev,0);
+       ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1);
+
+       /* TB13/RB3*/
+       ssp_write_word(&corgi_ssp_dev,0);
+       ssp_read_word(&corgi_ssp_dev, (u32*)&voltage2);
+
+       ssp_disable(&corgi_ssp_dev);
+       ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
+       ssp_enable(&corgi_ssp_dev);
+       if (ssp_machinfo->cs_max1111 >= 0)
+               GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
+       spin_unlock_irqrestore(&corgi_ssp_lock, flag);
+
+       if (voltage1 & 0xc0 || voltage2 & 0x3f)
+               voltage = -1;
+       else
+               voltage = ((voltage1 << 2) & 0xfc) | ((voltage2 >> 6) & 0x03);
+
+       return voltage;
+}
+
+EXPORT_SYMBOL(corgi_ssp_max1111_get);
+
+/*
+ *  Support Routines
+ */
+
+void __init corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo)
+{
+       ssp_machinfo = machinfo;
+}
+
+static int __init corgi_ssp_probe(struct platform_device *dev)
+{
+       int ret;
+
+       /* Chip Select - Disable All */
+       if (ssp_machinfo->cs_lcdcon >= 0)
+               pxa_gpio_mode(ssp_machinfo->cs_lcdcon  | GPIO_OUT | GPIO_DFLT_HIGH);
+       if (ssp_machinfo->cs_max1111 >= 0)
+               pxa_gpio_mode(ssp_machinfo->cs_max1111 | GPIO_OUT | GPIO_DFLT_HIGH);
+       if (ssp_machinfo->cs_ads7846 >= 0)
+               pxa_gpio_mode(ssp_machinfo->cs_ads7846 | GPIO_OUT | GPIO_DFLT_HIGH);
+
+       ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0);
+
+       if (ret)
+               printk(KERN_ERR "Unable to register SSP handler!\n");
+       else {
+               ssp_disable(&corgi_ssp_dev);
+               ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
+               ssp_enable(&corgi_ssp_dev);
+       }
+
+       return ret;
+}
+
+static int corgi_ssp_remove(struct platform_device *dev)
+{
+       ssp_exit(&corgi_ssp_dev);
+       return 0;
+}
+
+static int corgi_ssp_suspend(struct platform_device *dev, pm_message_t state)
+{
+       ssp_flush(&corgi_ssp_dev);
+       ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state);
+
+       return 0;
+}
+
+static int corgi_ssp_resume(struct platform_device *dev)
+{
+       if (ssp_machinfo->cs_lcdcon >= 0)
+               GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);  /* High - Disable LCD Control/Timing Gen */
+       if (ssp_machinfo->cs_max1111 >= 0)
+               GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
+       if (ssp_machinfo->cs_ads7846 >= 0)
+               GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
+       ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
+       ssp_enable(&corgi_ssp_dev);
+
+       return 0;
+}
+
+static struct platform_driver corgissp_driver = {
+       .probe          = corgi_ssp_probe,
+       .remove         = corgi_ssp_remove,
+       .suspend        = corgi_ssp_suspend,
+       .resume         = corgi_ssp_resume,
+       .driver         = {
+               .name   = "corgi-ssp",
+       },
+};
+
+int __init corgi_ssp_init(void)
+{
+       return platform_driver_register(&corgissp_driver);
+}
+
+arch_initcall(corgi_ssp_init);
index 585970ef08cec208b3f70779f87cb85001ea5859..7239281788de4bedb4c06b302e65710e0d185412 100644 (file)
  * Shared data structures
  */
 extern struct platform_device corgiscoop_device;
+extern struct platform_device corgissp_device;
 
 #endif /* __ASM_ARCH_CORGI_H  */
 
index 9c163e19ada939053f8b9366816d59c872d6369f..32bb4a2eb7f13660f43889d5aec7cdcdec07c97e 100644 (file)
@@ -9,7 +9,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#ifndef __ASM_MACH_IRQS_H
+#define __ASM_MACH_IRQS_H
 
 #ifdef CONFIG_PXA_HAVE_ISA_IRQS
 #define PXA_ISA_IRQ(x) (x)
 #endif
 
 #endif /* CONFIG_PCI_HOST_ITE8152 */
+
+#endif /* __ASM_MACH_IRQS_H */
index 31ac26b55bc1e486687fbdeefa0567422ef7e116..fa1998caa78eff3a8b764e42ff79ed495168595f 100644 (file)
 
 #define SPITZ_SCP2_GPIO_BASE           (NR_BUILTIN_GPIO + 12)
 #define SPITZ_GPIO_IR_ON               (SPITZ_SCP2_GPIO_BASE + 0)
-#define SPITZ_GPIO_AKIN_PULLUP         (SPITZ_SCP2_GPIO_BASE + 1
+#define SPITZ_GPIO_AKIN_PULLUP         (SPITZ_SCP2_GPIO_BASE + 1)
 #define SPITZ_GPIO_RESERVED_1          (SPITZ_SCP2_GPIO_BASE + 2)
 #define SPITZ_GPIO_RESERVED_2          (SPITZ_SCP2_GPIO_BASE + 3)
 #define SPITZ_GPIO_RESERVED_3          (SPITZ_SCP2_GPIO_BASE + 4)
  */
 extern struct platform_device spitzscoop_device;
 extern struct platform_device spitzscoop2_device;
+extern struct platform_device spitzssp_device;
 extern struct sharpsl_charger_machinfo spitz_pm_machinfo;
index 8bce6d8615b9ddec02856941fd1e700d79c505de..4df2d38507dc253d65aac1f3ea6be2c50dfe14cf 100644 (file)
 #define TOSA_KEY_MAIL          KEY_MAIL
 #endif
 
+struct spi_device;
+extern int tosa_bl_enable(struct spi_device *spi, int enable);
+
 #endif /* _ASM_ARCH_TOSA_H_ */
index 0d35ca04731e485fa655c5dccd087c59fd58fb0d..bf6785adccf45a02e725422994d17d77138d2bf9 100644 (file)
@@ -30,7 +30,7 @@ extern void zylonite_pxa300_init(void);
 static inline void zylonite_pxa300_init(void)
 {
        if (cpu_is_pxa300() || cpu_is_pxa310())
-               panic("%s: PXA300/PXA310 not supported\n", __FUNCTION__);
+               panic("%s: PXA300/PXA310 not supported\n", __func__);
 }
 #endif
 
@@ -40,7 +40,7 @@ extern void zylonite_pxa320_init(void);
 static inline void zylonite_pxa320_init(void)
 {
        if (cpu_is_pxa320())
-               panic("%s: PXA320 not supported\n", __FUNCTION__);
+               panic("%s: PXA320 not supported\n", __func__);
 }
 #endif
 
index 316cd986da5cea37dbe6692b57124dc0e9fb46b0..74e2ead8cee80fa7f52ca7d7e40b64ce8005fc00 100644 (file)
@@ -60,7 +60,7 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
        do_div(c, 1000000000);
        period_cycles = c;
 
-       if (period_cycles < 0)
+       if (period_cycles < 1)
                period_cycles = 1;
        prescale = (period_cycles - 1) / 1024;
        pv = period_cycles / (prescale + 1) - 1;
index 15c2f1a8623ba8b547dea59b9dcc6ab97e18adef..f0845c1b001c8a94fca44dbb93df2edf621ecbd8 100644 (file)
@@ -116,20 +116,33 @@ struct battery_thresh  spitz_battery_levels_noac[] = {
        {   0,   0},
 };
 
+/* MAX1111 Commands */
+#define MAXCTRL_PD0      1u << 0
+#define MAXCTRL_PD1      1u << 1
+#define MAXCTRL_SGL      1u << 2
+#define MAXCTRL_UNI      1u << 3
+#define MAXCTRL_SEL_SH   4
+#define MAXCTRL_STR      1u << 7
+
 /*
  * Read MAX1111 ADC
  */
-extern int max1111_read_channel(int);
-
 int sharpsl_pm_pxa_read_max1111(int channel)
 {
        if (machine_is_tosa()) // Ugly, better move this function into another module
            return 0;
 
+#ifdef CONFIG_CORGI_SSP_DEPRECATED
+       return corgi_ssp_max1111_get((channel << MAXCTRL_SEL_SH) | MAXCTRL_PD0 | MAXCTRL_PD1
+                       | MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR);
+#else
+       extern int max1111_read_channel(int);
+
        /* max1111 accepts channels from 0-3, however,
         * it is encoded from 0-7 here in the code.
         */
        return max1111_read_channel(channel >> 1);
+#endif
 }
 
 void sharpsl_pm_pxa_init(void)
index a6c4694359cabfdde423f8e669cac9dfeaca9163..224897a67d1593113cb43806ef861cad5ec95190 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/gpio.h>
 #include <linux/pda_power.h>
 #include <linux/rfkill.h>
+#include <linux/spi/spi.h>
 
 #include <asm/setup.h>
 #include <asm/mach-types.h>
@@ -42,6 +43,7 @@
 #include <mach/mmc.h>
 #include <mach/udc.h>
 #include <mach/tosa_bt.h>
+#include <mach/pxa2xx_spi.h>
 
 #include <asm/mach/arch.h>
 #include <mach/tosa.h>
@@ -612,7 +614,7 @@ static int tosa_tc6393xb_enable(struct platform_device *dev)
        rc = gpio_request(TOSA_GPIO_TC6393XB_SUSPEND, "tc6393xb #suspend");
        if (rc)
                goto err_req_suspend;
-       rc = gpio_request(TOSA_GPIO_TC6393XB_L3V_ON, "l3v");
+       rc = gpio_request(TOSA_GPIO_TC6393XB_L3V_ON, "tc6393xb l3v");
        if (rc)
                goto err_req_l3v;
        rc = gpio_direction_output(TOSA_GPIO_TC6393XB_L3V_ON, 0);
@@ -772,6 +774,20 @@ static struct platform_device tosa_bt_device = {
        .dev.platform_data = &tosa_bt_data,
 };
 
+static struct pxa2xx_spi_master pxa_ssp_master_info = {
+       .num_chipselect = 1,
+};
+
+static struct spi_board_info spi_board_info[] __initdata = {
+       {
+               .modalias       = "tosa-lcd",
+               // .platform_data
+               .max_speed_hz   = 28750,
+               .bus_num        = 2,
+               .chip_select    = 0,
+               .mode           = SPI_MODE_0,
+       },
+};
 
 static struct platform_device *devices[] __initdata = {
        &tosascoop_device,
@@ -826,6 +842,9 @@ static void __init tosa_init(void)
        pxa_set_i2c_info(NULL);
        platform_scoop_config = &tosa_pcmcia_config;
 
+       pxa2xx_set_spi_info(2, &pxa_ssp_master_info);
+       spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
        clk_add_alias("CLK_CK3P6MI", &tc6393xb_device.dev, "GPIO11_CLK", NULL);
 
        platform_add_devices(devices, ARRAY_SIZE(devices));
index a13dbf3c2c05bf6c796e219a5e9134ddbb8d34f8..a72e3add743c7d93b644649fe0cd6070ea850901 100644 (file)
@@ -399,7 +399,7 @@ static void trizeps4_irda_transceiver_mode(struct device *dev, int mode)
        /* Switch mode */
        if (mode & IR_SIRMODE)
                trizeps_conxs_ircr &= ~ConXS_IRCR_MODE; /* Slow mode */
-       else if (mode & IR_FIRMODE) {
+       else if (mode & IR_FIRMODE)
                trizeps_conxs_ircr |= ConXS_IRCR_MODE;  /* Fast mode */
 
        /* Switch power */
index 2f60bf6b8d4395e49bc49fcc3dfc072386c17656..f854e7385e3c75c44ea10f4917c42a92da338f2c 100644 (file)
@@ -1033,8 +1033,7 @@ void __init s3c2443_init_clocks(int xtal)
 
        fclk = pll / s3c2443_fclk_div(clkdiv0);
        hclk = s3c2443_prediv_getrate(&clk_prediv);
-       hclk = hclk / s3c2443_get_hdiv(clkdiv0);
-       hclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_HCLK) ? 2 : 1);
+       hclk /= s3c2443_get_hdiv(clkdiv0);
        pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
 
        s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
diff --git a/arch/arm/mach-sa1100/include/mach/ide.h b/arch/arm/mach-sa1100/include/mach/ide.h
deleted file mode 100644 (file)
index 4c99c8f..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * arch/arm/mach-sa1100/include/mach/ide.h
- *
- * Copyright (c) 1998 Hugo Fiennes & Nicolas Pitre
- *
- * 18-aug-2000: Cleanup by Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
- *              Get rid of the special ide_init_hwif_ports() functions
- *              and make a generalised function that can be used by all
- *              architectures.
- */
-
-#include <asm/irq.h>
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-
-#error "This code is broken and needs update to match with current ide support"
-
-
-/*
- * Set up a hw structure for a specified data port, control port and IRQ.
- * This should follow whatever the default interface uses.
- */
-static inline void ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
-                                      unsigned long ctrl_port, int *irq)
-{
-       unsigned long reg = data_port;
-       int i;
-       int regincr = 1;
-
-       /* The Empeg board has the first two address lines unused */
-       if (machine_is_empeg())
-               regincr = 1 << 2;
-
-       /* The LART doesn't use A0 for IDE */
-       if (machine_is_lart())
-               regincr = 1 << 1;
-
-       memset(hw, 0, sizeof(*hw));
-
-       for (i = 0; i <= 7; i++) {
-               hw->io_ports_array[i] = reg;
-               reg += regincr;
-       }
-
-       hw->io_ports.ctl_addr = ctrl_port;
-
-       if (irq)
-               *irq = 0;
-}
-
-/*
- * This registers the standard ports for this architecture with the IDE
- * driver.
- */
-static __inline__ void
-ide_init_default_hwifs(void)
-{
-    if (machine_is_lart()) {
-#ifdef CONFIG_SA1100_LART
-        hw_regs_t hw;
-
-        /* Enable GPIO as interrupt line */
-        GPDR &= ~LART_GPIO_IDE;
-       set_irq_type(LART_IRQ_IDE, IRQ_TYPE_EDGE_RISING);
-
-        /* set PCMCIA interface timing */
-        MECR = 0x00060006;
-
-        /* init the interface */
-       ide_init_hwif_ports(&hw, PCMCIA_IO_0_BASE + 0x0000, PCMCIA_IO_0_BASE + 0x1000, NULL);
-        hw.irq = LART_IRQ_IDE;
-        ide_register_hw(&hw);
-#endif
-    }
-}
index d1193884d76d9ce4540b5d2a9d11e94e0233536b..ab5f7a21350b3af41bd6a227d1920f09c8091ed1 100644 (file)
@@ -400,9 +400,9 @@ config CPU_FEROCEON_OLD_ID
 # ARMv6
 config CPU_V6
        bool "Support ARM V6 processor"
-       depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 || ARCH_MX3 || ARCH_MSM7X00A || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176
+       depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 || ARCH_MX3 || ARCH_MSM || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176
        default y if ARCH_MX3
-       default y if ARCH_MSM7X00A
+       default y if ARCH_MSM
        select CPU_32v6
        select CPU_ABRT_EV6
        select CPU_PABRT_NOIFAR
index 33926c9fcda696d0670014a406e5ad292154887e..5786adf100407c7c6eca30013656be2a7e49e68e 100644 (file)
@@ -29,7 +29,7 @@ ENTRY(v4_flush_user_cache_all)
  *     Clean and invalidate the entire cache.
  */
 ENTRY(v4_flush_kern_cache_all)
-#ifdef CPU_CP15
+#ifdef CONFIG_CPU_CP15
        mov     r0, #0
        mcr     p15, 0, r0, c7, c7, 0           @ flush ID cache
        mov     pc, lr
@@ -48,7 +48,7 @@ ENTRY(v4_flush_kern_cache_all)
  *     - flags - vma_area_struct flags describing address space
  */
 ENTRY(v4_flush_user_cache_range)
-#ifdef CPU_CP15
+#ifdef CONFIG_CPU_CP15
        mov     ip, #0
        mcreq   p15, 0, ip, c7, c7, 0           @ flush ID cache
        mov     pc, lr
@@ -116,7 +116,7 @@ ENTRY(v4_dma_inv_range)
  *     - end    - virtual end address
  */
 ENTRY(v4_dma_flush_range)
-#ifdef CPU_CP15
+#ifdef CONFIG_CPU_CP15
        mov     r0, #0
        mcr     p15, 0, r0, c7, c7, 0           @ flush ID cache
 #endif
index 34e424041927fe57f464fa4612cd5e99b0c1ebe9..07f82db70945f7d3582dcd6c9f589ebcce648af9 100644 (file)
@@ -180,8 +180,8 @@ __v7_setup:
        mov     r10, #0x1f                      @ domains 0, 1 = manager
        mcr     p15, 0, r10, c3, c0, 0          @ load domain access register
 #endif
-       ldr     r5, =0x40e040e0
-       ldr     r6, =0xff0aa1a8
+       ldr     r5, =0xff0aa1a8
+       ldr     r6, =0x40e040e0
        mcr     p15, 0, r5, c10, c2, 0          @ write PRRR
        mcr     p15, 0, r6, c10, c2, 1          @ write NMRR
        adr     r5, v7_crval
index b8e854f1b1d50dbc4f7524b2b9843ed614f51a4b..3fad68a1e6bc2613308e71121a3ca88c48e52562 100644 (file)
@@ -315,7 +315,7 @@ static int clk_pwm_tin_set_parent(struct clk *clk, struct clk *parent)
        if (parent == s3c24xx_pwmclk_tclk(id))
                bits = S3C2410_TCFG1_MUX_TCLK << shift;
        else if (parent == s3c24xx_pwmclk_tdiv(id))
-               bits = clk_pwm_tdiv_bits(to_tdiv(clk)) << shift;
+               bits = clk_pwm_tdiv_bits(to_tdiv(parent)) << shift;
        else
                return -EINVAL;
 
index feb770f2e84e1a470bcd3cc1b4e57686e10f0171..ec56b88866c43d597b885290c7e3507c3cff9982 100644 (file)
@@ -56,7 +56,7 @@ static struct clk *clk_scaler[2];
                }                                       \
        }
 
-#define DEFINE_TIMER(_tmr_no, _irq)                    \
+#define DEFINE_S3C_TIMER(_tmr_no, _irq)                        \
        .name           = "s3c24xx-pwm",                \
        .id             = _tmr_no,                      \
        .num_resources  = TIMER_RESOURCE_SIZE,          \
@@ -67,11 +67,11 @@ static struct clk *clk_scaler[2];
  */
 
 struct platform_device s3c_device_timer[] = {
-       [0] = { DEFINE_TIMER(0, IRQ_TIMER0) },
-       [1] = { DEFINE_TIMER(1, IRQ_TIMER1) },
-       [2] = { DEFINE_TIMER(2, IRQ_TIMER2) },
-       [3] = { DEFINE_TIMER(3, IRQ_TIMER3) },
-       [4] = { DEFINE_TIMER(4, IRQ_TIMER4) },
+       [0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) },
+       [1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) },
+       [2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) },
+       [3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
+       [4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
 };
 
 static inline int pwm_is_tdiv(struct pwm_device *pwm)
index 33a5b2969eb4addf24e36a59159d72488530dc0b..26eca87f673592d78617d16279a63aceebe0589f 100644 (file)
@@ -121,11 +121,19 @@ config BOARD_ATSTK1000
 config BOARD_ATNGW100
        bool "ATNGW100 Network Gateway"
        select CPU_AT32AP7000
+
+config BOARD_FAVR_32
+       bool "Favr-32 LCD-board"
+       select CPU_AT32AP7000
+
+config BOARD_MIMC200
+       bool "MIMC200 CPU board"
+       select CPU_AT32AP7000
 endchoice
 
-if BOARD_ATSTK1000
 source "arch/avr32/boards/atstk1000/Kconfig"
-endif
+source "arch/avr32/boards/atngw100/Kconfig"
+source "arch/avr32/boards/favr-32/Kconfig"
 
 choice
        prompt "Boot loader type"
index c9e1f0b47fd33c718e59d7f15fddb65fe6ff8f1f..b088e103e7530515aebaca2c7fa7c8ebc0fe1c30 100644 (file)
@@ -33,6 +33,8 @@ head-y                                        += arch/avr32/kernel/head.o
 core-y                                 += $(machdirs)
 core-$(CONFIG_BOARD_ATSTK1000)         += arch/avr32/boards/atstk1000/
 core-$(CONFIG_BOARD_ATNGW100)          += arch/avr32/boards/atngw100/
+core-$(CONFIG_BOARD_FAVR_32)           += arch/avr32/boards/favr-32/
+core-$(CONFIG_BOARD_MIMC200)           += arch/avr32/boards/mimc200/
 core-$(CONFIG_LOADER_U_BOOT)           += arch/avr32/boot/u-boot/
 core-y                                 += arch/avr32/kernel/
 core-y                                 += arch/avr32/mm/
diff --git a/arch/avr32/boards/atngw100/Kconfig b/arch/avr32/boards/atngw100/Kconfig
new file mode 100644 (file)
index 0000000..b3f9947
--- /dev/null
@@ -0,0 +1,35 @@
+# NGW100 customization
+
+if BOARD_ATNGW100
+
+config BOARD_ATNGW100_EVKLCD10X
+       bool "Add support for EVKLCD10X addon board"
+       help
+         This enables support for the EVKLCD100 (QVGA) or EVKLCD101 (VGA)
+         addon board for the NGW100. By enabling this the LCD controller and
+         AC97 controller is added as platform devices.
+
+         This choice disables the detect pin and the write-protect pin for the
+         MCI platform device, since it conflicts with the LCD platform device.
+         The MCI pins can be reenabled by editing the "add device function" but
+         this may break the setup for other displays that use these pins.
+
+         Choose 'Y' here if you have a EVKLCD100/101 connected to the NGW100.
+
+choice
+       prompt "LCD panel resolution on EVKLCD10X"
+       depends on BOARD_ATNGW100_EVKLCD10X
+       default BOARD_ATNGW100_EVKLCD10X_VGA
+
+config BOARD_ATNGW100_EVKLCD10X_QVGA
+       bool "QVGA (320x240)"
+
+config BOARD_ATNGW100_EVKLCD10X_VGA
+       bool "VGA (640x480)"
+
+config BOARD_ATNGW100_EVKLCD10X_POW_QVGA
+       bool "Powertip QVGA (320x240)"
+
+endchoice
+
+endif  # BOARD_ATNGW100
index c740aa116755592c9ef8e1e93756a5125003f55a..6376f5322e4d2c8537494821cfe55ac50eaed11c 100644 (file)
@@ -1 +1,2 @@
-obj-y                          += setup.o flash.o
+obj-y                                  += setup.o flash.o
+obj-$(CONFIG_BOARD_ATNGW100_EVKLCD10X) += evklcd10x.o
diff --git a/arch/avr32/boards/atngw100/evklcd10x.c b/arch/avr32/boards/atngw100/evklcd10x.c
new file mode 100644 (file)
index 0000000..8140b22
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Board-specific setup code for the ATEVKLCD10X addon board to the ATNGW100
+ * Network Gateway
+ *
+ * Copyright (C) 2008 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/fb.h>
+#include <linux/platform_device.h>
+
+#include <video/atmel_lcdc.h>
+
+#include <asm/setup.h>
+
+#include <mach/at32ap700x.h>
+#include <mach/board.h>
+
+static struct ac97c_platform_data __initdata ac97c0_data = {
+       .dma_rx_periph_id       = 3,
+       .dma_tx_periph_id       = 4,
+       .dma_controller_id      = 0,
+       .reset_pin              = GPIO_PIN_PB(19),
+};
+
+#ifdef CONFIG_BOARD_ATNGW100_EVKLCD10X_VGA
+static struct fb_videomode __initdata tcg057vglad_modes[] = {
+       {
+               .name           = "640x480 @ 60",
+               .refresh        = 60,
+               .xres           = 640,          .yres           = 480,
+               .pixclock       = KHZ2PICOS(25180),
+
+               .left_margin    = 64,           .right_margin   = 31,
+               .upper_margin   = 34,           .lower_margin   = 2,
+               .hsync_len      = 96,           .vsync_len      = 4,
+
+               .sync           = 0,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+};
+
+static struct fb_monspecs __initdata atevklcd10x_default_monspecs = {
+       .manufacturer           = "KYO",
+       .monitor                = "TCG057VGLAD",
+       .modedb                 = tcg057vglad_modes,
+       .modedb_len             = ARRAY_SIZE(tcg057vglad_modes),
+       .hfmin                  = 19948,
+       .hfmax                  = 31478,
+       .vfmin                  = 50,
+       .vfmax                  = 67,
+       .dclkmax                = 28330000,
+};
+
+static struct atmel_lcdfb_info __initdata atevklcd10x_lcdc_data = {
+       .default_bpp            = 16,
+       .default_dmacon         = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
+       .default_lcdcon2        = (ATMEL_LCDC_DISTYPE_TFT
+                                  | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
+                                  | ATMEL_LCDC_MEMOR_BIG),
+       .default_monspecs       = &atevklcd10x_default_monspecs,
+       .guard_time             = 2,
+};
+#elif CONFIG_BOARD_ATNGW100_EVKLCD10X_QVGA
+static struct fb_videomode __initdata tcg057qvlad_modes[] = {
+       {
+               .name           = "320x240 @ 60",
+               .refresh        = 60,
+               .xres           = 320,          .yres           = 240,
+               .pixclock       = KHZ2PICOS(6300),
+
+               .left_margin    = 52,           .right_margin   = 28,
+               .upper_margin   = 7,            .lower_margin   = 2,
+               .hsync_len      = 96,           .vsync_len      = 4,
+
+               .sync           = 0,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+};
+
+static struct fb_monspecs __initdata atevklcd10x_default_monspecs = {
+       .manufacturer           = "KYO",
+       .monitor                = "TCG057QVLAD",
+       .modedb                 = tcg057qvlad_modes,
+       .modedb_len             = ARRAY_SIZE(tcg057qvlad_modes),
+       .hfmin                  = 19948,
+       .hfmax                  = 31478,
+       .vfmin                  = 50,
+       .vfmax                  = 67,
+       .dclkmax                = 7000000,
+};
+
+static struct atmel_lcdfb_info __initdata atevklcd10x_lcdc_data = {
+       .default_bpp            = 16,
+       .default_dmacon         = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
+       .default_lcdcon2        = (ATMEL_LCDC_DISTYPE_TFT
+                                  | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
+                                  | ATMEL_LCDC_MEMOR_BIG),
+       .default_monspecs       = &atevklcd10x_default_monspecs,
+       .guard_time             = 2,
+};
+#elif CONFIG_BOARD_ATNGW100_EVKLCD10X_POW_QVGA
+static struct fb_videomode __initdata ph320240t_modes[] = {
+       {
+               .name           = "320x240 @ 60",
+               .refresh        = 60,
+               .xres           = 320,          .yres           = 240,
+               .pixclock       = KHZ2PICOS(6300),
+
+               .left_margin    = 38,           .right_margin   = 20,
+               .upper_margin   = 15,           .lower_margin   = 5,
+               .hsync_len      = 30,           .vsync_len      = 3,
+
+               .sync           = 0,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+};
+
+static struct fb_monspecs __initdata atevklcd10x_default_monspecs = {
+       .manufacturer           = "POW",
+       .monitor                = "PH320240T",
+       .modedb                 = ph320240t_modes,
+       .modedb_len             = ARRAY_SIZE(ph320240t_modes),
+       .hfmin                  = 14400,
+       .hfmax                  = 21600,
+       .vfmin                  = 50,
+       .vfmax                  = 90,
+       .dclkmax                = 6400000,
+};
+
+static struct atmel_lcdfb_info __initdata atevklcd10x_lcdc_data = {
+       .default_bpp            = 16,
+       .default_dmacon         = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
+       .default_lcdcon2        = (ATMEL_LCDC_DISTYPE_TFT
+                                  | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
+                                  | ATMEL_LCDC_MEMOR_BIG),
+       .default_monspecs       = &atevklcd10x_default_monspecs,
+       .guard_time             = 2,
+};
+#endif
+
+static int __init atevklcd10x_init(void)
+{
+       at32_add_device_ac97c(0, &ac97c0_data);
+
+       at32_add_device_lcdc(0, &atevklcd10x_lcdc_data,
+                       fbmem_start, fbmem_size, 1);
+       return 0;
+}
+postcore_initcall(atevklcd10x_init);
index 6c54580a66df77bdcba2d1e889c95ba9b6524291..32fb9ba0fbdfe40e6943b2c5bdebbfd706bd59ad 100644 (file)
@@ -56,8 +56,13 @@ static struct spi_board_info spi0_board_info[] __initdata = {
 static struct mci_platform_data __initdata mci0_data = {
        .slot[0] = {
                .bus_width      = 4,
+#ifndef CONFIG_BOARD_ATNGW100_EVKLCD10X
                .detect_pin     = GPIO_PIN_PC(25),
                .wp_pin         = GPIO_PIN_PE(0),
+#else
+               .detect_pin     = GPIO_PIN_NONE,
+               .wp_pin         = GPIO_PIN_NONE,
+#endif
        },
 };
 
@@ -172,8 +177,6 @@ static int __init atngw100_init(void)
         * reserve any pins for it.
         */
 
-       at32_add_system_devices();
-
        at32_add_device_usart(0);
 
        set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
index 29e5b51a7fd2b8801a23655e17edcff41ade6ab2..5c5cdf3b464fb8d99394e408ed49b700babc1ec4 100644 (file)
@@ -305,8 +305,6 @@ static int __init atstk1002_init(void)
        at32_reserve_pin(GPIO_PIN_PE(15));      /* DATA[31]     */
        at32_reserve_pin(GPIO_PIN_PE(26));      /* SDCS         */
 
-       at32_add_system_devices();
-
 #ifdef CONFIG_BOARD_ATSTK1006
        smc_set_timing(&nand_config, &nand_timing);
        smc_set_configuration(3, &nand_config);
index be089d7f37ebf1b0fe955475417fce4fb66e86f9..134b566630b0f62a75aad5832278c4dcf7aeac91 100644 (file)
@@ -149,8 +149,6 @@ static int __init atstk1003_init(void)
        at32_reserve_pin(GPIO_PIN_PE(15));      /* DATA[31]     */
        at32_reserve_pin(GPIO_PIN_PE(26));      /* SDCS         */
 
-       at32_add_system_devices();
-
 #ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
        at32_add_device_usart(1);
 #else
index 248ef237c167b95283c30dec20ca0080c97e6feb..cb32eb844aa743ca69d7ff181353ad669330832d 100644 (file)
@@ -132,8 +132,6 @@ void __init setup_board(void)
 
 static int __init atstk1004_init(void)
 {
-       at32_add_system_devices();
-
 #ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
        at32_add_device_usart(1);
 #else
diff --git a/arch/avr32/boards/favr-32/Kconfig b/arch/avr32/boards/favr-32/Kconfig
new file mode 100644 (file)
index 0000000..2c83d1d
--- /dev/null
@@ -0,0 +1,22 @@
+# Favr-32 customization
+
+if BOARD_FAVR_32
+
+config BOARD_FAVR32_ABDAC_RATE
+       int "DAC target rate"
+       default 44100
+       range 32000 50000
+       help
+         Specify the target rate the internal DAC should try to match. This
+         will use PLL1 to generate a frequency as close as possible to this
+         rate.
+
+         Must be within the range 32000 to 50000, which should be suitable to
+         generate most other frequencies in power of 2 steps.
+
+         Ex:
+               48000 will also suit 24000 and 12000
+               44100 will also suit 22050 and 11025
+               32000 will also suit 16000 and 8000
+
+endif # BOARD_FAVR_32
diff --git a/arch/avr32/boards/favr-32/Makefile b/arch/avr32/boards/favr-32/Makefile
new file mode 100644 (file)
index 0000000..234f215
--- /dev/null
@@ -0,0 +1 @@
+obj-y  += setup.o flash.o
diff --git a/arch/avr32/boards/favr-32/flash.c b/arch/avr32/boards/favr-32/flash.c
new file mode 100644 (file)
index 0000000..5f139b7
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Favr-32 board-specific flash initialization
+ *
+ * Copyright (C) 2008 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/arch/smc.h>
+
+static struct smc_timing flash_timing __initdata = {
+       .ncs_read_setup         = 0,
+       .nrd_setup              = 40,
+       .ncs_write_setup        = 0,
+       .nwe_setup              = 10,
+
+       .ncs_read_pulse         = 80,
+       .nrd_pulse              = 40,
+       .ncs_write_pulse        = 65,
+       .nwe_pulse              = 55,
+
+       .read_cycle             = 120,
+       .write_cycle            = 120,
+};
+
+static struct smc_config flash_config __initdata = {
+       .bus_width              = 2,
+       .nrd_controlled         = 1,
+       .nwe_controlled         = 1,
+       .byte_write             = 1,
+};
+
+static struct mtd_partition flash_parts[] = {
+       {
+               .name           = "u-boot",
+               .offset         = 0x00000000,
+               .size           = 0x00020000,           /* 128 KiB */
+               .mask_flags     = MTD_WRITEABLE,
+       },
+       {
+               .name           = "root",
+               .offset         = 0x00020000,
+               .size           = 0x007d0000,
+       },
+       {
+               .name           = "env",
+               .offset         = 0x007f0000,
+               .size           = 0x00010000,
+               .mask_flags     = MTD_WRITEABLE,
+       },
+};
+
+static struct physmap_flash_data flash_data = {
+       .width          = 2,
+       .nr_parts       = ARRAY_SIZE(flash_parts),
+       .parts          = flash_parts,
+};
+
+static struct resource flash_resource = {
+       .start          = 0x00000000,
+       .end            = 0x007fffff,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device flash_device = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .resource       = &flash_resource,
+       .num_resources  = 1,
+       .dev            = {
+               .platform_data = &flash_data,
+       },
+};
+
+/* This needs to be called after the SMC has been initialized */
+static int __init favr32_flash_init(void)
+{
+       int ret;
+
+       smc_set_timing(&flash_config, &flash_timing);
+       ret = smc_set_configuration(0, &flash_config);
+       if (ret < 0) {
+               printk(KERN_ERR "Favr-32: failed to set NOR flash timing\n");
+               return ret;
+       }
+
+       platform_device_register(&flash_device);
+
+       return 0;
+}
+device_initcall(favr32_flash_init);
diff --git a/arch/avr32/boards/favr-32/setup.c b/arch/avr32/boards/favr-32/setup.c
new file mode 100644 (file)
index 0000000..7538f3d
--- /dev/null
@@ -0,0 +1,352 @@
+/*
+ * Favr-32 board-specific setup code.
+ *
+ * Copyright (C) 2008 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/clk.h>
+#include <linux/etherdevice.h>
+#include <linux/bootmem.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/linkage.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/atmel-pwm-bl.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+
+#include <video/atmel_lcdc.h>
+
+#include <asm/setup.h>
+
+#include <asm/arch/at32ap700x.h>
+#include <asm/arch/init.h>
+#include <asm/arch/board.h>
+#include <asm/arch/portmux.h>
+
+/* Oscillator frequencies. These are board-specific */
+unsigned long at32_board_osc_rates[3] = {
+       [0] = 32768,    /* 32.768 kHz on RTC osc */
+       [1] = 20000000, /* 20 MHz on osc0 */
+       [2] = 12000000, /* 12 MHz on osc1 */
+};
+
+/* Initialized by bootloader-specific startup code. */
+struct tag *bootloader_tags __initdata;
+
+struct eth_addr {
+       u8 addr[6];
+};
+static struct eth_addr __initdata hw_addr[1];
+static struct eth_platform_data __initdata eth_data[1] = {
+       {
+               .phy_mask       = ~(1U << 1),
+       },
+};
+
+static int ads7843_get_pendown_state(void)
+{
+       return !gpio_get_value(GPIO_PIN_PB(3));
+}
+
+static struct ads7846_platform_data ads7843_data = {
+       .model                  = 7843,
+       .get_pendown_state      = ads7843_get_pendown_state,
+       .pressure_max           = 255,
+       /*
+        * Values below are for debounce filtering, these can be experimented
+        * with further.
+        */
+       .debounce_max           = 20,
+       .debounce_rep           = 4,
+       .debounce_tol           = 5,
+};
+
+static struct spi_board_info __initdata spi1_board_info[] = {
+       {
+               /* ADS7843 touch controller */
+               .modalias       = "ads7846",
+               .max_speed_hz   = 2000000,
+               .chip_select    = 0,
+               .bus_num        = 1,
+               .platform_data  = &ads7843_data,
+       },
+};
+
+static struct fb_videomode __initdata lb104v03_modes[] = {
+       {
+               .name           = "640x480 @ 50",
+               .refresh        = 50,
+               .xres           = 640,          .yres           = 480,
+               .pixclock       = KHZ2PICOS(25100),
+
+               .left_margin    = 90,           .right_margin   = 70,
+               .upper_margin   = 30,           .lower_margin   = 15,
+               .hsync_len      = 12,           .vsync_len      = 2,
+
+               .sync           = 0,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+};
+
+static struct fb_monspecs __initdata favr32_default_monspecs = {
+       .manufacturer           = "LG",
+       .monitor                = "LB104V03",
+       .modedb                 = lb104v03_modes,
+       .modedb_len             = ARRAY_SIZE(lb104v03_modes),
+       .hfmin                  = 27273,
+       .hfmax                  = 31111,
+       .vfmin                  = 45,
+       .vfmax                  = 60,
+       .dclkmax                = 28000000,
+};
+
+struct atmel_lcdfb_info __initdata favr32_lcdc_data = {
+       .default_bpp            = 16,
+       .default_dmacon         = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
+       .default_lcdcon2        = (ATMEL_LCDC_DISTYPE_TFT
+                                  | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
+                                  | ATMEL_LCDC_MEMOR_BIG),
+       .default_monspecs       = &favr32_default_monspecs,
+       .guard_time             = 2,
+};
+
+static struct gpio_led favr32_leds[] = {
+       {
+               .name            = "green",
+               .gpio            = GPIO_PIN_PE(19),
+               .default_trigger = "heartbeat",
+               .active_low      = 1,
+       },
+       {
+               .name            = "red",
+               .gpio            = GPIO_PIN_PE(20),
+               .active_low      = 1,
+       },
+};
+
+static struct gpio_led_platform_data favr32_led_data = {
+       .num_leds       = ARRAY_SIZE(favr32_leds),
+       .leds           = favr32_leds,
+};
+
+static struct platform_device favr32_led_dev = {
+       .name           = "leds-gpio",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &favr32_led_data,
+       },
+};
+
+/*
+ * The next two functions should go away as the boot loader is
+ * supposed to initialize the macb address registers with a valid
+ * ethernet address. But we need to keep it around for a while until
+ * we can be reasonably sure the boot loader does this.
+ *
+ * The phy_id is ignored as the driver will probe for it.
+ */
+static int __init parse_tag_ethernet(struct tag *tag)
+{
+       int i;
+
+       i = tag->u.ethernet.mac_index;
+       if (i < ARRAY_SIZE(hw_addr))
+               memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address,
+                      sizeof(hw_addr[i].addr));
+
+       return 0;
+}
+__tagtable(ATAG_ETHERNET, parse_tag_ethernet);
+
+static void __init set_hw_addr(struct platform_device *pdev)
+{
+       struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       const u8 *addr;
+       void __iomem *regs;
+       struct clk *pclk;
+
+       if (!res)
+               return;
+       if (pdev->id >= ARRAY_SIZE(hw_addr))
+               return;
+
+       addr = hw_addr[pdev->id].addr;
+       if (!is_valid_ether_addr(addr))
+               return;
+
+       /*
+        * Since this is board-specific code, we'll cheat and use the
+        * physical address directly as we happen to know that it's
+        * the same as the virtual address.
+        */
+       regs = (void __iomem __force *)res->start;
+       pclk = clk_get(&pdev->dev, "pclk");
+       if (!pclk)
+               return;
+
+       clk_enable(pclk);
+       __raw_writel((addr[3] << 24) | (addr[2] << 16)
+                    | (addr[1] << 8) | addr[0], regs + 0x98);
+       __raw_writel((addr[5] << 8) | addr[4], regs + 0x9c);
+       clk_disable(pclk);
+       clk_put(pclk);
+}
+
+void __init favr32_setup_leds(void)
+{
+       unsigned i;
+
+       for (i = 0; i < ARRAY_SIZE(favr32_leds); i++)
+               at32_select_gpio(favr32_leds[i].gpio, AT32_GPIOF_OUTPUT);
+
+       platform_device_register(&favr32_led_dev);
+}
+
+static struct atmel_pwm_bl_platform_data atmel_pwm_bl_pdata = {
+       .pwm_channel            = 2,
+       .pwm_frequency          = 200000,
+       .pwm_compare_max        = 345,
+       .pwm_duty_max           = 345,
+       .pwm_duty_min           = 90,
+       .pwm_active_low         = 1,
+       .gpio_on                = GPIO_PIN_PA(28),
+       .on_active_low          = 0,
+};
+
+static struct platform_device atmel_pwm_bl_dev = {
+       .name           = "atmel-pwm-bl",
+       .id             = 0,
+       .dev            = {
+               .platform_data = &atmel_pwm_bl_pdata,
+       },
+};
+
+static void __init favr32_setup_atmel_pwm_bl(void)
+{
+       platform_device_register(&atmel_pwm_bl_dev);
+       at32_select_gpio(atmel_pwm_bl_pdata.gpio_on, 0);
+}
+
+void __init setup_board(void)
+{
+       at32_map_usart(3, 0);   /* USART 3 => /dev/ttyS0 */
+       at32_setup_serial_console(0);
+}
+
+static int __init set_abdac_rate(struct platform_device *pdev)
+{
+       int retval;
+       struct clk *osc1;
+       struct clk *pll1;
+       struct clk *abdac;
+
+       if (pdev == NULL)
+               return -ENXIO;
+
+       osc1 = clk_get(NULL, "osc1");
+       if (IS_ERR(osc1)) {
+               retval = PTR_ERR(osc1);
+               goto out;
+       }
+
+       pll1 = clk_get(NULL, "pll1");
+       if (IS_ERR(pll1)) {
+               retval = PTR_ERR(pll1);
+               goto out_osc1;
+       }
+
+       abdac = clk_get(&pdev->dev, "sample_clk");
+       if (IS_ERR(abdac)) {
+               retval = PTR_ERR(abdac);
+               goto out_pll1;
+       }
+
+       retval = clk_set_parent(pll1, osc1);
+       if (retval != 0)
+               goto out_abdac;
+
+       /*
+        * Rate is 32000 to 50000 and ABDAC oversamples 256x. Multiply, in
+        * power of 2, to a value above 80 MHz. Power of 2 so it is possible
+        * for the generic clock to divide it down again and 80 MHz is the
+        * lowest frequency for the PLL.
+        */
+       retval = clk_round_rate(pll1,
+                       CONFIG_BOARD_FAVR32_ABDAC_RATE * 256 * 16);
+       if (retval < 0)
+               goto out_abdac;
+
+       retval = clk_set_rate(pll1, retval);
+       if (retval != 0)
+               goto out_abdac;
+
+       retval = clk_set_parent(abdac, pll1);
+       if (retval != 0)
+               goto out_abdac;
+
+out_abdac:
+       clk_put(abdac);
+out_pll1:
+       clk_put(pll1);
+out_osc1:
+       clk_put(osc1);
+out:
+       return retval;
+}
+
+static int __init favr32_init(void)
+{
+       /*
+        * Favr-32 uses 32-bit SDRAM interface. Reserve the SDRAM-specific
+        * pins so that nobody messes with them.
+        */
+       at32_reserve_pin(GPIO_PIN_PE(0));       /* DATA[16]     */
+       at32_reserve_pin(GPIO_PIN_PE(1));       /* DATA[17]     */
+       at32_reserve_pin(GPIO_PIN_PE(2));       /* DATA[18]     */
+       at32_reserve_pin(GPIO_PIN_PE(3));       /* DATA[19]     */
+       at32_reserve_pin(GPIO_PIN_PE(4));       /* DATA[20]     */
+       at32_reserve_pin(GPIO_PIN_PE(5));       /* DATA[21]     */
+       at32_reserve_pin(GPIO_PIN_PE(6));       /* DATA[22]     */
+       at32_reserve_pin(GPIO_PIN_PE(7));       /* DATA[23]     */
+       at32_reserve_pin(GPIO_PIN_PE(8));       /* DATA[24]     */
+       at32_reserve_pin(GPIO_PIN_PE(9));       /* DATA[25]     */
+       at32_reserve_pin(GPIO_PIN_PE(10));      /* DATA[26]     */
+       at32_reserve_pin(GPIO_PIN_PE(11));      /* DATA[27]     */
+       at32_reserve_pin(GPIO_PIN_PE(12));      /* DATA[28]     */
+       at32_reserve_pin(GPIO_PIN_PE(13));      /* DATA[29]     */
+       at32_reserve_pin(GPIO_PIN_PE(14));      /* DATA[30]     */
+       at32_reserve_pin(GPIO_PIN_PE(15));      /* DATA[31]     */
+       at32_reserve_pin(GPIO_PIN_PE(26));      /* SDCS         */
+
+       at32_select_gpio(GPIO_PIN_PB(3), 0);    /* IRQ from ADS7843 */
+
+       at32_add_system_devices();
+
+       at32_add_device_usart(0);
+
+       set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
+
+       spi1_board_info[0].irq = gpio_to_irq(GPIO_PIN_PB(3));
+
+       set_abdac_rate(at32_add_device_abdac(0));
+
+       at32_add_device_pwm(1 << atmel_pwm_bl_pdata.pwm_channel);
+       at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
+       at32_add_device_mci(0, NULL);
+       at32_add_device_usba(0, NULL);
+       at32_add_device_lcdc(0, &favr32_lcdc_data, fbmem_start, fbmem_size, 0);
+
+       favr32_setup_leds();
+
+       favr32_setup_atmel_pwm_bl();
+
+       return 0;
+}
+postcore_initcall(favr32_init);
diff --git a/arch/avr32/boards/mimc200/Makefile b/arch/avr32/boards/mimc200/Makefile
new file mode 100644 (file)
index 0000000..79c076e
--- /dev/null
@@ -0,0 +1 @@
+obj-y                          += setup.o flash.o fram.o
diff --git a/arch/avr32/boards/mimc200/flash.c b/arch/avr32/boards/mimc200/flash.c
new file mode 100644 (file)
index 0000000..d83d650
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * MIMC200 board-specific flash initialization
+ *
+ * Copyright (C) 2008 Mercury IMC Ltd
+ *
+ * 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/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+
+#include <mach/smc.h>
+
+static struct smc_timing flash_timing __initdata = {
+       .ncs_read_setup         = 0,
+       .nrd_setup              = 15,
+       .ncs_write_setup        = 0,
+       .nwe_setup              = 0,
+
+       .ncs_read_pulse         = 115,
+       .nrd_pulse              = 110,
+       .ncs_write_pulse        = 60,
+       .nwe_pulse              = 60,
+
+       .read_cycle             = 115,
+       .write_cycle            = 100,
+};
+
+static struct smc_config flash_config __initdata = {
+       .bus_width              = 2,
+       .nrd_controlled         = 1,
+       .nwe_controlled         = 1,
+       .byte_write             = 1,
+};
+
+/* system flash definition */
+
+static struct mtd_partition flash_parts_system[] = {
+       {
+               .name           = "u-boot",
+               .offset         = 0x00000000,
+               .size           = 0x00020000,           /* 128 KiB */
+               .mask_flags     = MTD_WRITEABLE,
+       },
+       {
+               .name           = "root",
+               .offset         = 0x00020000,
+               .size           = 0x007c0000,
+       },
+       {
+               .name           = "splash",
+               .offset         = 0x007e0000,
+               .size           = 0x00010000,           /* 64KiB */
+       },
+       {
+               .name           = "env",
+               .offset         = 0x007f0000,
+               .size           = 0x00010000,
+               .mask_flags     = MTD_WRITEABLE,
+       },
+};
+
+static struct physmap_flash_data flash_system = {
+       .width          = 2,
+       .nr_parts       = ARRAY_SIZE(flash_parts_system),
+       .parts          = flash_parts_system,
+};
+
+static struct resource flash_resource_system = {
+       .start          = 0x00000000,
+       .end            = 0x007fffff,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device flash_device_system = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .resource       = &flash_resource_system,
+       .num_resources  = 1,
+       .dev            = {
+               .platform_data = &flash_system,
+       },
+};
+
+/* data flash definition */
+
+static struct mtd_partition flash_parts_data[] = {
+       {
+               .name           = "data",
+               .offset         = 0x00000000,
+               .size           = 0x00800000,
+       },
+};
+
+static struct physmap_flash_data flash_data = {
+       .width          = 2,
+       .nr_parts       = ARRAY_SIZE(flash_parts_data),
+       .parts          = flash_parts_data,
+};
+
+static struct resource flash_resource_data = {
+       .start          = 0x08000000,
+       .end            = 0x087fffff,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device flash_device_data = {
+       .name           = "physmap-flash",
+       .id             = 1,
+       .resource       = &flash_resource_data,
+       .num_resources  = 1,
+       .dev            = {
+               .platform_data = &flash_data,
+       },
+};
+
+/* This needs to be called after the SMC has been initialized */
+static int __init mimc200_flash_init(void)
+{
+       int ret;
+
+       smc_set_timing(&flash_config, &flash_timing);
+       ret = smc_set_configuration(0, &flash_config);
+       if (ret < 0) {
+               printk(KERN_ERR "mimc200: failed to set 'System' NOR flash timing\n");
+               return ret;
+       }
+       ret = smc_set_configuration(1, &flash_config);
+       if (ret < 0) {
+               printk(KERN_ERR "mimc200: failed to set 'Data' NOR flash timing\n");
+               return ret;
+       }
+
+       platform_device_register(&flash_device_system);
+       platform_device_register(&flash_device_data);
+
+       return 0;
+}
+device_initcall(mimc200_flash_init);
diff --git a/arch/avr32/boards/mimc200/fram.c b/arch/avr32/boards/mimc200/fram.c
new file mode 100644 (file)
index 0000000..54fbd95
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * FRAM driver for MIMC200 board
+ *
+ * Copyright 2008 Mark Jackson <mpfj@mimc.co.uk>
+ *
+ * This module adds *very* simply support for the system's FRAM device.
+ * At the moment, this is hard-coded to the MIMC200 platform, and only
+ * supports mmap().
+ */
+
+#define FRAM_VERSION   "1.0"
+
+#include <linux/miscdevice.h>
+#include <linux/proc_fs.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+
+#define FRAM_BASE      0xac000000
+#define FRAM_SIZE      0x20000
+
+/*
+ * The are the file operation function for user access to /dev/fram
+ */
+
+static int fram_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+       int ret;
+
+       ret = remap_pfn_range(vma,
+               vma->vm_start,
+               virt_to_phys((void *)((unsigned long)FRAM_BASE)) >> PAGE_SHIFT,
+               vma->vm_end-vma->vm_start,
+               PAGE_SHARED);
+
+       if (ret != 0)
+               return -EAGAIN;
+
+       return 0;
+}
+
+static const struct file_operations fram_fops = {
+       .owner                  = THIS_MODULE,
+       .mmap                   = fram_mmap,
+};
+
+#define FRAM_MINOR     0
+
+static struct miscdevice fram_dev = {
+       FRAM_MINOR,
+       "fram",
+       &fram_fops
+};
+
+static int __init
+fram_init(void)
+{
+       int ret;
+
+       ret = misc_register(&fram_dev);
+       if (ret) {
+               printk(KERN_ERR "fram: can't misc_register on minor=%d\n",
+                   FRAM_MINOR);
+               return ret;
+       }
+       printk(KERN_INFO "FRAM memory driver v" FRAM_VERSION "\n");
+       return 0;
+}
+
+static void __exit
+fram_cleanup_module(void)
+{
+       misc_deregister(&fram_dev);
+}
+
+module_init(fram_init);
+module_exit(fram_cleanup_module);
+
+MODULE_LICENSE("GPL");
+
+MODULE_ALIAS_MISCDEV(FRAM_MINOR);
diff --git a/arch/avr32/boards/mimc200/setup.c b/arch/avr32/boards/mimc200/setup.c
new file mode 100644 (file)
index 0000000..397cbb8
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * Board-specific setup code for the MIMC200
+ *
+ * Copyright (C) 2008 Mercury IMC Ltd
+ *
+ * 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.
+ */
+
+extern struct atmel_lcdfb_info mimc200_lcdc_data;
+
+#include <linux/clk.h>
+#include <linux/etherdevice.h>
+#include <linux/i2c-gpio.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/leds.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/eeprom.h>
+
+#include <video/atmel_lcdc.h>
+#include <linux/fb.h>
+
+#include <asm/atmel-mci.h>
+#include <linux/io.h>
+#include <asm/setup.h>
+
+#include <mach/at32ap700x.h>
+#include <mach/board.h>
+#include <mach/init.h>
+#include <mach/portmux.h>
+
+/* Oscillator frequencies. These are board-specific */
+unsigned long at32_board_osc_rates[3] = {
+       [0] = 32768,    /* 32.768 kHz on RTC osc */
+       [1] = 10000000, /* 10 MHz on osc0 */
+       [2] = 12000000, /* 12 MHz on osc1 */
+};
+
+/* Initialized by bootloader-specific startup code. */
+struct tag *bootloader_tags __initdata;
+
+static struct fb_videomode __initdata tx14d14_modes[] = {
+       {
+               .name           = "640x480 @ 60",
+               .refresh        = 60,
+               .xres           = 640,          .yres           = 480,
+               .pixclock       = KHZ2PICOS(11666),
+
+               .left_margin    = 80,           .right_margin   = 1,
+               .upper_margin   = 13,           .lower_margin   = 2,
+               .hsync_len      = 64,           .vsync_len      = 1,
+
+               .sync           = 0,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+};
+
+static struct fb_monspecs __initdata mimc200_default_monspecs = {
+       .manufacturer           = "HIT",
+       .monitor                = "TX14D14VM1BAB",
+       .modedb                 = tx14d14_modes,
+       .modedb_len             = ARRAY_SIZE(tx14d14_modes),
+       .hfmin                  = 14820,
+       .hfmax                  = 22230,
+       .vfmin                  = 60,
+       .vfmax                  = 73.3,
+       .dclkmax                = 25200000,
+};
+
+struct atmel_lcdfb_info __initdata mimc200_lcdc_data = {
+       .default_bpp            = 16,
+       .default_dmacon         = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
+       .default_lcdcon2        = (ATMEL_LCDC_DISTYPE_TFT
+                                  | ATMEL_LCDC_INVCLK
+                                  | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
+                                  | ATMEL_LCDC_MEMOR_BIG),
+       .default_monspecs       = &mimc200_default_monspecs,
+       .guard_time             = 2,
+};
+
+struct eth_addr {
+       u8 addr[6];
+};
+static struct eth_addr __initdata hw_addr[2];
+static struct eth_platform_data __initdata eth_data[2];
+
+static struct spi_eeprom eeprom_25lc010 = {
+               .name = "25lc010",
+               .byte_len = 128,
+               .page_size = 16,
+               .flags = EE_ADDR1,
+};
+
+static struct spi_board_info spi0_board_info[] __initdata = {
+       {
+               .modalias       = "rtc-ds1390",
+               .max_speed_hz   = 4000000,
+               .chip_select    = 2,
+       },
+       {
+               .modalias       = "at25",
+               .max_speed_hz   = 1000000,
+               .chip_select    = 1,
+               .mode           = SPI_MODE_3,
+               .platform_data  = &eeprom_25lc010,
+       },
+};
+
+static struct mci_platform_data __initdata mci0_data = {
+       .slot[0] = {
+               .bus_width      = 4,
+               .detect_pin     = GPIO_PIN_PA(26),
+               .wp_pin         = GPIO_PIN_PA(27),
+       },
+};
+
+/*
+ * The next two functions should go away as the boot loader is
+ * supposed to initialize the macb address registers with a valid
+ * ethernet address. But we need to keep it around for a while until
+ * we can be reasonably sure the boot loader does this.
+ *
+ * The phy_id is ignored as the driver will probe for it.
+ */
+static int __init parse_tag_ethernet(struct tag *tag)
+{
+       int i;
+
+       i = tag->u.ethernet.mac_index;
+       if (i < ARRAY_SIZE(hw_addr))
+               memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address,
+                      sizeof(hw_addr[i].addr));
+
+       return 0;
+}
+__tagtable(ATAG_ETHERNET, parse_tag_ethernet);
+
+static void __init set_hw_addr(struct platform_device *pdev)
+{
+       struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       const u8 *addr;
+       void __iomem *regs;
+       struct clk *pclk;
+
+       if (!res)
+               return;
+       if (pdev->id >= ARRAY_SIZE(hw_addr))
+               return;
+
+       addr = hw_addr[pdev->id].addr;
+       if (!is_valid_ether_addr(addr))
+               return;
+
+       /*
+        * Since this is board-specific code, we'll cheat and use the
+        * physical address directly as we happen to know that it's
+        * the same as the virtual address.
+        */
+       regs = (void __iomem __force *)res->start;
+       pclk = clk_get(&pdev->dev, "pclk");
+       if (!pclk)
+               return;
+
+       clk_enable(pclk);
+       __raw_writel((addr[3] << 24) | (addr[2] << 16)
+                    | (addr[1] << 8) | addr[0], regs + 0x98);
+       __raw_writel((addr[5] << 8) | addr[4], regs + 0x9c);
+       clk_disable(pclk);
+       clk_put(pclk);
+}
+
+void __init setup_board(void)
+{
+       at32_map_usart(0, 0);   /* USART 0: /dev/ttyS0 (TTL --> Altera) */
+       at32_map_usart(1, 1);   /* USART 1: /dev/ttyS1 (RS232) */
+       at32_map_usart(2, 2);   /* USART 2: /dev/ttyS2 (RS485) */
+       at32_map_usart(3, 3);   /* USART 3: /dev/ttyS3 (RS422 Multidrop) */
+}
+
+static struct i2c_gpio_platform_data i2c_gpio_data = {
+       .sda_pin                = GPIO_PIN_PA(6),
+       .scl_pin                = GPIO_PIN_PA(7),
+       .sda_is_open_drain      = 1,
+       .scl_is_open_drain      = 1,
+       .udelay                 = 2,    /* close to 100 kHz */
+};
+
+static struct platform_device i2c_gpio_device = {
+       .name           = "i2c-gpio",
+       .id             = 0,
+       .dev            = {
+       .platform_data  = &i2c_gpio_data,
+       },
+};
+
+static struct i2c_board_info __initdata i2c_info[] = {
+};
+
+static int __init mimc200_init(void)
+{
+       /*
+        * MIMC200 uses 16-bit SDRAM interface, so we don't need to
+        * reserve any pins for it.
+        */
+
+       at32_add_system_devices();
+
+       at32_add_device_usart(0);
+       at32_add_device_usart(1);
+       at32_add_device_usart(2);
+       at32_add_device_usart(3);
+
+       set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
+       set_hw_addr(at32_add_device_eth(1, &eth_data[1]));
+
+       at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
+       at32_add_device_mci(0, &mci0_data);
+       at32_add_device_usba(0, NULL);
+
+       at32_select_periph(GPIO_PIOB_BASE, 1 << 28, 0, AT32_GPIOF_PULLUP);
+       at32_select_gpio(i2c_gpio_data.sda_pin,
+               AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
+       at32_select_gpio(i2c_gpio_data.scl_pin,
+               AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
+       platform_device_register(&i2c_gpio_device);
+       i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info));
+
+       at32_add_device_lcdc(0, &mimc200_lcdc_data,
+                            fbmem_start, fbmem_size, 1);
+
+       return 0;
+}
+postcore_initcall(mimc200_init);
diff --git a/arch/avr32/configs/atngw100_evklcd100_defconfig b/arch/avr32/configs/atngw100_evklcd100_defconfig
new file mode 100644 (file)
index 0000000..b0572d2
--- /dev/null
@@ -0,0 +1,1264 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.25.6
+# Wed Jun 18 16:06:32 2008
+#
+CONFIG_AVR32=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL 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=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_BASE_FULL is not set
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=m
+CONFIG_HAVE_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_HAVE_KPROBES=y
+# CONFIG_HAVE_KRETPROBES is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=1
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type and features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_SUBARCH_AVR32B=y
+CONFIG_MMU=y
+CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PLATFORM_AT32AP=y
+CONFIG_CPU_AT32AP700X=y
+CONFIG_CPU_AT32AP7000=y
+# CONFIG_BOARD_ATSTK1000 is not set
+CONFIG_BOARD_ATNGW100=y
+CONFIG_BOARD_ATNGW100_EVKLCD10X=y
+CONFIG_BOARD_ATNGW100_EVKLCD10X_QVGA=y
+# CONFIG_BOARD_ATNGW100_EVKLCD10X_VGA is not set
+# CONFIG_BOARD_ATNGW100_EVKLCD10X_POW_QVGA is not set
+CONFIG_BOARD_ATNGW100_I2C_GPIO=y
+CONFIG_LOADER_U_BOOT=y
+
+#
+# Atmel AVR32 AP options
+#
+# CONFIG_AP700X_32_BIT_SMC is not set
+CONFIG_AP700X_16_BIT_SMC=y
+# CONFIG_AP700X_8_BIT_SMC is not set
+CONFIG_GPIO_DEV=y
+CONFIG_LOAD_ADDRESS=0x10000000
+CONFIG_ENTRY_ADDRESS=0x90000000
+CONFIG_PHYS_OFFSET=0x10000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set
+# CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
+# CONFIG_NEED_NODE_MEMMAP_SIZE is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+# CONFIG_ARCH_SPARSEMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_OWNERSHIP_TRACE is not set
+CONFIG_NMI_DEBUGGING=y
+CONFIG_DW_DMAC=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_CMDLINE=""
+
+#
+# Power management options
+#
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+# CONFIG_CPU_FREQ_STAT is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_AT32AP=y
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# 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_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+# CONFIG_IP_PIMSM_V2 is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=y
+CONFIG_INET6_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+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_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER_ADVANCED is not set
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_XTABLES=y
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=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
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+# CONFIG_IP_NF_TARGET_ULOG is not set
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+# CONFIG_NF_NAT_TFTP is not set
+# CONFIG_NF_NAT_AMANDA is not set
+# CONFIG_NF_NAT_PPTP is not set
+# CONFIG_NF_NAT_H323 is not set
+CONFIG_NF_NAT_SIP=m
+CONFIG_IP_NF_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+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_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# 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_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x80000000
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=m
+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_MISC_DEVICES=y
+# CONFIG_ATMEL_PWM is not set
+CONFIG_ATMEL_TCLIB=y
+CONFIG_ATMEL_TCB_CLKSRC=y
+CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ATMEL_SSC is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HAVE_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_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_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_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_MACB=y
+# CONFIG_ENC28J60 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 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_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# 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=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH 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_UCB1400 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_ATMEL_PDC=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS 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=m
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_ATMELTWI=m
+CONFIG_I2C_GPIO=m
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+CONFIG_SPI_SPIDEV=m
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_HAVE_GPIO_LIB=y
+
+#
+# GPIO Support
+#
+# CONFIG_DEBUG_GPIO is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AT32AP700X_WDT=y
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC 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_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_ATMEL=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+# CONFIG_LOGO is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+# 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_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_AC97_CODEC=m
+# 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
+
+#
+# AVR32 devices
+#
+CONFIG_SND_ATMEL_AC97=m
+
+#
+# SPI devices
+#
+
+#
+# System on Chip audio support
+#
+# CONFIG_SND_SOC is not set
+
+#
+# SoC Audio support for SuperH
+#
+
+#
+# ALSA SoC audio for Freescale SOCs
+#
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+CONFIG_USB_GADGET_ATMEL_USBA=y
+CONFIG_USB_ATMEL_USBA=y
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+CONFIG_MMC_ATMELMCI=y
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_GPIO=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_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
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# 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_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AT32AP700X=y
+
+#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=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_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+
+#
+# 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=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=850
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_NFSD_TCP=y
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED 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=m
+# 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_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_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 is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_KPROBES_SANITY_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_BLKCIPHER=y
+# CONFIG_CRYPTO_SEQIV is not set
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+CONFIG_CRYPTO_AUTHENC=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=y
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/avr32/configs/atngw100_evklcd101_defconfig b/arch/avr32/configs/atngw100_evklcd101_defconfig
new file mode 100644 (file)
index 0000000..c5b898d
--- /dev/null
@@ -0,0 +1,1264 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.25.6
+# Wed Jun 18 16:09:32 2008
+#
+CONFIG_AVR32=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL 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=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_BASE_FULL is not set
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=m
+CONFIG_HAVE_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_HAVE_KPROBES=y
+# CONFIG_HAVE_KRETPROBES is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=1
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type and features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_SUBARCH_AVR32B=y
+CONFIG_MMU=y
+CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PLATFORM_AT32AP=y
+CONFIG_CPU_AT32AP700X=y
+CONFIG_CPU_AT32AP7000=y
+# CONFIG_BOARD_ATSTK1000 is not set
+CONFIG_BOARD_ATNGW100=y
+CONFIG_BOARD_ATNGW100_EVKLCD10X=y
+# CONFIG_BOARD_ATNGW100_EVKLCD10X_QVGA is not set
+CONFIG_BOARD_ATNGW100_EVKLCD10X_VGA=y
+# CONFIG_BOARD_ATNGW100_EVKLCD10X_POW_QVGA is not set
+CONFIG_BOARD_ATNGW100_I2C_GPIO=y
+CONFIG_LOADER_U_BOOT=y
+
+#
+# Atmel AVR32 AP options
+#
+# CONFIG_AP700X_32_BIT_SMC is not set
+CONFIG_AP700X_16_BIT_SMC=y
+# CONFIG_AP700X_8_BIT_SMC is not set
+CONFIG_GPIO_DEV=y
+CONFIG_LOAD_ADDRESS=0x10000000
+CONFIG_ENTRY_ADDRESS=0x90000000
+CONFIG_PHYS_OFFSET=0x10000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set
+# CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
+# CONFIG_NEED_NODE_MEMMAP_SIZE is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+# CONFIG_ARCH_SPARSEMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_OWNERSHIP_TRACE is not set
+CONFIG_NMI_DEBUGGING=y
+CONFIG_DW_DMAC=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_CMDLINE=""
+
+#
+# Power management options
+#
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+# CONFIG_CPU_FREQ_STAT is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_AT32AP=y
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# 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_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+# CONFIG_IP_PIMSM_V2 is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=y
+CONFIG_INET6_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+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_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER_ADVANCED is not set
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_XTABLES=y
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=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
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+# CONFIG_IP_NF_TARGET_ULOG is not set
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+# CONFIG_NF_NAT_TFTP is not set
+# CONFIG_NF_NAT_AMANDA is not set
+# CONFIG_NF_NAT_PPTP is not set
+# CONFIG_NF_NAT_H323 is not set
+CONFIG_NF_NAT_SIP=m
+CONFIG_IP_NF_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+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_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# 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_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x80000000
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=m
+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_MISC_DEVICES=y
+# CONFIG_ATMEL_PWM is not set
+CONFIG_ATMEL_TCLIB=y
+CONFIG_ATMEL_TCB_CLKSRC=y
+CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ATMEL_SSC is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HAVE_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_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_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_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_MACB=y
+# CONFIG_ENC28J60 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 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_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# 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=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH 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_UCB1400 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_ATMEL_PDC=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS 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=m
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_ATMELTWI=m
+CONFIG_I2C_GPIO=m
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+CONFIG_SPI_SPIDEV=m
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_HAVE_GPIO_LIB=y
+
+#
+# GPIO Support
+#
+# CONFIG_DEBUG_GPIO is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AT32AP700X_WDT=y
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC 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_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_ATMEL=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+# CONFIG_LOGO is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+# 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_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_AC97_CODEC=m
+# 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
+
+#
+# AVR32 devices
+#
+CONFIG_SND_ATMEL_AC97=m
+
+#
+# SPI devices
+#
+
+#
+# System on Chip audio support
+#
+# CONFIG_SND_SOC is not set
+
+#
+# SoC Audio support for SuperH
+#
+
+#
+# ALSA SoC audio for Freescale SOCs
+#
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+CONFIG_USB_GADGET_ATMEL_USBA=y
+CONFIG_USB_ATMEL_USBA=y
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+CONFIG_MMC_ATMELMCI=y
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_GPIO=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_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
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# 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_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AT32AP700X=y
+
+#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=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_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+
+#
+# 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=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=850
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_NFSD_TCP=y
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED 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=m
+# 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_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_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 is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_KPROBES_SANITY_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_BLKCIPHER=y
+# CONFIG_CRYPTO_SEQIV is not set
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+CONFIG_CRYPTO_AUTHENC=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=y
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/avr32/configs/favr-32_defconfig b/arch/avr32/configs/favr-32_defconfig
new file mode 100644 (file)
index 0000000..e2bd998
--- /dev/null
@@ -0,0 +1,1235 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27-rc8
+# Tue Oct 14 13:20:41 2008
+#
+CONFIG_AVR32=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL 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=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_BASE_FULL is not set
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=m
+CONFIG_HAVE_OPROFILE=y
+CONFIG_KPROBES=y
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
+CONFIG_HAVE_KPROBES=y
+# CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
+# CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_CLK=y
+CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=1
+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_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# 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=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type and features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_SUBARCH_AVR32B=y
+CONFIG_MMU=y
+CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PLATFORM_AT32AP=y
+CONFIG_CPU_AT32AP700X=y
+CONFIG_CPU_AT32AP7000=y
+# CONFIG_BOARD_ATSTK1000 is not set
+# CONFIG_BOARD_ATNGW100 is not set
+CONFIG_BOARD_FAVR_32=y
+# CONFIG_BOARD_MIMC200 is not set
+CONFIG_BOARD_FAVR32_ABDAC_RATE=44100
+CONFIG_LOADER_U_BOOT=y
+
+#
+# Atmel AVR32 AP options
+#
+# CONFIG_AP700X_32_BIT_SMC is not set
+CONFIG_AP700X_16_BIT_SMC=y
+# CONFIG_AP700X_8_BIT_SMC is not set
+CONFIG_LOAD_ADDRESS=0x10000000
+CONFIG_ENTRY_ADDRESS=0x90000000
+CONFIG_PHYS_OFFSET=0x10000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_QUICKLIST=y
+# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set
+# CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
+# CONFIG_NEED_NODE_MEMMAP_SIZE is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+# CONFIG_ARCH_SPARSEMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_OWNERSHIP_TRACE is not set
+CONFIG_NMI_DEBUGGING=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_CMDLINE=""
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+# CONFIG_CPU_FREQ_STAT is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_AT32AP=y
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC 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 is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
+CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_STP=m
+CONFIG_BRIDGE=m
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# 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_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 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# 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_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=m
+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_MISC_DEVICES=y
+CONFIG_ATMEL_PWM=m
+CONFIG_ATMEL_TCLIB=y
+CONFIG_ATMEL_TCB_CLKSRC=y
+CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_ATMEL_SSC=m
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HAVE_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_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_MACB=y
+# CONFIG_ENC28J60 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 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_IWLWIFI_LEDS is not set
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# 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=m
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_GPIO=m
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+CONFIG_MOUSE_GPIO=m
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=m
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO 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_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+# CONFIG_CONSOLE_TRANSLATIONS is not set
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_ATMEL_PDC=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS 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=m
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=m
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_GPIO=m
+# 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_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+CONFIG_SPI_SPIDEV=m
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+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:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AT32AP700X_WDT=y
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO 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
+
+#
+# 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_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_S1D13XXX is not set
+CONFIG_FB_ATMEL=y
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+# CONFIG_BACKLIGHT_ATMEL_LCDC is not set
+CONFIG_BACKLIGHT_ATMEL_PWM=m
+# CONFIG_BACKLIGHT_CORGI is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+# CONFIG_LOGO is not set
+CONFIG_SOUND=m
+# CONFIG_SND is not set
+CONFIG_SOUND_PRIME=m
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+CONFIG_USB_GADGET_ATMEL_USBA=y
+CONFIG_USB_ATMEL_USBA=y
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_USB_CDC_COMPOSITE=m
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD 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 Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_ATMELMCI=y
+CONFIG_MMC_ATMELMCI_DMA=y
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_ATMEL_PWM=m
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+# CONFIG_LEDS_PCA955X is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+# 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
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# 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_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AT32AP700X=y
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+CONFIG_DW_DMAC=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG 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_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=m
+
+#
+# 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=m
+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_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_JFFS2_FS_WRITEBUFFER is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL 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=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES 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 is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_KPROBES_SANITY_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=m
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=m
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB 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=m
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=m
+# 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=m
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+# CONFIG_CRYPTO_HW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/avr32/configs/mimc200_defconfig b/arch/avr32/configs/mimc200_defconfig
new file mode 100644 (file)
index 0000000..981e4f8
--- /dev/null
@@ -0,0 +1,1109 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27-rc8
+# Mon Oct 13 15:46:53 2008
+#
+CONFIG_AVR32=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL 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=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_BASE_FULL is not set
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+# CONFIG_OPROFILE is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
+CONFIG_HAVE_KPROBES=y
+# CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
+# CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_CLK=y
+CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=1
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# 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=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type and features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_SUBARCH_AVR32B=y
+CONFIG_MMU=y
+CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PLATFORM_AT32AP=y
+CONFIG_CPU_AT32AP700X=y
+CONFIG_CPU_AT32AP7000=y
+# CONFIG_BOARD_ATSTK1000 is not set
+# CONFIG_BOARD_ATNGW100 is not set
+CONFIG_BOARD_MIMC200=y
+CONFIG_LOADER_U_BOOT=y
+
+#
+# Atmel AVR32 AP options
+#
+# CONFIG_AP700X_32_BIT_SMC is not set
+CONFIG_AP700X_16_BIT_SMC=y
+# CONFIG_AP700X_8_BIT_SMC is not set
+CONFIG_LOAD_ADDRESS=0x10000000
+CONFIG_ENTRY_ADDRESS=0x90000000
+CONFIG_PHYS_OFFSET=0x10000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_QUICKLIST=y
+# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set
+# CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
+# CONFIG_NEED_NODE_MEMMAP_SIZE is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+# CONFIG_ARCH_SPARSEMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_OWNERSHIP_TRACE is not set
+CONFIG_NMI_DEBUGGING=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_CMDLINE=""
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+# CONFIG_CPU_FREQ_STAT is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_AT32AP=y
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=y
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# 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_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+# CONFIG_IP_PIMSM_V2 is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=y
+CONFIG_INET6_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+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_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# 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_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 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x80000000
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ATMEL_PWM is not set
+CONFIG_ATMEL_TCLIB=y
+CONFIG_ATMEL_TCB_CLKSRC=y
+CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ATMEL_SSC is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HAVE_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_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_MACB=y
+# CONFIG_ENC28J60 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 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_IWLWIFI_LEDS 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 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_ATMEL_PDC=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS 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_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_GPIO=y
+# 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
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+CONFIG_AT24=y
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_DS28CM00 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_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_AT25=y
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+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:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AT32AP700X_WDT=y
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO 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
+
+#
+# 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_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_S1D13XXX is not set
+CONFIG_FB_ATMEL=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_LOGO is not set
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+CONFIG_MMC_TEST=y
+
+#
+# MMC/SD Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_ATMELMCI=y
+# CONFIG_MMC_ATMELMCI_DMA is not set
+CONFIG_MMC_SPI=y
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_GPIO=y
+# CONFIG_LEDS_PCA955X is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+# 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
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+CONFIG_RTC_DRV_DS1390=y
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# 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_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_AT32AP700X is not set
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+CONFIG_DW_DMAC=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=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_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
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=850
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL 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=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# 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=y
+# 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=y
+# 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=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES 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 is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+
+#
+# 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=y
+# 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=y
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# 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=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=y
+# 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=y
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_CRC7=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index 813b6844cdf67a1ec485ccc4f3839baa42c2682d..0c6e02f80a31ce6cd562aa2147d0144a3e89b913 100644 (file)
@@ -813,7 +813,7 @@ static struct resource pio4_resource[] = {
 DEFINE_DEV(pio, 4);
 DEV_CLK(mck, pio4, pba, 14);
 
-void __init at32_add_system_devices(void)
+static int __init system_device_init(void)
 {
        platform_device_register(&at32_pm0_device);
        platform_device_register(&at32_intc0_device);
@@ -832,7 +832,10 @@ void __init at32_add_system_devices(void)
        platform_device_register(&pio2_device);
        platform_device_register(&pio3_device);
        platform_device_register(&pio4_device);
+
+       return 0;
 }
+core_initcall(system_device_init);
 
 /* --------------------------------------------------------------------
  *  PSIF
@@ -1091,7 +1094,9 @@ at32_add_device_eth(unsigned int id, struct eth_platform_data *data)
                        pin_mask |= (1 << 11);  /* RXD2 */
                        pin_mask |= (1 << 12);  /* RXD3 */
                        pin_mask |= (1 << 14);  /* RXCK */
+#ifndef CONFIG_BOARD_MIMC200
                        pin_mask |= (1 << 18);  /* SPD  */
+#endif
                }
 
                select_peripheral(PIOC, pin_mask, PERIPH_A, 0);
@@ -1112,8 +1117,10 @@ at32_add_device_eth(unsigned int id, struct eth_platform_data *data)
                pin_mask |= (1 << 3);   /* MDC  */
                pin_mask |= (1 << 2);   /* MDIO */
 
+#ifndef CONFIG_BOARD_MIMC200
                if (!data->is_rmii)
                        pin_mask |= (1 << 15);  /* SPD  */
+#endif
 
                select_peripheral(PIOD, pin_mask, PERIPH_B, 0);
 
@@ -1470,7 +1477,7 @@ at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
                        pin_mask = ATMEL_LCDC_PRI_24BIT | ATMEL_LCDC_PRI_CONTROL;
 
                /* LCDC on port C */
-               portc_mask = (pin_mask & 0xfff80000) >> 19;
+               portc_mask = pin_mask & 0xfff80000;
                select_peripheral(PIOC, portc_mask, PERIPH_A, 0);
 
                /* LCDC on port D */
index d84efe4984ab82da6aaae2a6ca2c09d700016c80..024c586e936c268956dbb59221e4ec8e2b77b129 100644 (file)
@@ -40,6 +40,9 @@ static unsigned int at32_get_speed(unsigned int cpu)
        return (unsigned int)((clk_get_rate(cpuclk) + 500) / 1000);
 }
 
+static unsigned int    ref_freq;
+static unsigned long   loops_per_jiffy_ref;
+
 static int at32_set_target(struct cpufreq_policy *policy,
                          unsigned int target_freq,
                          unsigned int relation)
@@ -61,8 +64,19 @@ static int at32_set_target(struct cpufreq_policy *policy,
        freqs.cpu = 0;
        freqs.flags = 0;
 
+       if (!ref_freq) {
+               ref_freq = freqs.old;
+               loops_per_jiffy_ref = boot_cpu_data.loops_per_jiffy;
+       }
+
        cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+       if (freqs.old < freqs.new)
+               boot_cpu_data.loops_per_jiffy = cpufreq_scale(
+                               loops_per_jiffy_ref, ref_freq, freqs.new);
        clk_set_rate(cpuclk, freq);
+       if (freqs.new < freqs.old)
+               boot_cpu_data.loops_per_jiffy = cpufreq_scale(
+                               loops_per_jiffy_ref, ref_freq, freqs.new);
        cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 
        pr_debug("cpufreq: set frequency %lu Hz\n", freq);
index c36a6d59d6f0785e900a7e905189e577bd4693bc..310477ba1bbf170a47af4e68bfc4bfa26d836a8d 100644 (file)
@@ -191,7 +191,7 @@ static int __init eic_probe(struct platform_device *pdev)
        struct eic *eic;
        struct resource *regs;
        unsigned int i;
-       unsigned int nr_irqs;
+       unsigned int nr_of_irqs;
        unsigned int int_irq;
        int ret;
        u32 pattern;
@@ -224,7 +224,7 @@ static int __init eic_probe(struct platform_device *pdev)
        eic_writel(eic, IDR, ~0UL);
        eic_writel(eic, MODE, ~0UL);
        pattern = eic_readl(eic, MODE);
-       nr_irqs = fls(pattern);
+       nr_of_irqs = fls(pattern);
 
        /* Trigger on low level unless overridden by driver */
        eic_writel(eic, EDGE, 0UL);
@@ -232,7 +232,7 @@ static int __init eic_probe(struct platform_device *pdev)
 
        eic->chip = &eic_chip;
 
-       for (i = 0; i < nr_irqs; i++) {
+       for (i = 0; i < nr_of_irqs; i++) {
                set_irq_chip_and_handler(eic->first_irq + i, &eic_chip,
                                         handle_level_irq);
                set_irq_chip_data(eic->first_irq + i, eic);
@@ -256,7 +256,7 @@ static int __init eic_probe(struct platform_device *pdev)
                 eic->regs, int_irq);
        dev_info(&pdev->dev,
                 "Handling %u external IRQs, starting with IRQ %u\n",
-                nr_irqs, eic->first_irq);
+                nr_of_irqs, eic->first_irq);
 
        return 0;
 
index c48386d66bc38f9fb0c1e287748b6de16a8ac903..aafaf7a78886951ed50017c6d414e6b5758cff05 100644 (file)
  */
 extern unsigned long at32_board_osc_rates[];
   
-/* Add basic devices: system manager, interrupt controller, portmuxes, etc. */
-void at32_add_system_devices(void);
+/*
+ * This used to add essential system devices, but this is now done
+ * automatically. Please don't use it in new board code.
+ */
+static inline void __deprecated at32_add_system_devices(void)
+{
+
+}
 
 #define ATMEL_MAX_UART 4
 extern struct platform_device *atmel_default_console_device;
index 07335e719bf835d7ad5e88a6b844f07210b4b6ba..b17aeea8d620c2ce4b0776ee06c0ba27a8fc3488 100644 (file)
@@ -679,6 +679,8 @@ source "fs/Kconfig"
 
 source "drivers/usb/Kconfig"
 
+source "drivers/uwb/Kconfig"
+
 source "arch/cris/Kconfig.debug"
 
 source "security/Kconfig"
index bd1995403c67d0f9b37b34674a6c80ab7ee2a76b..28f06fd9b7b709258b12d58737045f0b4c170412 100644 (file)
@@ -216,6 +216,8 @@ source "drivers/hwmon/Kconfig"
 
 source "drivers/usb/Kconfig"
 
+source "drivers/uwb/Kconfig"
+
 endmenu
 
 source "fs/Kconfig"
index 912c57db2d2180888ee9b366d7fae435c45c354d..27eec71429b052ac587e3dfe66a7fb64a483a31d 100644 (file)
@@ -23,6 +23,7 @@ config IA64
        select HAVE_KRETPROBES
        select HAVE_DMA_ATTRS
        select HAVE_KVM
+       select HAVE_ARCH_TRACEHOOK
        default y
        help
          The Itanium Processor Family is Intel's 64-bit successor to
@@ -110,6 +111,33 @@ config AUDIT_ARCH
        bool
        default y
 
+menuconfig PARAVIRT_GUEST
+       bool "Paravirtualized guest support"
+       help
+         Say Y here to get to see options related to running Linux under
+         various hypervisors.  This option alone does not add any kernel code.
+
+         If you say N, all options in this submenu will be skipped and disabled.
+
+if PARAVIRT_GUEST
+
+config PARAVIRT
+       bool "Enable paravirtualization code"
+       depends on PARAVIRT_GUEST
+       default y
+       bool
+       default y
+       help
+         This changes the kernel so it can modify itself when it is run
+         under a hypervisor, potentially improving performance significantly
+         over full virtualization.  However, when run without a hypervisor
+         the kernel is theoretically slower and slightly larger.
+
+
+source "arch/ia64/xen/Kconfig"
+
+endif
+
 choice
        prompt "System type"
        default IA64_GENERIC
@@ -119,6 +147,7 @@ config IA64_GENERIC
        select NUMA
        select ACPI_NUMA
        select SWIOTLB
+       select PCI_MSI
        help
          This selects the system type of your hardware.  A "generic" kernel
          will run on any supported IA-64 system.  However, if you configure
@@ -126,11 +155,13 @@ config IA64_GENERIC
 
          generic               For any supported IA-64 system
          DIG-compliant         For DIG ("Developer's Interface Guide") compliant systems
+         DIG+Intel+IOMMU       For DIG systems with Intel IOMMU
          HP-zx1/sx1000         For HP systems
          HP-zx1/sx1000+swiotlb For HP systems with (broken) DMA-constrained devices.
          SGI-SN2               For SGI Altix systems
          SGI-UV                For SGI UV systems
          Ski-simulator         For the HP simulator <http://www.hpl.hp.com/research/linux/ski/>
+         Xen-domU              For xen domU system
 
          If you don't know what to do, choose "generic".
 
@@ -138,6 +169,11 @@ config IA64_DIG
        bool "DIG-compliant"
        select SWIOTLB
 
+config IA64_DIG_VTD
+       bool "DIG+Intel+IOMMU"
+       select DMAR
+       select PCI_MSI
+
 config IA64_HP_ZX1
        bool "HP-zx1/sx1000"
        help
@@ -181,6 +217,10 @@ config IA64_HP_SIM
        bool "Ski-simulator"
        select SWIOTLB
 
+config IA64_XEN_GUEST
+       bool "Xen guest"
+       depends on XEN
+
 endchoice
 
 choice
@@ -583,6 +623,16 @@ source "drivers/pci/hotplug/Kconfig"
 
 source "drivers/pcmcia/Kconfig"
 
+config DMAR
+        bool "Support for DMA Remapping Devices (EXPERIMENTAL)"
+        depends on IA64_GENERIC && ACPI && EXPERIMENTAL
+       help
+         DMA remapping (DMAR) devices support enables independent address
+         translations for Direct Memory Access (DMA) from devices.
+         These DMA remapping devices are reported via ACPI tables
+         and include PCI device scope covered by these DMA
+         remapping devices.
+
 endmenu
 
 endif
index 905d25b13d5a10a9a988f2c546e5c968e99c38de..58a7e46affda28b44daf8199244ab3eca354fa8a 100644 (file)
@@ -53,12 +53,15 @@ libs-y                              += arch/ia64/lib/
 core-y                         += arch/ia64/kernel/ arch/ia64/mm/
 core-$(CONFIG_IA32_SUPPORT)    += arch/ia64/ia32/
 core-$(CONFIG_IA64_DIG)        += arch/ia64/dig/
+core-$(CONFIG_IA64_DIG_VTD)    += arch/ia64/dig/
 core-$(CONFIG_IA64_GENERIC)    += arch/ia64/dig/
 core-$(CONFIG_IA64_HP_ZX1)     += arch/ia64/dig/
 core-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/dig/
+core-$(CONFIG_IA64_XEN_GUEST)  += arch/ia64/dig/
 core-$(CONFIG_IA64_SGI_SN2)    += arch/ia64/sn/
 core-$(CONFIG_IA64_SGI_UV)     += arch/ia64/uv/
 core-$(CONFIG_KVM)             += arch/ia64/kvm/
+core-$(CONFIG_XEN)             += arch/ia64/xen/
 
 drivers-$(CONFIG_PCI)          += arch/ia64/pci/
 drivers-$(CONFIG_IA64_HP_SIM)  += arch/ia64/hp/sim/
index 9f483976228fffb84125ca7adf4915e824937af5..e05f9e1d3faaa7d0d1449d60766f4c7efb18f231 100644 (file)
@@ -233,6 +233,8 @@ CONFIG_DMIID=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
 
+# CONFIG_DMAR is not set
+
 #
 # Power management and ACPI
 #
index 797acf9066c1a0bd4de229d267a8f070b6e5a571..c522edf23c623732c06709cd05df178ac794d17e 100644 (file)
@@ -172,6 +172,8 @@ CONFIG_DMIID=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
 
+# CONFIG_DMAR is not set
+
 #
 # Power management and ACPI
 #
index 971cd7870dd4227e36ef9f65ccb573771880ac01..5c0283830bd611d951c28f3b64ed49b41f961c73 100644 (file)
@@ -6,4 +6,9 @@
 #
 
 obj-y := setup.o
+ifeq ($(CONFIG_DMAR), y)
+obj-$(CONFIG_IA64_GENERIC) += machvec.o machvec_vtd.o dig_vtd_iommu.o
+else
 obj-$(CONFIG_IA64_GENERIC) += machvec.o
+endif
+obj-$(CONFIG_IA64_DIG_VTD) += dig_vtd_iommu.o
diff --git a/arch/ia64/dig/dig_vtd_iommu.c b/arch/ia64/dig/dig_vtd_iommu.c
new file mode 100644 (file)
index 0000000..1c8a079
--- /dev/null
@@ -0,0 +1,59 @@
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/intel-iommu.h>
+
+void *
+vtd_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+                gfp_t flags)
+{
+       return intel_alloc_coherent(dev, size, dma_handle, flags);
+}
+EXPORT_SYMBOL_GPL(vtd_alloc_coherent);
+
+void
+vtd_free_coherent(struct device *dev, size_t size, void *vaddr,
+                dma_addr_t dma_handle)
+{
+       intel_free_coherent(dev, size, vaddr, dma_handle);
+}
+EXPORT_SYMBOL_GPL(vtd_free_coherent);
+
+dma_addr_t
+vtd_map_single_attrs(struct device *dev, void *addr, size_t size,
+                    int dir, struct dma_attrs *attrs)
+{
+       return intel_map_single(dev, (phys_addr_t)addr, size, dir);
+}
+EXPORT_SYMBOL_GPL(vtd_map_single_attrs);
+
+void
+vtd_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size,
+                      int dir, struct dma_attrs *attrs)
+{
+       intel_unmap_single(dev, iova, size, dir);
+}
+EXPORT_SYMBOL_GPL(vtd_unmap_single_attrs);
+
+int
+vtd_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents,
+                int dir, struct dma_attrs *attrs)
+{
+       return intel_map_sg(dev, sglist, nents, dir);
+}
+EXPORT_SYMBOL_GPL(vtd_map_sg_attrs);
+
+void
+vtd_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist,
+                  int nents, int dir, struct dma_attrs *attrs)
+{
+       intel_unmap_sg(dev, sglist, nents, dir);
+}
+EXPORT_SYMBOL_GPL(vtd_unmap_sg_attrs);
+
+int
+vtd_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+       return 0;
+}
+EXPORT_SYMBOL_GPL(vtd_dma_mapping_error);
diff --git a/arch/ia64/dig/machvec_vtd.c b/arch/ia64/dig/machvec_vtd.c
new file mode 100644 (file)
index 0000000..7cd3eb4
--- /dev/null
@@ -0,0 +1,3 @@
+#define MACHVEC_PLATFORM_NAME          dig_vtd
+#define MACHVEC_PLATFORM_HEADER                <asm/machvec_dig_vtd.h>
+#include <asm/machvec_init.h>
index 5e901c75df1bda93122aef924613d8a173cb722f..5c93ddd1e42d414066042ec8e876eba7471b551c 100644 (file)
@@ -1,4 +1,4 @@
-#include <asm-x86/unistd_32.h>
+#include "../../x86/include/asm/unistd_32.h"
 
 unsigned ia32_dir_class[] = {
 #include <asm-generic/audit_dir_write.h>
index 53505bb04771811b42a74fc7d15bebb8cb25e0e4..a8cf199588508e23c0d6e40e869b8540a37d965a 100644 (file)
@@ -108,6 +108,11 @@ GLOBAL_ENTRY(ia32_trace_syscall)
        ;;
        st8 [r2]=r3                             // initialize return code to -ENOSYS
        br.call.sptk.few rp=syscall_trace_enter // give parent a chance to catch syscall args
+       cmp.lt p6,p0=r8,r0                      // check tracehook
+       adds r2=IA64_PT_REGS_R8_OFFSET+16,sp    // r2 = &pt_regs.r8
+       ;;
+(p6)   st8.spill [r2]=r8                       // store return value in slot for r8
+(p6)   br.spnt.few .ret4
 .ret2: // Need to reload arguments (they may be changed by the tracing process)
        adds r2=IA64_PT_REGS_R1_OFFSET+16,sp    // r2 = &pt_regs.r1
        adds r3=IA64_PT_REGS_R13_OFFSET+16,sp   // r3 = &pt_regs.r13
@@ -199,10 +204,10 @@ ia32_syscall_table:
        data8 sys_setuid        /* 16-bit version */
        data8 sys_getuid        /* 16-bit version */
        data8 compat_sys_stime    /* 25 */
-       data8 sys32_ptrace
+       data8 compat_sys_ptrace
        data8 sys32_alarm
        data8 sys_ni_syscall
-       data8 sys32_pause
+       data8 sys_pause
        data8 compat_sys_utime    /* 30 */
        data8 sys_ni_syscall      /* old stty syscall holder */
        data8 sys_ni_syscall      /* old gtty syscall holder */
@@ -215,7 +220,7 @@ ia32_syscall_table:
        data8 sys_mkdir
        data8 sys_rmdir           /* 40 */
        data8 sys_dup
-       data8 sys32_pipe
+       data8 sys_pipe
        data8 compat_sys_times
        data8 sys_ni_syscall      /* old prof syscall holder */
        data8 sys32_brk           /* 45 */
index f4430bb4bbdcc46335cf4f21579f77cd26e6afd9..5e92ae00bdbba8403ee69ddd12d33ca44ce34699 100644 (file)
@@ -1098,21 +1098,6 @@ sys32_mremap (unsigned int addr, unsigned int old_len, unsigned int new_len,
        return ret;
 }
 
-asmlinkage long
-sys32_pipe (int __user *fd)
-{
-       int retval;
-       int fds[2];
-
-       retval = do_pipe_flags(fds, 0);
-       if (retval)
-               goto out;
-       if (copy_to_user(fd, fds, sizeof(fds)))
-               retval = -EFAULT;
-  out:
-       return retval;
-}
-
 asmlinkage unsigned long
 sys32_alarm (unsigned int seconds)
 {
@@ -1209,25 +1194,6 @@ sys32_waitpid (int pid, unsigned int *stat_addr, int options)
        return compat_sys_wait4(pid, stat_addr, options, NULL);
 }
 
-static unsigned int
-ia32_peek (struct task_struct *child, unsigned long addr, unsigned int *val)
-{
-       size_t copied;
-       unsigned int ret;
-
-       copied = access_process_vm(child, addr, val, sizeof(*val), 0);
-       return (copied != sizeof(ret)) ? -EIO : 0;
-}
-
-static unsigned int
-ia32_poke (struct task_struct *child, unsigned long addr, unsigned int val)
-{
-
-       if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val))
-               return -EIO;
-       return 0;
-}
-
 /*
  *  The order in which registers are stored in the ptrace regs structure
  */
@@ -1525,49 +1491,15 @@ restore_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __u
        return 0;
 }
 
-asmlinkage long
-sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data)
+long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
+       compat_ulong_t caddr, compat_ulong_t cdata)
 {
-       struct task_struct *child;
-       unsigned int value, tmp;
+       unsigned long addr = caddr;
+       unsigned long data = cdata;
+       unsigned int tmp;
        long i, ret;
 
-       lock_kernel();
-       if (request == PTRACE_TRACEME) {
-               ret = ptrace_traceme();
-               goto out;
-       }
-
-       child = ptrace_get_task_struct(pid);
-       if (IS_ERR(child)) {
-               ret = PTR_ERR(child);
-               goto out;
-       }
-
-       if (request == PTRACE_ATTACH) {
-               ret = sys_ptrace(request, pid, addr, data);
-               goto out_tsk;
-       }
-
-       ret = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (ret < 0)
-               goto out_tsk;
-
        switch (request) {
-             case PTRACE_PEEKTEXT:
-             case PTRACE_PEEKDATA:     /* read word at location addr */
-               ret = ia32_peek(child, addr, &value);
-               if (ret == 0)
-                       ret = put_user(value, (unsigned int __user *) compat_ptr(data));
-               else
-                       ret = -EIO;
-               goto out_tsk;
-
-             case PTRACE_POKETEXT:
-             case PTRACE_POKEDATA:     /* write the word at location addr */
-               ret = ia32_poke(child, addr, data);
-               goto out_tsk;
-
              case PTRACE_PEEKUSR:      /* read word at addr in USER area */
                ret = -EIO;
                if ((addr & 3) || addr > 17*sizeof(int))
@@ -1632,27 +1564,9 @@ sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data)
                                            compat_ptr(data));
                break;
 
-             case PTRACE_GETEVENTMSG:   
-               ret = put_user(child->ptrace_message, (unsigned int __user *) compat_ptr(data));
-               break;
-
-             case PTRACE_SYSCALL:      /* continue, stop after next syscall */
-             case PTRACE_CONT:         /* restart after signal. */
-             case PTRACE_KILL:
-             case PTRACE_SINGLESTEP:   /* execute chile for one instruction */
-             case PTRACE_DETACH:       /* detach a process */
-               ret = sys_ptrace(request, pid, addr, data);
-               break;
-
              default:
-               ret = ptrace_request(child, request, addr, data);
-               break;
-
+               return compat_ptrace_request(child, request, caddr, cdata);
        }
-  out_tsk:
-       put_task_struct(child);
-  out:
-       unlock_kernel();
        return ret;
 }
 
@@ -1703,14 +1617,6 @@ out:
        return ret;
 }
 
-asmlinkage int
-sys32_pause (void)
-{
-       current->state = TASK_INTERRUPTIBLE;
-       schedule();
-       return -ERESTARTNOHAND;
-}
-
 asmlinkage int
 sys32_msync (unsigned int start, unsigned int len, int flags)
 {
index f034020398962d34987431971c4f9c33006597aa..e90c40ec9edf282903cbd3099faac3131ea6de25 100644 (file)
  */
 #define __IA64_BREAK_SYSCALL           0x100000
 
+/*
+ * Xen specific break numbers:
+ */
+#define __IA64_XEN_HYPERCALL           0x1000
+/* [__IA64_XEN_HYPERPRIVOP_START, __IA64_XEN_HYPERPRIVOP_MAX] is used
+   for xen hyperprivops */
+#define __IA64_XEN_HYPERPRIVOP_START   0x1
+#define __IA64_XEN_HYPERPRIVOP_MAX     0x1a
+
 #endif /* _ASM_IA64_BREAK_H */
index afcfbda76e20f3f5914b579d16e0dae9c7f83249..c8ce2719fee82b8d7adab3dc24304b2e119be5ae 100644 (file)
@@ -34,6 +34,8 @@ do {                                          \
 #define flush_dcache_mmap_unlock(mapping)      do { } while (0)
 
 extern void flush_icache_range (unsigned long start, unsigned long end);
+extern void clflush_cache_range(void *addr, int size);
+
 
 #define flush_icache_user_range(vma, page, user_addr, len)                                     \
 do {                                                                                           \
index 3db6daf7f25125dc36e45ff6cb4e360be3d399f3..41ab85d66f33f8228cfa62da8ea8c88ef1888ea3 100644 (file)
@@ -10,6 +10,9 @@ struct dev_archdata {
 #ifdef CONFIG_ACPI
        void    *acpi_handle;
 #endif
+#ifdef CONFIG_DMAR
+       void *iommu; /* hook for IOMMU specific extension */
+#endif
 };
 
 #endif /* _ASM_IA64_DEVICE_H */
index 06ff1ba21465a38dff682a5b19d0a6a05eab938a..bbab7e2b0fc92f3f546a48fea7095d040975422b 100644 (file)
@@ -7,6 +7,49 @@
  */
 #include <asm/machvec.h>
 #include <linux/scatterlist.h>
+#include <asm/swiotlb.h>
+
+struct dma_mapping_ops {
+       int             (*mapping_error)(struct device *dev,
+                                        dma_addr_t dma_addr);
+       void*           (*alloc_coherent)(struct device *dev, size_t size,
+                               dma_addr_t *dma_handle, gfp_t gfp);
+       void            (*free_coherent)(struct device *dev, size_t size,
+                               void *vaddr, dma_addr_t dma_handle);
+       dma_addr_t      (*map_single)(struct device *hwdev, unsigned long ptr,
+                               size_t size, int direction);
+       void            (*unmap_single)(struct device *dev, dma_addr_t addr,
+                               size_t size, int direction);
+       void            (*sync_single_for_cpu)(struct device *hwdev,
+                               dma_addr_t dma_handle, size_t size,
+                               int direction);
+       void            (*sync_single_for_device)(struct device *hwdev,
+                               dma_addr_t dma_handle, size_t size,
+                               int direction);
+       void            (*sync_single_range_for_cpu)(struct device *hwdev,
+                               dma_addr_t dma_handle, unsigned long offset,
+                               size_t size, int direction);
+       void            (*sync_single_range_for_device)(struct device *hwdev,
+                               dma_addr_t dma_handle, unsigned long offset,
+                               size_t size, int direction);
+       void            (*sync_sg_for_cpu)(struct device *hwdev,
+                               struct scatterlist *sg, int nelems,
+                               int direction);
+       void            (*sync_sg_for_device)(struct device *hwdev,
+                               struct scatterlist *sg, int nelems,
+                               int direction);
+       int             (*map_sg)(struct device *hwdev, struct scatterlist *sg,
+                               int nents, int direction);
+       void            (*unmap_sg)(struct device *hwdev,
+                               struct scatterlist *sg, int nents,
+                               int direction);
+       int             (*dma_supported_op)(struct device *hwdev, u64 mask);
+       int             is_phys;
+};
+
+extern struct dma_mapping_ops *dma_ops;
+extern struct ia64_machine_vector ia64_mv;
+extern void set_iommu_machvec(void);
 
 #define dma_alloc_coherent(dev, size, handle, gfp)     \
        platform_dma_alloc_coherent(dev, size, handle, (gfp) | GFP_DMA)
@@ -96,4 +139,11 @@ dma_cache_sync (struct device *dev, void *vaddr, size_t size,
 
 #define dma_is_consistent(d, h)        (1)     /* all we do is coherent memory... */
 
+static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
+{
+       return dma_ops;
+}
+
+
+
 #endif /* _ASM_IA64_DMA_MAPPING_H */
diff --git a/arch/ia64/include/asm/iommu.h b/arch/ia64/include/asm/iommu.h
new file mode 100644 (file)
index 0000000..5fb2bb9
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef _ASM_IA64_IOMMU_H
+#define _ASM_IA64_IOMMU_H 1
+
+#define cpu_has_x2apic 0
+/* 10 seconds */
+#define DMAR_OPERATION_TIMEOUT (((cycles_t) local_cpu_data->itc_freq)*10)
+
+extern void pci_iommu_shutdown(void);
+extern void no_iommu_init(void);
+extern int force_iommu, no_iommu;
+extern int iommu_detected;
+extern void iommu_dma_init(void);
+extern void machvec_init(const char *name);
+extern int forbid_dac;
+
+#endif
index aefcdfee7f234070f968dd5dbea5709b3fb769bf..39e65f6639f5a780b163c40c7412b19c56fe12e3 100644 (file)
@@ -32,7 +32,7 @@
 #define IA64_TR_CURRENT_STACK  1       /* dtr1: maps kernel's memory- & register-stacks */
 
 #define IA64_TR_ALLOC_BASE     2       /* itr&dtr: Base of dynamic TR resource*/
-#define IA64_TR_ALLOC_MAX      32      /* Max number for dynamic use*/
+#define IA64_TR_ALLOC_MAX      64      /* Max number for dynamic use*/
 
 /* Processor status register bits: */
 #define IA64_PSR_BE_BIT                1
index 2b850ccafef58105192e0ba5b1aab6b555ddc811..1ea28bcee33be27b8bc141c15733837d4e0c0303 100644 (file)
@@ -120,6 +120,8 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *);
 #  include <asm/machvec_hpsim.h>
 # elif defined (CONFIG_IA64_DIG)
 #  include <asm/machvec_dig.h>
+# elif defined(CONFIG_IA64_DIG_VTD)
+#  include <asm/machvec_dig_vtd.h>
 # elif defined (CONFIG_IA64_HP_ZX1)
 #  include <asm/machvec_hpzx1.h>
 # elif defined (CONFIG_IA64_HP_ZX1_SWIOTLB)
@@ -128,6 +130,8 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *);
 #  include <asm/machvec_sn2.h>
 # elif defined (CONFIG_IA64_SGI_UV)
 #  include <asm/machvec_uv.h>
+# elif defined (CONFIG_IA64_XEN_GUEST)
+#  include <asm/machvec_xen.h>
 # elif defined (CONFIG_IA64_GENERIC)
 
 # ifdef MACHVEC_PLATFORM_HEADER
diff --git a/arch/ia64/include/asm/machvec_dig_vtd.h b/arch/ia64/include/asm/machvec_dig_vtd.h
new file mode 100644 (file)
index 0000000..3400b56
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef _ASM_IA64_MACHVEC_DIG_VTD_h
+#define _ASM_IA64_MACHVEC_DIG_VTD_h
+
+extern ia64_mv_setup_t                 dig_setup;
+extern ia64_mv_dma_alloc_coherent      vtd_alloc_coherent;
+extern ia64_mv_dma_free_coherent       vtd_free_coherent;
+extern ia64_mv_dma_map_single_attrs    vtd_map_single_attrs;
+extern ia64_mv_dma_unmap_single_attrs  vtd_unmap_single_attrs;
+extern ia64_mv_dma_map_sg_attrs                vtd_map_sg_attrs;
+extern ia64_mv_dma_unmap_sg_attrs      vtd_unmap_sg_attrs;
+extern ia64_mv_dma_supported           iommu_dma_supported;
+extern ia64_mv_dma_mapping_error       vtd_dma_mapping_error;
+extern ia64_mv_dma_init                        pci_iommu_alloc;
+
+/*
+ * This stuff has dual use!
+ *
+ * For a generic kernel, the macros are used to initialize the
+ * platform's machvec structure.  When compiling a non-generic kernel,
+ * the macros are used directly.
+ */
+#define platform_name                          "dig_vtd"
+#define platform_setup                         dig_setup
+#define platform_dma_init                      pci_iommu_alloc
+#define platform_dma_alloc_coherent            vtd_alloc_coherent
+#define platform_dma_free_coherent             vtd_free_coherent
+#define platform_dma_map_single_attrs          vtd_map_single_attrs
+#define platform_dma_unmap_single_attrs                vtd_unmap_single_attrs
+#define platform_dma_map_sg_attrs              vtd_map_sg_attrs
+#define platform_dma_unmap_sg_attrs            vtd_unmap_sg_attrs
+#define platform_dma_sync_single_for_cpu       machvec_dma_sync_single
+#define platform_dma_sync_sg_for_cpu           machvec_dma_sync_sg
+#define platform_dma_sync_single_for_device    machvec_dma_sync_single
+#define platform_dma_sync_sg_for_device                machvec_dma_sync_sg
+#define platform_dma_supported                 iommu_dma_supported
+#define platform_dma_mapping_error             vtd_dma_mapping_error
+
+#endif /* _ASM_IA64_MACHVEC_DIG_VTD_h */
index 7f21249fba3fd2193b811c156484f1e2b95a1120..ef964b2868425cf161b98cedf9060be0b63bfad9 100644 (file)
@@ -1,3 +1,4 @@
+#include <asm/iommu.h>
 #include <asm/machvec.h>
 
 extern ia64_mv_send_ipi_t ia64_send_ipi;
diff --git a/arch/ia64/include/asm/machvec_xen.h b/arch/ia64/include/asm/machvec_xen.h
new file mode 100644 (file)
index 0000000..55f9228
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef _ASM_IA64_MACHVEC_XEN_h
+#define _ASM_IA64_MACHVEC_XEN_h
+
+extern ia64_mv_setup_t                 dig_setup;
+extern ia64_mv_cpu_init_t              xen_cpu_init;
+extern ia64_mv_irq_init_t              xen_irq_init;
+extern ia64_mv_send_ipi_t              xen_platform_send_ipi;
+
+/*
+ * This stuff has dual use!
+ *
+ * For a generic kernel, the macros are used to initialize the
+ * platform's machvec structure.  When compiling a non-generic kernel,
+ * the macros are used directly.
+ */
+#define platform_name                          "xen"
+#define platform_setup                         dig_setup
+#define platform_cpu_init                      xen_cpu_init
+#define platform_irq_init                      xen_irq_init
+#define platform_send_ipi                      xen_platform_send_ipi
+
+#endif /* _ASM_IA64_MACHVEC_XEN_h */
index 7245a5781594932ee6a8b3d7cab5b1c3ec25939f..6bc96ee54327a5aa2fefd08f5d87e57a25e7cf2c 100644 (file)
  *     - crash dumping code reserved region
  *     - Kernel memory map built from EFI memory map
  *     - ELF core header
+ *     - xen start info if CONFIG_XEN
  *
  * More could be added if necessary
  */
-#define IA64_MAX_RSVD_REGIONS 8
+#define IA64_MAX_RSVD_REGIONS 9
 
 struct rsvd_region {
        unsigned long start;    /* virtual address of beginning of element */
index c8efbf7b849ef4959f606bd6e4d3afd0b78f9199..0a1026cca4fab0bd68d4ca1158dfb3466c580729 100644 (file)
        ;;                                      \
        movl clob = PARAVIRT_POISON;            \
        ;;
+# define CLOBBER_PRED(pred_clob)               \
+       ;;                                      \
+       cmp.eq pred_clob, p0 = r0, r0           \
+       ;;
 #else
-# define CLOBBER(clob)         /* nothing */
+# define CLOBBER(clob)                 /* nothing */
+# define CLOBBER_PRED(pred_clob)       /* nothing */
 #endif
 
 #define MOV_FROM_IFA(reg)      \
 
 #define SSM_PSR_I(pred, pred_clob, clob)       \
 (pred) ssm psr.i                               \
-       CLOBBER(clob)
+       CLOBBER(clob)                           \
+       CLOBBER_PRED(pred_clob)
 
 #define RSM_PSR_I(pred, clob0, clob1)  \
 (pred) rsm psr.i                       \
diff --git a/arch/ia64/include/asm/native/pvchk_inst.h b/arch/ia64/include/asm/native/pvchk_inst.h
new file mode 100644 (file)
index 0000000..b8e6eb1
--- /dev/null
@@ -0,0 +1,263 @@
+#ifndef _ASM_NATIVE_PVCHK_INST_H
+#define _ASM_NATIVE_PVCHK_INST_H
+
+/******************************************************************************
+ * arch/ia64/include/asm/native/pvchk_inst.h
+ * Checker for paravirtualizations of privileged operations.
+ *
+ * Copyright (C) 2005 Hewlett-Packard Co
+ *      Dan Magenheimer <dan.magenheimer@hp.com>
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * 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
+ *
+ */
+
+/**********************************************
+ * Instructions paravirtualized for correctness
+ **********************************************/
+
+/* "fc" and "thash" are privilege-sensitive instructions, meaning they
+ *  may have different semantics depending on whether they are executed
+ *  at PL0 vs PL!=0.  When paravirtualized, these instructions mustn't
+ *  be allowed to execute directly, lest incorrect semantics result.
+ */
+
+#define fc     .error "fc should not be used directly."
+#define thash  .error "thash should not be used directly."
+
+/* Note that "ttag" and "cover" are also privilege-sensitive; "ttag"
+ * is not currently used (though it may be in a long-format VHPT system!)
+ * and the semantics of cover only change if psr.ic is off which is very
+ * rare (and currently non-existent outside of assembly code
+ */
+#define ttag   .error "ttag should not be used directly."
+#define cover  .error "cover should not be used directly."
+
+/* There are also privilege-sensitive registers.  These registers are
+ * readable at any privilege level but only writable at PL0.
+ */
+#define cpuid  .error "cpuid should not be used directly."
+#define pmd    .error "pmd should not be used directly."
+
+/*
+ * mov ar.eflag =
+ * mov = ar.eflag
+ */
+
+/**********************************************
+ * Instructions paravirtualized for performance
+ **********************************************/
+/*
+ * Those instructions include '.' which can't be handled by cpp.
+ * or can't be handled by cpp easily.
+ * They are handled by sed instead of cpp.
+ */
+
+/* for .S
+ * itc.i
+ * itc.d
+ *
+ * bsw.0
+ * bsw.1
+ *
+ * ssm psr.ic | PSR_DEFAULT_BITS
+ * ssm psr.ic
+ * rsm psr.ic
+ * ssm psr.i
+ * rsm psr.i
+ * rsm psr.i | psr.ic
+ * rsm psr.dt
+ * ssm psr.dt
+ *
+ * mov = cr.ifa
+ * mov = cr.itir
+ * mov = cr.isr
+ * mov = cr.iha
+ * mov = cr.ipsr
+ * mov = cr.iim
+ * mov = cr.iip
+ * mov = cr.ivr
+ * mov = psr
+ *
+ * mov cr.ifa =
+ * mov cr.itir =
+ * mov cr.iha =
+ * mov cr.ipsr =
+ * mov cr.ifs =
+ * mov cr.iip =
+ * mov cr.kr =
+ */
+
+/* for intrinsics
+ * ssm psr.i
+ * rsm psr.i
+ * mov = psr
+ * mov = ivr
+ * mov = tpr
+ * mov cr.itm =
+ * mov eoi =
+ * mov rr[] =
+ * mov = rr[]
+ * mov = kr
+ * mov kr =
+ * ptc.ga
+ */
+
+/*************************************************************
+ * define paravirtualized instrcution macros as nop to ingore.
+ * and check whether arguments are appropriate.
+ *************************************************************/
+
+/* check whether reg is a regular register */
+.macro is_rreg_in reg
+       .ifc "\reg", "r0"
+               nop 0
+               .exitm
+       .endif
+       ;;
+       mov \reg = r0
+       ;;
+.endm
+#define IS_RREG_IN(reg)        is_rreg_in reg ;
+
+#define IS_RREG_OUT(reg)                       \
+       ;;                                      \
+       mov reg = r0                            \
+       ;;
+
+#define IS_RREG_CLOB(reg)      IS_RREG_OUT(reg)
+
+/* check whether pred is a predicate register */
+#define IS_PRED_IN(pred)                       \
+       ;;                                      \
+       (pred)  nop 0                           \
+       ;;
+
+#define IS_PRED_OUT(pred)                      \
+       ;;                                      \
+       cmp.eq pred, p0 = r0, r0                \
+       ;;
+
+#define IS_PRED_CLOB(pred)     IS_PRED_OUT(pred)
+
+
+#define DO_SAVE_MIN(__COVER, SAVE_IFS, EXTRA, WORKAROUND)      \
+       nop 0
+#define MOV_FROM_IFA(reg)                      \
+       IS_RREG_OUT(reg)
+#define MOV_FROM_ITIR(reg)                     \
+       IS_RREG_OUT(reg)
+#define MOV_FROM_ISR(reg)                      \
+       IS_RREG_OUT(reg)
+#define MOV_FROM_IHA(reg)                      \
+       IS_RREG_OUT(reg)
+#define MOV_FROM_IPSR(pred, reg)               \
+       IS_PRED_IN(pred)                        \
+       IS_RREG_OUT(reg)
+#define MOV_FROM_IIM(reg)                      \
+       IS_RREG_OUT(reg)
+#define MOV_FROM_IIP(reg)                      \
+       IS_RREG_OUT(reg)
+#define MOV_FROM_IVR(reg, clob)                        \
+       IS_RREG_OUT(reg)                        \
+       IS_RREG_CLOB(clob)
+#define MOV_FROM_PSR(pred, reg, clob)          \
+       IS_PRED_IN(pred)                        \
+       IS_RREG_OUT(reg)                        \
+       IS_RREG_CLOB(clob)
+#define MOV_TO_IFA(reg, clob)                  \
+       IS_RREG_IN(reg)                         \
+       IS_RREG_CLOB(clob)
+#define MOV_TO_ITIR(pred, reg, clob)           \
+       IS_PRED_IN(pred)                        \
+       IS_RREG_IN(reg)                         \
+       IS_RREG_CLOB(clob)
+#define MOV_TO_IHA(pred, reg, clob)            \
+       IS_PRED_IN(pred)                        \
+       IS_RREG_IN(reg)                         \
+       IS_RREG_CLOB(clob)
+#define MOV_TO_IPSR(pred, reg, clob)           \
+       IS_PRED_IN(pred)                        \
+       IS_RREG_IN(reg)                         \
+       IS_RREG_CLOB(clob)
+#define MOV_TO_IFS(pred, reg, clob)            \
+       IS_PRED_IN(pred)                        \
+       IS_RREG_IN(reg)                         \
+       IS_RREG_CLOB(clob)
+#define MOV_TO_IIP(reg, clob)                  \
+       IS_RREG_IN(reg)                         \
+       IS_RREG_CLOB(clob)
+#define MOV_TO_KR(kr, reg, clob0, clob1)       \
+       IS_RREG_IN(reg)                         \
+       IS_RREG_CLOB(clob0)                     \
+       IS_RREG_CLOB(clob1)
+#define ITC_I(pred, reg, clob)                 \
+       IS_PRED_IN(pred)                        \
+       IS_RREG_IN(reg)                         \
+       IS_RREG_CLOB(clob)
+#define ITC_D(pred, reg, clob)                 \
+       IS_PRED_IN(pred)                        \
+       IS_RREG_IN(reg)                         \
+       IS_RREG_CLOB(clob)
+#define ITC_I_AND_D(pred_i, pred_d, reg, clob) \
+       IS_PRED_IN(pred_i)                      \
+       IS_PRED_IN(pred_d)                      \
+       IS_RREG_IN(reg)                         \
+       IS_RREG_CLOB(clob)
+#define THASH(pred, reg0, reg1, clob)          \
+       IS_PRED_IN(pred)                        \
+       IS_RREG_OUT(reg0)                       \
+       IS_RREG_IN(reg1)                        \
+       IS_RREG_CLOB(clob)
+#define SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(clob0, clob1)   \
+       IS_RREG_CLOB(clob0)                                     \
+       IS_RREG_CLOB(clob1)
+#define SSM_PSR_IC_AND_SRLZ_D(clob0, clob1)    \
+       IS_RREG_CLOB(clob0)                     \
+       IS_RREG_CLOB(clob1)
+#define RSM_PSR_IC(clob)                       \
+       IS_RREG_CLOB(clob)
+#define SSM_PSR_I(pred, pred_clob, clob)       \
+       IS_PRED_IN(pred)                        \
+       IS_PRED_CLOB(pred_clob)                 \
+       IS_RREG_CLOB(clob)
+#define RSM_PSR_I(pred, clob0, clob1)          \
+       IS_PRED_IN(pred)                        \
+       IS_RREG_CLOB(clob0)                     \
+       IS_RREG_CLOB(clob1)
+#define RSM_PSR_I_IC(clob0, clob1, clob2)      \
+       IS_RREG_CLOB(clob0)                     \
+       IS_RREG_CLOB(clob1)                     \
+       IS_RREG_CLOB(clob2)
+#define RSM_PSR_DT                             \
+       nop 0
+#define SSM_PSR_DT_AND_SRLZ_I                  \
+       nop 0
+#define BSW_0(clob0, clob1, clob2)             \
+       IS_RREG_CLOB(clob0)                     \
+       IS_RREG_CLOB(clob1)                     \
+       IS_RREG_CLOB(clob2)
+#define BSW_1(clob0, clob1)                    \
+       IS_RREG_CLOB(clob0)                     \
+       IS_RREG_CLOB(clob1)
+#define COVER                                  \
+       nop 0
+#define RFI                                    \
+       br.ret.sptk.many rp /* defining nop causes dependency error */
+
+#endif /* _ASM_NATIVE_PVCHK_INST_H */
index 660cab044834b448b1b82e67361f62db1d20384f..2bf3636473fe9c5b826b53488f00ff4aa5a1f33b 100644 (file)
@@ -117,7 +117,7 @@ static inline void paravirt_post_smp_prepare_boot_cpu(void)
 struct pv_iosapic_ops {
        void (*pcat_compat_init)(void);
 
-       struct irq_chip *(*get_irq_chip)(unsigned long trigger);
+       struct irq_chip *(*__get_irq_chip)(unsigned long trigger);
 
        unsigned int (*__read)(char __iomem *iosapic, unsigned int reg);
        void (*__write)(char __iomem *iosapic, unsigned int reg, u32 val);
@@ -135,7 +135,7 @@ iosapic_pcat_compat_init(void)
 static inline struct irq_chip*
 iosapic_get_irq_chip(unsigned long trigger)
 {
-       return pv_iosapic_ops.get_irq_chip(trigger);
+       return pv_iosapic_ops.__get_irq_chip(trigger);
 }
 
 static inline unsigned int
index 0149097b736d70bd5e4d2f73801b5805ffe8a88a..1d660d89db0dc6ebb3f6814a1a72976dc9b12322 100644 (file)
@@ -95,16 +95,8 @@ extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
                                enum pci_mmap_state mmap_state, int write_combine);
 #define HAVE_PCI_LEGACY
 extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
-                                     struct vm_area_struct *vma);
-extern ssize_t pci_read_legacy_io(struct kobject *kobj,
-                                 struct bin_attribute *bin_attr,
-                                 char *buf, loff_t off, size_t count);
-extern ssize_t pci_write_legacy_io(struct kobject *kobj,
-                                  struct bin_attribute *bin_attr,
-                                  char *buf, loff_t off, size_t count);
-extern int pci_mmap_legacy_mem(struct kobject *kobj,
-                              struct bin_attribute *attr,
-                              struct vm_area_struct *vma);
+                                     struct vm_area_struct *vma,
+                                     enum pci_mmap_state mmap_state);
 
 #define pci_get_legacy_mem platform_pci_get_legacy_mem
 #define pci_legacy_read platform_pci_legacy_read
@@ -164,4 +156,7 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
        return channel ? isa_irq_to_vector(15) : isa_irq_to_vector(14);
 }
 
+#ifdef CONFIG_DMAR
+extern void pci_iommu_alloc(void);
+#endif
 #endif /* _ASM_IA64_PCI_H */
index 15f8dcfe6eeef8d675d07cb13d7aa71ceea0fc00..6417c1ecb44ec47192f70ec6a2f009a502b5022a 100644 (file)
@@ -240,6 +240,12 @@ struct switch_stack {
  */
 # define instruction_pointer(regs) ((regs)->cr_iip + ia64_psr(regs)->ri)
 
+static inline unsigned long user_stack_pointer(struct pt_regs *regs)
+{
+       /* FIXME: should this be bspstore + nr_dirty regs? */
+       return regs->ar_bspstore;
+}
+
 #define regs_return_value(regs) ((regs)->r8)
 
 /* Conserve space in histogram by encoding slot bits in address
@@ -319,6 +325,8 @@ struct switch_stack {
   #define arch_has_block_step()   (1)
   extern void user_enable_block_step(struct task_struct *);
 
+#define __ARCH_WANT_COMPAT_SYS_PTRACE
+
 #endif /* !__KERNEL__ */
 
 /* pt_all_user_regs is used for PTRACE_GETREGS PTRACE_SETREGS */
diff --git a/arch/ia64/include/asm/pvclock-abi.h b/arch/ia64/include/asm/pvclock-abi.h
new file mode 100644 (file)
index 0000000..44ef9ef
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * same structure to x86's
+ * Hopefully asm-x86/pvclock-abi.h would be moved to somewhere more generic.
+ * For now, define same duplicated definitions.
+ */
+
+#ifndef _ASM_IA64__PVCLOCK_ABI_H
+#define _ASM_IA64__PVCLOCK_ABI_H
+#ifndef __ASSEMBLY__
+
+/*
+ * These structs MUST NOT be changed.
+ * They are the ABI between hypervisor and guest OS.
+ * Both Xen and KVM are using this.
+ *
+ * pvclock_vcpu_time_info holds the system time and the tsc timestamp
+ * of the last update. So the guest can use the tsc delta to get a
+ * more precise system time.  There is one per virtual cpu.
+ *
+ * pvclock_wall_clock references the point in time when the system
+ * time was zero (usually boot time), thus the guest calculates the
+ * current wall clock by adding the system time.
+ *
+ * Protocol for the "version" fields is: hypervisor raises it (making
+ * it uneven) before it starts updating the fields and raises it again
+ * (making it even) when it is done.  Thus the guest can make sure the
+ * time values it got are consistent by checking the version before
+ * and after reading them.
+ */
+
+struct pvclock_vcpu_time_info {
+       u32   version;
+       u32   pad0;
+       u64   tsc_timestamp;
+       u64   system_time;
+       u32   tsc_to_system_mul;
+       s8    tsc_shift;
+       u8    pad[3];
+} __attribute__((__packed__)); /* 32 bytes */
+
+struct pvclock_wall_clock {
+       u32   version;
+       u32   sec;
+       u32   nsec;
+} __attribute__((__packed__));
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_IA64__PVCLOCK_ABI_H */
diff --git a/arch/ia64/include/asm/swiotlb.h b/arch/ia64/include/asm/swiotlb.h
new file mode 100644 (file)
index 0000000..fb79423
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef ASM_IA64__SWIOTLB_H
+#define ASM_IA64__SWIOTLB_H
+
+#include <linux/dma-mapping.h>
+
+/* SWIOTLB interface */
+
+extern dma_addr_t swiotlb_map_single(struct device *hwdev, void *ptr,
+                                    size_t size, int dir);
+extern void *swiotlb_alloc_coherent(struct device *hwdev, size_t size,
+                                   dma_addr_t *dma_handle, gfp_t flags);
+extern void swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
+                                size_t size, int dir);
+extern void swiotlb_sync_single_for_cpu(struct device *hwdev,
+                                       dma_addr_t dev_addr,
+                                       size_t size, int dir);
+extern void swiotlb_sync_single_for_device(struct device *hwdev,
+                                          dma_addr_t dev_addr,
+                                          size_t size, int dir);
+extern void swiotlb_sync_single_range_for_cpu(struct device *hwdev,
+                                             dma_addr_t dev_addr,
+                                             unsigned long offset,
+                                             size_t size, int dir);
+extern void swiotlb_sync_single_range_for_device(struct device *hwdev,
+                                                dma_addr_t dev_addr,
+                                                unsigned long offset,
+                                                size_t size, int dir);
+extern void swiotlb_sync_sg_for_cpu(struct device *hwdev,
+                                   struct scatterlist *sg, int nelems,
+                                   int dir);
+extern void swiotlb_sync_sg_for_device(struct device *hwdev,
+                                      struct scatterlist *sg, int nelems,
+                                      int dir);
+extern int swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg,
+                         int nents, int direction);
+extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg,
+                            int nents, int direction);
+extern int swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr);
+extern void swiotlb_free_coherent(struct device *hwdev, size_t size,
+                                 void *vaddr, dma_addr_t dma_handle);
+extern int swiotlb_dma_supported(struct device *hwdev, u64 mask);
+extern void swiotlb_init(void);
+
+extern int swiotlb_force;
+
+#ifdef CONFIG_SWIOTLB
+extern int swiotlb;
+extern void pci_swiotlb_init(void);
+#else
+#define swiotlb 0
+static inline void pci_swiotlb_init(void)
+{
+}
+#endif
+
+#endif /* ASM_IA64__SWIOTLB_H */
diff --git a/arch/ia64/include/asm/sync_bitops.h b/arch/ia64/include/asm/sync_bitops.h
new file mode 100644 (file)
index 0000000..593c12e
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef _ASM_IA64_SYNC_BITOPS_H
+#define _ASM_IA64_SYNC_BITOPS_H
+
+/*
+ * Copyright (C) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *
+ * Based on synch_bitops.h which Dan Magenhaimer wrote.
+ *
+ * bit operations which provide guaranteed strong synchronisation
+ * when communicating with Xen or other guest OSes running on other CPUs.
+ */
+
+static inline void sync_set_bit(int nr, volatile void *addr)
+{
+       set_bit(nr, addr);
+}
+
+static inline void sync_clear_bit(int nr, volatile void *addr)
+{
+       clear_bit(nr, addr);
+}
+
+static inline void sync_change_bit(int nr, volatile void *addr)
+{
+       change_bit(nr, addr);
+}
+
+static inline int sync_test_and_set_bit(int nr, volatile void *addr)
+{
+       return test_and_set_bit(nr, addr);
+}
+
+static inline int sync_test_and_clear_bit(int nr, volatile void *addr)
+{
+       return test_and_clear_bit(nr, addr);
+}
+
+static inline int sync_test_and_change_bit(int nr, volatile void *addr)
+{
+       return test_and_change_bit(nr, addr);
+}
+
+static inline int sync_test_bit(int nr, const volatile void *addr)
+{
+       return test_bit(nr, addr);
+}
+
+#define sync_cmpxchg(ptr, old, new)                            \
+       ((__typeof__(*(ptr)))cmpxchg_acq((ptr), (old), (new)))
+
+#endif /* _ASM_IA64_SYNC_BITOPS_H */
diff --git a/arch/ia64/include/asm/syscall.h b/arch/ia64/include/asm/syscall.h
new file mode 100644 (file)
index 0000000..2f758a4
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Access to user system call parameters and results
+ *
+ * Copyright (C) 2008 Intel Corp.  Shaohua Li <shaohua.li@intel.com>
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * See asm-generic/syscall.h for descriptions of what we must do here.
+ */
+
+#ifndef _ASM_SYSCALL_H
+#define _ASM_SYSCALL_H 1
+
+#include <linux/sched.h>
+#include <linux/err.h>
+
+static inline long syscall_get_nr(struct task_struct *task,
+                                 struct pt_regs *regs)
+{
+       if ((long)regs->cr_ifs < 0) /* Not a syscall */
+               return -1;
+
+#ifdef CONFIG_IA32_SUPPORT
+       if (IS_IA32_PROCESS(regs))
+               return regs->r1;
+#endif
+
+       return regs->r15;
+}
+
+static inline void syscall_rollback(struct task_struct *task,
+                                   struct pt_regs *regs)
+{
+#ifdef CONFIG_IA32_SUPPORT
+       if (IS_IA32_PROCESS(regs))
+               regs->r8 = regs->r1;
+#endif
+
+       /* do nothing */
+}
+
+static inline long syscall_get_error(struct task_struct *task,
+                                    struct pt_regs *regs)
+{
+#ifdef CONFIG_IA32_SUPPORT
+       if (IS_IA32_PROCESS(regs))
+               return regs->r8;
+#endif
+
+       return regs->r10 == -1 ? regs->r8:0;
+}
+
+static inline long syscall_get_return_value(struct task_struct *task,
+                                           struct pt_regs *regs)
+{
+       return regs->r8;
+}
+
+static inline void syscall_set_return_value(struct task_struct *task,
+                                           struct pt_regs *regs,
+                                           int error, long val)
+{
+#ifdef CONFIG_IA32_SUPPORT
+       if (IS_IA32_PROCESS(regs)) {
+               regs->r8 = (long) error ? error : val;
+               return;
+       }
+#endif
+
+       if (error) {
+               /* error < 0, but ia64 uses > 0 return value */
+               regs->r8 = -error;
+               regs->r10 = -1;
+       } else {
+               regs->r8 = val;
+               regs->r10 = 0;
+       }
+}
+
+extern void ia64_syscall_get_set_arguments(struct task_struct *task,
+       struct pt_regs *regs, unsigned int i, unsigned int n,
+       unsigned long *args, int rw);
+static inline void syscall_get_arguments(struct task_struct *task,
+                                        struct pt_regs *regs,
+                                        unsigned int i, unsigned int n,
+                                        unsigned long *args)
+{
+       BUG_ON(i + n > 6);
+
+#ifdef CONFIG_IA32_SUPPORT
+       if (IS_IA32_PROCESS(regs)) {
+               switch (i + n) {
+               case 6:
+                       if (!n--) break;
+                       *args++ = regs->r13;
+               case 5:
+                       if (!n--) break;
+                       *args++ = regs->r15;
+               case 4:
+                       if (!n--) break;
+                       *args++ = regs->r14;
+               case 3:
+                       if (!n--) break;
+                       *args++ = regs->r10;
+               case 2:
+                       if (!n--) break;
+                       *args++ = regs->r9;
+               case 1:
+                       if (!n--) break;
+                       *args++ = regs->r11;
+               case 0:
+                       if (!n--) break;
+               default:
+                       BUG();
+                       break;
+               }
+
+               return;
+       }
+#endif
+       ia64_syscall_get_set_arguments(task, regs, i, n, args, 0);
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+                                        struct pt_regs *regs,
+                                        unsigned int i, unsigned int n,
+                                        unsigned long *args)
+{
+       BUG_ON(i + n > 6);
+
+#ifdef CONFIG_IA32_SUPPORT
+       if (IS_IA32_PROCESS(regs)) {
+               switch (i + n) {
+               case 6:
+                       if (!n--) break;
+                       regs->r13 = *args++;
+               case 5:
+                       if (!n--) break;
+                       regs->r15 = *args++;
+               case 4:
+                       if (!n--) break;
+                       regs->r14 = *args++;
+               case 3:
+                       if (!n--) break;
+                       regs->r10 = *args++;
+               case 2:
+                       if (!n--) break;
+                       regs->r9 = *args++;
+               case 1:
+                       if (!n--) break;
+                       regs->r11 = *args++;
+               case 0:
+                       if (!n--) break;
+               }
+
+               return;
+       }
+#endif
+       ia64_syscall_get_set_arguments(task, regs, i, n, args, 1);
+}
+#endif /* _ASM_SYSCALL_H */
index 7c60fcdd2efdb6f6f79615b051f18c755c4ff69e..ae6922626bf49bbecae323b08e58478bcaeb4e07 100644 (file)
@@ -87,9 +87,6 @@ struct thread_info {
 #define alloc_task_struct()    ((struct task_struct *)__get_free_pages(GFP_KERNEL | __GFP_COMP, KERNEL_STACK_SIZE_ORDER))
 #define free_task_struct(tsk)  free_pages((unsigned long) (tsk), KERNEL_STACK_SIZE_ORDER)
 
-#define tsk_set_notify_resume(tsk) \
-       set_ti_thread_flag(task_thread_info(tsk), TIF_NOTIFY_RESUME)
-extern void tsk_clear_notify_resume(struct task_struct *tsk);
 #endif /* !__ASSEMBLY */
 
 /*
index 05a6baf8a472a5daef978db6858c35a9a0e664bb..4e03cfe74a0c40712c7ff328c0436eca46946e95 100644 (file)
@@ -39,4 +39,6 @@ get_cycles (void)
        return ret;
 }
 
+extern void ia64_cpu_local_tick (void);
+
 #endif /* _ASM_IA64_TIMEX_H */
index d535833aab5e54420a72cd8915f8a87a1dda2fb0..f791576355ad32535951d1a05b762c243da6f3a3 100644 (file)
 # define __ARCH_WANT_SYS_NICE
 # define __ARCH_WANT_SYS_OLD_GETRLIMIT
 # define __ARCH_WANT_SYS_OLDUMOUNT
+# define __ARCH_WANT_SYS_PAUSE
 # define __ARCH_WANT_SYS_SIGPENDING
 # define __ARCH_WANT_SYS_SIGPROCMASK
 # define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
diff --git a/arch/ia64/include/asm/xen/events.h b/arch/ia64/include/asm/xen/events.h
new file mode 100644 (file)
index 0000000..7324878
--- /dev/null
@@ -0,0 +1,50 @@
+/******************************************************************************
+ * arch/ia64/include/asm/xen/events.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * 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 _ASM_IA64_XEN_EVENTS_H
+#define _ASM_IA64_XEN_EVENTS_H
+
+enum ipi_vector {
+       XEN_RESCHEDULE_VECTOR,
+       XEN_IPI_VECTOR,
+       XEN_CMCP_VECTOR,
+       XEN_CPEP_VECTOR,
+
+       XEN_NR_IPIS,
+};
+
+static inline int xen_irqs_disabled(struct pt_regs *regs)
+{
+       return !(ia64_psr(regs)->i);
+}
+
+static inline void xen_do_IRQ(int irq, struct pt_regs *regs)
+{
+       struct pt_regs *old_regs;
+       old_regs = set_irq_regs(regs);
+       irq_enter();
+       __do_IRQ(irq);
+       irq_exit();
+       set_irq_regs(old_regs);
+}
+#define irq_ctx_init(cpu)      do { } while (0)
+
+#endif /* _ASM_IA64_XEN_EVENTS_H */
diff --git a/arch/ia64/include/asm/xen/grant_table.h b/arch/ia64/include/asm/xen/grant_table.h
new file mode 100644 (file)
index 0000000..2b1fae0
--- /dev/null
@@ -0,0 +1,29 @@
+/******************************************************************************
+ * arch/ia64/include/asm/xen/grant_table.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * 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 _ASM_IA64_XEN_GRANT_TABLE_H
+#define _ASM_IA64_XEN_GRANT_TABLE_H
+
+struct vm_struct *xen_alloc_vm_area(unsigned long size);
+void xen_free_vm_area(struct vm_struct *area);
+
+#endif /* _ASM_IA64_XEN_GRANT_TABLE_H */
diff --git a/arch/ia64/include/asm/xen/hypercall.h b/arch/ia64/include/asm/xen/hypercall.h
new file mode 100644 (file)
index 0000000..96fc623
--- /dev/null
@@ -0,0 +1,265 @@
+/******************************************************************************
+ * hypercall.h
+ *
+ * Linux-specific hypervisor handling.
+ *
+ * Copyright (c) 2002-2004, K A Fraser
+ *
+ * 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; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (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
+ * 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 _ASM_IA64_XEN_HYPERCALL_H
+#define _ASM_IA64_XEN_HYPERCALL_H
+
+#include <xen/interface/xen.h>
+#include <xen/interface/physdev.h>
+#include <xen/interface/sched.h>
+#include <asm/xen/xcom_hcall.h>
+struct xencomm_handle;
+extern unsigned long __hypercall(unsigned long a1, unsigned long a2,
+                                unsigned long a3, unsigned long a4,
+                                unsigned long a5, unsigned long cmd);
+
+/*
+ * Assembler stubs for hyper-calls.
+ */
+
+#define _hypercall0(type, name)                                        \
+({                                                             \
+       long __res;                                             \
+       __res = __hypercall(0, 0, 0, 0, 0, __HYPERVISOR_##name);\
+       (type)__res;                                            \
+})
+
+#define _hypercall1(type, name, a1)                            \
+({                                                             \
+       long __res;                                             \
+       __res = __hypercall((unsigned long)a1,                  \
+                            0, 0, 0, 0, __HYPERVISOR_##name);  \
+       (type)__res;                                            \
+})
+
+#define _hypercall2(type, name, a1, a2)                                \
+({                                                             \
+       long __res;                                             \
+       __res = __hypercall((unsigned long)a1,                  \
+                           (unsigned long)a2,                  \
+                           0, 0, 0, __HYPERVISOR_##name);      \
+       (type)__res;                                            \
+})
+
+#define _hypercall3(type, name, a1, a2, a3)                    \
+({                                                             \
+       long __res;                                             \
+       __res = __hypercall((unsigned long)a1,                  \
+                           (unsigned long)a2,                  \
+                           (unsigned long)a3,                  \
+                           0, 0, __HYPERVISOR_##name);         \
+       (type)__res;                                            \
+})
+
+#define _hypercall4(type, name, a1, a2, a3, a4)                        \
+({                                                             \
+       long __res;                                             \
+       __res = __hypercall((unsigned long)a1,                  \
+                           (unsigned long)a2,                  \
+                           (unsigned long)a3,                  \
+                           (unsigned long)a4,                  \
+                           0, __HYPERVISOR_##name);            \
+       (type)__res;                                            \
+})
+
+#define _hypercall5(type, name, a1, a2, a3, a4, a5)            \
+({                                                             \
+       long __res;                                             \
+       __res = __hypercall((unsigned long)a1,                  \
+                           (unsigned long)a2,                  \
+                           (unsigned long)a3,                  \
+                           (unsigned long)a4,                  \
+                           (unsigned long)a5,                  \
+                           __HYPERVISOR_##name);               \
+       (type)__res;                                            \
+})
+
+
+static inline int
+xencomm_arch_hypercall_sched_op(int cmd, struct xencomm_handle *arg)
+{
+       return _hypercall2(int, sched_op_new, cmd, arg);
+}
+
+static inline long
+HYPERVISOR_set_timer_op(u64 timeout)
+{
+       unsigned long timeout_hi = (unsigned long)(timeout >> 32);
+       unsigned long timeout_lo = (unsigned long)timeout;
+       return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi);
+}
+
+static inline int
+xencomm_arch_hypercall_multicall(struct xencomm_handle *call_list,
+                                int nr_calls)
+{
+       return _hypercall2(int, multicall, call_list, nr_calls);
+}
+
+static inline int
+xencomm_arch_hypercall_memory_op(unsigned int cmd, struct xencomm_handle *arg)
+{
+       return _hypercall2(int, memory_op, cmd, arg);
+}
+
+static inline int
+xencomm_arch_hypercall_event_channel_op(int cmd, struct xencomm_handle *arg)
+{
+       return _hypercall2(int, event_channel_op, cmd, arg);
+}
+
+static inline int
+xencomm_arch_hypercall_xen_version(int cmd, struct xencomm_handle *arg)
+{
+       return _hypercall2(int, xen_version, cmd, arg);
+}
+
+static inline int
+xencomm_arch_hypercall_console_io(int cmd, int count,
+                                 struct xencomm_handle *str)
+{
+       return _hypercall3(int, console_io, cmd, count, str);
+}
+
+static inline int
+xencomm_arch_hypercall_physdev_op(int cmd, struct xencomm_handle *arg)
+{
+       return _hypercall2(int, physdev_op, cmd, arg);
+}
+
+static inline int
+xencomm_arch_hypercall_grant_table_op(unsigned int cmd,
+                                     struct xencomm_handle *uop,
+                                     unsigned int count)
+{
+       return _hypercall3(int, grant_table_op, cmd, uop, count);
+}
+
+int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
+
+extern int xencomm_arch_hypercall_suspend(struct xencomm_handle *arg);
+
+static inline int
+xencomm_arch_hypercall_callback_op(int cmd, struct xencomm_handle *arg)
+{
+       return _hypercall2(int, callback_op, cmd, arg);
+}
+
+static inline long
+xencomm_arch_hypercall_vcpu_op(int cmd, int cpu, void *arg)
+{
+       return _hypercall3(long, vcpu_op, cmd, cpu, arg);
+}
+
+static inline int
+HYPERVISOR_physdev_op(int cmd, void *arg)
+{
+       switch (cmd) {
+       case PHYSDEVOP_eoi:
+               return _hypercall1(int, ia64_fast_eoi,
+                                  ((struct physdev_eoi *)arg)->irq);
+       default:
+               return xencomm_hypercall_physdev_op(cmd, arg);
+       }
+}
+
+static inline long
+xencomm_arch_hypercall_opt_feature(struct xencomm_handle *arg)
+{
+       return _hypercall1(long, opt_feature, arg);
+}
+
+/* for balloon driver */
+#define HYPERVISOR_update_va_mapping(va, new_val, flags) (0)
+
+/* Use xencomm to do hypercalls.  */
+#define HYPERVISOR_sched_op xencomm_hypercall_sched_op
+#define HYPERVISOR_event_channel_op xencomm_hypercall_event_channel_op
+#define HYPERVISOR_callback_op xencomm_hypercall_callback_op
+#define HYPERVISOR_multicall xencomm_hypercall_multicall
+#define HYPERVISOR_xen_version xencomm_hypercall_xen_version
+#define HYPERVISOR_console_io xencomm_hypercall_console_io
+#define HYPERVISOR_memory_op xencomm_hypercall_memory_op
+#define HYPERVISOR_suspend xencomm_hypercall_suspend
+#define HYPERVISOR_vcpu_op xencomm_hypercall_vcpu_op
+#define HYPERVISOR_opt_feature xencomm_hypercall_opt_feature
+
+/* to compile gnttab_copy_grant_page() in drivers/xen/core/gnttab.c */
+#define HYPERVISOR_mmu_update(req, count, success_count, domid) ({ BUG(); 0; })
+
+static inline int
+HYPERVISOR_shutdown(
+       unsigned int reason)
+{
+       struct sched_shutdown sched_shutdown = {
+               .reason = reason
+       };
+
+       int rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
+
+       return rc;
+}
+
+/* for netfront.c, netback.c */
+#define MULTI_UVMFLAGS_INDEX 0 /* XXX any value */
+
+static inline void
+MULTI_update_va_mapping(
+       struct multicall_entry *mcl, unsigned long va,
+       pte_t new_val, unsigned long flags)
+{
+       mcl->op = __HYPERVISOR_update_va_mapping;
+       mcl->result = 0;
+}
+
+static inline void
+MULTI_grant_table_op(struct multicall_entry *mcl, unsigned int cmd,
+       void *uop, unsigned int count)
+{
+       mcl->op = __HYPERVISOR_grant_table_op;
+       mcl->args[0] = cmd;
+       mcl->args[1] = (unsigned long)uop;
+       mcl->args[2] = count;
+}
+
+static inline void
+MULTI_mmu_update(struct multicall_entry *mcl, struct mmu_update *req,
+                int count, int *success_count, domid_t domid)
+{
+       mcl->op = __HYPERVISOR_mmu_update;
+       mcl->args[0] = (unsigned long)req;
+       mcl->args[1] = count;
+       mcl->args[2] = (unsigned long)success_count;
+       mcl->args[3] = domid;
+}
+
+#endif /* _ASM_IA64_XEN_HYPERCALL_H */
diff --git a/arch/ia64/include/asm/xen/hypervisor.h b/arch/ia64/include/asm/xen/hypervisor.h
new file mode 100644 (file)
index 0000000..7a804e8
--- /dev/null
@@ -0,0 +1,89 @@
+/******************************************************************************
+ * hypervisor.h
+ *
+ * Linux-specific hypervisor handling.
+ *
+ * Copyright (c) 2002-2004, K A Fraser
+ *
+ * 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; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (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
+ * 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 _ASM_IA64_XEN_HYPERVISOR_H
+#define _ASM_IA64_XEN_HYPERVISOR_H
+
+#ifdef CONFIG_XEN
+
+#include <linux/init.h>
+#include <xen/interface/xen.h>
+#include <xen/interface/version.h>     /* to compile feature.c */
+#include <xen/features.h>              /* to comiple xen-netfront.c */
+#include <asm/xen/hypercall.h>
+
+/* xen_domain_type is set before executing any C code by early_xen_setup */
+enum xen_domain_type {
+       XEN_NATIVE,
+       XEN_PV_DOMAIN,
+       XEN_HVM_DOMAIN,
+};
+
+extern enum xen_domain_type xen_domain_type;
+
+#define xen_domain()           (xen_domain_type != XEN_NATIVE)
+#define xen_pv_domain()                (xen_domain_type == XEN_PV_DOMAIN)
+#define xen_initial_domain()   (xen_pv_domain() && \
+                                (xen_start_info->flags & SIF_INITDOMAIN))
+#define xen_hvm_domain()       (xen_domain_type == XEN_HVM_DOMAIN)
+
+/* deprecated. remove this */
+#define is_running_on_xen()    (xen_domain_type == XEN_PV_DOMAIN)
+
+extern struct shared_info *HYPERVISOR_shared_info;
+extern struct start_info *xen_start_info;
+
+void __init xen_setup_vcpu_info_placement(void);
+void force_evtchn_callback(void);
+
+/* for drivers/xen/balloon/balloon.c */
+#ifdef CONFIG_XEN_SCRUB_PAGES
+#define scrub_pages(_p, _n) memset((void *)(_p), 0, (_n) << PAGE_SHIFT)
+#else
+#define scrub_pages(_p, _n) ((void)0)
+#endif
+
+/* For setup_arch() in arch/ia64/kernel/setup.c */
+void xen_ia64_enable_opt_feature(void);
+
+#else /* CONFIG_XEN */
+
+#define xen_domain()           (0)
+#define xen_pv_domain()                (0)
+#define xen_initial_domain()   (0)
+#define xen_hvm_domain()       (0)
+#define is_running_on_xen()    (0)     /* deprecated. remove this */
+#endif
+
+#define is_initial_xendomain() (0)     /* deprecated. remove this */
+
+#endif /* _ASM_IA64_XEN_HYPERVISOR_H */
diff --git a/arch/ia64/include/asm/xen/inst.h b/arch/ia64/include/asm/xen/inst.h
new file mode 100644 (file)
index 0000000..19c2ae1
--- /dev/null
@@ -0,0 +1,458 @@
+/******************************************************************************
+ * arch/ia64/include/asm/xen/inst.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <asm/xen/privop.h>
+
+#define ia64_ivt                               xen_ivt
+#define DO_SAVE_MIN                            XEN_DO_SAVE_MIN
+
+#define __paravirt_switch_to                   xen_switch_to
+#define __paravirt_leave_syscall               xen_leave_syscall
+#define __paravirt_work_processed_syscall      xen_work_processed_syscall
+#define __paravirt_leave_kernel                        xen_leave_kernel
+#define __paravirt_pending_syscall_end         xen_work_pending_syscall_end
+#define __paravirt_work_processed_syscall_target \
+                                               xen_work_processed_syscall
+
+#define MOV_FROM_IFA(reg)      \
+       movl reg = XSI_IFA;     \
+       ;;                      \
+       ld8 reg = [reg]
+
+#define MOV_FROM_ITIR(reg)     \
+       movl reg = XSI_ITIR;    \
+       ;;                      \
+       ld8 reg = [reg]
+
+#define MOV_FROM_ISR(reg)      \
+       movl reg = XSI_ISR;     \
+       ;;                      \
+       ld8 reg = [reg]
+
+#define MOV_FROM_IHA(reg)      \
+       movl reg = XSI_IHA;     \
+       ;;                      \
+       ld8 reg = [reg]
+
+#define MOV_FROM_IPSR(pred, reg)       \
+(pred) movl reg = XSI_IPSR;            \
+       ;;                              \
+(pred) ld8 reg = [reg]
+
+#define MOV_FROM_IIM(reg)      \
+       movl reg = XSI_IIM;     \
+       ;;                      \
+       ld8 reg = [reg]
+
+#define MOV_FROM_IIP(reg)      \
+       movl reg = XSI_IIP;     \
+       ;;                      \
+       ld8 reg = [reg]
+
+.macro __MOV_FROM_IVR reg, clob
+       .ifc "\reg", "r8"
+               XEN_HYPER_GET_IVR
+               .exitm
+       .endif
+       .ifc "\clob", "r8"
+               XEN_HYPER_GET_IVR
+               ;;
+               mov \reg = r8
+               .exitm
+       .endif
+
+       mov \clob = r8
+       ;;
+       XEN_HYPER_GET_IVR
+       ;;
+       mov \reg = r8
+       ;;
+       mov r8 = \clob
+.endm
+#define MOV_FROM_IVR(reg, clob)        __MOV_FROM_IVR reg, clob
+
+.macro __MOV_FROM_PSR pred, reg, clob
+       .ifc "\reg", "r8"
+               (\pred) XEN_HYPER_GET_PSR;
+               .exitm
+       .endif
+       .ifc "\clob", "r8"
+               (\pred) XEN_HYPER_GET_PSR
+               ;;
+               (\pred) mov \reg = r8
+               .exitm
+       .endif
+
+       (\pred) mov \clob = r8
+       (\pred) XEN_HYPER_GET_PSR
+       ;;
+       (\pred) mov \reg = r8
+       (\pred) mov r8 = \clob
+.endm
+#define MOV_FROM_PSR(pred, reg, clob)  __MOV_FROM_PSR pred, reg, clob
+
+
+#define MOV_TO_IFA(reg, clob)  \
+       movl clob = XSI_IFA;    \
+       ;;                      \
+       st8 [clob] = reg        \
+
+#define MOV_TO_ITIR(pred, reg, clob)   \
+(pred) movl clob = XSI_ITIR;           \
+       ;;                              \
+(pred) st8 [clob] = reg
+
+#define MOV_TO_IHA(pred, reg, clob)    \
+(pred) movl clob = XSI_IHA;            \
+       ;;                              \
+(pred) st8 [clob] = reg
+
+#define MOV_TO_IPSR(pred, reg, clob)   \
+(pred) movl clob = XSI_IPSR;           \
+       ;;                              \
+(pred) st8 [clob] = reg;               \
+       ;;
+
+#define MOV_TO_IFS(pred, reg, clob)    \
+(pred) movl clob = XSI_IFS;            \
+       ;;                              \
+(pred) st8 [clob] = reg;               \
+       ;;
+
+#define MOV_TO_IIP(reg, clob)  \
+       movl clob = XSI_IIP;    \
+       ;;                      \
+       st8 [clob] = reg
+
+.macro ____MOV_TO_KR kr, reg, clob0, clob1
+       .ifc "\clob0", "r9"
+               .error "clob0 \clob0 must not be r9"
+       .endif
+       .ifc "\clob1", "r8"
+               .error "clob1 \clob1 must not be r8"
+       .endif
+
+       .ifnc "\reg", "r9"
+               .ifnc "\clob1", "r9"
+                       mov \clob1 = r9
+               .endif
+               mov r9 = \reg
+       .endif
+       .ifnc "\clob0", "r8"
+               mov \clob0 = r8
+       .endif
+       mov r8 = \kr
+       ;;
+       XEN_HYPER_SET_KR
+
+       .ifnc "\reg", "r9"
+               .ifnc "\clob1", "r9"
+                       mov r9 = \clob1
+               .endif
+       .endif
+       .ifnc "\clob0", "r8"
+               mov r8 = \clob0
+       .endif
+.endm
+
+.macro __MOV_TO_KR kr, reg, clob0, clob1
+       .ifc "\clob0", "r9"
+               ____MOV_TO_KR \kr, \reg, \clob1, \clob0
+               .exitm
+       .endif
+       .ifc "\clob1", "r8"
+               ____MOV_TO_KR \kr, \reg, \clob1, \clob0
+               .exitm
+       .endif
+
+       ____MOV_TO_KR \kr, \reg, \clob0, \clob1
+.endm
+
+#define MOV_TO_KR(kr, reg, clob0, clob1) \
+       __MOV_TO_KR IA64_KR_ ## kr, reg, clob0, clob1
+
+
+.macro __ITC_I pred, reg, clob
+       .ifc "\reg", "r8"
+               (\pred) XEN_HYPER_ITC_I
+               .exitm
+       .endif
+       .ifc "\clob", "r8"
+               (\pred) mov r8 = \reg
+               ;;
+               (\pred) XEN_HYPER_ITC_I
+               .exitm
+       .endif
+
+       (\pred) mov \clob = r8
+       (\pred) mov r8 = \reg
+       ;;
+       (\pred) XEN_HYPER_ITC_I
+       ;;
+       (\pred) mov r8 = \clob
+       ;;
+.endm
+#define ITC_I(pred, reg, clob) __ITC_I pred, reg, clob
+
+.macro __ITC_D pred, reg, clob
+       .ifc "\reg", "r8"
+               (\pred) XEN_HYPER_ITC_D
+               ;;
+               .exitm
+       .endif
+       .ifc "\clob", "r8"
+               (\pred) mov r8 = \reg
+               ;;
+               (\pred) XEN_HYPER_ITC_D
+               ;;
+               .exitm
+       .endif
+
+       (\pred) mov \clob = r8
+       (\pred) mov r8 = \reg
+       ;;
+       (\pred) XEN_HYPER_ITC_D
+       ;;
+       (\pred) mov r8 = \clob
+       ;;
+.endm
+#define ITC_D(pred, reg, clob) __ITC_D pred, reg, clob
+
+.macro __ITC_I_AND_D pred_i, pred_d, reg, clob
+       .ifc "\reg", "r8"
+               (\pred_i)XEN_HYPER_ITC_I
+               ;;
+               (\pred_d)XEN_HYPER_ITC_D
+               ;;
+               .exitm
+       .endif
+       .ifc "\clob", "r8"
+               mov r8 = \reg
+               ;;
+               (\pred_i)XEN_HYPER_ITC_I
+               ;;
+               (\pred_d)XEN_HYPER_ITC_D
+               ;;
+               .exitm
+       .endif
+
+       mov \clob = r8
+       mov r8 = \reg
+       ;;
+       (\pred_i)XEN_HYPER_ITC_I
+       ;;
+       (\pred_d)XEN_HYPER_ITC_D
+       ;;
+       mov r8 = \clob
+       ;;
+.endm
+#define ITC_I_AND_D(pred_i, pred_d, reg, clob) \
+       __ITC_I_AND_D pred_i, pred_d, reg, clob
+
+.macro __THASH pred, reg0, reg1, clob
+       .ifc "\reg0", "r8"
+               (\pred) mov r8 = \reg1
+               (\pred) XEN_HYPER_THASH
+               .exitm
+       .endc
+       .ifc "\reg1", "r8"
+               (\pred) XEN_HYPER_THASH
+               ;;
+               (\pred) mov \reg0 = r8
+               ;;
+               .exitm
+       .endif
+       .ifc "\clob", "r8"
+               (\pred) mov r8 = \reg1
+               (\pred) XEN_HYPER_THASH
+               ;;
+               (\pred) mov \reg0 = r8
+               ;;
+               .exitm
+       .endif
+
+       (\pred) mov \clob = r8
+       (\pred) mov r8 = \reg1
+       (\pred) XEN_HYPER_THASH
+       ;;
+       (\pred) mov \reg0 = r8
+       (\pred) mov r8 = \clob
+       ;;
+.endm
+#define THASH(pred, reg0, reg1, clob) __THASH pred, reg0, reg1, clob
+
+#define SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(clob0, clob1)   \
+       mov clob0 = 1;                                          \
+       movl clob1 = XSI_PSR_IC;                                \
+       ;;                                                      \
+       st4 [clob1] = clob0                                     \
+       ;;
+
+#define SSM_PSR_IC_AND_SRLZ_D(clob0, clob1)    \
+       ;;                                      \
+       srlz.d;                                 \
+       mov clob1 = 1;                          \
+       movl clob0 = XSI_PSR_IC;                \
+       ;;                                      \
+       st4 [clob0] = clob1
+
+#define RSM_PSR_IC(clob)       \
+       movl clob = XSI_PSR_IC; \
+       ;;                      \
+       st4 [clob] = r0;        \
+       ;;
+
+/* pred will be clobbered */
+#define MASK_TO_PEND_OFS    (-1)
+#define SSM_PSR_I(pred, pred_clob, clob)                               \
+(pred) movl clob = XSI_PSR_I_ADDR                                      \
+       ;;                                                              \
+(pred) ld8 clob = [clob]                                               \
+       ;;                                                              \
+       /* if (pred) vpsr.i = 1 */                                      \
+       /* if (pred) (vcpu->vcpu_info->evtchn_upcall_mask)=0 */         \
+(pred) st1 [clob] = r0, MASK_TO_PEND_OFS                               \
+       ;;                                                              \
+       /* if (vcpu->vcpu_info->evtchn_upcall_pending) */               \
+(pred) ld1 clob = [clob]                                               \
+       ;;                                                              \
+(pred) cmp.ne.unc pred_clob, p0 = clob, r0                             \
+       ;;                                                              \
+(pred_clob)XEN_HYPER_SSM_I     /* do areal ssm psr.i */
+
+#define RSM_PSR_I(pred, clob0, clob1)  \
+       movl clob0 = XSI_PSR_I_ADDR;    \
+       mov clob1 = 1;                  \
+       ;;                              \
+       ld8 clob0 = [clob0];            \
+       ;;                              \
+(pred) st1 [clob0] = clob1
+
+#define RSM_PSR_I_IC(clob0, clob1, clob2)              \
+       movl clob0 = XSI_PSR_I_ADDR;                    \
+       movl clob1 = XSI_PSR_IC;                        \
+       ;;                                              \
+       ld8 clob0 = [clob0];                            \
+       mov clob2 = 1;                                  \
+       ;;                                              \
+       /* note: clears both vpsr.i and vpsr.ic! */     \
+       st1 [clob0] = clob2;                            \
+       st4 [clob1] = r0;                               \
+       ;;
+
+#define RSM_PSR_DT             \
+       XEN_HYPER_RSM_PSR_DT
+
+#define SSM_PSR_DT_AND_SRLZ_I  \
+       XEN_HYPER_SSM_PSR_DT
+
+#define BSW_0(clob0, clob1, clob2)                     \
+       ;;                                              \
+       /* r16-r31 all now hold bank1 values */         \
+       mov clob2 = ar.unat;                            \
+       movl clob0 = XSI_BANK1_R16;                     \
+       movl clob1 = XSI_BANK1_R16 + 8;                 \
+       ;;                                              \
+.mem.offset 0, 0; st8.spill [clob0] = r16, 16;         \
+.mem.offset 8, 0; st8.spill [clob1] = r17, 16;         \
+       ;;                                              \
+.mem.offset 0, 0; st8.spill [clob0] = r18, 16;         \
+.mem.offset 8, 0; st8.spill [clob1] = r19, 16;         \
+       ;;                                              \
+.mem.offset 0, 0; st8.spill [clob0] = r20, 16;         \
+.mem.offset 8, 0; st8.spill [clob1] = r21, 16;         \
+       ;;                                              \
+.mem.offset 0, 0; st8.spill [clob0] = r22, 16;         \
+.mem.offset 8, 0; st8.spill [clob1] = r23, 16;         \
+       ;;                                              \
+.mem.offset 0, 0; st8.spill [clob0] = r24, 16;         \
+.mem.offset 8, 0; st8.spill [clob1] = r25, 16;         \
+       ;;                                              \
+.mem.offset 0, 0; st8.spill [clob0] = r26, 16;         \
+.mem.offset 8, 0; st8.spill [clob1] = r27, 16;         \
+       ;;                                              \
+.mem.offset 0, 0; st8.spill [clob0] = r28, 16;         \
+.mem.offset 8, 0; st8.spill [clob1] = r29, 16;         \
+       ;;                                              \
+.mem.offset 0, 0; st8.spill [clob0] = r30, 16;         \
+.mem.offset 8, 0; st8.spill [clob1] = r31, 16;         \
+       ;;                                              \
+       mov clob1 = ar.unat;                            \
+       movl clob0 = XSI_B1NAT;                         \
+       ;;                                              \
+       st8 [clob0] = clob1;                            \
+       mov ar.unat = clob2;                            \
+       movl clob0 = XSI_BANKNUM;                       \
+       ;;                                              \
+       st4 [clob0] = r0
+
+
+       /* FIXME: THIS CODE IS NOT NaT SAFE! */
+#define XEN_BSW_1(clob)                        \
+       mov clob = ar.unat;             \
+       movl r30 = XSI_B1NAT;           \
+       ;;                              \
+       ld8 r30 = [r30];                \
+       mov r31 = 1;                    \
+       ;;                              \
+       mov ar.unat = r30;              \
+       movl r30 = XSI_BANKNUM;         \
+       ;;                              \
+       st4 [r30] = r31;                \
+       movl r30 = XSI_BANK1_R16;       \
+       movl r31 = XSI_BANK1_R16+8;     \
+       ;;                              \
+       ld8.fill r16 = [r30], 16;       \
+       ld8.fill r17 = [r31], 16;       \
+       ;;                              \
+       ld8.fill r18 = [r30], 16;       \
+       ld8.fill r19 = [r31], 16;       \
+       ;;                              \
+       ld8.fill r20 = [r30], 16;       \
+       ld8.fill r21 = [r31], 16;       \
+       ;;                              \
+       ld8.fill r22 = [r30], 16;       \
+       ld8.fill r23 = [r31], 16;       \
+       ;;                              \
+       ld8.fill r24 = [r30], 16;       \
+       ld8.fill r25 = [r31], 16;       \
+       ;;                              \
+       ld8.fill r26 = [r30], 16;       \
+       ld8.fill r27 = [r31], 16;       \
+       ;;                              \
+       ld8.fill r28 = [r30], 16;       \
+       ld8.fill r29 = [r31], 16;       \
+       ;;                              \
+       ld8.fill r30 = [r30];           \
+       ld8.fill r31 = [r31];           \
+       ;;                              \
+       mov ar.unat = clob
+
+#define BSW_1(clob0, clob1)    XEN_BSW_1(clob1)
+
+
+#define COVER  \
+       XEN_HYPER_COVER
+
+#define RFI                    \
+       XEN_HYPER_RFI;          \
+       dv_serialize_data
diff --git a/arch/ia64/include/asm/xen/interface.h b/arch/ia64/include/asm/xen/interface.h
new file mode 100644 (file)
index 0000000..f00fab4
--- /dev/null
@@ -0,0 +1,346 @@
+/******************************************************************************
+ * arch-ia64/hypervisor-if.h
+ *
+ * Guest OS interface to IA64 Xen.
+ *
+ * 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
+ * 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.
+ *
+ * Copyright by those who contributed. (in alphabetical order)
+ *
+ * Anthony Xu <anthony.xu@intel.com>
+ * Eddie Dong <eddie.dong@intel.com>
+ * Fred Yang <fred.yang@intel.com>
+ * Kevin Tian <kevin.tian@intel.com>
+ * Alex Williamson <alex.williamson@hp.com>
+ * Chris Wright <chrisw@sous-sol.org>
+ * Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
+ * Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
+ * Hollis Blanchard <hollisb@us.ibm.com>
+ * Isaku Yamahata <yamahata@valinux.co.jp>
+ * Jan Beulich <jbeulich@novell.com>
+ * John Levon <john.levon@sun.com>
+ * Kazuhiro Suzuki <kaz@jp.fujitsu.com>
+ * Keir Fraser <keir.fraser@citrix.com>
+ * Kouya Shimura <kouya@jp.fujitsu.com>
+ * Masaki Kanno <kanno.masaki@jp.fujitsu.com>
+ * Matt Chapman <matthewc@hp.com>
+ * Matthew Chapman <matthewc@hp.com>
+ * Samuel Thibault <samuel.thibault@eu.citrix.com>
+ * Tomonari Horikoshi <t.horikoshi@jp.fujitsu.com>
+ * Tristan Gingold <tgingold@free.fr>
+ * Tsunehisa Doi <Doi.Tsunehisa@jp.fujitsu.com>
+ * Yutaka Ezaki <yutaka.ezaki@jp.fujitsu.com>
+ * Zhang Xin <xing.z.zhang@intel.com>
+ * Zhang xiantao <xiantao.zhang@intel.com>
+ * dan.magenheimer@hp.com
+ * ian.pratt@cl.cam.ac.uk
+ * michael.fetterman@cl.cam.ac.uk
+ */
+
+#ifndef _ASM_IA64_XEN_INTERFACE_H
+#define _ASM_IA64_XEN_INTERFACE_H
+
+#define __DEFINE_GUEST_HANDLE(name, type)      \
+       typedef struct { type *p; } __guest_handle_ ## name
+
+#define DEFINE_GUEST_HANDLE_STRUCT(name)       \
+       __DEFINE_GUEST_HANDLE(name, struct name)
+#define DEFINE_GUEST_HANDLE(name)      __DEFINE_GUEST_HANDLE(name, name)
+#define GUEST_HANDLE(name)             __guest_handle_ ## name
+#define GUEST_HANDLE_64(name)          GUEST_HANDLE(name)
+#define set_xen_guest_handle(hnd, val) do { (hnd).p = val; } while (0)
+
+#ifndef __ASSEMBLY__
+/* Guest handles for primitive C types. */
+__DEFINE_GUEST_HANDLE(uchar, unsigned char);
+__DEFINE_GUEST_HANDLE(uint, unsigned int);
+__DEFINE_GUEST_HANDLE(ulong, unsigned long);
+__DEFINE_GUEST_HANDLE(u64, unsigned long);
+DEFINE_GUEST_HANDLE(char);
+DEFINE_GUEST_HANDLE(int);
+DEFINE_GUEST_HANDLE(long);
+DEFINE_GUEST_HANDLE(void);
+
+typedef unsigned long xen_pfn_t;
+DEFINE_GUEST_HANDLE(xen_pfn_t);
+#define PRI_xen_pfn    "lx"
+#endif
+
+/* Arch specific VIRQs definition */
+#define VIRQ_ITC       VIRQ_ARCH_0     /* V. Virtual itc timer */
+#define VIRQ_MCA_CMC   VIRQ_ARCH_1     /* MCA cmc interrupt */
+#define VIRQ_MCA_CPE   VIRQ_ARCH_2     /* MCA cpe interrupt */
+
+/* Maximum number of virtual CPUs in multi-processor guests. */
+/* keep sizeof(struct shared_page) <= PAGE_SIZE.
+ * this is checked in arch/ia64/xen/hypervisor.c. */
+#define MAX_VIRT_CPUS  64
+
+#ifndef __ASSEMBLY__
+
+#define INVALID_MFN    (~0UL)
+
+union vac {
+       unsigned long value;
+       struct {
+               int a_int:1;
+               int a_from_int_cr:1;
+               int a_to_int_cr:1;
+               int a_from_psr:1;
+               int a_from_cpuid:1;
+               int a_cover:1;
+               int a_bsw:1;
+               long reserved:57;
+       };
+};
+
+union vdc {
+       unsigned long value;
+       struct {
+               int d_vmsw:1;
+               int d_extint:1;
+               int d_ibr_dbr:1;
+               int d_pmc:1;
+               int d_to_pmd:1;
+               int d_itm:1;
+               long reserved:58;
+       };
+};
+
+struct mapped_regs {
+       union vac vac;
+       union vdc vdc;
+       unsigned long virt_env_vaddr;
+       unsigned long reserved1[29];
+       unsigned long vhpi;
+       unsigned long reserved2[95];
+       union {
+               unsigned long vgr[16];
+               unsigned long bank1_regs[16];   /* bank1 regs (r16-r31)
+                                                  when bank0 active */
+       };
+       union {
+               unsigned long vbgr[16];
+               unsigned long bank0_regs[16];   /* bank0 regs (r16-r31)
+                                                  when bank1 active */
+       };
+       unsigned long vnat;
+       unsigned long vbnat;
+       unsigned long vcpuid[5];
+       unsigned long reserved3[11];
+       unsigned long vpsr;
+       unsigned long vpr;
+       unsigned long reserved4[76];
+       union {
+               unsigned long vcr[128];
+               struct {
+                       unsigned long dcr;      /* CR0 */
+                       unsigned long itm;
+                       unsigned long iva;
+                       unsigned long rsv1[5];
+                       unsigned long pta;      /* CR8 */
+                       unsigned long rsv2[7];
+                       unsigned long ipsr;     /* CR16 */
+                       unsigned long isr;
+                       unsigned long rsv3;
+                       unsigned long iip;
+                       unsigned long ifa;
+                       unsigned long itir;
+                       unsigned long iipa;
+                       unsigned long ifs;
+                       unsigned long iim;      /* CR24 */
+                       unsigned long iha;
+                       unsigned long rsv4[38];
+                       unsigned long lid;      /* CR64 */
+                       unsigned long ivr;
+                       unsigned long tpr;
+                       unsigned long eoi;
+                       unsigned long irr[4];
+                       unsigned long itv;      /* CR72 */
+                       unsigned long pmv;
+                       unsigned long cmcv;
+                       unsigned long rsv5[5];
+                       unsigned long lrr0;     /* CR80 */
+                       unsigned long lrr1;
+                       unsigned long rsv6[46];
+               };
+       };
+       union {
+               unsigned long reserved5[128];
+               struct {
+                       unsigned long precover_ifs;
+                       unsigned long unat;     /* not sure if this is needed
+                                                  until NaT arch is done */
+                       int interrupt_collection_enabled; /* virtual psr.ic */
+
+                       /* virtual interrupt deliverable flag is
+                        * evtchn_upcall_mask in shared info area now.
+                        * interrupt_mask_addr is the address
+                        * of evtchn_upcall_mask for current vcpu
+                        */
+                       unsigned char *interrupt_mask_addr;
+                       int pending_interruption;
+                       unsigned char vpsr_pp;
+                       unsigned char vpsr_dfh;
+                       unsigned char hpsr_dfh;
+                       unsigned char hpsr_mfh;
+                       unsigned long reserved5_1[4];
+                       int metaphysical_mode;  /* 1 = use metaphys mapping
+                                                  0 = use virtual */
+                       int banknum;            /* 0 or 1, which virtual
+                                                  register bank is active */
+                       unsigned long rrs[8];   /* region registers */
+                       unsigned long krs[8];   /* kernel registers */
+                       unsigned long tmp[16];  /* temp registers
+                                                  (e.g. for hyperprivops) */
+               };
+       };
+};
+
+struct arch_vcpu_info {
+       /* nothing */
+};
+
+/*
+ * This structure is used for magic page in domain pseudo physical address
+ * space and the result of XENMEM_machine_memory_map.
+ * As the XENMEM_machine_memory_map result,
+ * xen_memory_map::nr_entries indicates the size in bytes
+ * including struct xen_ia64_memmap_info. Not the number of entries.
+ */
+struct xen_ia64_memmap_info {
+       uint64_t efi_memmap_size;       /* size of EFI memory map */
+       uint64_t efi_memdesc_size;      /* size of an EFI memory map
+                                        * descriptor */
+       uint32_t efi_memdesc_version;   /* memory descriptor version */
+       void *memdesc[0];               /* array of efi_memory_desc_t */
+};
+
+struct arch_shared_info {
+       /* PFN of the start_info page.  */
+       unsigned long start_info_pfn;
+
+       /* Interrupt vector for event channel.  */
+       int evtchn_vector;
+
+       /* PFN of memmap_info page */
+       unsigned int memmap_info_num_pages;     /* currently only = 1 case is
+                                                  supported. */
+       unsigned long memmap_info_pfn;
+
+       uint64_t pad[31];
+};
+
+struct xen_callback {
+       unsigned long ip;
+};
+typedef struct xen_callback xen_callback_t;
+
+#endif /* !__ASSEMBLY__ */
+
+/* Size of the shared_info area (this is not related to page size).  */
+#define XSI_SHIFT                      14
+#define XSI_SIZE                       (1 << XSI_SHIFT)
+/* Log size of mapped_regs area (64 KB - only 4KB is used).  */
+#define XMAPPEDREGS_SHIFT              12
+#define XMAPPEDREGS_SIZE               (1 << XMAPPEDREGS_SHIFT)
+/* Offset of XASI (Xen arch shared info) wrt XSI_BASE. */
+#define XMAPPEDREGS_OFS                        XSI_SIZE
+
+/* Hyperprivops.  */
+#define HYPERPRIVOP_START              0x1
+#define HYPERPRIVOP_RFI                        (HYPERPRIVOP_START + 0x0)
+#define HYPERPRIVOP_RSM_DT             (HYPERPRIVOP_START + 0x1)
+#define HYPERPRIVOP_SSM_DT             (HYPERPRIVOP_START + 0x2)
+#define HYPERPRIVOP_COVER              (HYPERPRIVOP_START + 0x3)
+#define HYPERPRIVOP_ITC_D              (HYPERPRIVOP_START + 0x4)
+#define HYPERPRIVOP_ITC_I              (HYPERPRIVOP_START + 0x5)
+#define HYPERPRIVOP_SSM_I              (HYPERPRIVOP_START + 0x6)
+#define HYPERPRIVOP_GET_IVR            (HYPERPRIVOP_START + 0x7)
+#define HYPERPRIVOP_GET_TPR            (HYPERPRIVOP_START + 0x8)
+#define HYPERPRIVOP_SET_TPR            (HYPERPRIVOP_START + 0x9)
+#define HYPERPRIVOP_EOI                        (HYPERPRIVOP_START + 0xa)
+#define HYPERPRIVOP_SET_ITM            (HYPERPRIVOP_START + 0xb)
+#define HYPERPRIVOP_THASH              (HYPERPRIVOP_START + 0xc)
+#define HYPERPRIVOP_PTC_GA             (HYPERPRIVOP_START + 0xd)
+#define HYPERPRIVOP_ITR_D              (HYPERPRIVOP_START + 0xe)
+#define HYPERPRIVOP_GET_RR             (HYPERPRIVOP_START + 0xf)
+#define HYPERPRIVOP_SET_RR             (HYPERPRIVOP_START + 0x10)
+#define HYPERPRIVOP_SET_KR             (HYPERPRIVOP_START + 0x11)
+#define HYPERPRIVOP_FC                 (HYPERPRIVOP_START + 0x12)
+#define HYPERPRIVOP_GET_CPUID          (HYPERPRIVOP_START + 0x13)
+#define HYPERPRIVOP_GET_PMD            (HYPERPRIVOP_START + 0x14)
+#define HYPERPRIVOP_GET_EFLAG          (HYPERPRIVOP_START + 0x15)
+#define HYPERPRIVOP_SET_EFLAG          (HYPERPRIVOP_START + 0x16)
+#define HYPERPRIVOP_RSM_BE             (HYPERPRIVOP_START + 0x17)
+#define HYPERPRIVOP_GET_PSR            (HYPERPRIVOP_START + 0x18)
+#define HYPERPRIVOP_SET_RR0_TO_RR4     (HYPERPRIVOP_START + 0x19)
+#define HYPERPRIVOP_MAX                        (0x1a)
+
+/* Fast and light hypercalls.  */
+#define __HYPERVISOR_ia64_fast_eoi     __HYPERVISOR_arch_1
+
+/* Xencomm macros.  */
+#define XENCOMM_INLINE_MASK            0xf800000000000000UL
+#define XENCOMM_INLINE_FLAG            0x8000000000000000UL
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Optimization features.
+ * The hypervisor may do some special optimizations for guests. This hypercall
+ * can be used to switch on/of these special optimizations.
+ */
+#define __HYPERVISOR_opt_feature       0x700UL
+
+#define XEN_IA64_OPTF_OFF              0x0
+#define XEN_IA64_OPTF_ON               0x1
+
+/*
+ * If this feature is switched on, the hypervisor inserts the
+ * tlb entries without calling the guests traphandler.
+ * This is useful in guests using region 7 for identity mapping
+ * like the linux kernel does.
+ */
+#define XEN_IA64_OPTF_IDENT_MAP_REG7   1
+
+/* Identity mapping of region 4 addresses in HVM. */
+#define XEN_IA64_OPTF_IDENT_MAP_REG4   2
+
+/* Identity mapping of region 5 addresses in HVM. */
+#define XEN_IA64_OPTF_IDENT_MAP_REG5   3
+
+#define XEN_IA64_OPTF_IDENT_MAP_NOT_SET         (0)
+
+struct xen_ia64_opt_feature {
+       unsigned long cmd;      /* Which feature */
+       unsigned char on;       /* Switch feature on/off */
+       union {
+               struct {
+                       /* The page protection bit mask of the pte.
+                        * This will be or'ed with the pte. */
+                       unsigned long pgprot;
+                       unsigned long key;      /* A protection key for itir.*/
+               };
+       };
+};
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_IA64_XEN_INTERFACE_H */
diff --git a/arch/ia64/include/asm/xen/irq.h b/arch/ia64/include/asm/xen/irq.h
new file mode 100644 (file)
index 0000000..a904509
--- /dev/null
@@ -0,0 +1,44 @@
+/******************************************************************************
+ * arch/ia64/include/asm/xen/irq.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * 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 _ASM_IA64_XEN_IRQ_H
+#define _ASM_IA64_XEN_IRQ_H
+
+/*
+ * The flat IRQ space is divided into two regions:
+ *  1. A one-to-one mapping of real physical IRQs. This space is only used
+ *     if we have physical device-access privilege. This region is at the
+ *     start of the IRQ space so that existing device drivers do not need
+ *     to be modified to translate physical IRQ numbers into our IRQ space.
+ *  3. A dynamic mapping of inter-domain and Xen-sourced virtual IRQs. These
+ *     are bound using the provided bind/unbind functions.
+ */
+
+#define XEN_PIRQ_BASE          0
+#define XEN_NR_PIRQS           256
+
+#define XEN_DYNIRQ_BASE                (XEN_PIRQ_BASE + XEN_NR_PIRQS)
+#define XEN_NR_DYNIRQS         (NR_CPUS * 8)
+
+#define XEN_NR_IRQS            (XEN_NR_PIRQS + XEN_NR_DYNIRQS)
+
+#endif /* _ASM_IA64_XEN_IRQ_H */
diff --git a/arch/ia64/include/asm/xen/minstate.h b/arch/ia64/include/asm/xen/minstate.h
new file mode 100644 (file)
index 0000000..4d92d9b
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves
+ * the minimum state necessary that allows us to turn psr.ic back
+ * on.
+ *
+ * Assumed state upon entry:
+ *     psr.ic: off
+ *     r31:    contains saved predicates (pr)
+ *
+ * Upon exit, the state is as follows:
+ *     psr.ic: off
+ *      r2 = points to &pt_regs.r16
+ *      r8 = contents of ar.ccv
+ *      r9 = contents of ar.csd
+ *     r10 = contents of ar.ssd
+ *     r11 = FPSR_DEFAULT
+ *     r12 = kernel sp (kernel virtual address)
+ *     r13 = points to current task_struct (kernel virtual address)
+ *     p15 = TRUE if psr.i is set in cr.ipsr
+ *     predicate registers (other than p2, p3, and p15), b6, r3, r14, r15:
+ *             preserved
+ * CONFIG_XEN note: p6/p7 are not preserved
+ *
+ * Note that psr.ic is NOT turned on by this macro.  This is so that
+ * we can pass interruption state as arguments to a handler.
+ */
+#define XEN_DO_SAVE_MIN(__COVER,SAVE_IFS,EXTRA,WORKAROUND)                                     \
+       mov r16=IA64_KR(CURRENT);       /* M */                                                 \
+       mov r27=ar.rsc;                 /* M */                                                 \
+       mov r20=r1;                     /* A */                                                 \
+       mov r25=ar.unat;                /* M */                                                 \
+       MOV_FROM_IPSR(p0,r29);          /* M */                                                 \
+       MOV_FROM_IIP(r28);              /* M */                                                 \
+       mov r21=ar.fpsr;                /* M */                                                 \
+       mov r26=ar.pfs;                 /* I */                                                 \
+       __COVER;                        /* B;; (or nothing) */                                  \
+       adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16;                                         \
+       ;;                                                                                      \
+       ld1 r17=[r16];                          /* load current->thread.on_ustack flag */       \
+       st1 [r16]=r0;                           /* clear current->thread.on_ustack flag */      \
+       adds r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16                                          \
+       /* switch from user to kernel RBS: */                                                   \
+       ;;                                                                                      \
+       invala;                         /* M */                                                 \
+       /* SAVE_IFS;*/ /* see xen special handling below */                                     \
+       cmp.eq pKStk,pUStk=r0,r17;              /* are we in kernel mode already? */            \
+       ;;                                                                                      \
+(pUStk)        mov ar.rsc=0;           /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */     \
+       ;;                                                                                      \
+(pUStk)        mov.m r24=ar.rnat;                                                                      \
+(pUStk)        addl r22=IA64_RBS_OFFSET,r1;                    /* compute base of RBS */               \
+(pKStk) mov r1=sp;                                     /* get sp  */                           \
+       ;;                                                                                      \
+(pUStk) lfetch.fault.excl.nt1 [r22];                                                           \
+(pUStk)        addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1;   /* compute base of memory stack */      \
+(pUStk)        mov r23=ar.bspstore;                            /* save ar.bspstore */                  \
+       ;;                                                                                      \
+(pUStk)        mov ar.bspstore=r22;                            /* switch to kernel RBS */              \
+(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1;                 /* if in kernel mode, use sp (r12) */   \
+       ;;                                                                                      \
+(pUStk)        mov r18=ar.bsp;                                                                         \
+(pUStk)        mov ar.rsc=0x3;         /* set eager mode, pl 0, little-endian, loadrs=0 */             \
+       adds r17=2*L1_CACHE_BYTES,r1;           /* really: biggest cache-line size */           \
+       adds r16=PT(CR_IPSR),r1;                                                                \
+       ;;                                                                                      \
+       lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES;                                             \
+       st8 [r16]=r29;          /* save cr.ipsr */                                              \
+       ;;                                                                                      \
+       lfetch.fault.excl.nt1 [r17];                                                            \
+       tbit.nz p15,p0=r29,IA64_PSR_I_BIT;                                                      \
+       mov r29=b0                                                                              \
+       ;;                                                                                      \
+       WORKAROUND;                                                                             \
+       adds r16=PT(R8),r1;     /* initialize first base pointer */                             \
+       adds r17=PT(R9),r1;     /* initialize second base pointer */                            \
+(pKStk)        mov r18=r0;             /* make sure r18 isn't NaT */                                   \
+       ;;                                                                                      \
+.mem.offset 0,0; st8.spill [r16]=r8,16;                                                                \
+.mem.offset 8,0; st8.spill [r17]=r9,16;                                                                \
+        ;;                                                                                     \
+.mem.offset 0,0; st8.spill [r16]=r10,24;                                                       \
+       movl r8=XSI_PRECOVER_IFS;                                                               \
+.mem.offset 8,0; st8.spill [r17]=r11,24;                                                       \
+        ;;                                                                                     \
+       /* xen special handling for possibly lazy cover */                                      \
+       /* SAVE_MIN case in dispatch_ia32_handler: mov r30=r0 */                                \
+       ld8 r30=[r8];                                                                           \
+(pUStk)        sub r18=r18,r22;        /* r18=RSE.ndirty*8 */                                          \
+       st8 [r16]=r28,16;       /* save cr.iip */                                               \
+       ;;                                                                                      \
+       st8 [r17]=r30,16;       /* save cr.ifs */                                               \
+       mov r8=ar.ccv;                                                                          \
+       mov r9=ar.csd;                                                                          \
+       mov r10=ar.ssd;                                                                         \
+       movl r11=FPSR_DEFAULT;   /* L-unit */                                                   \
+       ;;                                                                                      \
+       st8 [r16]=r25,16;       /* save ar.unat */                                              \
+       st8 [r17]=r26,16;       /* save ar.pfs */                                               \
+       shl r18=r18,16;         /* compute ar.rsc to be used for "loadrs" */                    \
+       ;;                                                                                      \
+       st8 [r16]=r27,16;       /* save ar.rsc */                                               \
+(pUStk)        st8 [r17]=r24,16;       /* save ar.rnat */                                              \
+(pKStk)        adds r17=16,r17;        /* skip over ar_rnat field */                                   \
+       ;;                      /* avoid RAW on r16 & r17 */                                    \
+(pUStk)        st8 [r16]=r23,16;       /* save ar.bspstore */                                          \
+       st8 [r17]=r31,16;       /* save predicates */                                           \
+(pKStk)        adds r16=16,r16;        /* skip over ar_bspstore field */                               \
+       ;;                                                                                      \
+       st8 [r16]=r29,16;       /* save b0 */                                                   \
+       st8 [r17]=r18,16;       /* save ar.rsc value for "loadrs" */                            \
+       cmp.eq pNonSys,pSys=r0,r0       /* initialize pSys=0, pNonSys=1 */                      \
+       ;;                                                                                      \
+.mem.offset 0,0; st8.spill [r16]=r20,16;       /* save original r1 */                          \
+.mem.offset 8,0; st8.spill [r17]=r12,16;                                                       \
+       adds r12=-16,r1;        /* switch to kernel memory stack (with 16 bytes of scratch) */  \
+       ;;                                                                                      \
+.mem.offset 0,0; st8.spill [r16]=r13,16;                                                       \
+.mem.offset 8,0; st8.spill [r17]=r21,16;       /* save ar.fpsr */                              \
+       mov r13=IA64_KR(CURRENT);       /* establish `current' */                               \
+       ;;                                                                                      \
+.mem.offset 0,0; st8.spill [r16]=r15,16;                                                       \
+.mem.offset 8,0; st8.spill [r17]=r14,16;                                                       \
+       ;;                                                                                      \
+.mem.offset 0,0; st8.spill [r16]=r2,16;                                                                \
+.mem.offset 8,0; st8.spill [r17]=r3,16;                                                                \
+       ACCOUNT_GET_STAMP                                                                       \
+       adds r2=IA64_PT_REGS_R16_OFFSET,r1;                                                     \
+       ;;                                                                                      \
+       EXTRA;                                                                                  \
+       movl r1=__gp;           /* establish kernel global pointer */                           \
+       ;;                                                                                      \
+       ACCOUNT_SYS_ENTER                                                                       \
+       BSW_1(r3,r14);  /* switch back to bank 1 (must be last in insn group) */                \
+       ;;
diff --git a/arch/ia64/include/asm/xen/page.h b/arch/ia64/include/asm/xen/page.h
new file mode 100644 (file)
index 0000000..03441a7
--- /dev/null
@@ -0,0 +1,65 @@
+/******************************************************************************
+ * arch/ia64/include/asm/xen/page.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * 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 _ASM_IA64_XEN_PAGE_H
+#define _ASM_IA64_XEN_PAGE_H
+
+#define INVALID_P2M_ENTRY      (~0UL)
+
+static inline unsigned long mfn_to_pfn(unsigned long mfn)
+{
+       return mfn;
+}
+
+static inline unsigned long pfn_to_mfn(unsigned long pfn)
+{
+       return pfn;
+}
+
+#define phys_to_machine_mapping_valid(_x)      (1)
+
+static inline void *mfn_to_virt(unsigned long mfn)
+{
+       return __va(mfn << PAGE_SHIFT);
+}
+
+static inline unsigned long virt_to_mfn(void *virt)
+{
+       return __pa(virt) >> PAGE_SHIFT;
+}
+
+/* for tpmfront.c */
+static inline unsigned long virt_to_machine(void *virt)
+{
+       return __pa(virt);
+}
+
+static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
+{
+       /* nothing */
+}
+
+#define pte_mfn(_x)    pte_pfn(_x)
+#define mfn_pte(_x, _y)        __pte_ma(0)             /* unmodified use */
+#define __pte_ma(_x)   ((pte_t) {(_x)})        /* unmodified use */
+
+#endif /* _ASM_IA64_XEN_PAGE_H */
diff --git a/arch/ia64/include/asm/xen/privop.h b/arch/ia64/include/asm/xen/privop.h
new file mode 100644 (file)
index 0000000..71ec754
--- /dev/null
@@ -0,0 +1,129 @@
+#ifndef _ASM_IA64_XEN_PRIVOP_H
+#define _ASM_IA64_XEN_PRIVOP_H
+
+/*
+ * Copyright (C) 2005 Hewlett-Packard Co
+ *     Dan Magenheimer <dan.magenheimer@hp.com>
+ *
+ * Paravirtualizations of privileged operations for Xen/ia64
+ *
+ *
+ * inline privop and paravirt_alt support
+ * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ */
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>               /* arch-ia64.h requires uint64_t */
+#endif
+#include <asm/xen/interface.h>
+
+/* At 1 MB, before per-cpu space but still addressable using addl instead
+   of movl. */
+#define XSI_BASE                       0xfffffffffff00000
+
+/* Address of mapped regs.  */
+#define XMAPPEDREGS_BASE               (XSI_BASE + XSI_SIZE)
+
+#ifdef __ASSEMBLY__
+#define XEN_HYPER_RFI                  break HYPERPRIVOP_RFI
+#define XEN_HYPER_RSM_PSR_DT           break HYPERPRIVOP_RSM_DT
+#define XEN_HYPER_SSM_PSR_DT           break HYPERPRIVOP_SSM_DT
+#define XEN_HYPER_COVER                        break HYPERPRIVOP_COVER
+#define XEN_HYPER_ITC_D                        break HYPERPRIVOP_ITC_D
+#define XEN_HYPER_ITC_I                        break HYPERPRIVOP_ITC_I
+#define XEN_HYPER_SSM_I                        break HYPERPRIVOP_SSM_I
+#define XEN_HYPER_GET_IVR              break HYPERPRIVOP_GET_IVR
+#define XEN_HYPER_THASH                        break HYPERPRIVOP_THASH
+#define XEN_HYPER_ITR_D                        break HYPERPRIVOP_ITR_D
+#define XEN_HYPER_SET_KR               break HYPERPRIVOP_SET_KR
+#define XEN_HYPER_GET_PSR              break HYPERPRIVOP_GET_PSR
+#define XEN_HYPER_SET_RR0_TO_RR4       break HYPERPRIVOP_SET_RR0_TO_RR4
+
+#define XSI_IFS                                (XSI_BASE + XSI_IFS_OFS)
+#define XSI_PRECOVER_IFS               (XSI_BASE + XSI_PRECOVER_IFS_OFS)
+#define XSI_IFA                                (XSI_BASE + XSI_IFA_OFS)
+#define XSI_ISR                                (XSI_BASE + XSI_ISR_OFS)
+#define XSI_IIM                                (XSI_BASE + XSI_IIM_OFS)
+#define XSI_ITIR                       (XSI_BASE + XSI_ITIR_OFS)
+#define XSI_PSR_I_ADDR                 (XSI_BASE + XSI_PSR_I_ADDR_OFS)
+#define XSI_PSR_IC                     (XSI_BASE + XSI_PSR_IC_OFS)
+#define XSI_IPSR                       (XSI_BASE + XSI_IPSR_OFS)
+#define XSI_IIP                                (XSI_BASE + XSI_IIP_OFS)
+#define XSI_B1NAT                      (XSI_BASE + XSI_B1NATS_OFS)
+#define XSI_BANK1_R16                  (XSI_BASE + XSI_BANK1_R16_OFS)
+#define XSI_BANKNUM                    (XSI_BASE + XSI_BANKNUM_OFS)
+#define XSI_IHA                                (XSI_BASE + XSI_IHA_OFS)
+#endif
+
+#ifndef __ASSEMBLY__
+
+/************************************************/
+/* Instructions paravirtualized for correctness */
+/************************************************/
+
+/* "fc" and "thash" are privilege-sensitive instructions, meaning they
+ *  may have different semantics depending on whether they are executed
+ *  at PL0 vs PL!=0.  When paravirtualized, these instructions mustn't
+ *  be allowed to execute directly, lest incorrect semantics result. */
+extern void xen_fc(unsigned long addr);
+extern unsigned long xen_thash(unsigned long addr);
+
+/* Note that "ttag" and "cover" are also privilege-sensitive; "ttag"
+ * is not currently used (though it may be in a long-format VHPT system!)
+ * and the semantics of cover only change if psr.ic is off which is very
+ * rare (and currently non-existent outside of assembly code */
+
+/* There are also privilege-sensitive registers.  These registers are
+ * readable at any privilege level but only writable at PL0. */
+extern unsigned long xen_get_cpuid(int index);
+extern unsigned long xen_get_pmd(int index);
+
+extern unsigned long xen_get_eflag(void);      /* see xen_ia64_getreg */
+extern void xen_set_eflag(unsigned long);      /* see xen_ia64_setreg */
+
+/************************************************/
+/* Instructions paravirtualized for performance */
+/************************************************/
+
+/* Xen uses memory-mapped virtual privileged registers for access to many
+ * performance-sensitive privileged registers.  Some, like the processor
+ * status register (psr), are broken up into multiple memory locations.
+ * Others, like "pend", are abstractions based on privileged registers.
+ * "Pend" is guaranteed to be set if reading cr.ivr would return a
+ * (non-spurious) interrupt. */
+#define XEN_MAPPEDREGS ((struct mapped_regs *)XMAPPEDREGS_BASE)
+
+#define XSI_PSR_I                      \
+       (*XEN_MAPPEDREGS->interrupt_mask_addr)
+#define xen_get_virtual_psr_i()                \
+       (!XSI_PSR_I)
+#define xen_set_virtual_psr_i(_val)    \
+       ({ XSI_PSR_I = (uint8_t)(_val) ? 0 : 1; })
+#define xen_set_virtual_psr_ic(_val)   \
+       ({ XEN_MAPPEDREGS->interrupt_collection_enabled = _val ? 1 : 0; })
+#define xen_get_virtual_pend()         \
+       (*(((uint8_t *)XEN_MAPPEDREGS->interrupt_mask_addr) - 1))
+
+/* Although all privileged operations can be left to trap and will
+ * be properly handled by Xen, some are frequent enough that we use
+ * hyperprivops for performance. */
+extern unsigned long xen_get_psr(void);
+extern unsigned long xen_get_ivr(void);
+extern unsigned long xen_get_tpr(void);
+extern void xen_hyper_ssm_i(void);
+extern void xen_set_itm(unsigned long);
+extern void xen_set_tpr(unsigned long);
+extern void xen_eoi(unsigned long);
+extern unsigned long xen_get_rr(unsigned long index);
+extern void xen_set_rr(unsigned long index, unsigned long val);
+extern void xen_set_rr0_to_rr4(unsigned long val0, unsigned long val1,
+                              unsigned long val2, unsigned long val3,
+                              unsigned long val4);
+extern void xen_set_kr(unsigned long index, unsigned long val);
+extern void xen_ptcga(unsigned long addr, unsigned long size);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_IA64_XEN_PRIVOP_H */
diff --git a/arch/ia64/include/asm/xen/xcom_hcall.h b/arch/ia64/include/asm/xen/xcom_hcall.h
new file mode 100644 (file)
index 0000000..20b2950
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2006 Tristan Gingold <tristan.gingold@bull.net>, Bull SAS
+ *
+ * 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 _ASM_IA64_XEN_XCOM_HCALL_H
+#define _ASM_IA64_XEN_XCOM_HCALL_H
+
+/* These function creates inline or mini descriptor for the parameters and
+   calls the corresponding xencomm_arch_hypercall_X.
+   Architectures should defines HYPERVISOR_xxx as xencomm_hypercall_xxx unless
+   they want to use their own wrapper.  */
+extern int xencomm_hypercall_console_io(int cmd, int count, char *str);
+
+extern int xencomm_hypercall_event_channel_op(int cmd, void *op);
+
+extern int xencomm_hypercall_xen_version(int cmd, void *arg);
+
+extern int xencomm_hypercall_physdev_op(int cmd, void *op);
+
+extern int xencomm_hypercall_grant_table_op(unsigned int cmd, void *op,
+                                           unsigned int count);
+
+extern int xencomm_hypercall_sched_op(int cmd, void *arg);
+
+extern int xencomm_hypercall_multicall(void *call_list, int nr_calls);
+
+extern int xencomm_hypercall_callback_op(int cmd, void *arg);
+
+extern int xencomm_hypercall_memory_op(unsigned int cmd, void *arg);
+
+extern int xencomm_hypercall_suspend(unsigned long srec);
+
+extern long xencomm_hypercall_vcpu_op(int cmd, int cpu, void *arg);
+
+extern long xencomm_hypercall_opt_feature(void *arg);
+
+#endif /* _ASM_IA64_XEN_XCOM_HCALL_H */
diff --git a/arch/ia64/include/asm/xen/xencomm.h b/arch/ia64/include/asm/xen/xencomm.h
new file mode 100644 (file)
index 0000000..cded677
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2006 Hollis Blanchard <hollisb@us.ibm.com>, 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.
+ *
+ * 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_IA64_XEN_XENCOMM_H
+#define _ASM_IA64_XEN_XENCOMM_H
+
+#include <xen/xencomm.h>
+#include <asm/pgtable.h>
+
+/* Must be called before any hypercall.  */
+extern void xencomm_initialize(void);
+extern int xencomm_is_initialized(void);
+
+/* Check if virtual contiguity means physical contiguity
+ * where the passed address is a pointer value in virtual address.
+ * On ia64, identity mapping area in region 7 or the piece of region 5
+ * that is mapped by itr[IA64_TR_KERNEL]/dtr[IA64_TR_KERNEL]
+ */
+static inline int xencomm_is_phys_contiguous(unsigned long addr)
+{
+       return (PAGE_OFFSET <= addr &&
+               addr < (PAGE_OFFSET + (1UL << IA64_MAX_PHYS_BITS))) ||
+               (KERNEL_START <= addr &&
+                addr < KERNEL_START + KERNEL_TR_PAGE_SIZE);
+}
+
+#endif /* _ASM_IA64_XEN_XENCOMM_H */
index 87fea11aecb71b1f9464904a5be7b4833c10aa12..c381ea9548924149835ba223f758729dea3ebc03 100644 (file)
@@ -42,6 +42,10 @@ obj-$(CONFIG_IA64_ESI)               += esi.o
 ifneq ($(CONFIG_IA64_ESI),)
 obj-y                          += esi_stub.o   # must be in kernel proper
 endif
+obj-$(CONFIG_DMAR)             += pci-dma.o
+ifeq ($(CONFIG_DMAR), y)
+obj-$(CONFIG_SWIOTLB)          += pci-swiotlb.o
+endif
 
 # The gate DSO image is built using a special linker script.
 targets += gate.so gate-syms.o
@@ -112,5 +116,23 @@ clean-files += $(objtree)/include/asm-ia64/nr-irqs.h
 ASM_PARAVIRT_OBJS = ivt.o entry.o
 define paravirtualized_native
 AFLAGS_$(1) += -D__IA64_ASM_PARAVIRTUALIZED_NATIVE
+AFLAGS_pvchk-sed-$(1) += -D__IA64_ASM_PARAVIRTUALIZED_PVCHECK
+extra-y += pvchk-$(1)
 endef
 $(foreach obj,$(ASM_PARAVIRT_OBJS),$(eval $(call paravirtualized_native,$(obj))))
+
+#
+# Checker for paravirtualizations of privileged operations.
+#
+quiet_cmd_pv_check_sed = PVCHK   $@
+define cmd_pv_check_sed
+       sed -f $(srctree)/arch/$(SRCARCH)/scripts/pvcheck.sed $< > $@
+endef
+
+$(obj)/pvchk-sed-%.s: $(src)/%.S $(srctree)/arch/$(SRCARCH)/scripts/pvcheck.sed FORCE
+       $(call if_changed_dep,as_s_S)
+$(obj)/pvchk-%.s: $(obj)/pvchk-sed-%.s FORCE
+       $(call if_changed,pv_check_sed)
+$(obj)/pvchk-%.o: $(obj)/pvchk-%.s FORCE
+       $(call if_changed,as_o_S)
+.PRECIOUS: $(obj)/pvchk-sed-%.s $(obj)/pvchk-%.s $(obj)/pvchk-%.o
index 5d1eb7ee2bf6562282bdccd92520271ca7aedc13..0635015d0aaada0de519d1b0487a787b41594db7 100644 (file)
@@ -52,6 +52,7 @@
 #include <asm/numa.h>
 #include <asm/sal.h>
 #include <asm/cyclone.h>
+#include <asm/xen/hypervisor.h>
 
 #define BAD_MADT_ENTRY(entry, end) (                                        \
                (!entry) || (unsigned long)entry + sizeof(*entry) > end ||  \
@@ -91,6 +92,9 @@ acpi_get_sysname(void)
        struct acpi_table_rsdp *rsdp;
        struct acpi_table_xsdt *xsdt;
        struct acpi_table_header *hdr;
+#ifdef CONFIG_DMAR
+       u64 i, nentries;
+#endif
 
        rsdp_phys = acpi_find_rsdp();
        if (!rsdp_phys) {
@@ -121,7 +125,21 @@ acpi_get_sysname(void)
                        return "uv";
                else
                        return "sn2";
+       } else if (xen_pv_domain() && !strcmp(hdr->oem_id, "XEN")) {
+               return "xen";
+       }
+
+#ifdef CONFIG_DMAR
+       /* Look for Intel IOMMU */
+       nentries = (hdr->length - sizeof(*hdr)) /
+                        sizeof(xsdt->table_offset_entry[0]);
+       for (i = 0; i < nentries; i++) {
+               hdr = __va(xsdt->table_offset_entry[i]);
+               if (strncmp(hdr->signature, ACPI_SIG_DMAR,
+                       sizeof(ACPI_SIG_DMAR) - 1) == 0)
+                       return "dig_vtd";
        }
+#endif
 
        return "dig";
 #else
@@ -137,6 +155,10 @@ acpi_get_sysname(void)
        return "uv";
 # elif defined (CONFIG_IA64_DIG)
        return "dig";
+# elif defined (CONFIG_IA64_XEN_GUEST)
+       return "xen";
+# elif defined(CONFIG_IA64_DIG_VTD)
+       return "dig_vtd";
 # else
 #      error Unknown platform.  Fix acpi.c.
 # endif
index 94c44b1ccfd0de7fb136247756b4ea1a4e08c4e1..742dbb1d5a4fb06cd8cfd3a2f63358b48e20535e 100644 (file)
@@ -16,6 +16,9 @@
 #include <asm/sigcontext.h>
 #include <asm/mca.h>
 
+#include <asm/xen/interface.h>
+#include <asm/xen/hypervisor.h>
+
 #include "../kernel/sigframe.h"
 #include "../kernel/fsyscall_gtod_data.h"
 
@@ -286,4 +289,32 @@ void foo(void)
                offsetof (struct itc_jitter_data_t, itc_jitter));
        DEFINE(IA64_ITC_LASTCYCLE_OFFSET,
                offsetof (struct itc_jitter_data_t, itc_lastcycle));
+
+#ifdef CONFIG_XEN
+       BLANK();
+
+       DEFINE(XEN_NATIVE_ASM, XEN_NATIVE);
+       DEFINE(XEN_PV_DOMAIN_ASM, XEN_PV_DOMAIN);
+
+#define DEFINE_MAPPED_REG_OFS(sym, field) \
+       DEFINE(sym, (XMAPPEDREGS_OFS + offsetof(struct mapped_regs, field)))
+
+       DEFINE_MAPPED_REG_OFS(XSI_PSR_I_ADDR_OFS, interrupt_mask_addr);
+       DEFINE_MAPPED_REG_OFS(XSI_IPSR_OFS, ipsr);
+       DEFINE_MAPPED_REG_OFS(XSI_IIP_OFS, iip);
+       DEFINE_MAPPED_REG_OFS(XSI_IFS_OFS, ifs);
+       DEFINE_MAPPED_REG_OFS(XSI_PRECOVER_IFS_OFS, precover_ifs);
+       DEFINE_MAPPED_REG_OFS(XSI_ISR_OFS, isr);
+       DEFINE_MAPPED_REG_OFS(XSI_IFA_OFS, ifa);
+       DEFINE_MAPPED_REG_OFS(XSI_IIPA_OFS, iipa);
+       DEFINE_MAPPED_REG_OFS(XSI_IIM_OFS, iim);
+       DEFINE_MAPPED_REG_OFS(XSI_IHA_OFS, iha);
+       DEFINE_MAPPED_REG_OFS(XSI_ITIR_OFS, itir);
+       DEFINE_MAPPED_REG_OFS(XSI_PSR_IC_OFS, interrupt_collection_enabled);
+       DEFINE_MAPPED_REG_OFS(XSI_BANKNUM_OFS, banknum);
+       DEFINE_MAPPED_REG_OFS(XSI_BANK0_R16_OFS, bank0_regs[0]);
+       DEFINE_MAPPED_REG_OFS(XSI_BANK1_R16_OFS, bank1_regs[0]);
+       DEFINE_MAPPED_REG_OFS(XSI_B0NATS_OFS, vbnat);
+       DEFINE_MAPPED_REG_OFS(XSI_B1NATS_OFS, vnat);
+#endif /* CONFIG_XEN */
 }
index 0dd6c1419d8dfa6be2a9996a54c714f8f3488423..7ef0c594f5ed9a7e618101770d6b9a5469936d69 100644 (file)
@@ -534,6 +534,11 @@ GLOBAL_ENTRY(ia64_trace_syscall)
        stf.spill [r16]=f10
        stf.spill [r17]=f11
        br.call.sptk.many rp=syscall_trace_enter // give parent a chance to catch syscall args
+       cmp.lt p6,p0=r8,r0                      // check tracehook
+       adds r2=PT(R8)+16,sp                    // r2 = &pt_regs.r8
+       adds r3=PT(R10)+16,sp                   // r3 = &pt_regs.r10
+       mov r10=0
+(p6)   br.cond.sptk strace_error               // syscall failed ->
        adds r16=PT(F6)+16,sp
        adds r17=PT(F7)+16,sp
        ;;
index 416a952b19bde4eb1685f96c1ef30e43e485989c..f675d8e338533c5f2b47ce416a56624915835aa3 100644 (file)
@@ -580,7 +580,7 @@ ENTRY(dirty_bit)
        mov b0=r29                              // restore b0
        ;;
        st8 [r17]=r18                           // store back updated PTE
-       itc.d r18                               // install updated PTE
+       ITC_D(p0, r18, r16)                     // install updated PTE
 #endif
        mov pr=r31,-1                           // restore pr
        RFI
@@ -646,7 +646,7 @@ ENTRY(iaccess_bit)
        mov b0=r29                              // restore b0
        ;;
        st8 [r17]=r18                           // store back updated PTE
-       itc.i r18                               // install updated PTE
+       ITC_I(p0, r18, r16)                     // install updated PTE
 #endif /* !CONFIG_SMP */
        mov pr=r31,-1
        RFI
@@ -698,7 +698,7 @@ ENTRY(daccess_bit)
        or r18=_PAGE_A,r18                      // set the accessed bit
        ;;
        st8 [r17]=r18                           // store back updated PTE
-       itc.d r18                               // install updated PTE
+       ITC_D(p0, r18, r16)                     // install updated PTE
 #endif
        mov b0=r29                              // restore b0
        mov pr=r31,-1
index 60c6ef67ebb215267c79eae647984893d0684f66..702a09c132387577fa7d3b954a499feaa59705bc 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/pci.h>
 #include <linux/irq.h>
 #include <linux/msi.h>
+#include <linux/dmar.h>
 #include <asm/smp.h>
 
 /*
@@ -162,3 +163,82 @@ void arch_teardown_msi_irq(unsigned int irq)
 
        return ia64_teardown_msi_irq(irq);
 }
+
+#ifdef CONFIG_DMAR
+#ifdef CONFIG_SMP
+static void dmar_msi_set_affinity(unsigned int irq, cpumask_t mask)
+{
+       struct irq_cfg *cfg = irq_cfg + irq;
+       struct msi_msg msg;
+       int cpu = first_cpu(mask);
+
+
+       if (!cpu_online(cpu))
+               return;
+
+       if (irq_prepare_move(irq, cpu))
+               return;
+
+       dmar_msi_read(irq, &msg);
+
+       msg.data &= ~MSI_DATA_VECTOR_MASK;
+       msg.data |= MSI_DATA_VECTOR(cfg->vector);
+       msg.address_lo &= ~MSI_ADDR_DESTID_MASK;
+       msg.address_lo |= MSI_ADDR_DESTID_CPU(cpu_physical_id(cpu));
+
+       dmar_msi_write(irq, &msg);
+       irq_desc[irq].affinity = mask;
+}
+#endif /* CONFIG_SMP */
+
+struct irq_chip dmar_msi_type = {
+       .name = "DMAR_MSI",
+       .unmask = dmar_msi_unmask,
+       .mask = dmar_msi_mask,
+       .ack = ia64_ack_msi_irq,
+#ifdef CONFIG_SMP
+       .set_affinity = dmar_msi_set_affinity,
+#endif
+       .retrigger = ia64_msi_retrigger_irq,
+};
+
+static int
+msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
+{
+       struct irq_cfg *cfg = irq_cfg + irq;
+       unsigned dest;
+       cpumask_t mask;
+
+       cpus_and(mask, irq_to_domain(irq), cpu_online_map);
+       dest = cpu_physical_id(first_cpu(mask));
+
+       msg->address_hi = 0;
+       msg->address_lo =
+               MSI_ADDR_HEADER |
+               MSI_ADDR_DESTMODE_PHYS |
+               MSI_ADDR_REDIRECTION_CPU |
+               MSI_ADDR_DESTID_CPU(dest);
+
+       msg->data =
+               MSI_DATA_TRIGGER_EDGE |
+               MSI_DATA_LEVEL_ASSERT |
+               MSI_DATA_DELIVERY_FIXED |
+               MSI_DATA_VECTOR(cfg->vector);
+       return 0;
+}
+
+int arch_setup_dmar_msi(unsigned int irq)
+{
+       int ret;
+       struct msi_msg msg;
+
+       ret = msi_compose_msg(NULL, irq, &msg);
+       if (ret < 0)
+               return ret;
+       dmar_msi_write(irq, &msg);
+       set_irq_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq,
+               "edge");
+       return 0;
+}
+#endif /* CONFIG_DMAR */
+
index 8273afc32db8cf342a526e2c75c70cf3b3995e78..ee564575148ed54da0b03cfdddae484acbcb9b1a 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/kbuild.h>
 #include <linux/threads.h>
 #include <asm/native/irq.h>
+#include <asm/xen/irq.h>
 
 void foo(void)
 {
index afaf5b9a2cf0735c60c1c73996fefba6f44635e2..de35d8e8b7d27360fac4ccd7e05256701c27ee9d 100644 (file)
@@ -332,7 +332,7 @@ ia64_native_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
 
 struct pv_iosapic_ops pv_iosapic_ops = {
        .pcat_compat_init = ia64_native_iosapic_pcat_compat_init,
-       .get_irq_chip = ia64_native_iosapic_get_irq_chip,
+       .__get_irq_chip = ia64_native_iosapic_get_irq_chip,
 
        .__read = ia64_native_iosapic_read,
        .__write = ia64_native_iosapic_write,
index 5cad6fb2ed1964c3fcc251b7ca56e9883eb610e9..64d6d810c64b8e06d16a04c21e48da954570de17 100644 (file)
@@ -20,7 +20,9 @@
  *
  */
 
-#ifdef __IA64_ASM_PARAVIRTUALIZED_XEN
+#ifdef __IA64_ASM_PARAVIRTUALIZED_PVCHECK
+#include <asm/native/pvchk_inst.h>
+#elif defined(__IA64_ASM_PARAVIRTUALIZED_XEN)
 #include <asm/xen/inst.h>
 #include <asm/xen/minstate.h>
 #else
diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c
new file mode 100644 (file)
index 0000000..10a75b5
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Dynamic DMA mapping support.
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <linux/dmar.h>
+#include <asm/iommu.h>
+#include <asm/machvec.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/machvec.h>
+#include <asm/system.h>
+
+#ifdef CONFIG_DMAR
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/page.h>
+#include <asm/iommu.h>
+
+dma_addr_t bad_dma_address __read_mostly;
+EXPORT_SYMBOL(bad_dma_address);
+
+static int iommu_sac_force __read_mostly;
+
+int no_iommu __read_mostly;
+#ifdef CONFIG_IOMMU_DEBUG
+int force_iommu __read_mostly = 1;
+#else
+int force_iommu __read_mostly;
+#endif
+
+/* Set this to 1 if there is a HW IOMMU in the system */
+int iommu_detected __read_mostly;
+
+/* Dummy device used for NULL arguments (normally ISA). Better would
+   be probably a smaller DMA mask, but this is bug-to-bug compatible
+   to i386. */
+struct device fallback_dev = {
+       .bus_id = "fallback device",
+       .coherent_dma_mask = DMA_32BIT_MASK,
+       .dma_mask = &fallback_dev.coherent_dma_mask,
+};
+
+void __init pci_iommu_alloc(void)
+{
+       /*
+        * The order of these functions is important for
+        * fall-back/fail-over reasons
+        */
+       detect_intel_iommu();
+
+#ifdef CONFIG_SWIOTLB
+       pci_swiotlb_init();
+#endif
+}
+
+static int __init pci_iommu_init(void)
+{
+       if (iommu_detected)
+               intel_iommu_init();
+
+       return 0;
+}
+
+/* Must execute after PCI subsystem */
+fs_initcall(pci_iommu_init);
+
+void pci_iommu_shutdown(void)
+{
+       return;
+}
+
+void __init
+iommu_dma_init(void)
+{
+       return;
+}
+
+struct dma_mapping_ops *dma_ops;
+EXPORT_SYMBOL(dma_ops);
+
+int iommu_dma_supported(struct device *dev, u64 mask)
+{
+       struct dma_mapping_ops *ops = get_dma_ops(dev);
+
+#ifdef CONFIG_PCI
+       if (mask > 0xffffffff && forbid_dac > 0) {
+               dev_info(dev, "Disallowing DAC for device\n");
+               return 0;
+       }
+#endif
+
+       if (ops->dma_supported_op)
+               return ops->dma_supported_op(dev, mask);
+
+       /* Copied from i386. Doesn't make much sense, because it will
+          only work for pci_alloc_coherent.
+          The caller just has to use GFP_DMA in this case. */
+       if (mask < DMA_24BIT_MASK)
+               return 0;
+
+       /* Tell the device to use SAC when IOMMU force is on.  This
+          allows the driver to use cheaper accesses in some cases.
+
+          Problem with this is that if we overflow the IOMMU area and
+          return DAC as fallback address the device may not handle it
+          correctly.
+
+          As a special case some controllers have a 39bit address
+          mode that is as efficient as 32bit (aic79xx). Don't force
+          SAC for these.  Assume all masks <= 40 bits are of this
+          type. Normally this doesn't make any difference, but gives
+          more gentle handling of IOMMU overflow. */
+       if (iommu_sac_force && (mask >= DMA_40BIT_MASK)) {
+               dev_info(dev, "Force SAC with mask %lx\n", mask);
+               return 0;
+       }
+
+       return 1;
+}
+EXPORT_SYMBOL(iommu_dma_supported);
+
+#endif
diff --git a/arch/ia64/kernel/pci-swiotlb.c b/arch/ia64/kernel/pci-swiotlb.c
new file mode 100644 (file)
index 0000000..16c5051
--- /dev/null
@@ -0,0 +1,46 @@
+/* Glue code to lib/swiotlb.c */
+
+#include <linux/pci.h>
+#include <linux/cache.h>
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/swiotlb.h>
+#include <asm/dma.h>
+#include <asm/iommu.h>
+#include <asm/machvec.h>
+
+int swiotlb __read_mostly;
+EXPORT_SYMBOL(swiotlb);
+
+struct dma_mapping_ops swiotlb_dma_ops = {
+       .mapping_error = swiotlb_dma_mapping_error,
+       .alloc_coherent = swiotlb_alloc_coherent,
+       .free_coherent = swiotlb_free_coherent,
+       .map_single = swiotlb_map_single,
+       .unmap_single = swiotlb_unmap_single,
+       .sync_single_for_cpu = swiotlb_sync_single_for_cpu,
+       .sync_single_for_device = swiotlb_sync_single_for_device,
+       .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu,
+       .sync_single_range_for_device = swiotlb_sync_single_range_for_device,
+       .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
+       .sync_sg_for_device = swiotlb_sync_sg_for_device,
+       .map_sg = swiotlb_map_sg,
+       .unmap_sg = swiotlb_unmap_sg,
+       .dma_supported_op = swiotlb_dma_supported,
+};
+
+void __init pci_swiotlb_init(void)
+{
+       if (!iommu_detected) {
+#ifdef CONFIG_IA64_GENERIC
+               swiotlb = 1;
+               printk(KERN_INFO "PCI-DMA: Re-initialize machine vector.\n");
+               machvec_init("dig");
+               swiotlb_init();
+               dma_ops = &swiotlb_dma_ops;
+#else
+               panic("Unable to find Intel IOMMU");
+#endif
+       }
+}
index fc8f3509df270ba010ec4e2ce9765d0459d6f77e..ada4605d12236cdf682d182b35034afd1ccf821b 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/capability.h>
 #include <linux/rcupdate.h>
 #include <linux/completion.h>
+#include <linux/tracehook.h>
 
 #include <asm/errno.h>
 #include <asm/intrinsics.h>
@@ -3684,7 +3685,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 
                PFM_SET_WORK_PENDING(task, 1);
 
-               tsk_set_notify_resume(task);
+               set_notify_resume(task);
 
                /*
                 * XXX: send reschedule if task runs on another CPU
@@ -5044,8 +5045,6 @@ pfm_handle_work(void)
 
        PFM_SET_WORK_PENDING(current, 0);
 
-       tsk_clear_notify_resume(current);
-
        regs = task_pt_regs(current);
 
        /*
@@ -5414,7 +5413,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str
                         * when coming from ctxsw, current still points to the
                         * previous task, therefore we must work with task and not current.
                         */
-                       tsk_set_notify_resume(task);
+                       set_notify_resume(task);
                }
                /*
                 * defer until state is changed (shorten spin window). the context is locked
index 3ab8373103ecf9252f1ceeff4f2076e8da471113..c57162705147e500981235cbec79bd416c5ec136 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/delay.h>
 #include <linux/kdebug.h>
 #include <linux/utsname.h>
+#include <linux/tracehook.h>
 
 #include <asm/cpu.h>
 #include <asm/delay.h>
@@ -160,21 +161,6 @@ show_regs (struct pt_regs *regs)
                show_stack(NULL, NULL);
 }
 
-void tsk_clear_notify_resume(struct task_struct *tsk)
-{
-#ifdef CONFIG_PERFMON
-       if (tsk->thread.pfm_needs_checking)
-               return;
-#endif
-       if (test_ti_thread_flag(task_thread_info(tsk), TIF_RESTORE_RSE))
-               return;
-       clear_ti_thread_flag(task_thread_info(tsk), TIF_NOTIFY_RESUME);
-}
-
-/*
- * do_notify_resume_user():
- *     Called from notify_resume_user at entry.S, with interrupts disabled.
- */
 void
 do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
 {
@@ -203,6 +189,11 @@ do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
                ia64_do_signal(scr, in_syscall);
        }
 
+       if (test_thread_flag(TIF_NOTIFY_RESUME)) {
+               clear_thread_flag(TIF_NOTIFY_RESUME);
+               tracehook_notify_resume(&scr->pt);
+       }
+
        /* copy user rbs to kernel rbs */
        if (unlikely(test_thread_flag(TIF_RESTORE_RSE))) {
                local_irq_enable();     /* force interrupt enable */
@@ -251,7 +242,6 @@ default_idle (void)
 /* We don't actually take CPU down, just spin without interrupts. */
 static inline void play_dead(void)
 {
-       extern void ia64_cpu_local_tick (void);
        unsigned int this_cpu = smp_processor_id();
 
        /* Ack it */
index 2a9943b5947f9d68cae7f30c214852dc5c5c0bc8..92c9689b7d9764a80fc72b8a06f2c45b10443387 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/signal.h>
 #include <linux/regset.h>
 #include <linux/elf.h>
+#include <linux/tracehook.h>
 
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -603,7 +604,7 @@ void ia64_ptrace_stop(void)
 {
        if (test_and_set_tsk_thread_flag(current, TIF_RESTORE_RSE))
                return;
-       tsk_set_notify_resume(current);
+       set_notify_resume(current);
        unw_init_running(do_sync_rbs, ia64_sync_user_rbs);
 }
 
@@ -613,7 +614,6 @@ void ia64_ptrace_stop(void)
 void ia64_sync_krbs(void)
 {
        clear_tsk_thread_flag(current, TIF_RESTORE_RSE);
-       tsk_clear_notify_resume(current);
 
        unw_init_running(do_sync_rbs, ia64_sync_kernel_rbs);
 }
@@ -644,7 +644,7 @@ ptrace_attach_sync_user_rbs (struct task_struct *child)
                spin_lock_irq(&child->sighand->siglock);
                if (child->state == TASK_STOPPED &&
                    !test_and_set_tsk_thread_flag(child, TIF_RESTORE_RSE)) {
-                       tsk_set_notify_resume(child);
+                       set_notify_resume(child);
 
                        child->state = TASK_TRACED;
                        stopped = 1;
@@ -1232,37 +1232,16 @@ arch_ptrace (struct task_struct *child, long request, long addr, long data)
 }
 
 
-static void
-syscall_trace (void)
-{
-       /*
-        * 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;
-       }
-}
-
 /* "asmlinkage" so the input arguments are preserved... */
 
-asmlinkage void
+asmlinkage long
 syscall_trace_enter (long arg0, long arg1, long arg2, long arg3,
                     long arg4, long arg5, long arg6, long arg7,
                     struct pt_regs regs)
 {
-       if (test_thread_flag(TIF_SYSCALL_TRACE) 
-           && (current->ptrace & PT_PTRACED))
-               syscall_trace();
+       if (test_thread_flag(TIF_SYSCALL_TRACE))
+               if (tracehook_report_syscall_entry(&regs))
+                       return -ENOSYS;
 
        /* copy user rbs to kernel rbs */
        if (test_thread_flag(TIF_RESTORE_RSE))
@@ -1283,6 +1262,7 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3,
                audit_syscall_entry(arch, syscall, arg0, arg1, arg2, arg3);
        }
 
+       return 0;
 }
 
 /* "asmlinkage" so the input arguments are preserved... */
@@ -1292,6 +1272,8 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
                     long arg4, long arg5, long arg6, long arg7,
                     struct pt_regs regs)
 {
+       int step;
+
        if (unlikely(current->audit_context)) {
                int success = AUDITSC_RESULT(regs.r10);
                long result = regs.r8;
@@ -1301,10 +1283,9 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
                audit_syscall_exit(success, result);
        }
 
-       if ((test_thread_flag(TIF_SYSCALL_TRACE)
-           || test_thread_flag(TIF_SINGLESTEP))
-           && (current->ptrace & PT_PTRACED))
-               syscall_trace();
+       step = test_thread_flag(TIF_SINGLESTEP);
+       if (step || test_thread_flag(TIF_SYSCALL_TRACE))
+               tracehook_report_syscall_exit(&regs, step);
 
        /* copy user rbs to kernel rbs */
        if (test_thread_flag(TIF_RESTORE_RSE))
@@ -1940,7 +1921,7 @@ gpregs_writeback(struct task_struct *target,
 {
        if (test_and_set_tsk_thread_flag(target, TIF_RESTORE_RSE))
                return 0;
-       tsk_set_notify_resume(target);
+       set_notify_resume(target);
        return do_regset_call(do_gpregs_writeback, target, regset, 0, 0,
                NULL, NULL);
 }
@@ -2199,3 +2180,68 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *tsk)
 #endif
        return &user_ia64_view;
 }
+
+struct syscall_get_set_args {
+       unsigned int i;
+       unsigned int n;
+       unsigned long *args;
+       struct pt_regs *regs;
+       int rw;
+};
+
+static void syscall_get_set_args_cb(struct unw_frame_info *info, void *data)
+{
+       struct syscall_get_set_args *args = data;
+       struct pt_regs *pt = args->regs;
+       unsigned long *krbs, cfm, ndirty;
+       int i, count;
+
+       if (unw_unwind_to_user(info) < 0)
+               return;
+
+       cfm = pt->cr_ifs;
+       krbs = (unsigned long *)info->task + IA64_RBS_OFFSET/8;
+       ndirty = ia64_rse_num_regs(krbs, krbs + (pt->loadrs >> 19));
+
+       count = 0;
+       if (in_syscall(pt))
+               count = min_t(int, args->n, cfm & 0x7f);
+
+       for (i = 0; i < count; i++) {
+               if (args->rw)
+                       *ia64_rse_skip_regs(krbs, ndirty + i + args->i) =
+                               args->args[i];
+               else
+                       args->args[i] = *ia64_rse_skip_regs(krbs,
+                               ndirty + i + args->i);
+       }
+
+       if (!args->rw) {
+               while (i < args->n) {
+                       args->args[i] = 0;
+                       i++;
+               }
+       }
+}
+
+void ia64_syscall_get_set_arguments(struct task_struct *task,
+       struct pt_regs *regs, unsigned int i, unsigned int n,
+       unsigned long *args, int rw)
+{
+       struct syscall_get_set_args data = {
+               .i = i,
+               .n = n,
+               .args = args,
+               .regs = regs,
+               .rw = rw,
+       };
+
+       if (task == current)
+               unw_init_running(syscall_get_set_args_cb, &data);
+       else {
+               struct unw_frame_info ufi;
+               memset(&ufi, 0, sizeof(ufi));
+               unw_init_from_blocked_task(&ufi, task);
+               syscall_get_set_args_cb(&ufi, &data);
+       }
+}
index 916ba898237f27a6eca8d5b79cc92cce86b716f1..ae7911702bf8ac412921e6b1448da9eaa473b9d6 100644 (file)
@@ -116,6 +116,13 @@ unsigned int num_io_spaces;
  */
 #define        I_CACHE_STRIDE_SHIFT    5       /* Safest way to go: 32 bytes by 32 bytes */
 unsigned long ia64_i_cache_stride_shift = ~0;
+/*
+ * "clflush_cache_range()" needs to know what processor dependent stride size to
+ * use when it flushes cache lines including both d-cache and i-cache.
+ */
+/* Safest way to go: 32 bytes by 32 bytes */
+#define        CACHE_STRIDE_SHIFT      5
+unsigned long ia64_cache_stride_shift = ~0;
 
 /*
  * The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1).  This
@@ -852,13 +859,14 @@ setup_per_cpu_areas (void)
 }
 
 /*
- * Calculate the max. cache line size.
+ * Do the following calculations:
  *
- * In addition, the minimum of the i-cache stride sizes is calculated for
- * "flush_icache_range()".
+ * 1. the max. cache line size.
+ * 2. the minimum of the i-cache stride sizes for "flush_icache_range()".
+ * 3. the minimum of the cache stride sizes for "clflush_cache_range()".
  */
 static void __cpuinit
-get_max_cacheline_size (void)
+get_cache_info(void)
 {
        unsigned long line_size, max = 1;
        u64 l, levels, unique_caches;
@@ -872,12 +880,14 @@ get_max_cacheline_size (void)
                 max = SMP_CACHE_BYTES;
                /* Safest setup for "flush_icache_range()" */
                ia64_i_cache_stride_shift = I_CACHE_STRIDE_SHIFT;
+               /* Safest setup for "clflush_cache_range()" */
+               ia64_cache_stride_shift = CACHE_STRIDE_SHIFT;
                goto out;
         }
 
        for (l = 0; l < levels; ++l) {
-               status = ia64_pal_cache_config_info(l, /* cache_type (data_or_unified)= */ 2,
-                                                   &cci);
+               /* cache_type (data_or_unified)=2 */
+               status = ia64_pal_cache_config_info(l, 2, &cci);
                if (status != 0) {
                        printk(KERN_ERR
                               "%s: ia64_pal_cache_config_info(l=%lu, 2) failed (status=%ld)\n",
@@ -885,15 +895,21 @@ get_max_cacheline_size (void)
                        max = SMP_CACHE_BYTES;
                        /* The safest setup for "flush_icache_range()" */
                        cci.pcci_stride = I_CACHE_STRIDE_SHIFT;
+                       /* The safest setup for "clflush_cache_range()" */
+                       ia64_cache_stride_shift = CACHE_STRIDE_SHIFT;
                        cci.pcci_unified = 1;
+               } else {
+                       if (cci.pcci_stride < ia64_cache_stride_shift)
+                               ia64_cache_stride_shift = cci.pcci_stride;
+
+                       line_size = 1 << cci.pcci_line_size;
+                       if (line_size > max)
+                               max = line_size;
                }
-               line_size = 1 << cci.pcci_line_size;
-               if (line_size > max)
-                       max = line_size;
+
                if (!cci.pcci_unified) {
-                       status = ia64_pal_cache_config_info(l,
-                                                   /* cache_type (instruction)= */ 1,
-                                                   &cci);
+                       /* cache_type (instruction)=1*/
+                       status = ia64_pal_cache_config_info(l, 1, &cci);
                        if (status != 0) {
                                printk(KERN_ERR
                                "%s: ia64_pal_cache_config_info(l=%lu, 1) failed (status=%ld)\n",
@@ -947,7 +963,7 @@ cpu_init (void)
        }
 #endif
 
-       get_max_cacheline_size();
+       get_cache_info();
 
        /*
         * We can't pass "local_cpu_data" to identify_cpu() because we haven't called
index 19c5a78636fc92fd78a38642063107da1895bd59..e12500a9c44390b025feeb0b670baac1c1ffd523 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/ptrace.h>
+#include <linux/tracehook.h>
 #include <linux/sched.h>
 #include <linux/signal.h>
 #include <linux/smp.h>
@@ -439,6 +440,13 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigse
                sigaddset(&current->blocked, sig);
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
+
+       /*
+        * Let tracing know that we've done the handler setup.
+        */
+       tracehook_signal_handler(sig, info, ka, &scr->pt,
+                                test_thread_flag(TIF_SINGLESTEP));
+
        return 1;
 }
 
index c0699f0e35a926936113e42d925b4fd08318c1c3..a312c9e9b9efa2ecd194aa7f88a98a233749dbf6 100644 (file)
@@ -1114,7 +1114,7 @@ static void kvm_migrate_hlt_timer(struct kvm_vcpu *vcpu)
        struct hrtimer *p_ht = &vcpu->arch.hlt_timer;
 
        if (hrtimer_cancel(p_ht))
-               hrtimer_start(p_ht, p_ht->expires, HRTIMER_MODE_ABS);
+               hrtimer_start_expires(p_ht, HRTIMER_MODE_ABS);
 }
 
 static enum hrtimer_restart hlt_timer_fn(struct hrtimer *data)
index 2a0d27f2f21bdd200df5c62a010e4673bc314abd..1d8c88860063d303c7efa807078326744b55e118 100644 (file)
@@ -60,3 +60,58 @@ GLOBAL_ENTRY(flush_icache_range)
        mov     ar.lc=r3                // restore ar.lc
        br.ret.sptk.many rp
 END(flush_icache_range)
+
+       /*
+        * clflush_cache_range(start,size)
+        *
+        *      Flush cache lines from start to start+size-1.
+        *
+        *      Must deal with range from start to start+size-1 but nothing else
+        *      (need to be careful not to touch addresses that may be
+        *      unmapped).
+        *
+        *      Note: "in0" and "in1" are preserved for debugging purposes.
+        */
+       .section .kprobes.text,"ax"
+GLOBAL_ENTRY(clflush_cache_range)
+
+       .prologue
+       alloc   r2=ar.pfs,2,0,0,0
+       movl    r3=ia64_cache_stride_shift
+       mov     r21=1
+       add     r22=in1,in0
+       ;;
+       ld8     r20=[r3]                // r20: stride shift
+       sub     r22=r22,r0,1            // last byte address
+       ;;
+       shr.u   r23=in0,r20             // start / (stride size)
+       shr.u   r22=r22,r20             // (last byte address) / (stride size)
+       shl     r21=r21,r20             // r21: stride size of the i-cache(s)
+       ;;
+       sub     r8=r22,r23              // number of strides - 1
+       shl     r24=r23,r20             // r24: addresses for "fc" =
+                                       //      "start" rounded down to stride
+                                       //      boundary
+       .save   ar.lc,r3
+       mov     r3=ar.lc                // save ar.lc
+       ;;
+
+       .body
+       mov     ar.lc=r8
+       ;;
+       /*
+        * 32 byte aligned loop, even number of (actually 2) bundles
+        */
+.Loop_fc:
+       fc      r24             // issuable on M0 only
+       add     r24=r21,r24     // we flush "stride size" bytes per iteration
+       nop.i   0
+       br.cloop.sptk.few .Loop_fc
+       ;;
+       sync.i
+       ;;
+       srlz.i
+       ;;
+       mov     ar.lc=r3                // restore ar.lc
+       br.ret.sptk.many rp
+END(clflush_cache_range)
index 8caf42471f0d1e72d3b2adc007a9d8e8dcc76bf0..bd9818a36b4769e9aa961ea82206bdfb8ff21fb9 100644 (file)
@@ -362,9 +362,13 @@ ia64_tlb_init (void)
                per_cpu(ia64_tr_num, cpu) =
                                vm_info_1.pal_vm_info_1_s.max_dtr_entry+1;
        if (per_cpu(ia64_tr_num, cpu) > IA64_TR_ALLOC_MAX) {
+               static int justonce = 1;
                per_cpu(ia64_tr_num, cpu) = IA64_TR_ALLOC_MAX;
-               printk(KERN_DEBUG "TR register number exceeds IA64_TR_ALLOC_MAX!"
-                       "IA64_TR_ALLOC_MAX should be extended\n");
+               if (justonce) {
+                       justonce = 0;
+                       printk(KERN_DEBUG "TR register number exceeds "
+                              "IA64_TR_ALLOC_MAX!\n");
+               }
        }
 }
 
index 125a602a660d13205a4227b14ec309cf4a00837d..31b545c35460851d8e46e1e935198c13d218afe7 100644 (file)
 #include <linux/init.h>
 #include <linux/errno.h>
  
-extern int perfmon_init(struct oprofile_operations * ops);
+extern int perfmon_init(struct oprofile_operations *ops);
 extern void perfmon_exit(void);
 extern void ia64_backtrace(struct pt_regs * const regs, unsigned int depth);
 
-int __init oprofile_arch_init(struct oprofile_operations * ops)
+int __init oprofile_arch_init(struct oprofile_operations *ops)
 {
        int ret = -ENODEV;
 
index bc41dd32fec674c418bff10ce2979179a4ee359e..192d3e8e1f6597703a13203acc4ba5bdeac55e2e 100644 (file)
@@ -56,7 +56,7 @@ static pfm_buffer_fmt_t oprofile_fmt = {
 };
 
 
-static char * get_cpu_type(void)
+static char *get_cpu_type(void)
 {
        __u8 family = local_cpu_data->family;
 
@@ -75,7 +75,7 @@ static char * get_cpu_type(void)
 
 static int using_perfmon;
 
-int perfmon_init(struct oprofile_operations * ops)
+int perfmon_init(struct oprofile_operations *ops)
 {
        int ret = pfm_register_buffer_fmt(&oprofile_fmt);
        if (ret)
index 7545037a86254f1f5da925f9b96f80fafcfc1a33..211fcfd115f91f1e6ec169e8abd9849c257b975f 100644 (file)
@@ -614,12 +614,17 @@ char *ia64_pci_get_legacy_mem(struct pci_bus *bus)
  * vector to get the base address.
  */
 int
-pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma)
+pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma,
+                          enum pci_mmap_state mmap_state)
 {
        unsigned long size = vma->vm_end - vma->vm_start;
        pgprot_t prot;
        char *addr;
 
+       /* We only support mmap'ing of legacy memory space */
+       if (mmap_state != pci_mmap_mem)
+               return -ENOSYS;
+
        /*
         * Avoid attribute aliasing.  See Documentation/ia64/aliasing.txt
         * for more details.
diff --git a/arch/ia64/scripts/pvcheck.sed b/arch/ia64/scripts/pvcheck.sed
new file mode 100644 (file)
index 0000000..ba66ac2
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# Checker for paravirtualizations of privileged operations.
+#
+s/ssm.*psr\.ic.*/.warning \"ssm psr.ic should not be used directly\"/g
+s/rsm.*psr\.ic.*/.warning \"rsm psr.ic should not be used directly\"/g
+s/ssm.*psr\.i.*/.warning \"ssm psr.i should not be used directly\"/g
+s/rsm.*psr\.i.*/.warning \"rsm psr.i should not be used directly\"/g
+s/ssm.*psr\.dt.*/.warning \"ssm psr.dt should not be used directly\"/g
+s/rsm.*psr\.dt.*/.warning \"rsm psr.dt should not be used directly\"/g
+s/mov.*=.*cr\.ifa/.warning \"cr.ifa should not used directly\"/g
+s/mov.*=.*cr\.itir/.warning \"cr.itir should not used directly\"/g
+s/mov.*=.*cr\.isr/.warning \"cr.isr should not used directly\"/g
+s/mov.*=.*cr\.iha/.warning \"cr.iha should not used directly\"/g
+s/mov.*=.*cr\.ipsr/.warning \"cr.ipsr should not used directly\"/g
+s/mov.*=.*cr\.iim/.warning \"cr.iim should not used directly\"/g
+s/mov.*=.*cr\.iip/.warning \"cr.iip should not used directly\"/g
+s/mov.*=.*cr\.ivr/.warning \"cr.ivr should not used directly\"/g
+s/mov.*=[^\.]*psr/.warning \"psr should not used directly\"/g  # avoid ar.fpsr
+s/mov.*=.*ar\.eflags/.warning \"ar.eflags should not used directly\"/g
+s/mov.*cr\.ifa.*=.*/.warning \"cr.ifa should not used directly\"/g
+s/mov.*cr\.itir.*=.*/.warning \"cr.itir should not used directly\"/g
+s/mov.*cr\.iha.*=.*/.warning \"cr.iha should not used directly\"/g
+s/mov.*cr\.ipsr.*=.*/.warning \"cr.ipsr should not used directly\"/g
+s/mov.*cr\.ifs.*=.*/.warning \"cr.ifs should not used directly\"/g
+s/mov.*cr\.iip.*=.*/.warning \"cr.iip should not used directly\"/g
+s/mov.*cr\.kr.*=.*/.warning \"cr.kr should not used directly\"/g
+s/mov.*ar\.eflags.*=.*/.warning \"ar.eflags should not used directly\"/g
+s/itc\.i.*/.warning \"itc.i should not be used directly.\"/g
+s/itc\.d.*/.warning \"itc.d should not be used directly.\"/g
+s/bsw\.0/.warning \"bsw.0 should not be used directly.\"/g
+s/bsw\.1/.warning \"bsw.1 should not be used directly.\"/g
+s/ptc\.ga.*/.warning \"ptc.ga should not be used directly.\"/g
index 6568942a95f074514d28a96e7ab5b0acffff5173..bc610a6c7851bab9c4a58c639cea8d12778724c9 100644 (file)
@@ -232,7 +232,7 @@ exit:
 static unsigned int
 get_host_devfn(acpi_handle device_handle, acpi_handle rootbus_handle)
 {
-       unsigned long adr;
+       unsigned long long adr;
        acpi_handle child;
        unsigned int devfn;
        int function;
@@ -292,8 +292,8 @@ get_host_devfn(acpi_handle device_handle, acpi_handle rootbus_handle)
 static acpi_status
 find_matching_device(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
-       unsigned long bbn = -1;
-       unsigned long adr;
+       unsigned long long bbn = -1;
+       unsigned long long adr;
        acpi_handle parent = NULL;
        acpi_status status;
        unsigned int devfn;
@@ -348,7 +348,7 @@ sn_acpi_get_pcidev_info(struct pci_dev *dev, struct pcidev_info **pcidev_info,
        unsigned int host_devfn;
        struct sn_pcidev_match pcidev_match;
        acpi_handle rootbus_handle;
-       unsigned long segment;
+       unsigned long long segment;
        acpi_status status;
 
        rootbus_handle = PCI_CONTROLLER(dev)->acpi_handle;
@@ -357,7 +357,7 @@ sn_acpi_get_pcidev_info(struct pci_dev *dev, struct pcidev_info **pcidev_info,
         if (ACPI_SUCCESS(status)) {
                if (segment != pci_domain_nr(dev)) {
                        printk(KERN_ERR
-                              "%s: Segment number mismatch, 0x%lx vs 0x%x for: ",
+                              "%s: Segment number mismatch, 0x%llx vs 0x%x for: ",
                               __func__, segment, pci_domain_nr(dev));
                        acpi_ns_print_node_pathname(rootbus_handle, NULL);
                        printk("\n");
diff --git a/arch/ia64/xen/Kconfig b/arch/ia64/xen/Kconfig
new file mode 100644 (file)
index 0000000..f1683a2
--- /dev/null
@@ -0,0 +1,26 @@
+#
+# This Kconfig describes xen/ia64 options
+#
+
+config XEN
+       bool "Xen hypervisor support"
+       default y
+       depends on PARAVIRT && MCKINLEY && IA64_PAGE_SIZE_16KB && EXPERIMENTAL
+       select XEN_XENCOMM
+       select NO_IDLE_HZ
+
+       # those are required to save/restore.
+       select ARCH_SUSPEND_POSSIBLE
+       select SUSPEND
+       select PM_SLEEP
+       help
+         Enable Xen hypervisor support.  Resulting kernel runs
+         both as a guest OS on Xen and natively on hardware.
+
+config XEN_XENCOMM
+       depends on XEN
+       bool
+
+config NO_IDLE_HZ
+       depends on XEN
+       bool
diff --git a/arch/ia64/xen/Makefile b/arch/ia64/xen/Makefile
new file mode 100644 (file)
index 0000000..0ad0224
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# Makefile for Xen components
+#
+
+obj-y := hypercall.o xenivt.o xensetup.o xen_pv_ops.o irq_xen.o \
+        hypervisor.o xencomm.o xcom_hcall.o grant-table.o time.o suspend.o
+
+obj-$(CONFIG_IA64_GENERIC) += machvec.o
+
+AFLAGS_xenivt.o += -D__IA64_ASM_PARAVIRTUALIZED_XEN
+
+# xen multi compile
+ASM_PARAVIRT_MULTI_COMPILE_SRCS = ivt.S entry.S
+ASM_PARAVIRT_OBJS = $(addprefix xen-,$(ASM_PARAVIRT_MULTI_COMPILE_SRCS:.S=.o))
+obj-y += $(ASM_PARAVIRT_OBJS)
+define paravirtualized_xen
+AFLAGS_$(1) += -D__IA64_ASM_PARAVIRTUALIZED_XEN
+endef
+$(foreach o,$(ASM_PARAVIRT_OBJS),$(eval $(call paravirtualized_xen,$(o))))
+
+$(obj)/xen-%.o: $(src)/../kernel/%.S FORCE
+       $(call if_changed_dep,as_o_S)
diff --git a/arch/ia64/xen/grant-table.c b/arch/ia64/xen/grant-table.c
new file mode 100644 (file)
index 0000000..777dd9a
--- /dev/null
@@ -0,0 +1,155 @@
+/******************************************************************************
+ * arch/ia64/xen/grant-table.c
+ *
+ * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * 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/vmalloc.h>
+#include <linux/mm.h>
+
+#include <xen/interface/xen.h>
+#include <xen/interface/memory.h>
+#include <xen/grant_table.h>
+
+#include <asm/xen/hypervisor.h>
+
+struct vm_struct *xen_alloc_vm_area(unsigned long size)
+{
+       int order;
+       unsigned long virt;
+       unsigned long nr_pages;
+       struct vm_struct *area;
+
+       order = get_order(size);
+       virt = __get_free_pages(GFP_KERNEL, order);
+       if (virt == 0)
+               goto err0;
+       nr_pages = 1 << order;
+       scrub_pages(virt, nr_pages);
+
+       area = kmalloc(sizeof(*area), GFP_KERNEL);
+       if (area == NULL)
+               goto err1;
+
+       area->flags = VM_IOREMAP;
+       area->addr = (void *)virt;
+       area->size = size;
+       area->pages = NULL;
+       area->nr_pages = nr_pages;
+       area->phys_addr = 0;    /* xenbus_map_ring_valloc uses this field!  */
+
+       return area;
+
+err1:
+       free_pages(virt, order);
+err0:
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(xen_alloc_vm_area);
+
+void xen_free_vm_area(struct vm_struct *area)
+{
+       unsigned int order = get_order(area->size);
+       unsigned long i;
+       unsigned long phys_addr = __pa(area->addr);
+
+       /* This area is used for foreign page mappping.
+        * So underlying machine page may not be assigned. */
+       for (i = 0; i < (1 << order); i++) {
+               unsigned long ret;
+               unsigned long gpfn = (phys_addr >> PAGE_SHIFT) + i;
+               struct xen_memory_reservation reservation = {
+                       .nr_extents   = 1,
+                       .address_bits = 0,
+                       .extent_order = 0,
+                       .domid        = DOMID_SELF
+               };
+               set_xen_guest_handle(reservation.extent_start, &gpfn);
+               ret = HYPERVISOR_memory_op(XENMEM_populate_physmap,
+                                          &reservation);
+               BUG_ON(ret != 1);
+       }
+       free_pages((unsigned long)area->addr, order);
+       kfree(area);
+}
+EXPORT_SYMBOL_GPL(xen_free_vm_area);
+
+
+/****************************************************************************
+ * grant table hack
+ * cmd: GNTTABOP_xxx
+ */
+
+int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
+                          unsigned long max_nr_gframes,
+                          struct grant_entry **__shared)
+{
+       *__shared = __va(frames[0] << PAGE_SHIFT);
+       return 0;
+}
+
+void arch_gnttab_unmap_shared(struct grant_entry *shared,
+                             unsigned long nr_gframes)
+{
+       /* nothing */
+}
+
+static void
+gnttab_map_grant_ref_pre(struct gnttab_map_grant_ref *uop)
+{
+       uint32_t flags;
+
+       flags = uop->flags;
+
+       if (flags & GNTMAP_host_map) {
+               if (flags & GNTMAP_application_map) {
+                       printk(KERN_DEBUG
+                              "GNTMAP_application_map is not supported yet: "
+                              "flags 0x%x\n", flags);
+                       BUG();
+               }
+               if (flags & GNTMAP_contains_pte) {
+                       printk(KERN_DEBUG
+                              "GNTMAP_contains_pte is not supported yet: "
+                              "flags 0x%x\n", flags);
+                       BUG();
+               }
+       } else if (flags & GNTMAP_device_map) {
+               printk("GNTMAP_device_map is not supported yet 0x%x\n", flags);
+               BUG();  /* not yet. actually this flag is not used. */
+       } else {
+               BUG();
+       }
+}
+
+int
+HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
+{
+       if (cmd == GNTTABOP_map_grant_ref) {
+               unsigned int i;
+               for (i = 0; i < count; i++) {
+                       gnttab_map_grant_ref_pre(
+                               (struct gnttab_map_grant_ref *)uop + i);
+               }
+       }
+       return xencomm_hypercall_grant_table_op(cmd, uop, count);
+}
+
+EXPORT_SYMBOL(HYPERVISOR_grant_table_op);
diff --git a/arch/ia64/xen/hypercall.S b/arch/ia64/xen/hypercall.S
new file mode 100644 (file)
index 0000000..d4ff0b9
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Support routines for Xen hypercalls
+ *
+ * Copyright (C) 2005 Dan Magenheimer <dan.magenheimer@hp.com>
+ * Copyright (C) 2008 Yaozu (Eddie) Dong <eddie.dong@intel.com>
+ */
+
+#include <asm/asmmacro.h>
+#include <asm/intrinsics.h>
+#include <asm/xen/privop.h>
+
+/*
+ * Hypercalls without parameter.
+ */
+#define __HCALL0(name,hcall)           \
+       GLOBAL_ENTRY(name);             \
+       break   hcall;                  \
+       br.ret.sptk.many rp;            \
+       END(name)
+
+/*
+ * Hypercalls with 1 parameter.
+ */
+#define __HCALL1(name,hcall)           \
+       GLOBAL_ENTRY(name);             \
+       mov r8=r32;                     \
+       break   hcall;                  \
+       br.ret.sptk.many rp;            \
+       END(name)
+
+/*
+ * Hypercalls with 2 parameters.
+ */
+#define __HCALL2(name,hcall)           \
+       GLOBAL_ENTRY(name);             \
+       mov r8=r32;                     \
+       mov r9=r33;                     \
+       break   hcall;                  \
+       br.ret.sptk.many rp;            \
+       END(name)
+
+__HCALL0(xen_get_psr, HYPERPRIVOP_GET_PSR)
+__HCALL0(xen_get_ivr, HYPERPRIVOP_GET_IVR)
+__HCALL0(xen_get_tpr, HYPERPRIVOP_GET_TPR)
+__HCALL0(xen_hyper_ssm_i, HYPERPRIVOP_SSM_I)
+
+__HCALL1(xen_set_tpr, HYPERPRIVOP_SET_TPR)
+__HCALL1(xen_eoi, HYPERPRIVOP_EOI)
+__HCALL1(xen_thash, HYPERPRIVOP_THASH)
+__HCALL1(xen_set_itm, HYPERPRIVOP_SET_ITM)
+__HCALL1(xen_get_rr, HYPERPRIVOP_GET_RR)
+__HCALL1(xen_fc, HYPERPRIVOP_FC)
+__HCALL1(xen_get_cpuid, HYPERPRIVOP_GET_CPUID)
+__HCALL1(xen_get_pmd, HYPERPRIVOP_GET_PMD)
+
+__HCALL2(xen_ptcga, HYPERPRIVOP_PTC_GA)
+__HCALL2(xen_set_rr, HYPERPRIVOP_SET_RR)
+__HCALL2(xen_set_kr, HYPERPRIVOP_SET_KR)
+
+#ifdef CONFIG_IA32_SUPPORT
+__HCALL1(xen_get_eflag, HYPERPRIVOP_GET_EFLAG)
+__HCALL1(xen_set_eflag, HYPERPRIVOP_SET_EFLAG) // refer SDM vol1 3.1.8
+#endif /* CONFIG_IA32_SUPPORT */
+
+GLOBAL_ENTRY(xen_set_rr0_to_rr4)
+       mov r8=r32
+       mov r9=r33
+       mov r10=r34
+       mov r11=r35
+       mov r14=r36
+       XEN_HYPER_SET_RR0_TO_RR4
+       br.ret.sptk.many rp
+       ;;
+END(xen_set_rr0_to_rr4)
+
+GLOBAL_ENTRY(xen_send_ipi)
+       mov r14=r32
+       mov r15=r33
+       mov r2=0x400
+       break 0x1000
+       ;;
+       br.ret.sptk.many rp
+       ;;
+END(xen_send_ipi)
+
+GLOBAL_ENTRY(__hypercall)
+       mov r2=r37
+       break 0x1000
+       br.ret.sptk.many b0
+       ;;
+END(__hypercall)
diff --git a/arch/ia64/xen/hypervisor.c b/arch/ia64/xen/hypervisor.c
new file mode 100644 (file)
index 0000000..cac4d97
--- /dev/null
@@ -0,0 +1,96 @@
+/******************************************************************************
+ * arch/ia64/xen/hypervisor.c
+ *
+ * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * 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/efi.h>
+#include <asm/xen/hypervisor.h>
+#include <asm/xen/privop.h>
+
+#include "irq_xen.h"
+
+struct shared_info *HYPERVISOR_shared_info __read_mostly =
+       (struct shared_info *)XSI_BASE;
+EXPORT_SYMBOL(HYPERVISOR_shared_info);
+
+DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
+
+struct start_info *xen_start_info;
+EXPORT_SYMBOL(xen_start_info);
+
+EXPORT_SYMBOL(xen_domain_type);
+
+EXPORT_SYMBOL(__hypercall);
+
+/* Stolen from arch/x86/xen/enlighten.c */
+/*
+ * Flag to determine whether vcpu info placement is available on all
+ * VCPUs.  We assume it is to start with, and then set it to zero on
+ * the first failure.  This is because it can succeed on some VCPUs
+ * and not others, since it can involve hypervisor memory allocation,
+ * or because the guest failed to guarantee all the appropriate
+ * constraints on all VCPUs (ie buffer can't cross a page boundary).
+ *
+ * Note that any particular CPU may be using a placed vcpu structure,
+ * but we can only optimise if the all are.
+ *
+ * 0: not available, 1: available
+ */
+
+static void __init xen_vcpu_setup(int cpu)
+{
+       /*
+        * WARNING:
+        * before changing MAX_VIRT_CPUS,
+        * check that shared_info fits on a page
+        */
+       BUILD_BUG_ON(sizeof(struct shared_info) > PAGE_SIZE);
+       per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
+}
+
+void __init xen_setup_vcpu_info_placement(void)
+{
+       int cpu;
+
+       for_each_possible_cpu(cpu)
+               xen_vcpu_setup(cpu);
+}
+
+void __cpuinit
+xen_cpu_init(void)
+{
+       xen_smp_intr_init();
+}
+
+/**************************************************************************
+ * opt feature
+ */
+void
+xen_ia64_enable_opt_feature(void)
+{
+       /* Enable region 7 identity map optimizations in Xen */
+       struct xen_ia64_opt_feature optf;
+
+       optf.cmd = XEN_IA64_OPTF_IDENT_MAP_REG7;
+       optf.on = XEN_IA64_OPTF_ON;
+       optf.pgprot = pgprot_val(PAGE_KERNEL);
+       optf.key = 0;   /* No key on linux. */
+       HYPERVISOR_opt_feature(&optf);
+}
diff --git a/arch/ia64/xen/irq_xen.c b/arch/ia64/xen/irq_xen.c
new file mode 100644 (file)
index 0000000..af93aad
--- /dev/null
@@ -0,0 +1,435 @@
+/******************************************************************************
+ * arch/ia64/xen/irq_xen.c
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * 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/cpu.h>
+
+#include <xen/interface/xen.h>
+#include <xen/interface/callback.h>
+#include <xen/events.h>
+
+#include <asm/xen/privop.h>
+
+#include "irq_xen.h"
+
+/***************************************************************************
+ * pv_irq_ops
+ * irq operations
+ */
+
+static int
+xen_assign_irq_vector(int irq)
+{
+       struct physdev_irq irq_op;
+
+       irq_op.irq = irq;
+       if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op))
+               return -ENOSPC;
+
+       return irq_op.vector;
+}
+
+static void
+xen_free_irq_vector(int vector)
+{
+       struct physdev_irq irq_op;
+
+       if (vector < IA64_FIRST_DEVICE_VECTOR ||
+           vector > IA64_LAST_DEVICE_VECTOR)
+               return;
+
+       irq_op.vector = vector;
+       if (HYPERVISOR_physdev_op(PHYSDEVOP_free_irq_vector, &irq_op))
+               printk(KERN_WARNING "%s: xen_free_irq_vecotr fail vector=%d\n",
+                      __func__, vector);
+}
+
+
+static DEFINE_PER_CPU(int, timer_irq) = -1;
+static DEFINE_PER_CPU(int, ipi_irq) = -1;
+static DEFINE_PER_CPU(int, resched_irq) = -1;
+static DEFINE_PER_CPU(int, cmc_irq) = -1;
+static DEFINE_PER_CPU(int, cmcp_irq) = -1;
+static DEFINE_PER_CPU(int, cpep_irq) = -1;
+#define NAME_SIZE      15
+static DEFINE_PER_CPU(char[NAME_SIZE], timer_name);
+static DEFINE_PER_CPU(char[NAME_SIZE], ipi_name);
+static DEFINE_PER_CPU(char[NAME_SIZE], resched_name);
+static DEFINE_PER_CPU(char[NAME_SIZE], cmc_name);
+static DEFINE_PER_CPU(char[NAME_SIZE], cmcp_name);
+static DEFINE_PER_CPU(char[NAME_SIZE], cpep_name);
+#undef NAME_SIZE
+
+struct saved_irq {
+       unsigned int irq;
+       struct irqaction *action;
+};
+/* 16 should be far optimistic value, since only several percpu irqs
+ * are registered early.
+ */
+#define MAX_LATE_IRQ   16
+static struct saved_irq saved_percpu_irqs[MAX_LATE_IRQ];
+static unsigned short late_irq_cnt;
+static unsigned short saved_irq_cnt;
+static int xen_slab_ready;
+
+#ifdef CONFIG_SMP
+/* Dummy stub. Though we may check XEN_RESCHEDULE_VECTOR before __do_IRQ,
+ * it ends up to issue several memory accesses upon percpu data and
+ * thus adds unnecessary traffic to other paths.
+ */
+static irqreturn_t
+xen_dummy_handler(int irq, void *dev_id)
+{
+
+       return IRQ_HANDLED;
+}
+
+static struct irqaction xen_ipi_irqaction = {
+       .handler =      handle_IPI,
+       .flags =        IRQF_DISABLED,
+       .name =         "IPI"
+};
+
+static struct irqaction xen_resched_irqaction = {
+       .handler =      xen_dummy_handler,
+       .flags =        IRQF_DISABLED,
+       .name =         "resched"
+};
+
+static struct irqaction xen_tlb_irqaction = {
+       .handler =      xen_dummy_handler,
+       .flags =        IRQF_DISABLED,
+       .name =         "tlb_flush"
+};
+#endif
+
+/*
+ * This is xen version percpu irq registration, which needs bind
+ * to xen specific evtchn sub-system. One trick here is that xen
+ * evtchn binding interface depends on kmalloc because related
+ * port needs to be freed at device/cpu down. So we cache the
+ * registration on BSP before slab is ready and then deal them
+ * at later point. For rest instances happening after slab ready,
+ * we hook them to xen evtchn immediately.
+ *
+ * FIXME: MCA is not supported by far, and thus "nomca" boot param is
+ * required.
+ */
+static void
+__xen_register_percpu_irq(unsigned int cpu, unsigned int vec,
+                       struct irqaction *action, int save)
+{
+       irq_desc_t *desc;
+       int irq = 0;
+
+       if (xen_slab_ready) {
+               switch (vec) {
+               case IA64_TIMER_VECTOR:
+                       snprintf(per_cpu(timer_name, cpu),
+                                sizeof(per_cpu(timer_name, cpu)),
+                                "%s%d", action->name, cpu);
+                       irq = bind_virq_to_irqhandler(VIRQ_ITC, cpu,
+                               action->handler, action->flags,
+                               per_cpu(timer_name, cpu), action->dev_id);
+                       per_cpu(timer_irq, cpu) = irq;
+                       break;
+               case IA64_IPI_RESCHEDULE:
+                       snprintf(per_cpu(resched_name, cpu),
+                                sizeof(per_cpu(resched_name, cpu)),
+                                "%s%d", action->name, cpu);
+                       irq = bind_ipi_to_irqhandler(XEN_RESCHEDULE_VECTOR, cpu,
+                               action->handler, action->flags,
+                               per_cpu(resched_name, cpu), action->dev_id);
+                       per_cpu(resched_irq, cpu) = irq;
+                       break;
+               case IA64_IPI_VECTOR:
+                       snprintf(per_cpu(ipi_name, cpu),
+                                sizeof(per_cpu(ipi_name, cpu)),
+                                "%s%d", action->name, cpu);
+                       irq = bind_ipi_to_irqhandler(XEN_IPI_VECTOR, cpu,
+                               action->handler, action->flags,
+                               per_cpu(ipi_name, cpu), action->dev_id);
+                       per_cpu(ipi_irq, cpu) = irq;
+                       break;
+               case IA64_CMC_VECTOR:
+                       snprintf(per_cpu(cmc_name, cpu),
+                                sizeof(per_cpu(cmc_name, cpu)),
+                                "%s%d", action->name, cpu);
+                       irq = bind_virq_to_irqhandler(VIRQ_MCA_CMC, cpu,
+                                                     action->handler,
+                                                     action->flags,
+                                                     per_cpu(cmc_name, cpu),
+                                                     action->dev_id);
+                       per_cpu(cmc_irq, cpu) = irq;
+                       break;
+               case IA64_CMCP_VECTOR:
+                       snprintf(per_cpu(cmcp_name, cpu),
+                                sizeof(per_cpu(cmcp_name, cpu)),
+                                "%s%d", action->name, cpu);
+                       irq = bind_ipi_to_irqhandler(XEN_CMCP_VECTOR, cpu,
+                                                    action->handler,
+                                                    action->flags,
+                                                    per_cpu(cmcp_name, cpu),
+                                                    action->dev_id);
+                       per_cpu(cmcp_irq, cpu) = irq;
+                       break;
+               case IA64_CPEP_VECTOR:
+                       snprintf(per_cpu(cpep_name, cpu),
+                                sizeof(per_cpu(cpep_name, cpu)),
+                                "%s%d", action->name, cpu);
+                       irq = bind_ipi_to_irqhandler(XEN_CPEP_VECTOR, cpu,
+                                                    action->handler,
+                                                    action->flags,
+                                                    per_cpu(cpep_name, cpu),
+                                                    action->dev_id);
+                       per_cpu(cpep_irq, cpu) = irq;
+                       break;
+               case IA64_CPE_VECTOR:
+               case IA64_MCA_RENDEZ_VECTOR:
+               case IA64_PERFMON_VECTOR:
+               case IA64_MCA_WAKEUP_VECTOR:
+               case IA64_SPURIOUS_INT_VECTOR:
+                       /* No need to complain, these aren't supported. */
+                       break;
+               default:
+                       printk(KERN_WARNING "Percpu irq %d is unsupported "
+                              "by xen!\n", vec);
+                       break;
+               }
+               BUG_ON(irq < 0);
+
+               if (irq > 0) {
+                       /*
+                        * Mark percpu.  Without this, migrate_irqs() will
+                        * mark the interrupt for migrations and trigger it
+                        * on cpu hotplug.
+                        */
+                       desc = irq_desc + irq;
+                       desc->status |= IRQ_PER_CPU;
+               }
+       }
+
+       /* For BSP, we cache registered percpu irqs, and then re-walk
+        * them when initializing APs
+        */
+       if (!cpu && save) {
+               BUG_ON(saved_irq_cnt == MAX_LATE_IRQ);
+               saved_percpu_irqs[saved_irq_cnt].irq = vec;
+               saved_percpu_irqs[saved_irq_cnt].action = action;
+               saved_irq_cnt++;
+               if (!xen_slab_ready)
+                       late_irq_cnt++;
+       }
+}
+
+static void
+xen_register_percpu_irq(ia64_vector vec, struct irqaction *action)
+{
+       __xen_register_percpu_irq(smp_processor_id(), vec, action, 1);
+}
+
+static void
+xen_bind_early_percpu_irq(void)
+{
+       int i;
+
+       xen_slab_ready = 1;
+       /* There's no race when accessing this cached array, since only
+        * BSP will face with such step shortly
+        */
+       for (i = 0; i < late_irq_cnt; i++)
+               __xen_register_percpu_irq(smp_processor_id(),
+                                         saved_percpu_irqs[i].irq,
+                                         saved_percpu_irqs[i].action, 0);
+}
+
+/* FIXME: There's no obvious point to check whether slab is ready. So
+ * a hack is used here by utilizing a late time hook.
+ */
+
+#ifdef CONFIG_HOTPLUG_CPU
+static int __devinit
+unbind_evtchn_callback(struct notifier_block *nfb,
+                      unsigned long action, void *hcpu)
+{
+       unsigned int cpu = (unsigned long)hcpu;
+
+       if (action == CPU_DEAD) {
+               /* Unregister evtchn.  */
+               if (per_cpu(cpep_irq, cpu) >= 0) {
+                       unbind_from_irqhandler(per_cpu(cpep_irq, cpu), NULL);
+                       per_cpu(cpep_irq, cpu) = -1;
+               }
+               if (per_cpu(cmcp_irq, cpu) >= 0) {
+                       unbind_from_irqhandler(per_cpu(cmcp_irq, cpu), NULL);
+                       per_cpu(cmcp_irq, cpu) = -1;
+               }
+               if (per_cpu(cmc_irq, cpu) >= 0) {
+                       unbind_from_irqhandler(per_cpu(cmc_irq, cpu), NULL);
+                       per_cpu(cmc_irq, cpu) = -1;
+               }
+               if (per_cpu(ipi_irq, cpu) >= 0) {
+                       unbind_from_irqhandler(per_cpu(ipi_irq, cpu), NULL);
+                       per_cpu(ipi_irq, cpu) = -1;
+               }
+               if (per_cpu(resched_irq, cpu) >= 0) {
+                       unbind_from_irqhandler(per_cpu(resched_irq, cpu),
+                                               NULL);
+                       per_cpu(resched_irq, cpu) = -1;
+               }
+               if (per_cpu(timer_irq, cpu) >= 0) {
+                       unbind_from_irqhandler(per_cpu(timer_irq, cpu), NULL);
+                       per_cpu(timer_irq, cpu) = -1;
+               }
+       }
+       return NOTIFY_OK;
+}
+
+static struct notifier_block unbind_evtchn_notifier = {
+       .notifier_call = unbind_evtchn_callback,
+       .priority = 0
+};
+#endif
+
+void xen_smp_intr_init_early(unsigned int cpu)
+{
+#ifdef CONFIG_SMP
+       unsigned int i;
+
+       for (i = 0; i < saved_irq_cnt; i++)
+               __xen_register_percpu_irq(cpu, saved_percpu_irqs[i].irq,
+                                         saved_percpu_irqs[i].action, 0);
+#endif
+}
+
+void xen_smp_intr_init(void)
+{
+#ifdef CONFIG_SMP
+       unsigned int cpu = smp_processor_id();
+       struct callback_register event = {
+               .type = CALLBACKTYPE_event,
+               .address = { .ip = (unsigned long)&xen_event_callback },
+       };
+
+       if (cpu == 0) {
+               /* Initialization was already done for boot cpu.  */
+#ifdef CONFIG_HOTPLUG_CPU
+               /* Register the notifier only once.  */
+               register_cpu_notifier(&unbind_evtchn_notifier);
+#endif
+               return;
+       }
+
+       /* This should be piggyback when setup vcpu guest context */
+       BUG_ON(HYPERVISOR_callback_op(CALLBACKOP_register, &event));
+#endif /* CONFIG_SMP */
+}
+
+void __init
+xen_irq_init(void)
+{
+       struct callback_register event = {
+               .type = CALLBACKTYPE_event,
+               .address = { .ip = (unsigned long)&xen_event_callback },
+       };
+
+       xen_init_IRQ();
+       BUG_ON(HYPERVISOR_callback_op(CALLBACKOP_register, &event));
+       late_time_init = xen_bind_early_percpu_irq;
+}
+
+void
+xen_platform_send_ipi(int cpu, int vector, int delivery_mode, int redirect)
+{
+#ifdef CONFIG_SMP
+       /* TODO: we need to call vcpu_up here */
+       if (unlikely(vector == ap_wakeup_vector)) {
+               /* XXX
+                * This should be in __cpu_up(cpu) in ia64 smpboot.c
+                * like x86. But don't want to modify it,
+                * keep it untouched.
+                */
+               xen_smp_intr_init_early(cpu);
+
+               xen_send_ipi(cpu, vector);
+               /* vcpu_prepare_and_up(cpu); */
+               return;
+       }
+#endif
+
+       switch (vector) {
+       case IA64_IPI_VECTOR:
+               xen_send_IPI_one(cpu, XEN_IPI_VECTOR);
+               break;
+       case IA64_IPI_RESCHEDULE:
+               xen_send_IPI_one(cpu, XEN_RESCHEDULE_VECTOR);
+               break;
+       case IA64_CMCP_VECTOR:
+               xen_send_IPI_one(cpu, XEN_CMCP_VECTOR);
+               break;
+       case IA64_CPEP_VECTOR:
+               xen_send_IPI_one(cpu, XEN_CPEP_VECTOR);
+               break;
+       case IA64_TIMER_VECTOR: {
+               /* this is used only once by check_sal_cache_flush()
+                  at boot time */
+               static int used = 0;
+               if (!used) {
+                       xen_send_ipi(cpu, IA64_TIMER_VECTOR);
+                       used = 1;
+                       break;
+               }
+               /* fallthrough */
+       }
+       default:
+               printk(KERN_WARNING "Unsupported IPI type 0x%x\n",
+                      vector);
+               notify_remote_via_irq(0); /* defaults to 0 irq */
+               break;
+       }
+}
+
+static void __init
+xen_register_ipi(void)
+{
+#ifdef CONFIG_SMP
+       register_percpu_irq(IA64_IPI_VECTOR, &xen_ipi_irqaction);
+       register_percpu_irq(IA64_IPI_RESCHEDULE, &xen_resched_irqaction);
+       register_percpu_irq(IA64_IPI_LOCAL_TLB_FLUSH, &xen_tlb_irqaction);
+#endif
+}
+
+static void
+xen_resend_irq(unsigned int vector)
+{
+       (void)resend_irq_on_evtchn(vector);
+}
+
+const struct pv_irq_ops xen_irq_ops __initdata = {
+       .register_ipi = xen_register_ipi,
+
+       .assign_irq_vector = xen_assign_irq_vector,
+       .free_irq_vector = xen_free_irq_vector,
+       .register_percpu_irq = xen_register_percpu_irq,
+
+       .resend_irq = xen_resend_irq,
+};
diff --git a/arch/ia64/xen/irq_xen.h b/arch/ia64/xen/irq_xen.h
new file mode 100644 (file)
index 0000000..26110f3
--- /dev/null
@@ -0,0 +1,34 @@
+/******************************************************************************
+ * arch/ia64/xen/irq_xen.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * 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 IRQ_XEN_H
+#define IRQ_XEN_H
+
+extern void (*late_time_init)(void);
+extern char xen_event_callback;
+void __init xen_init_IRQ(void);
+
+extern const struct pv_irq_ops xen_irq_ops __initdata;
+extern void xen_smp_intr_init(void);
+extern void xen_send_ipi(int cpu, int vec);
+
+#endif /* IRQ_XEN_H */
diff --git a/arch/ia64/xen/machvec.c b/arch/ia64/xen/machvec.c
new file mode 100644 (file)
index 0000000..4ad588a
--- /dev/null
@@ -0,0 +1,4 @@
+#define MACHVEC_PLATFORM_NAME           xen
+#define MACHVEC_PLATFORM_HEADER         <asm/machvec_xen.h>
+#include <asm/machvec_init.h>
+
diff --git a/arch/ia64/xen/suspend.c b/arch/ia64/xen/suspend.c
new file mode 100644 (file)
index 0000000..fd66b04
--- /dev/null
@@ -0,0 +1,64 @@
+/******************************************************************************
+ * arch/ia64/xen/suspend.c
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * 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
+ *
+ * suspend/resume
+ */
+
+#include <xen/xen-ops.h>
+#include <asm/xen/hypervisor.h>
+#include "time.h"
+
+void
+xen_mm_pin_all(void)
+{
+       /* nothing */
+}
+
+void
+xen_mm_unpin_all(void)
+{
+       /* nothing */
+}
+
+void xen_pre_device_suspend(void)
+{
+       /* nothing */
+}
+
+void
+xen_pre_suspend()
+{
+       /* nothing */
+}
+
+void
+xen_post_suspend(int suspend_cancelled)
+{
+       if (suspend_cancelled)
+               return;
+
+       xen_ia64_enable_opt_feature();
+       /* add more if necessary */
+}
+
+void xen_arch_resume(void)
+{
+       xen_timer_resume_on_aps();
+}
diff --git a/arch/ia64/xen/time.c b/arch/ia64/xen/time.c
new file mode 100644 (file)
index 0000000..d15a94c
--- /dev/null
@@ -0,0 +1,213 @@
+/******************************************************************************
+ * arch/ia64/xen/time.c
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * 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/delay.h>
+#include <linux/kernel_stat.h>
+#include <linux/posix-timers.h>
+#include <linux/irq.h>
+#include <linux/clocksource.h>
+
+#include <asm/timex.h>
+
+#include <asm/xen/hypervisor.h>
+
+#include <xen/interface/vcpu.h>
+
+#include "../kernel/fsyscall_gtod_data.h"
+
+DEFINE_PER_CPU(struct vcpu_runstate_info, runstate);
+DEFINE_PER_CPU(unsigned long, processed_stolen_time);
+DEFINE_PER_CPU(unsigned long, processed_blocked_time);
+
+/* taken from i386/kernel/time-xen.c */
+static void xen_init_missing_ticks_accounting(int cpu)
+{
+       struct vcpu_register_runstate_memory_area area;
+       struct vcpu_runstate_info *runstate = &per_cpu(runstate, cpu);
+       int rc;
+
+       memset(runstate, 0, sizeof(*runstate));
+
+       area.addr.v = runstate;
+       rc = HYPERVISOR_vcpu_op(VCPUOP_register_runstate_memory_area, cpu,
+                               &area);
+       WARN_ON(rc && rc != -ENOSYS);
+
+       per_cpu(processed_blocked_time, cpu) = runstate->time[RUNSTATE_blocked];
+       per_cpu(processed_stolen_time, cpu) = runstate->time[RUNSTATE_runnable]
+                                           + runstate->time[RUNSTATE_offline];
+}
+
+/*
+ * Runstate accounting
+ */
+/* stolen from arch/x86/xen/time.c */
+static void get_runstate_snapshot(struct vcpu_runstate_info *res)
+{
+       u64 state_time;
+       struct vcpu_runstate_info *state;
+
+       BUG_ON(preemptible());
+
+       state = &__get_cpu_var(runstate);
+
+       /*
+        * The runstate info is always updated by the hypervisor on
+        * the current CPU, so there's no need to use anything
+        * stronger than a compiler barrier when fetching it.
+        */
+       do {
+               state_time = state->state_entry_time;
+               rmb();
+               *res = *state;
+               rmb();
+       } while (state->state_entry_time != state_time);
+}
+
+#define NS_PER_TICK (1000000000LL/HZ)
+
+static unsigned long
+consider_steal_time(unsigned long new_itm)
+{
+       unsigned long stolen, blocked;
+       unsigned long delta_itm = 0, stolentick = 0;
+       int cpu = smp_processor_id();
+       struct vcpu_runstate_info runstate;
+       struct task_struct *p = current;
+
+       get_runstate_snapshot(&runstate);
+
+       /*
+        * Check for vcpu migration effect
+        * In this case, itc value is reversed.
+        * This causes huge stolen value.
+        * This function just checks and reject this effect.
+        */
+       if (!time_after_eq(runstate.time[RUNSTATE_blocked],
+                          per_cpu(processed_blocked_time, cpu)))
+               blocked = 0;
+
+       if (!time_after_eq(runstate.time[RUNSTATE_runnable] +
+                          runstate.time[RUNSTATE_offline],
+                          per_cpu(processed_stolen_time, cpu)))
+               stolen = 0;
+
+       if (!time_after(delta_itm + new_itm, ia64_get_itc()))
+               stolentick = ia64_get_itc() - new_itm;
+
+       do_div(stolentick, NS_PER_TICK);
+       stolentick++;
+
+       do_div(stolen, NS_PER_TICK);
+
+       if (stolen > stolentick)
+               stolen = stolentick;
+
+       stolentick -= stolen;
+       do_div(blocked, NS_PER_TICK);
+
+       if (blocked > stolentick)
+               blocked = stolentick;
+
+       if (stolen > 0 || blocked > 0) {
+               account_steal_time(NULL, jiffies_to_cputime(stolen));
+               account_steal_time(idle_task(cpu), jiffies_to_cputime(blocked));
+               run_local_timers();
+
+               if (rcu_pending(cpu))
+                       rcu_check_callbacks(cpu, user_mode(get_irq_regs()));
+
+               scheduler_tick();
+               run_posix_cpu_timers(p);
+               delta_itm += local_cpu_data->itm_delta * (stolen + blocked);
+
+               if (cpu == time_keeper_id) {
+                       write_seqlock(&xtime_lock);
+                       do_timer(stolen + blocked);
+                       local_cpu_data->itm_next = delta_itm + new_itm;
+                       write_sequnlock(&xtime_lock);
+               } else {
+                       local_cpu_data->itm_next = delta_itm + new_itm;
+               }
+               per_cpu(processed_stolen_time, cpu) += NS_PER_TICK * stolen;
+               per_cpu(processed_blocked_time, cpu) += NS_PER_TICK * blocked;
+       }
+       return delta_itm;
+}
+
+static int xen_do_steal_accounting(unsigned long *new_itm)
+{
+       unsigned long delta_itm;
+       delta_itm = consider_steal_time(*new_itm);
+       *new_itm += delta_itm;
+       if (time_after(*new_itm, ia64_get_itc()) && delta_itm)
+               return 1;
+
+       return 0;
+}
+
+static void xen_itc_jitter_data_reset(void)
+{
+       u64 lcycle, ret;
+
+       do {
+               lcycle = itc_jitter_data.itc_lastcycle;
+               ret = cmpxchg(&itc_jitter_data.itc_lastcycle, lcycle, 0);
+       } while (unlikely(ret != lcycle));
+}
+
+struct pv_time_ops xen_time_ops __initdata = {
+       .init_missing_ticks_accounting  = xen_init_missing_ticks_accounting,
+       .do_steal_accounting            = xen_do_steal_accounting,
+       .clocksource_resume             = xen_itc_jitter_data_reset,
+};
+
+/* Called after suspend, to resume time.  */
+static void xen_local_tick_resume(void)
+{
+       /* Just trigger a tick.  */
+       ia64_cpu_local_tick();
+       touch_softlockup_watchdog();
+}
+
+void
+xen_timer_resume(void)
+{
+       unsigned int cpu;
+
+       xen_local_tick_resume();
+
+       for_each_online_cpu(cpu)
+               xen_init_missing_ticks_accounting(cpu);
+}
+
+static void ia64_cpu_local_tick_fn(void *unused)
+{
+       xen_local_tick_resume();
+       xen_init_missing_ticks_accounting(smp_processor_id());
+}
+
+void
+xen_timer_resume_on_aps(void)
+{
+       smp_call_function(&ia64_cpu_local_tick_fn, NULL, 1);
+}
diff --git a/arch/ia64/xen/time.h b/arch/ia64/xen/time.h
new file mode 100644 (file)
index 0000000..f98d7e1
--- /dev/null
@@ -0,0 +1,24 @@
+/******************************************************************************
+ * arch/ia64/xen/time.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * 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
+ *
+ */
+
+extern struct pv_time_ops xen_time_ops __initdata;
+void xen_timer_resume_on_aps(void);
diff --git a/arch/ia64/xen/xcom_hcall.c b/arch/ia64/xen/xcom_hcall.c
new file mode 100644 (file)
index 0000000..ccaf743
--- /dev/null
@@ -0,0 +1,441 @@
+/*
+ * 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, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *          Tristan Gingold <tristan.gingold@bull.net>
+ *
+ *          Copyright (c) 2007
+ *          Isaku Yamahata <yamahata at valinux co jp>
+ *                          VA Linux Systems Japan K.K.
+ *          consolidate mini and inline version.
+ */
+
+#include <linux/module.h>
+#include <xen/interface/xen.h>
+#include <xen/interface/memory.h>
+#include <xen/interface/grant_table.h>
+#include <xen/interface/callback.h>
+#include <xen/interface/vcpu.h>
+#include <asm/xen/hypervisor.h>
+#include <asm/xen/xencomm.h>
+
+/* Xencomm notes:
+ * This file defines hypercalls to be used by xencomm.  The hypercalls simply
+ * create inlines or mini descriptors for pointers and then call the raw arch
+ * hypercall xencomm_arch_hypercall_XXX
+ *
+ * If the arch wants to directly use these hypercalls, simply define macros
+ * in asm/xen/hypercall.h, eg:
+ *  #define HYPERVISOR_sched_op xencomm_hypercall_sched_op
+ *
+ * The arch may also define HYPERVISOR_xxx as a function and do more operations
+ * before/after doing the hypercall.
+ *
+ * Note: because only inline or mini descriptors are created these functions
+ * must only be called with in kernel memory parameters.
+ */
+
+int
+xencomm_hypercall_console_io(int cmd, int count, char *str)
+{
+       /* xen early printk uses console io hypercall before
+        * xencomm initialization. In that case, we just ignore it.
+        */
+       if (!xencomm_is_initialized())
+               return 0;
+
+       return xencomm_arch_hypercall_console_io
+               (cmd, count, xencomm_map_no_alloc(str, count));
+}
+EXPORT_SYMBOL_GPL(xencomm_hypercall_console_io);
+
+int
+xencomm_hypercall_event_channel_op(int cmd, void *op)
+{
+       struct xencomm_handle *desc;
+       desc = xencomm_map_no_alloc(op, sizeof(struct evtchn_op));
+       if (desc == NULL)
+               return -EINVAL;
+
+       return xencomm_arch_hypercall_event_channel_op(cmd, desc);
+}
+EXPORT_SYMBOL_GPL(xencomm_hypercall_event_channel_op);
+
+int
+xencomm_hypercall_xen_version(int cmd, void *arg)
+{
+       struct xencomm_handle *desc;
+       unsigned int argsize;
+
+       switch (cmd) {
+       case XENVER_version:
+               /* do not actually pass an argument */
+               return xencomm_arch_hypercall_xen_version(cmd, 0);
+       case XENVER_extraversion:
+               argsize = sizeof(struct xen_extraversion);
+               break;
+       case XENVER_compile_info:
+               argsize = sizeof(struct xen_compile_info);
+               break;
+       case XENVER_capabilities:
+               argsize = sizeof(struct xen_capabilities_info);
+               break;
+       case XENVER_changeset:
+               argsize = sizeof(struct xen_changeset_info);
+               break;
+       case XENVER_platform_parameters:
+               argsize = sizeof(struct xen_platform_parameters);
+               break;
+       case XENVER_get_features:
+               argsize = (arg == NULL) ? 0 : sizeof(struct xen_feature_info);
+               break;
+
+       default:
+               printk(KERN_DEBUG
+                      "%s: unknown version op %d\n", __func__, cmd);
+               return -ENOSYS;
+       }
+
+       desc = xencomm_map_no_alloc(arg, argsize);
+       if (desc == NULL)
+               return -EINVAL;
+
+       return xencomm_arch_hypercall_xen_version(cmd, desc);
+}
+EXPORT_SYMBOL_GPL(xencomm_hypercall_xen_version);
+
+int
+xencomm_hypercall_physdev_op(int cmd, void *op)
+{
+       unsigned int argsize;
+
+       switch (cmd) {
+       case PHYSDEVOP_apic_read:
+       case PHYSDEVOP_apic_write:
+               argsize = sizeof(struct physdev_apic);
+               break;
+       case PHYSDEVOP_alloc_irq_vector:
+       case PHYSDEVOP_free_irq_vector:
+               argsize = sizeof(struct physdev_irq);
+               break;
+       case PHYSDEVOP_irq_status_query:
+               argsize = sizeof(struct physdev_irq_status_query);
+               break;
+
+       default:
+               printk(KERN_DEBUG
+                      "%s: unknown physdev op %d\n", __func__, cmd);
+               return -ENOSYS;
+       }
+
+       return xencomm_arch_hypercall_physdev_op
+               (cmd, xencomm_map_no_alloc(op, argsize));
+}
+
+static int
+xencommize_grant_table_op(struct xencomm_mini **xc_area,
+                         unsigned int cmd, void *op, unsigned int count,
+                         struct xencomm_handle **desc)
+{
+       struct xencomm_handle *desc1;
+       unsigned int argsize;
+
+       switch (cmd) {
+       case GNTTABOP_map_grant_ref:
+               argsize = sizeof(struct gnttab_map_grant_ref);
+               break;
+       case GNTTABOP_unmap_grant_ref:
+               argsize = sizeof(struct gnttab_unmap_grant_ref);
+               break;
+       case GNTTABOP_setup_table:
+       {
+               struct gnttab_setup_table *setup = op;
+
+               argsize = sizeof(*setup);
+
+               if (count != 1)
+                       return -EINVAL;
+               desc1 = __xencomm_map_no_alloc
+                       (xen_guest_handle(setup->frame_list),
+                        setup->nr_frames *
+                        sizeof(*xen_guest_handle(setup->frame_list)),
+                        *xc_area);
+               if (desc1 == NULL)
+                       return -EINVAL;
+               (*xc_area)++;
+               set_xen_guest_handle(setup->frame_list, (void *)desc1);
+               break;
+       }
+       case GNTTABOP_dump_table:
+               argsize = sizeof(struct gnttab_dump_table);
+               break;
+       case GNTTABOP_transfer:
+               argsize = sizeof(struct gnttab_transfer);
+               break;
+       case GNTTABOP_copy:
+               argsize = sizeof(struct gnttab_copy);
+               break;
+       case GNTTABOP_query_size:
+               argsize = sizeof(struct gnttab_query_size);
+               break;
+       default:
+               printk(KERN_DEBUG "%s: unknown hypercall grant table op %d\n",
+                      __func__, cmd);
+               BUG();
+       }
+
+       *desc = __xencomm_map_no_alloc(op, count * argsize, *xc_area);
+       if (*desc == NULL)
+               return -EINVAL;
+       (*xc_area)++;
+
+       return 0;
+}
+
+int
+xencomm_hypercall_grant_table_op(unsigned int cmd, void *op,
+                                unsigned int count)
+{
+       int rc;
+       struct xencomm_handle *desc;
+       XENCOMM_MINI_ALIGNED(xc_area, 2);
+
+       rc = xencommize_grant_table_op(&xc_area, cmd, op, count, &desc);
+       if (rc)
+               return rc;
+
+       return xencomm_arch_hypercall_grant_table_op(cmd, desc, count);
+}
+EXPORT_SYMBOL_GPL(xencomm_hypercall_grant_table_op);
+
+int
+xencomm_hypercall_sched_op(int cmd, void *arg)
+{
+       struct xencomm_handle *desc;
+       unsigned int argsize;
+
+       switch (cmd) {
+       case SCHEDOP_yield:
+       case SCHEDOP_block:
+               argsize = 0;
+               break;
+       case SCHEDOP_shutdown:
+               argsize = sizeof(struct sched_shutdown);
+               break;
+       case SCHEDOP_poll:
+       {
+               struct sched_poll *poll = arg;
+               struct xencomm_handle *ports;
+
+               argsize = sizeof(struct sched_poll);
+               ports = xencomm_map_no_alloc(xen_guest_handle(poll->ports),
+                                    sizeof(*xen_guest_handle(poll->ports)));
+
+               set_xen_guest_handle(poll->ports, (void *)ports);
+               break;
+       }
+       default:
+               printk(KERN_DEBUG "%s: unknown sched op %d\n", __func__, cmd);
+               return -ENOSYS;
+       }
+
+       desc = xencomm_map_no_alloc(arg, argsize);
+       if (desc == NULL)
+               return -EINVAL;
+
+       return xencomm_arch_hypercall_sched_op(cmd, desc);
+}
+EXPORT_SYMBOL_GPL(xencomm_hypercall_sched_op);
+
+int
+xencomm_hypercall_multicall(void *call_list, int nr_calls)
+{
+       int rc;
+       int i;
+       struct multicall_entry *mce;
+       struct xencomm_handle *desc;
+       XENCOMM_MINI_ALIGNED(xc_area, nr_calls * 2);
+
+       for (i = 0; i < nr_calls; i++) {
+               mce = (struct multicall_entry *)call_list + i;
+
+               switch (mce->op) {
+               case __HYPERVISOR_update_va_mapping:
+               case __HYPERVISOR_mmu_update:
+                       /* No-op on ia64.  */
+                       break;
+               case __HYPERVISOR_grant_table_op:
+                       rc = xencommize_grant_table_op
+                               (&xc_area,
+                                mce->args[0], (void *)mce->args[1],
+                                mce->args[2], &desc);
+                       if (rc)
+                               return rc;
+                       mce->args[1] = (unsigned long)desc;
+                       break;
+               case __HYPERVISOR_memory_op:
+               default:
+                       printk(KERN_DEBUG
+                              "%s: unhandled multicall op entry op %lu\n",
+                              __func__, mce->op);
+                       return -ENOSYS;
+               }
+       }
+
+       desc = xencomm_map_no_alloc(call_list,
+                                   nr_calls * sizeof(struct multicall_entry));
+       if (desc == NULL)
+               return -EINVAL;
+
+       return xencomm_arch_hypercall_multicall(desc, nr_calls);
+}
+EXPORT_SYMBOL_GPL(xencomm_hypercall_multicall);
+
+int
+xencomm_hypercall_callback_op(int cmd, void *arg)
+{
+       unsigned int argsize;
+       switch (cmd) {
+       case CALLBACKOP_register:
+               argsize = sizeof(struct callback_register);
+               break;
+       case CALLBACKOP_unregister:
+               argsize = sizeof(struct callback_unregister);
+               break;
+       default:
+               printk(KERN_DEBUG
+                      "%s: unknown callback op %d\n", __func__, cmd);
+               return -ENOSYS;
+       }
+
+       return xencomm_arch_hypercall_callback_op
+               (cmd, xencomm_map_no_alloc(arg, argsize));
+}
+
+static int
+xencommize_memory_reservation(struct xencomm_mini *xc_area,
+                             struct xen_memory_reservation *mop)
+{
+       struct xencomm_handle *desc;
+
+       desc = __xencomm_map_no_alloc(xen_guest_handle(mop->extent_start),
+                       mop->nr_extents *
+                       sizeof(*xen_guest_handle(mop->extent_start)),
+                       xc_area);
+       if (desc == NULL)
+               return -EINVAL;
+
+       set_xen_guest_handle(mop->extent_start, (void *)desc);
+       return 0;
+}
+
+int
+xencomm_hypercall_memory_op(unsigned int cmd, void *arg)
+{
+       GUEST_HANDLE(xen_pfn_t) extent_start_va[2] = { {NULL}, {NULL} };
+       struct xen_memory_reservation *xmr = NULL;
+       int rc;
+       struct xencomm_handle *desc;
+       unsigned int argsize;
+       XENCOMM_MINI_ALIGNED(xc_area, 2);
+
+       switch (cmd) {
+       case XENMEM_increase_reservation:
+       case XENMEM_decrease_reservation:
+       case XENMEM_populate_physmap:
+               xmr = (struct xen_memory_reservation *)arg;
+               set_xen_guest_handle(extent_start_va[0],
+                                    xen_guest_handle(xmr->extent_start));
+
+               argsize = sizeof(*xmr);
+               rc = xencommize_memory_reservation(xc_area, xmr);
+               if (rc)
+                       return rc;
+               xc_area++;
+               break;
+
+       case XENMEM_maximum_ram_page:
+               argsize = 0;
+               break;
+
+       case XENMEM_add_to_physmap:
+               argsize = sizeof(struct xen_add_to_physmap);
+               break;
+
+       default:
+               printk(KERN_DEBUG "%s: unknown memory op %d\n", __func__, cmd);
+               return -ENOSYS;
+       }
+
+       desc = xencomm_map_no_alloc(arg, argsize);
+       if (desc == NULL)
+               return -EINVAL;
+
+       rc = xencomm_arch_hypercall_memory_op(cmd, desc);
+
+       switch (cmd) {
+       case XENMEM_increase_reservation:
+       case XENMEM_decrease_reservation:
+       case XENMEM_populate_physmap:
+               set_xen_guest_handle(xmr->extent_start,
+                                    xen_guest_handle(extent_start_va[0]));
+               break;
+       }
+
+       return rc;
+}
+EXPORT_SYMBOL_GPL(xencomm_hypercall_memory_op);
+
+int
+xencomm_hypercall_suspend(unsigned long srec)
+{
+       struct sched_shutdown arg;
+
+       arg.reason = SHUTDOWN_suspend;
+
+       return xencomm_arch_hypercall_sched_op(
+               SCHEDOP_shutdown, xencomm_map_no_alloc(&arg, sizeof(arg)));
+}
+
+long
+xencomm_hypercall_vcpu_op(int cmd, int cpu, void *arg)
+{
+       unsigned int argsize;
+       switch (cmd) {
+       case VCPUOP_register_runstate_memory_area: {
+               struct vcpu_register_runstate_memory_area *area =
+                       (struct vcpu_register_runstate_memory_area *)arg;
+               argsize = sizeof(*arg);
+               set_xen_guest_handle(area->addr.h,
+                    (void *)xencomm_map_no_alloc(area->addr.v,
+                                                 sizeof(area->addr.v)));
+               break;
+       }
+
+       default:
+               printk(KERN_DEBUG "%s: unknown vcpu op %d\n", __func__, cmd);
+               return -ENOSYS;
+       }
+
+       return xencomm_arch_hypercall_vcpu_op(cmd, cpu,
+                                       xencomm_map_no_alloc(arg, argsize));
+}
+
+long
+xencomm_hypercall_opt_feature(void *arg)
+{
+       return xencomm_arch_hypercall_opt_feature(
+               xencomm_map_no_alloc(arg,
+                                    sizeof(struct xen_ia64_opt_feature)));
+}
diff --git a/arch/ia64/xen/xen_pv_ops.c b/arch/ia64/xen/xen_pv_ops.c
new file mode 100644 (file)
index 0000000..04cd123
--- /dev/null
@@ -0,0 +1,364 @@
+/******************************************************************************
+ * arch/ia64/xen/xen_pv_ops.c
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * 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/console.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/pm.h>
+
+#include <asm/xen/hypervisor.h>
+#include <asm/xen/xencomm.h>
+#include <asm/xen/privop.h>
+
+#include "irq_xen.h"
+#include "time.h"
+
+/***************************************************************************
+ * general info
+ */
+static struct pv_info xen_info __initdata = {
+       .kernel_rpl = 2,        /* or 1: determin at runtime */
+       .paravirt_enabled = 1,
+       .name = "Xen/ia64",
+};
+
+#define IA64_RSC_PL_SHIFT      2
+#define IA64_RSC_PL_BIT_SIZE   2
+#define IA64_RSC_PL_MASK       \
+       (((1UL << IA64_RSC_PL_BIT_SIZE) - 1) << IA64_RSC_PL_SHIFT)
+
+static void __init
+xen_info_init(void)
+{
+       /* Xenified Linux/ia64 may run on pl = 1 or 2.
+        * determin at run time. */
+       unsigned long rsc = ia64_getreg(_IA64_REG_AR_RSC);
+       unsigned int rpl = (rsc & IA64_RSC_PL_MASK) >> IA64_RSC_PL_SHIFT;
+       xen_info.kernel_rpl = rpl;
+}
+
+/***************************************************************************
+ * pv_init_ops
+ * initialization hooks.
+ */
+
+static void
+xen_panic_hypercall(struct unw_frame_info *info, void *arg)
+{
+       current->thread.ksp = (__u64)info->sw - 16;
+       HYPERVISOR_shutdown(SHUTDOWN_crash);
+       /* we're never actually going to get here... */
+}
+
+static int
+xen_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+       unw_init_running(xen_panic_hypercall, NULL);
+       /* we're never actually going to get here... */
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block xen_panic_block = {
+       xen_panic_event, NULL, 0 /* try to go last */
+};
+
+static void xen_pm_power_off(void)
+{
+       local_irq_disable();
+       HYPERVISOR_shutdown(SHUTDOWN_poweroff);
+}
+
+static void __init
+xen_banner(void)
+{
+       printk(KERN_INFO
+              "Running on Xen! pl = %d start_info_pfn=0x%lx nr_pages=%ld "
+              "flags=0x%x\n",
+              xen_info.kernel_rpl,
+              HYPERVISOR_shared_info->arch.start_info_pfn,
+              xen_start_info->nr_pages, xen_start_info->flags);
+}
+
+static int __init
+xen_reserve_memory(struct rsvd_region *region)
+{
+       region->start = (unsigned long)__va(
+               (HYPERVISOR_shared_info->arch.start_info_pfn << PAGE_SHIFT));
+       region->end   = region->start + PAGE_SIZE;
+       return 1;
+}
+
+static void __init
+xen_arch_setup_early(void)
+{
+       struct shared_info *s;
+       BUG_ON(!xen_pv_domain());
+
+       s = HYPERVISOR_shared_info;
+       xen_start_info = __va(s->arch.start_info_pfn << PAGE_SHIFT);
+
+       /* Must be done before any hypercall.  */
+       xencomm_initialize();
+
+       xen_setup_features();
+       /* Register a call for panic conditions. */
+       atomic_notifier_chain_register(&panic_notifier_list,
+                                      &xen_panic_block);
+       pm_power_off = xen_pm_power_off;
+
+       xen_ia64_enable_opt_feature();
+}
+
+static void __init
+xen_arch_setup_console(char **cmdline_p)
+{
+       add_preferred_console("xenboot", 0, NULL);
+       add_preferred_console("tty", 0, NULL);
+       /* use hvc_xen */
+       add_preferred_console("hvc", 0, NULL);
+
+#if !defined(CONFIG_VT) || !defined(CONFIG_DUMMY_CONSOLE)
+       conswitchp = NULL;
+#endif
+}
+
+static int __init
+xen_arch_setup_nomca(void)
+{
+       return 1;
+}
+
+static void __init
+xen_post_smp_prepare_boot_cpu(void)
+{
+       xen_setup_vcpu_info_placement();
+}
+
+static const struct pv_init_ops xen_init_ops __initdata = {
+       .banner = xen_banner,
+
+       .reserve_memory = xen_reserve_memory,
+
+       .arch_setup_early = xen_arch_setup_early,
+       .arch_setup_console = xen_arch_setup_console,
+       .arch_setup_nomca = xen_arch_setup_nomca,
+
+       .post_smp_prepare_boot_cpu = xen_post_smp_prepare_boot_cpu,
+};
+
+/***************************************************************************
+ * pv_cpu_ops
+ * intrinsics hooks.
+ */
+
+static void xen_setreg(int regnum, unsigned long val)
+{
+       switch (regnum) {
+       case _IA64_REG_AR_KR0 ... _IA64_REG_AR_KR7:
+               xen_set_kr(regnum - _IA64_REG_AR_KR0, val);
+               break;
+#ifdef CONFIG_IA32_SUPPORT
+       case _IA64_REG_AR_EFLAG:
+               xen_set_eflag(val);
+               break;
+#endif
+       case _IA64_REG_CR_TPR:
+               xen_set_tpr(val);
+               break;
+       case _IA64_REG_CR_ITM:
+               xen_set_itm(val);
+               break;
+       case _IA64_REG_CR_EOI:
+               xen_eoi(val);
+               break;
+       default:
+               ia64_native_setreg_func(regnum, val);
+               break;
+       }
+}
+
+static unsigned long xen_getreg(int regnum)
+{
+       unsigned long res;
+
+       switch (regnum) {
+       case _IA64_REG_PSR:
+               res = xen_get_psr();
+               break;
+#ifdef CONFIG_IA32_SUPPORT
+       case _IA64_REG_AR_EFLAG:
+               res = xen_get_eflag();
+               break;
+#endif
+       case _IA64_REG_CR_IVR:
+               res = xen_get_ivr();
+               break;
+       case _IA64_REG_CR_TPR:
+               res = xen_get_tpr();
+               break;
+       default:
+               res = ia64_native_getreg_func(regnum);
+               break;
+       }
+       return res;
+}
+
+/* turning on interrupts is a bit more complicated.. write to the
+ * memory-mapped virtual psr.i bit first (to avoid race condition),
+ * then if any interrupts were pending, we have to execute a hyperprivop
+ * to ensure the pending interrupt gets delivered; else we're done! */
+static void
+xen_ssm_i(void)
+{
+       int old = xen_get_virtual_psr_i();
+       xen_set_virtual_psr_i(1);
+       barrier();
+       if (!old && xen_get_virtual_pend())
+               xen_hyper_ssm_i();
+}
+
+/* turning off interrupts can be paravirtualized simply by writing
+ * to a memory-mapped virtual psr.i bit (implemented as a 16-bit bool) */
+static void
+xen_rsm_i(void)
+{
+       xen_set_virtual_psr_i(0);
+       barrier();
+}
+
+static unsigned long
+xen_get_psr_i(void)
+{
+       return xen_get_virtual_psr_i() ? IA64_PSR_I : 0;
+}
+
+static void
+xen_intrin_local_irq_restore(unsigned long mask)
+{
+       if (mask & IA64_PSR_I)
+               xen_ssm_i();
+       else
+               xen_rsm_i();
+}
+
+static const struct pv_cpu_ops xen_cpu_ops __initdata = {
+       .fc             = xen_fc,
+       .thash          = xen_thash,
+       .get_cpuid      = xen_get_cpuid,
+       .get_pmd        = xen_get_pmd,
+       .getreg         = xen_getreg,
+       .setreg         = xen_setreg,
+       .ptcga          = xen_ptcga,
+       .get_rr         = xen_get_rr,
+       .set_rr         = xen_set_rr,
+       .set_rr0_to_rr4 = xen_set_rr0_to_rr4,
+       .ssm_i          = xen_ssm_i,
+       .rsm_i          = xen_rsm_i,
+       .get_psr_i      = xen_get_psr_i,
+       .intrin_local_irq_restore
+                       = xen_intrin_local_irq_restore,
+};
+
+/******************************************************************************
+ * replacement of hand written assembly codes.
+ */
+
+extern char xen_switch_to;
+extern char xen_leave_syscall;
+extern char xen_work_processed_syscall;
+extern char xen_leave_kernel;
+
+const struct pv_cpu_asm_switch xen_cpu_asm_switch = {
+       .switch_to              = (unsigned long)&xen_switch_to,
+       .leave_syscall          = (unsigned long)&xen_leave_syscall,
+       .work_processed_syscall = (unsigned long)&xen_work_processed_syscall,
+       .leave_kernel           = (unsigned long)&xen_leave_kernel,
+};
+
+/***************************************************************************
+ * pv_iosapic_ops
+ * iosapic read/write hooks.
+ */
+static void
+xen_pcat_compat_init(void)
+{
+       /* nothing */
+}
+
+static struct irq_chip*
+xen_iosapic_get_irq_chip(unsigned long trigger)
+{
+       return NULL;
+}
+
+static unsigned int
+xen_iosapic_read(char __iomem *iosapic, unsigned int reg)
+{
+       struct physdev_apic apic_op;
+       int ret;
+
+       apic_op.apic_physbase = (unsigned long)iosapic -
+                                       __IA64_UNCACHED_OFFSET;
+       apic_op.reg = reg;
+       ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op);
+       if (ret)
+               return ret;
+       return apic_op.value;
+}
+
+static void
+xen_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
+{
+       struct physdev_apic apic_op;
+
+       apic_op.apic_physbase = (unsigned long)iosapic -
+                                       __IA64_UNCACHED_OFFSET;
+       apic_op.reg = reg;
+       apic_op.value = val;
+       HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
+}
+
+static const struct pv_iosapic_ops xen_iosapic_ops __initdata = {
+       .pcat_compat_init = xen_pcat_compat_init,
+       .__get_irq_chip = xen_iosapic_get_irq_chip,
+
+       .__read = xen_iosapic_read,
+       .__write = xen_iosapic_write,
+};
+
+/***************************************************************************
+ * pv_ops initialization
+ */
+
+void __init
+xen_setup_pv_ops(void)
+{
+       xen_info_init();
+       pv_info = xen_info;
+       pv_init_ops = xen_init_ops;
+       pv_cpu_ops = xen_cpu_ops;
+       pv_iosapic_ops = xen_iosapic_ops;
+       pv_irq_ops = xen_irq_ops;
+       pv_time_ops = xen_time_ops;
+
+       paravirt_cpu_asm_init(&xen_cpu_asm_switch);
+}
diff --git a/arch/ia64/xen/xencomm.c b/arch/ia64/xen/xencomm.c
new file mode 100644 (file)
index 0000000..1f5d7ac
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2006 Hollis Blanchard <hollisb@us.ibm.com>, 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.
+ *
+ * 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/mm.h>
+
+static unsigned long kernel_virtual_offset;
+static int is_xencomm_initialized;
+
+/* for xen early printk. It uses console io hypercall which uses xencomm.
+ * However early printk may use it before xencomm initialization.
+ */
+int
+xencomm_is_initialized(void)
+{
+       return is_xencomm_initialized;
+}
+
+void
+xencomm_initialize(void)
+{
+       kernel_virtual_offset = KERNEL_START - ia64_tpa(KERNEL_START);
+       is_xencomm_initialized = 1;
+}
+
+/* Translate virtual address to physical address.  */
+unsigned long
+xencomm_vtop(unsigned long vaddr)
+{
+       struct page *page;
+       struct vm_area_struct *vma;
+
+       if (vaddr == 0)
+               return 0UL;
+
+       if (REGION_NUMBER(vaddr) == 5) {
+               pgd_t *pgd;
+               pud_t *pud;
+               pmd_t *pmd;
+               pte_t *ptep;
+
+               /* On ia64, TASK_SIZE refers to current.  It is not initialized
+                  during boot.
+                  Furthermore the kernel is relocatable and __pa() doesn't
+                  work on  addresses.  */
+               if (vaddr >= KERNEL_START
+                   && vaddr < (KERNEL_START + KERNEL_TR_PAGE_SIZE))
+                       return vaddr - kernel_virtual_offset;
+
+               /* In kernel area -- virtually mapped.  */
+               pgd = pgd_offset_k(vaddr);
+               if (pgd_none(*pgd) || pgd_bad(*pgd))
+                       return ~0UL;
+
+               pud = pud_offset(pgd, vaddr);
+               if (pud_none(*pud) || pud_bad(*pud))
+                       return ~0UL;
+
+               pmd = pmd_offset(pud, vaddr);
+               if (pmd_none(*pmd) || pmd_bad(*pmd))
+                       return ~0UL;
+
+               ptep = pte_offset_kernel(pmd, vaddr);
+               if (!ptep)
+                       return ~0UL;
+
+               return (pte_val(*ptep) & _PFN_MASK) | (vaddr & ~PAGE_MASK);
+       }
+
+       if (vaddr > TASK_SIZE) {
+               /* percpu variables */
+               if (REGION_NUMBER(vaddr) == 7 &&
+                   REGION_OFFSET(vaddr) >= (1ULL << IA64_MAX_PHYS_BITS))
+                       ia64_tpa(vaddr);
+
+               /* kernel address */
+               return __pa(vaddr);
+       }
+
+       /* XXX double-check (lack of) locking */
+       vma = find_extend_vma(current->mm, vaddr);
+       if (!vma)
+               return ~0UL;
+
+       /* We assume the page is modified.  */
+       page = follow_page(vma, vaddr, FOLL_WRITE | FOLL_TOUCH);
+       if (!page)
+               return ~0UL;
+
+       return (page_to_pfn(page) << PAGE_SHIFT) | (vaddr & ~PAGE_MASK);
+}
diff --git a/arch/ia64/xen/xenivt.S b/arch/ia64/xen/xenivt.S
new file mode 100644 (file)
index 0000000..3e71d50
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * arch/ia64/xen/ivt.S
+ *
+ * Copyright (C) 2005 Hewlett-Packard Co
+ *     Dan Magenheimer <dan.magenheimer@hp.com>
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *                    pv_ops.
+ */
+
+#include <asm/asmmacro.h>
+#include <asm/kregs.h>
+#include <asm/pgtable.h>
+
+#include "../kernel/minstate.h"
+
+       .section .text,"ax"
+GLOBAL_ENTRY(xen_event_callback)
+       mov r31=pr              // prepare to save predicates
+       ;;
+       SAVE_MIN_WITH_COVER     // uses r31; defines r2 and r3
+       ;;
+       movl r3=XSI_PSR_IC
+       mov r14=1
+       ;;
+       st4 [r3]=r14
+       ;;
+       adds r3=8,r2            // set up second base pointer for SAVE_REST
+       srlz.i                  // ensure everybody knows psr.ic is back on
+       ;;
+       SAVE_REST
+       ;;
+1:
+       alloc r14=ar.pfs,0,0,1,0 // must be first in an insn group
+       add out0=16,sp          // pass pointer to pt_regs as first arg
+       ;;
+       br.call.sptk.many b0=xen_evtchn_do_upcall
+       ;;
+       movl r20=XSI_PSR_I_ADDR
+       ;;
+       ld8 r20=[r20]
+       ;;
+       adds r20=-1,r20         // vcpu_info->evtchn_upcall_pending
+       ;;
+       ld1 r20=[r20]
+       ;;
+       cmp.ne p6,p0=r20,r0     // if there are pending events,
+       (p6) br.spnt.few 1b     // call evtchn_do_upcall again.
+       br.sptk.many xen_leave_kernel   // we know ia64_leave_kernel is
+                                       // paravirtualized as xen_leave_kernel
+END(xen_event_callback)
diff --git a/arch/ia64/xen/xensetup.S b/arch/ia64/xen/xensetup.S
new file mode 100644 (file)
index 0000000..28fed1f
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Support routines for Xen
+ *
+ * Copyright (C) 2005 Dan Magenheimer <dan.magenheimer@hp.com>
+ */
+
+#include <asm/processor.h>
+#include <asm/asmmacro.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/paravirt.h>
+#include <asm/xen/privop.h>
+#include <linux/elfnote.h>
+#include <linux/init.h>
+#include <xen/interface/elfnote.h>
+
+       .section .data.read_mostly
+       .align 8
+       .global xen_domain_type
+xen_domain_type:
+       data4 XEN_NATIVE_ASM
+       .previous
+
+       __INIT
+ENTRY(startup_xen)
+       // Calculate load offset.
+       // The constant, LOAD_OFFSET, can't be used because the boot
+       // loader doesn't always load to the LMA specified by the vmlinux.lds.
+       mov r9=ip       // must be the first instruction to make sure
+                       // that r9 = the physical address of startup_xen.
+                       // Usually r9 = startup_xen - LOAD_OFFSET
+       movl r8=startup_xen
+       ;;
+       sub r9=r9,r8    // Usually r9 = -LOAD_OFFSET.
+
+       mov r10=PARAVIRT_HYPERVISOR_TYPE_XEN
+       movl r11=_start
+       ;;
+       add r11=r11,r9
+       movl r8=hypervisor_type
+       ;;
+       add r8=r8,r9
+       mov b0=r11
+       ;;
+       st8 [r8]=r10
+       br.cond.sptk.many b0
+       ;;
+END(startup_xen)
+
+       ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,      .asciz "linux")
+       ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz "2.6")
+       ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,   .asciz "xen-3.0")
+       ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,         data8.ua startup_xen - LOAD_OFFSET)
+
+#define isBP   p3      // are we the Bootstrap Processor?
+
+       .text
+
+GLOBAL_ENTRY(xen_setup_hook)
+       mov r8=XEN_PV_DOMAIN_ASM
+(isBP) movl r9=xen_domain_type;;
+(isBP) st4 [r9]=r8
+       movl r10=xen_ivt;;
+
+       mov cr.iva=r10
+
+       /* Set xsi base.  */
+#define FW_HYPERCALL_SET_SHARED_INFO_VA                        0x600
+(isBP) mov r2=FW_HYPERCALL_SET_SHARED_INFO_VA
+(isBP) movl r28=XSI_BASE;;
+(isBP) break 0x1000;;
+
+       /* setup pv_ops */
+(isBP) mov r4=rp
+       ;;
+(isBP) br.call.sptk.many rp=xen_setup_pv_ops
+       ;;
+(isBP) mov rp=r4
+       ;;
+
+       br.ret.sptk.many rp
+       ;;
+END(xen_setup_hook)
index fc2994811f150c991986b6294538ca5b9c6a64ab..39cb6da72dcbef3358d04e2b419a150f88c299ba 100644 (file)
@@ -40,6 +40,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/cpu.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
index b7773e45c43fe2da770217cfa2c9ed4a648a3563..fa56860f4258b11607ef3ac32a3d59bc604a167e 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 
-int __init oprofile_arch_init(struct oprofile_operations * ops)
+int __init oprofile_arch_init(struct oprofile_operations *ops)
 {
        return -ENODEV;
 }
index 0a3f9e8ebde0db468365abf2a429a11a04c1e934..ab9862c3a136f4bc49f744b04bd2feae51912e83 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/seq_file.h>
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/rtc.h>
@@ -93,7 +94,7 @@ static char amiga_model_name[13] = "Amiga ";
 
 static void amiga_sched_init(irq_handler_t handler);
 static void amiga_get_model(char *model);
-static int amiga_get_hardware_list(char *buffer);
+static void amiga_get_hardware_list(struct seq_file *m);
 /* amiga specific timer functions */
 static unsigned long amiga_gettimeoffset(void);
 static int a3000_hwclk(int, struct rtc_time *);
@@ -911,13 +912,11 @@ static void amiga_get_model(char *model)
 }
 
 
-static int amiga_get_hardware_list(char *buffer)
+static void amiga_get_hardware_list(struct seq_file *m)
 {
-       int len = 0;
-
        if (AMIGAHW_PRESENT(CHIP_RAM))
-               len += sprintf(buffer+len, "Chip RAM:\t%ldK\n", amiga_chip_size>>10);
-       len += sprintf(buffer+len, "PS Freq:\t%dHz\nEClock Freq:\t%ldHz\n",
+               seq_printf(m, "Chip RAM:\t%ldK\n", amiga_chip_size>>10);
+       seq_printf(m, "PS Freq:\t%dHz\nEClock Freq:\t%ldHz\n",
                        amiga_psfreq, amiga_eclock);
        if (AMIGAHW_PRESENT(AMI_VIDEO)) {
                char *type;
@@ -935,14 +934,14 @@ static int amiga_get_hardware_list(char *buffer)
                        type = "Old or Unknown";
                        break;
                }
-               len += sprintf(buffer+len, "Graphics:\t%s\n", type);
+               seq_printf(m, "Graphics:\t%s\n", type);
        }
 
 #define AMIGAHW_ANNOUNCE(name, str)                    \
        if (AMIGAHW_PRESENT(name))                      \
-               len += sprintf (buffer+len, "\t%s\n", str)
+               seq_printf (m, "\t%s\n", str)
 
-       len += sprintf (buffer + len, "Detected hardware:\n");
+       seq_printf (m, "Detected hardware:\n");
 
        AMIGAHW_ANNOUNCE(AMI_VIDEO, "Amiga Video");
        AMIGAHW_ANNOUNCE(AMI_BLITTER, "Blitter");
@@ -975,15 +974,13 @@ static int amiga_get_hardware_list(char *buffer)
        AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA Slot");
 #ifdef CONFIG_ZORRO
        if (AMIGAHW_PRESENT(ZORRO))
-               len += sprintf(buffer+len, "\tZorro II%s AutoConfig: %d Expansion "
+               seq_printf(m, "\tZorro II%s AutoConfig: %d Expansion "
                                "Device%s\n",
                                AMIGAHW_PRESENT(ZORRO3) ? "I" : "",
                                zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");
 #endif /* CONFIG_ZORRO */
 
 #undef AMIGAHW_ANNOUNCE
-
-       return len;
 }
 
 /*
index af031855f796f4b61bd716f092d5065c97d1bc12..49c28cdbea5c5bf6cc89d00be99eee339900838c 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/types.h>
 #include <linux/mm.h>
+#include <linux/seq_file.h>
 #include <linux/console.h>
 #include <linux/init.h>
 #include <linux/delay.h>
@@ -63,7 +64,7 @@ int atari_rtc_year_offset;
 /* local function prototypes */
 static void atari_reset(void);
 static void atari_get_model(char *model);
-static int atari_get_hardware_list(char *buffer);
+static void atari_get_hardware_list(struct seq_file *m);
 
 /* atari specific irq functions */
 extern void atari_init_IRQ (void);
@@ -611,21 +612,21 @@ static void atari_get_model(char *model)
 }
 
 
-static int atari_get_hardware_list(char *buffer)
+static void atari_get_hardware_list(struct seq_file *m)
 {
-       int len = 0, i;
+       int i;
 
        for (i = 0; i < m68k_num_memory; i++)
-               len += sprintf(buffer+len, "\t%3ld MB at 0x%08lx (%s)\n",
+               seq_printf(m, "\t%3ld MB at 0x%08lx (%s)\n",
                                m68k_memory[i].size >> 20, m68k_memory[i].addr,
                                (m68k_memory[i].addr & 0xff000000 ?
                                 "alternate RAM" : "ST-RAM"));
 
 #define ATARIHW_ANNOUNCE(name, str)                    \
        if (ATARIHW_PRESENT(name))                      \
-               len += sprintf(buffer + len, "\t%s\n", str)
+               seq_printf(m, "\t%s\n", str)
 
-       len += sprintf(buffer + len, "Detected hardware:\n");
+       seq_printf(m, "Detected hardware:\n");
        ATARIHW_ANNOUNCE(STND_SHIFTER, "ST Shifter");
        ATARIHW_ANNOUNCE(EXTD_SHIFTER, "STe Shifter");
        ATARIHW_ANNOUNCE(TT_SHIFTER, "TT Shifter");
@@ -654,6 +655,4 @@ static int atari_get_hardware_list(char *buffer)
        ATARIHW_ANNOUNCE(BLITTER, "Blitter");
        ATARIHW_ANNOUNCE(VME, "VME Bus");
        ATARIHW_ANNOUNCE(DSP56K, "DSP56001 processor");
-
-       return len;
 }
index 04c69ffbea71635b23a1652e9c6159e37eb8f82c..6ec3b7f33779bcef5bb00ffea045d8dce7f3e46b 100644 (file)
@@ -42,6 +42,7 @@
 /* abbrev for the && above... */
 #define DO_PROC
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #endif
 
 /*
@@ -323,19 +324,16 @@ static int remove_region( BLOCK *block )
 
 #ifdef DO_PROC
 
-#define        PRINT_PROC(fmt,args...) len += sprintf( buf+len, fmt, ##args )
+#define        PRINT_PROC(fmt,args...) seq_printf( m, fmt, ##args )
 
-int get_stram_list( char *buf )
+static int stram_proc_show(struct seq_file *m, void *v)
 {
-       int len = 0;
        BLOCK *p;
 
        PRINT_PROC("Total ST-RAM:      %8u kB\n",
                           (stram_end - stram_start) >> 10);
        PRINT_PROC( "Allocated regions:\n" );
        for( p = alloc_list; p; p = p->next ) {
-               if (len + 50 >= PAGE_SIZE)
-                       break;
                PRINT_PROC("0x%08lx-0x%08lx: %s (",
                           virt_to_phys(p->start),
                           virt_to_phys(p->start+p->size-1),
@@ -346,9 +344,27 @@ int get_stram_list( char *buf )
                        PRINT_PROC( "??)\n" );
        }
 
-       return( len );
+       return 0;
+}
+
+static int stram_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, stram_proc_show, NULL);
 }
 
+static const struct file_operations stram_proc_fops = {
+       .open           = stram_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int __init proc_stram_init(void)
+{
+       proc_create("stram", 0, NULL, &stram_proc_fops);
+       return 0;
+}
+module_init(proc_stram_init);
 #endif
 
 
index 65c9204ab9ac626aaec3066967bdce9b1792ea60..c072595928c06d0496df7ec0b9a197b763709925 100644 (file)
@@ -38,7 +38,6 @@
 #include <asm/bvme6000hw.h>
 
 static void bvme6000_get_model(char *model);
-static int  bvme6000_get_hardware_list(char *buffer);
 extern void bvme6000_sched_init(irq_handler_t handler);
 extern unsigned long bvme6000_gettimeoffset (void);
 extern int bvme6000_hwclk (int, struct rtc_time *);
@@ -82,15 +81,6 @@ static void bvme6000_get_model(char *model)
     sprintf(model, "BVME%d000", m68k_cputype == CPU_68060 ? 6 : 4);
 }
 
-
-/* No hardware options on BVME6000? */
-
-static int bvme6000_get_hardware_list(char *buffer)
-{
-    *buffer = '\0';
-    return 0;
-}
-
 /*
  * This function is called during kernel startup to initialize
  * the bvme6000 IRQ handling routines.
@@ -127,7 +117,6 @@ void __init config_bvme6000(void)
     mach_set_clock_mmss         = bvme6000_set_clock_mmss;
     mach_reset          = bvme6000_reset;
     mach_get_model       = bvme6000_get_model;
-    mach_get_hardware_list = bvme6000_get_hardware_list;
 
     printk ("Board is %sconfigured as a System Controller\n",
                *config_reg_ptr & BVME_CONFIG_SW1 ? "" : "not ");
index ea1e44da19b9145a2cccd159488b0d427902f10e..4d97bd2bd573845db42d11b8b03c096b5148eac9 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
+#include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/module.h>
 #include <linux/initrd.h>
@@ -80,7 +81,7 @@ void (*mach_sched_init) (irq_handler_t handler) __initdata = NULL;
 /* machine dependent irq functions */
 void (*mach_init_IRQ) (void) __initdata = NULL;
 void (*mach_get_model) (char *model);
-int (*mach_get_hardware_list) (char *buffer);
+void (*mach_get_hardware_list) (struct seq_file *m);
 /* machine dependent timer functions */
 unsigned long (*mach_gettimeoffset) (void);
 int (*mach_hwclk) (int, struct rtc_time*);
@@ -467,9 +468,9 @@ const struct seq_operations cpuinfo_op = {
        .show   = show_cpuinfo,
 };
 
-int get_hardware_list(char *buffer)
+#ifdef CONFIG_PROC_HARDWARE
+static int hardware_proc_show(struct seq_file *m, void *v)
 {
-       int len = 0;
        char model[80];
        unsigned long mem;
        int i;
@@ -479,17 +480,37 @@ int get_hardware_list(char *buffer)
        else
                strcpy(model, "Unknown m68k");
 
-       len += sprintf(buffer + len, "Model:\t\t%s\n", model);
+       seq_printf(m, "Model:\t\t%s\n", model);
        for (mem = 0, i = 0; i < m68k_num_memory; i++)
                mem += m68k_memory[i].size;
-       len += sprintf(buffer + len, "System Memory:\t%ldK\n", mem >> 10);
+       seq_printf(m, "System Memory:\t%ldK\n", mem >> 10);
 
        if (mach_get_hardware_list)
-               len += mach_get_hardware_list(buffer + len);
+               mach_get_hardware_list(m);
 
-       return len;
+       return 0;
+}
+
+static int hardware_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, hardware_proc_show, NULL);
 }
 
+static const struct file_operations hardware_proc_fops = {
+       .open           = hardware_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int __init proc_hardware_init(void)
+{
+       proc_create("hardware", 0, NULL, &hardware_proc_fops);
+       return 0;
+}
+module_init(proc_hardware_init);
+#endif
+
 void check_bugs(void)
 {
 #ifndef CONFIG_M68KFPU_EMU
index 92fe507141126fd566973e9598c86dd31e9eb389..43cdf476ffab17cd690b1bb8e8abba98082755a4 100644 (file)
@@ -37,7 +37,6 @@
 
 
 static void mvme147_get_model(char *model);
-static int  mvme147_get_hardware_list(char *buffer);
 extern void mvme147_sched_init(irq_handler_t handler);
 extern unsigned long mvme147_gettimeoffset (void);
 extern int mvme147_hwclk (int, struct rtc_time *);
@@ -76,14 +75,6 @@ static void mvme147_get_model(char *model)
        sprintf(model, "Motorola MVME147");
 }
 
-
-static int mvme147_get_hardware_list(char *buffer)
-{
-       *buffer = '\0';
-
-       return 0;
-}
-
 /*
  * This function is called during kernel startup to initialize
  * the mvme147 IRQ handling routines.
@@ -104,7 +95,6 @@ void __init config_mvme147(void)
        mach_set_clock_mmss     = mvme147_set_clock_mmss;
        mach_reset              = mvme147_reset;
        mach_get_model          = mvme147_get_model;
-       mach_get_hardware_list  = mvme147_get_hardware_list;
 
        /* Board type is only set by newer versions of vmelilo/tftplilo */
        if (!vme_brdtype)
index 24cbc3030454aed4a76e847cfed91f415d8fc33b..1521826fc3c7caef9a62935a2bde21f0f6135378 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/seq_file.h>
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/linkage.h>
@@ -42,7 +43,6 @@ extern t_bdid mvme_bdid;
 static MK48T08ptr_t volatile rtc = (MK48T08ptr_t)MVME_RTC_BASE;
 
 static void mvme16x_get_model(char *model);
-static int  mvme16x_get_hardware_list(char *buffer);
 extern void mvme16x_sched_init(irq_handler_t handler);
 extern unsigned long mvme16x_gettimeoffset (void);
 extern int mvme16x_hwclk (int, struct rtc_time *);
@@ -93,26 +93,21 @@ static void mvme16x_get_model(char *model)
 }
 
 
-static int mvme16x_get_hardware_list(char *buffer)
+static void mvme16x_get_hardware_list(struct seq_file *m)
 {
     p_bdid p = &mvme_bdid;
-    int len = 0;
 
     if (p->brdno == 0x0162 || p->brdno == 0x0172)
     {
        unsigned char rev = *(unsigned char *)MVME162_VERSION_REG;
 
-       len += sprintf (buffer+len, "VMEchip2        %spresent\n",
+       seq_printf (m, "VMEchip2        %spresent\n",
                        rev & MVME16x_CONFIG_NO_VMECHIP2 ? "NOT " : "");
-       len += sprintf (buffer+len, "SCSI interface  %spresent\n",
+       seq_printf (m, "SCSI interface  %spresent\n",
                        rev & MVME16x_CONFIG_NO_SCSICHIP ? "NOT " : "");
-       len += sprintf (buffer+len, "Ethernet i/f    %spresent\n",
+       seq_printf (m, "Ethernet i/f    %spresent\n",
                        rev & MVME16x_CONFIG_NO_ETHERNET ? "NOT " : "");
     }
-    else
-       *buffer = '\0';
-
-    return (len);
 }
 
 /*
index 9c7eefa3f98a133bd53d767b0edbf3f622993416..7110546e3c00f412dcc88c7ad69111feb890d339 100644 (file)
@@ -39,7 +39,6 @@
 extern irqreturn_t q40_process_int(int level, struct pt_regs *regs);
 extern void q40_init_IRQ(void);
 static void q40_get_model(char *model);
-static int  q40_get_hardware_list(char *buffer);
 extern void q40_sched_init(irq_handler_t handler);
 
 static unsigned long q40_gettimeoffset(void);
@@ -153,14 +152,6 @@ static void q40_get_model(char *model)
        sprintf(model, "Q40");
 }
 
-/* No hardware options on Q40? */
-
-static int q40_get_hardware_list(char *buffer)
-{
-       *buffer = '\0';
-       return 0;
-}
-
 static unsigned int serports[] =
 {
        0x3f8,0x2f8,0x3e8,0x2e8,0
@@ -191,7 +182,6 @@ void __init config_q40(void)
 
        mach_reset = q40_reset;
        mach_get_model = q40_get_model;
-       mach_get_hardware_list = q40_get_hardware_list;
 
 #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
        mach_beep = q40_mksound;
index 732087d0735cf53d02e80d9f18fa63e24208429a..8dfaa201342e142726fc7d4671649da57148040a 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/seq_file.h>
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/init.h>
@@ -46,16 +47,9 @@ extern volatile unsigned char* sun3_intreg;
 extern unsigned long availmem;
 unsigned long num_pages;
 
-static int sun3_get_hardware_list(char *buffer)
+static void sun3_get_hardware_list(struct seq_file *m)
 {
-
-       int len = 0;
-
-       len += sprintf(buffer + len, "PROM Revision:\t%s\n",
-                      romvec->pv_monid);
-
-       return len;
-
+       seq_printf(m, "PROM Revision:\t%s\n", romvec->pv_monid);
 }
 
 void __init sun3_init(void)
index 987891783a472f64662ba93b2093639aebcd0960..2b1ca2db070fc429e25cfb9ae9140c5b26f8cbe9 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/types.h>
 #include <linux/mm.h>
+#include <linux/seq_file.h>
 #include <linux/console.h>
 #include <linux/init.h>
 
@@ -31,16 +32,9 @@ void sun3_leds(unsigned int i)
 
 }
 
-static int sun3x_get_hardware_list(char *buffer)
+static void sun3x_get_hardware_list(struct seq_file *m)
 {
-
-       int len = 0;
-
-       len += sprintf(buffer + len, "PROM Revision:\t%s\n",
-                      romvec->pv_monid);
-
-       return len;
-
+       seq_printf(m, "PROM Revision:\t%s\n", romvec->pv_monid);
 }
 
 /*
index dd2fbd6645c1fd78719d2be71ac653308b59e30d..3bf3354547f656971827c523f041dd72ab05cfb7 100644 (file)
@@ -32,7 +32,7 @@ static int op_mips_setup(void)
         return 0;
 }
 
-static int op_mips_create_files(struct super_block * sb, struct dentry * root)
+static int op_mips_create_files(struct super_block *sb, struct dentry *root)
 {
        int i;
 
index 2bfc17c3010613d7a8a4ea87e92fac9112810675..f04b54fb37d14a7050f96f058262728e88ae4aa4 100644 (file)
@@ -27,7 +27,7 @@ struct op_counter_config {
 /* Per-architecture configury and hooks.  */
 struct op_mips_model {
        void (*reg_setup) (struct op_counter_config *);
-       void (*cpu_setup) (void * dummy);
+       void (*cpu_setup) (void *dummy);
        int (*init)(void);
        void (*exit)(void);
        void (*cpu_start)(void *args);
index a45d3202894ff6e98f64bca4788c99dba95c388e..3aa81384966de8e726a5ab6ea1222d1ba6e8c09e 100644 (file)
@@ -80,7 +80,7 @@ static void rm9000_cpu_stop(void *args)
        write_c0_perfcontrol(0);
 }
 
-static irqreturn_t rm9000_perfcount_handler(int irq, void * dev_id)
+static irqreturn_t rm9000_perfcount_handler(int irq, void *dev_id)
 {
        unsigned int control = read_c0_perfcontrol();
        struct pt_regs *regs = get_irq_regs();
index 2bd1f6ef5db0c6bd45269701b36b4713c0a6def3..644a70b1b04e4fd9ecf16d2e73d6e22ea5227115 100644 (file)
@@ -9,6 +9,8 @@ config PARISC
        def_bool y
        select HAVE_IDE
        select HAVE_OPROFILE
+       select RTC_CLASS
+       select RTC_DRV_PARISC
        help
          The PA-RISC microprocessor is designed by Hewlett-Packard and used
          in many of their workstations & servers (HP9000 700 and 800 series,
index 12c04c5e558be01c1a219214721bfbd1901c1b4e..bd9a4db3bd4cd1ab14ddb6c7aadcdd44afc37dcd 100644 (file)
@@ -127,9 +127,8 @@ int hpux_getdents(unsigned int fd, struct hpux_dirent __user *dirent, unsigned i
        buf.error = 0;
 
        error = vfs_readdir(file, filldir, &buf);
-       if (error < 0)
-               goto out_putf;
-       error = buf.error;
+       if (error >= 0)
+               error = buf.error;
        lastdirent = buf.previous;
        if (lastdirent) {
                if (put_user(file->f_pos, &lastdirent->d_off))
similarity index 77%
rename from include/asm-parisc/ide.h
rename to arch/parisc/include/asm/ide.h
index c246ef75017db7fc048699577c0603121bb19f51..81700a2321cff3926bbf60320a2bed1cba248118 100644 (file)
 
 #ifdef __KERNEL__
 
-#define ide_request_irq(irq,hand,flg,dev,id)   request_irq((irq),(hand),(flg),(dev),(id))
-#define ide_free_irq(irq,dev_id)               free_irq((irq), (dev_id))
-#define ide_request_region(from,extent,name)   request_region((from), (extent), (name))
-#define ide_release_region(from,extent)                release_region((from), (extent))
 /* Generic I/O and MEMIO string operations.  */
 
 #define __ide_insw     insw
similarity index 99%
rename from include/asm-parisc/pdc.h
rename to arch/parisc/include/asm/pdc.h
index 9eaa794c3e4a3f1de70716e450896e1cddf8d570..c584b00c6074af9419ac31badf1e432f38262815 100644 (file)
 #define BOOT_CONSOLE_SPA_OFFSET  0x3c4
 #define BOOT_CONSOLE_PATH_OFFSET 0x3a8
 
+/* size of the pdc_result buffer for firmware.c */
+#define NUM_PDC_RESULT 32
+
 #if !defined(__ASSEMBLY__)
 #ifdef __KERNEL__
 
@@ -600,6 +603,7 @@ int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsi
 int pdc_chassis_disp(unsigned long disp);
 int pdc_chassis_warn(unsigned long *warn);
 int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info);
+int pdc_coproc_cfg_unlocked(struct pdc_coproc_cfg *pdc_coproc_info);
 int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index,
                  void *iodc_data, unsigned int iodc_data_size);
 int pdc_system_map_find_mods(struct pdc_system_map_mod_info *pdc_mod_info,
@@ -638,6 +642,7 @@ int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,
 #endif
 
 void set_firmware_width(void);
+void set_firmware_width_unlocked(void);
 int pdc_do_firm_test_reset(unsigned long ftc_bitmap);
 int pdc_do_reset(void);
 int pdc_soft_power_info(unsigned long *power_reg);
similarity index 85%
rename from include/asm-parisc/ptrace.h
rename to arch/parisc/include/asm/ptrace.h
index 3e94c5d85ff5715a3d95af8e6444b27ae081a1fd..afa5333187b4519126d2556b008e9fdfaba0fde5 100644 (file)
@@ -47,6 +47,16 @@ struct pt_regs {
 
 #define task_regs(task) ((struct pt_regs *) ((char *)(task) + TASK_REGS))
 
+#define __ARCH_WANT_COMPAT_SYS_PTRACE
+
+struct task_struct;
+#define arch_has_single_step() 1
+void user_disable_single_step(struct task_struct *task);
+void user_enable_single_step(struct task_struct *task);
+
+#define arch_has_block_step()  1
+void user_enable_block_step(struct task_struct *task);
+
 /* XXX should we use iaoq[1] or iaoq[0] ? */
 #define user_mode(regs)                        (((regs)->iaoq[0] & 3) ? 1 : 0)
 #define user_space(regs)               (((regs)->iasq[1] != 0) ? 1 : 0)
similarity index 99%
rename from include/asm-parisc/ropes.h
rename to arch/parisc/include/asm/ropes.h
index 007a880615eb80d766863f8e0b3708750c2ebbef..09f51d5ab57c254d78693b633d9077fd26454856 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _ASM_PARISC_ROPES_H_
 #define _ASM_PARISC_ROPES_H_
 
-#include <asm-parisc/parisc-device.h>
+#include <asm/parisc-device.h>
 
 #ifdef CONFIG_64BIT
 /* "low end" PA8800 machines use ZX1 chipset: PAT PDC and only run 64-bit */
similarity index 99%
rename from include/asm-parisc/unistd.h
rename to arch/parisc/include/asm/unistd.h
index a7d857f0e4f404963c86f2baeb240f80d7a6f110..ef26b009dc5da1f323a7fc77d329e6c520b5e40f 100644 (file)
 #define __NR_timerfd_create    (__NR_Linux + 306)
 #define __NR_timerfd_settime   (__NR_Linux + 307)
 #define __NR_timerfd_gettime   (__NR_Linux + 308)
-
-#define __NR_Linux_syscalls    (__NR_timerfd_gettime + 1)
+#define __NR_signalfd4         (__NR_Linux + 309)
+#define __NR_eventfd2          (__NR_Linux + 310)
+#define __NR_epoll_create1     (__NR_Linux + 311)
+#define __NR_dup3              (__NR_Linux + 312)
+#define __NR_pipe2             (__NR_Linux + 313)
+#define __NR_inotify_init1     (__NR_Linux + 314)
+
+#define __NR_Linux_syscalls    (__NR_inotify_init1 + 1)
 
 
 #define __IGNORE_select                /* newselect */
similarity index 99%
rename from include/asm-parisc/unwind.h
rename to arch/parisc/include/asm/unwind.h
index 2f7e6e50a1580de34d23216018cc015d1bf7780f..52482e4fc20d1f11407243915968523160839fbb 100644 (file)
@@ -74,4 +74,6 @@ void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *r
 int unwind_once(struct unwind_frame_info *info);
 int unwind_to_user(struct unwind_frame_info *info);
 
+int unwind_init(void);
+
 #endif
diff --git a/arch/parisc/kernel/.gitignore b/arch/parisc/kernel/.gitignore
new file mode 100644 (file)
index 0000000..c5f676c
--- /dev/null
@@ -0,0 +1 @@
+vmlinux.lds
index 3efc0b73e4ff9ce71efd7bf93550af12f1710394..699cf8ef211816576c5ee10d29c7bc67257580fc 100644 (file)
@@ -290,5 +290,8 @@ int main(void)
        DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip));
        DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space));
        DEFINE(EXCDATA_ADDR, offsetof(struct exception_data, fault_addr));
+       BLANK();
+       DEFINE(ASM_PDC_RESULT_SIZE, NUM_PDC_RESULT * sizeof(unsigned long));
+       BLANK();
        return 0;
 }
index 7177a6cd1b7f58b0fcc83f60ea5c11cf1bd96e1a..03f26bd75bd8ebcb301beb7a7e90c07454d08412 100644 (file)
@@ -71,8 +71,8 @@
 #include <asm/processor.h>     /* for boot_cpu_data */
 
 static DEFINE_SPINLOCK(pdc_lock);
-static unsigned long pdc_result[32] __attribute__ ((aligned (8)));
-static unsigned long pdc_result2[32] __attribute__ ((aligned (8)));
+extern unsigned long pdc_result[NUM_PDC_RESULT];
+extern unsigned long pdc_result2[NUM_PDC_RESULT];
 
 #ifdef CONFIG_64BIT
 #define WIDE_FIRMWARE 0x1
@@ -150,26 +150,40 @@ static void convert_to_wide(unsigned long *addr)
 #endif
 }
 
+#ifdef CONFIG_64BIT
+void __init set_firmware_width_unlocked(void)
+{
+       int ret;
+
+       ret = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES,
+               __pa(pdc_result), 0);
+       convert_to_wide(pdc_result);
+       if (pdc_result[0] != NARROW_FIRMWARE)
+               parisc_narrow_firmware = 0;
+}
+       
 /**
  * set_firmware_width - Determine if the firmware is wide or narrow.
  * 
- * This function must be called before any pdc_* function that uses the convert_to_wide
- * function.
+ * This function must be called before any pdc_* function that uses the
+ * convert_to_wide function.
  */
 void __init set_firmware_width(void)
 {
-#ifdef CONFIG_64BIT
-       int retval;
        unsigned long flags;
+       spin_lock_irqsave(&pdc_lock, flags);
+       set_firmware_width_unlocked();
+       spin_unlock_irqrestore(&pdc_lock, flags);
+}
+#else
+void __init set_firmware_width_unlocked(void) {
+       return;
+}
 
-        spin_lock_irqsave(&pdc_lock, flags);
-       retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0);
-       convert_to_wide(pdc_result);
-       if(pdc_result[0] != NARROW_FIRMWARE)
-               parisc_narrow_firmware = 0;
-        spin_unlock_irqrestore(&pdc_lock, flags);
-#endif
+void __init set_firmware_width(void) {
+       return;
 }
+#endif /*CONFIG_64BIT*/
 
 /**
  * pdc_emergency_unlock - Unlock the linux pdc lock
@@ -288,6 +302,20 @@ int pdc_chassis_warn(unsigned long *warn)
        return retval;
 }
 
+int __init pdc_coproc_cfg_unlocked(struct pdc_coproc_cfg *pdc_coproc_info)
+{
+       int ret;
+
+       ret = mem_pdc_call(PDC_COPROC, PDC_COPROC_CFG, __pa(pdc_result));
+       convert_to_wide(pdc_result);
+       pdc_coproc_info->ccr_functional = pdc_result[0];
+       pdc_coproc_info->ccr_present = pdc_result[1];
+       pdc_coproc_info->revision = pdc_result[17];
+       pdc_coproc_info->model = pdc_result[18];
+
+       return ret;
+}
+
 /**
  * pdc_coproc_cfg - To identify coprocessors attached to the processor.
  * @pdc_coproc_info: Return buffer address.
@@ -297,19 +325,14 @@ int pdc_chassis_warn(unsigned long *warn)
  */
 int __init pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info)
 {
-        int retval;
+       int ret;
        unsigned long flags;
 
-        spin_lock_irqsave(&pdc_lock, flags);
-        retval = mem_pdc_call(PDC_COPROC, PDC_COPROC_CFG, __pa(pdc_result));
-        convert_to_wide(pdc_result);
-        pdc_coproc_info->ccr_functional = pdc_result[0];
-        pdc_coproc_info->ccr_present = pdc_result[1];
-        pdc_coproc_info->revision = pdc_result[17];
-        pdc_coproc_info->model = pdc_result[18];
-        spin_unlock_irqrestore(&pdc_lock, flags);
+       spin_lock_irqsave(&pdc_lock, flags);
+       ret = pdc_coproc_cfg_unlocked(pdc_coproc_info);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
-        return retval;
+       return ret;
 }
 
 /**
index a84e31e828768943a7ac288ccb26aa49499b275c..0e3d9f9b9e33e97680190e3752cea063fce9c251 100644 (file)
@@ -121,7 +121,7 @@ $pgt_fill_loop:
        copy            %r0,%r2
 
        /* And the RFI Target address too */
-       load32          start_kernel,%r11
+       load32          start_parisc,%r11
 
        /* And the initial task pointer */
        load32          init_thread_union,%r6
index 49c637970789ba81da5741a75817ef1274e3b1ac..90904f9dfc504fb1e0337abb196b1617006ce514 100644 (file)
@@ -4,6 +4,7 @@
  * Copyright (C) 2000 Hewlett-Packard Co, Linuxcare Inc.
  * Copyright (C) 2000 Matthew Wilcox <matthew@wil.cx>
  * Copyright (C) 2000 David Huggins-Daines <dhd@debian.org>
+ * Copyright (C) 2008 Helge Deller <deller@gmx.de>
  */
 
 #include <linux/kernel.h>
 /* PSW bits we allow the debugger to modify */
 #define USER_PSW_BITS  (PSW_N | PSW_V | PSW_CB)
 
-#undef DEBUG_PTRACE
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Make sure single step bits etc are not set.
+ */
+void ptrace_disable(struct task_struct *task)
+{
+       task->ptrace &= ~(PT_SINGLESTEP|PT_BLOCKSTEP);
 
-#ifdef DEBUG_PTRACE
-#define DBG(x...)      printk(x)
-#else
-#define DBG(x...)
-#endif
+       /* make sure the trap bits are not set */
+       pa_psw(task)->r = 0;
+       pa_psw(task)->t = 0;
+       pa_psw(task)->h = 0;
+       pa_psw(task)->l = 0;
+}
+
+/*
+ * The following functions are called by ptrace_resume() when
+ * enabling or disabling single/block tracing.
+ */
+void user_disable_single_step(struct task_struct *task)
+{
+       ptrace_disable(task);
+}
+
+void user_enable_single_step(struct task_struct *task)
+{
+       task->ptrace &= ~PT_BLOCKSTEP;
+       task->ptrace |= PT_SINGLESTEP;
+
+       if (pa_psw(task)->n) {
+               struct siginfo si;
+
+               /* Nullified, just crank over the queue. */
+               task_regs(task)->iaoq[0] = task_regs(task)->iaoq[1];
+               task_regs(task)->iasq[0] = task_regs(task)->iasq[1];
+               task_regs(task)->iaoq[1] = task_regs(task)->iaoq[0] + 4;
+               pa_psw(task)->n = 0;
+               pa_psw(task)->x = 0;
+               pa_psw(task)->y = 0;
+               pa_psw(task)->z = 0;
+               pa_psw(task)->b = 0;
+               ptrace_disable(task);
+               /* Don't wake up the task, but let the
+                  parent know something happened. */
+               si.si_code = TRAP_TRACE;
+               si.si_addr = (void __user *) (task_regs(task)->iaoq[0] & ~3);
+               si.si_signo = SIGTRAP;
+               si.si_errno = 0;
+               force_sig_info(SIGTRAP, &si, task);
+               /* notify_parent(task, SIGCHLD); */
+               return;
+       }
+
+       /* Enable recovery counter traps.  The recovery counter
+        * itself will be set to zero on a task switch.  If the
+        * task is suspended on a syscall then the syscall return
+        * path will overwrite the recovery counter with a suitable
+        * value such that it traps once back in user space.  We
+        * disable interrupts in the tasks PSW here also, to avoid
+        * interrupts while the recovery counter is decrementing.
+        */
+       pa_psw(task)->r = 1;
+       pa_psw(task)->t = 0;
+       pa_psw(task)->h = 0;
+       pa_psw(task)->l = 0;
+}
+
+void user_enable_block_step(struct task_struct *task)
+{
+       task->ptrace &= ~PT_SINGLESTEP;
+       task->ptrace |= PT_BLOCKSTEP;
+
+       /* Enable taken branch trap. */
+       pa_psw(task)->r = 0;
+       pa_psw(task)->t = 1;
+       pa_psw(task)->h = 0;
+       pa_psw(task)->l = 0;
+}
+
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+{
+       unsigned long tmp;
+       long ret = -EIO;
 
-#ifdef CONFIG_64BIT
+       switch (request) {
+
+       /* Read the word at location addr in the USER area.  For ptraced
+          processes, the kernel saves all regs on a syscall. */
+       case PTRACE_PEEKUSR:
+               if ((addr & (sizeof(long)-1)) ||
+                   (unsigned long) addr >= sizeof(struct pt_regs))
+                       break;
+               tmp = *(unsigned long *) ((char *) task_regs(child) + addr);
+               ret = put_user(tmp, (unsigned long *) data);
+               break;
+
+       /* Write the word at location addr in the USER area.  This will need
+          to change when the kernel no longer saves all regs on a syscall.
+          FIXME.  There is a problem at the moment in that r3-r18 are only
+          saved if the process is ptraced on syscall entry, and even then
+          those values are overwritten by actual register values on syscall
+          exit. */
+       case PTRACE_POKEUSR:
+               /* Some register values written here may be ignored in
+                * entry.S:syscall_restore_rfi; e.g. iaoq is written with
+                * r31/r31+4, and not with the values in pt_regs.
+                */
+               if (addr == PT_PSW) {
+                       /* Allow writing to Nullify, Divide-step-correction,
+                        * and carry/borrow bits.
+                        * BEWARE, if you set N, and then single step, it won't
+                        * stop on the nullified instruction.
+                        */
+                       data &= USER_PSW_BITS;
+                       task_regs(child)->gr[0] &= ~USER_PSW_BITS;
+                       task_regs(child)->gr[0] |= data;
+                       ret = 0;
+                       break;
+               }
+
+               if ((addr & (sizeof(long)-1)) ||
+                   (unsigned long) addr >= sizeof(struct pt_regs))
+                       break;
+               if ((addr >= PT_GR1 && addr <= PT_GR31) ||
+                               addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
+                               (addr >= PT_FR0 && addr <= PT_FR31 + 4) ||
+                               addr == PT_SAR) {
+                       *(unsigned long *) ((char *) task_regs(child) + addr) = data;
+                       ret = 0;
+               }
+               break;
+
+       default:
+               ret = ptrace_request(child, request, addr, data);
+               break;
+       }
+
+       return ret;
+}
+
+
+#ifdef CONFIG_COMPAT
 
 /* This function is needed to translate 32 bit pt_regs offsets in to
  * 64 bit pt_regs offsets.  For example, a 32 bit gdb under a 64 bit kernel
@@ -61,106 +196,25 @@ static long translate_usr_offset(long offset)
        else
                return -1;
 }
-#endif
 
-/*
- * Called by kernel/ptrace.c when detaching..
- *
- * Make sure single step bits etc are not set.
- */
-void ptrace_disable(struct task_struct *child)
+long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
+                       compat_ulong_t addr, compat_ulong_t data)
 {
-       /* make sure the trap bits are not set */
-       pa_psw(child)->r = 0;
-       pa_psw(child)->t = 0;
-       pa_psw(child)->h = 0;
-       pa_psw(child)->l = 0;
-}
-
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
-{
-       long ret;
-#ifdef DEBUG_PTRACE
-       long oaddr=addr, odata=data;
-#endif
+       compat_uint_t tmp;
+       long ret = -EIO;
 
        switch (request) {
-       case PTRACE_PEEKTEXT: /* read word at location addr. */ 
-       case PTRACE_PEEKDATA: {
-#ifdef CONFIG_64BIT
-               if (__is_compat_task(child)) {
-                       int copied;
-                       unsigned int tmp;
-
-                       addr &= 0xffffffffL;
-                       copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
-                       ret = -EIO;
-                       if (copied != sizeof(tmp))
-                               goto out_tsk;
-                       ret = put_user(tmp,(unsigned int *) data);
-                       DBG("sys_ptrace(PEEK%s, %d, %lx, %lx) returning %ld, data %x\n",
-                               request == PTRACE_PEEKTEXT ? "TEXT" : "DATA",
-                               pid, oaddr, odata, ret, tmp);
-               }
-               else
-#endif
-                       ret = generic_ptrace_peekdata(child, addr, data);
-               goto out_tsk;
-       }
 
-       /* when I and D space are separate, this will have to be fixed. */
-       case PTRACE_POKETEXT: /* write the word at location addr. */
-       case PTRACE_POKEDATA:
-               ret = 0;
-#ifdef CONFIG_64BIT
-               if (__is_compat_task(child)) {
-                       unsigned int tmp = (unsigned int)data;
-                       DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n",
-                               request == PTRACE_POKETEXT ? "TEXT" : "DATA",
-                               pid, oaddr, odata);
-                       addr &= 0xffffffffL;
-                       if (access_process_vm(child, addr, &tmp, sizeof(tmp), 1) == sizeof(tmp))
-                               goto out_tsk;
-               }
-               else
-#endif
-               {
-                       if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
-                               goto out_tsk;
-               }
-               ret = -EIO;
-               goto out_tsk;
-
-       /* Read the word at location addr in the USER area.  For ptraced
-          processes, the kernel saves all regs on a syscall. */
-       case PTRACE_PEEKUSR: {
-               ret = -EIO;
-#ifdef CONFIG_64BIT
-               if (__is_compat_task(child)) {
-                       unsigned int tmp;
-
-                       if (addr & (sizeof(int)-1))
-                               goto out_tsk;
-                       if ((addr = translate_usr_offset(addr)) < 0)
-                               goto out_tsk;
-
-                       tmp = *(unsigned int *) ((char *) task_regs(child) + addr);
-                       ret = put_user(tmp, (unsigned int *) data);
-                       DBG("sys_ptrace(PEEKUSR, %d, %lx, %lx) returning %ld, addr %lx, data %x\n",
-                               pid, oaddr, odata, ret, addr, tmp);
-               }
-               else
-#endif
-               {
-                       unsigned long tmp;
+       case PTRACE_PEEKUSR:
+               if (addr & (sizeof(compat_uint_t)-1))
+                       break;
+               addr = translate_usr_offset(addr);
+               if (addr < 0)
+                       break;
 
-                       if ((addr & (sizeof(long)-1)) || (unsigned long) addr >= sizeof(struct pt_regs))
-                               goto out_tsk;
-                       tmp = *(unsigned long *) ((char *) task_regs(child) + addr);
-                       ret = put_user(tmp, (unsigned long *) data);
-               }
-               goto out_tsk;
-       }
+               tmp = *(compat_uint_t *) ((char *) task_regs(child) + addr);
+               ret = put_user(tmp, (compat_uint_t *) (unsigned long) data);
+               break;
 
        /* Write the word at location addr in the USER area.  This will need
           to change when the kernel no longer saves all regs on a syscall.
@@ -169,185 +223,46 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
           those values are overwritten by actual register values on syscall
           exit. */
        case PTRACE_POKEUSR:
-               ret = -EIO;
                /* Some register values written here may be ignored in
                 * entry.S:syscall_restore_rfi; e.g. iaoq is written with
                 * r31/r31+4, and not with the values in pt_regs.
                 */
-                /* PT_PSW=0, so this is valid for 32 bit processes under 64
-                * bit kernels.
-                */
                if (addr == PT_PSW) {
-                       /* PT_PSW=0, so this is valid for 32 bit processes
-                        * under 64 bit kernels.
-                        *
-                        * Allow writing to Nullify, Divide-step-correction,
-                        * and carry/borrow bits.
-                        * BEWARE, if you set N, and then single step, it won't
-                        * stop on the nullified instruction.
+                       /* Since PT_PSW==0, it is valid for 32 bit processes
+                        * under 64 bit kernels as well.
                         */
-                       DBG("sys_ptrace(POKEUSR, %d, %lx, %lx)\n",
-                               pid, oaddr, odata);
-                       data &= USER_PSW_BITS;
-                       task_regs(child)->gr[0] &= ~USER_PSW_BITS;
-                       task_regs(child)->gr[0] |= data;
-                       ret = 0;
-                       goto out_tsk;
-               }
-#ifdef CONFIG_64BIT
-               if (__is_compat_task(child)) {
-                       if (addr & (sizeof(int)-1))
-                               goto out_tsk;
-                       if ((addr = translate_usr_offset(addr)) < 0)
-                               goto out_tsk;
-                       DBG("sys_ptrace(POKEUSR, %d, %lx, %lx) addr %lx\n",
-                               pid, oaddr, odata, addr);
+                       ret = arch_ptrace(child, request, addr, data);
+               } else {
+                       if (addr & (sizeof(compat_uint_t)-1))
+                               break;
+                       addr = translate_usr_offset(addr);
+                       if (addr < 0)
+                               break;
                        if (addr >= PT_FR0 && addr <= PT_FR31 + 4) {
                                /* Special case, fp regs are 64 bits anyway */
-                               *(unsigned int *) ((char *) task_regs(child) + addr) = data;
+                               *(__u64 *) ((char *) task_regs(child) + addr) = data;
                                ret = 0;
                        }
                        else if ((addr >= PT_GR1+4 && addr <= PT_GR31+4) ||
                                        addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4 ||
                                        addr == PT_SAR+4) {
                                /* Zero the top 32 bits */
-                               *(unsigned int *) ((char *) task_regs(child) + addr - 4) = 0;
-                               *(unsigned int *) ((char *) task_regs(child) + addr) = data;
+                               *(__u32 *) ((char *) task_regs(child) + addr - 4) = 0;
+                               *(__u32 *) ((char *) task_regs(child) + addr) = data;
                                ret = 0;
                        }
-                       goto out_tsk;
                }
-               else
-#endif
-               {
-                       if ((addr & (sizeof(long)-1)) || (unsigned long) addr >= sizeof(struct pt_regs))
-                               goto out_tsk;
-                       if ((addr >= PT_GR1 && addr <= PT_GR31) ||
-                                       addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
-                                       (addr >= PT_FR0 && addr <= PT_FR31 + 4) ||
-                                       addr == PT_SAR) {
-                               *(unsigned long *) ((char *) task_regs(child) + addr) = data;
-                               ret = 0;
-                       }
-                       goto out_tsk;
-               }
-
-       case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
-       case PTRACE_CONT:
-               ret = -EIO;
-               DBG("sys_ptrace(%s)\n",
-                       request == PTRACE_SYSCALL ? "SYSCALL" : "CONT");
-               if (!valid_signal(data))
-                       goto out_tsk;
-               child->ptrace &= ~(PT_SINGLESTEP|PT_BLOCKSTEP);
-               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;
-               goto out_wake_notrap;
-
-       case PTRACE_KILL:
-               /*
-                * make the child exit.  Best I can do is send it a
-                * sigkill.  perhaps it should be put in the status
-                * that it wants to exit.
-                */
-               ret = 0;
-               DBG("sys_ptrace(KILL)\n");
-               if (child->exit_state == EXIT_ZOMBIE)   /* already dead */
-                       goto out_tsk;
-               child->exit_code = SIGKILL;
-               goto out_wake_notrap;
-
-       case PTRACE_SINGLEBLOCK:
-               DBG("sys_ptrace(SINGLEBLOCK)\n");
-               ret = -EIO;
-               if (!valid_signal(data))
-                       goto out_tsk;
-               clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-               child->ptrace &= ~PT_SINGLESTEP;
-               child->ptrace |= PT_BLOCKSTEP;
-               child->exit_code = data;
-
-               /* Enable taken branch trap. */
-               pa_psw(child)->r = 0;
-               pa_psw(child)->t = 1;
-               pa_psw(child)->h = 0;
-               pa_psw(child)->l = 0;
-               goto out_wake;
-
-       case PTRACE_SINGLESTEP:
-               DBG("sys_ptrace(SINGLESTEP)\n");
-               ret = -EIO;
-               if (!valid_signal(data))
-                       goto out_tsk;
-
-               clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-               child->ptrace &= ~PT_BLOCKSTEP;
-               child->ptrace |= PT_SINGLESTEP;
-               child->exit_code = data;
-
-               if (pa_psw(child)->n) {
-                       struct siginfo si;
-
-                       /* Nullified, just crank over the queue. */
-                       task_regs(child)->iaoq[0] = task_regs(child)->iaoq[1];
-                       task_regs(child)->iasq[0] = task_regs(child)->iasq[1];
-                       task_regs(child)->iaoq[1] = task_regs(child)->iaoq[0] + 4;
-                       pa_psw(child)->n = 0;
-                       pa_psw(child)->x = 0;
-                       pa_psw(child)->y = 0;
-                       pa_psw(child)->z = 0;
-                       pa_psw(child)->b = 0;
-                       ptrace_disable(child);
-                       /* Don't wake up the child, but let the
-                          parent know something happened. */
-                       si.si_code = TRAP_TRACE;
-                       si.si_addr = (void __user *) (task_regs(child)->iaoq[0] & ~3);
-                       si.si_signo = SIGTRAP;
-                       si.si_errno = 0;
-                       force_sig_info(SIGTRAP, &si, child);
-                       //notify_parent(child, SIGCHLD);
-                       //ret = 0;
-                       goto out_wake;
-               }
-
-               /* Enable recovery counter traps.  The recovery counter
-                * itself will be set to zero on a task switch.  If the
-                * task is suspended on a syscall then the syscall return
-                * path will overwrite the recovery counter with a suitable
-                * value such that it traps once back in user space.  We
-                * disable interrupts in the childs PSW here also, to avoid
-                * interrupts while the recovery counter is decrementing.
-                */
-               pa_psw(child)->r = 1;
-               pa_psw(child)->t = 0;
-               pa_psw(child)->h = 0;
-               pa_psw(child)->l = 0;
-               /* give it a chance to run. */
-               goto out_wake;
-
-       case PTRACE_GETEVENTMSG:
-                ret = put_user(child->ptrace_message, (unsigned int __user *) data);
-               goto out_tsk;
+               break;
 
        default:
-               ret = ptrace_request(child, request, addr, data);
-               goto out_tsk;
+               ret = compat_ptrace_request(child, request, addr, data);
+               break;
        }
 
-out_wake_notrap:
-       ptrace_disable(child);
-out_wake:
-       wake_up_process(child);
-       ret = 0;
-out_tsk:
-       DBG("arch_ptrace(%ld, %d, %lx, %lx) returning %ld\n",
-               request, pid, oaddr, odata, ret);
        return ret;
 }
+#endif
+
 
 void syscall_trace(void)
 {
index 7a92695d95a6bf814a72803da7d02403953eacd4..5f3d3a1f9037c7438b980c3e5f8d23589c4a5461 100644 (file)
@@ -8,12 +8,24 @@
  *
  */
 
+#include <asm/pdc.h>
 #include <asm/psw.h>
 #include <asm/assembly.h>
+#include <asm/asm-offsets.h>
 
 #include <linux/linkage.h>
 
+
        .section        .bss
+
+       .export pdc_result
+       .export pdc_result2
+       .align 8
+pdc_result:
+       .block  ASM_PDC_RESULT_SIZE
+pdc_result2:
+       .block  ASM_PDC_RESULT_SIZE
+
        .export real_stack
        .export real32_stack
        .export real64_stack
index 39e7c5a5946a8981deee1afa1296efc7cff9eadc..7d27853ff8c8b6233ec4a0e1f2fe3747fbbf88aa 100644 (file)
@@ -44,6 +44,7 @@
 #include <asm/pdc_chassis.h>
 #include <asm/io.h>
 #include <asm/setup.h>
+#include <asm/unwind.h>
 
 static char __initdata command_line[COMMAND_LINE_SIZE];
 
@@ -123,6 +124,7 @@ void __init setup_arch(char **cmdline_p)
 #ifdef CONFIG_64BIT
        extern int parisc_narrow_firmware;
 #endif
+       unwind_init();
 
        init_per_cpu(smp_processor_id());       /* Set Modes & Enable FP */
 
@@ -368,6 +370,31 @@ static int __init parisc_init(void)
 
        return 0;
 }
-
 arch_initcall(parisc_init);
 
+void start_parisc(void)
+{
+       extern void start_kernel(void);
+
+       int ret, cpunum;
+       struct pdc_coproc_cfg coproc_cfg;
+
+       cpunum = smp_processor_id();
+
+       set_firmware_width_unlocked();
+
+       ret = pdc_coproc_cfg_unlocked(&coproc_cfg);
+       if (ret >= 0 && coproc_cfg.ccr_functional) {
+               mtctl(coproc_cfg.ccr_functional, 10);
+
+               cpu_data[cpunum].fp_rev = coproc_cfg.revision;
+               cpu_data[cpunum].fp_model = coproc_cfg.model;
+
+               asm volatile ("fstd     %fr0,8(%sp)");
+       } else {
+               panic("must have an fpu to boot linux");
+       }
+
+       start_kernel();
+       // not reached
+}
index c7e59f548817fb36554954d663bfedcdf5e3b2f6..303d2b647e418daab682f586565ade19e5420325 100644 (file)
@@ -87,7 +87,7 @@
        ENTRY_SAME(setuid)
        ENTRY_SAME(getuid)
        ENTRY_COMP(stime)               /* 25 */
-       ENTRY_SAME(ptrace)
+       ENTRY_COMP(ptrace)
        ENTRY_SAME(alarm)
        /* see stat comment */
        ENTRY_COMP(newfstat)
        ENTRY_SAME(timerfd_create)
        ENTRY_COMP(timerfd_settime)
        ENTRY_COMP(timerfd_gettime)
+       ENTRY_COMP(signalfd4)
+       ENTRY_SAME(eventfd2)            /* 310 */
+       ENTRY_SAME(epoll_create1)
+       ENTRY_SAME(dup3)
+       ENTRY_SAME(pipe2)
+       ENTRY_SAME(inotify_init1)
 
        /* Nothing yet */
 
index 24be86bba94d6bdf93618109bb490bf6fbe68205..4d09203bc69307275afcb92f5f3a53d2bdff5057 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/smp.h>
 #include <linux/profile.h>
 #include <linux/clocksource.h>
+#include <linux/platform_device.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -215,6 +216,24 @@ void __init start_cpu_itimer(void)
        cpu_data[cpu].it_value = next_tick;
 }
 
+struct platform_device rtc_parisc_dev = {
+       .name = "rtc-parisc",
+       .id = -1,
+};
+
+static int __init rtc_init(void)
+{
+       int ret;
+
+       ret = platform_device_register(&rtc_parisc_dev);
+       if (ret < 0)
+               printk(KERN_ERR "unable to register rtc device...\n");
+
+       /* not necessarily an error */
+       return 0;
+}
+module_init(rtc_init);
+
 void __init time_init(void)
 {
        static struct pdc_tod tod_data;
@@ -245,4 +264,3 @@ void __init time_init(void)
                xtime.tv_nsec = 0;
        }
 }
-
index 701b2d2d88823f55fb2d18a2c03c1e91b2b3f2a9..6773c582e457a15b3e9ddb5006e462754bddd06e 100644 (file)
@@ -170,7 +170,7 @@ void unwind_table_remove(struct unwind_table *table)
 }
 
 /* Called from setup_arch to import the kernel unwind info */
-static int unwind_init(void)
+int unwind_init(void)
 {
        long start, stop;
        register unsigned long gp __asm__ ("r27");
@@ -417,5 +417,3 @@ int unwind_to_user(struct unwind_frame_info *info)
 
        return ret;
 }
-
-module_init(unwind_init);
index 113f5139f5518e778f35f765180b28985dc6373a..026cba2af07ad1672eb97b4dae44942971da13b0 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/oprofile.h>
 
-int __init oprofile_arch_init(struct oprofile_operations * ops)
+int __init oprofile_arch_init(struct oprofile_operations *ops)
 {
        return -ENODEV;
 }
index 9391199d9e7731d166b45130fa322e27936b1da0..5b1527883fcb590b361fcda998164a59f4a33e4a 100644 (file)
@@ -19,9 +19,6 @@ config WORD_SIZE
        default 64 if PPC64
        default 32 if !PPC64
 
-config PPC_MERGE
-       def_bool y
-
 config ARCH_PHYS_ADDR_T_64BIT
        def_bool PPC64 || PHYS_64BIT
 
@@ -326,13 +323,11 @@ config KEXEC
 
 config CRASH_DUMP
        bool "Build a kdump crash kernel"
-       depends on PPC_MULTIPLATFORM && PPC64
+       depends on PPC_MULTIPLATFORM && PPC64 && RELOCATABLE
        help
          Build a kernel suitable for use as a kdump capture kernel.
-         The kernel will be linked at a different address than normal, and
-         so can only be used for Kdump.
-
-         Don't change this unless you know what you are doing.
+         The same kernel binary can be used as production kernel and dump
+         capture kernel.
 
 config PHYP_DUMP
        bool "Hypervisor-assisted dump (EXPERIMENTAL)"
@@ -832,11 +827,9 @@ config PAGE_OFFSET
        default "0xc000000000000000"
 config KERNEL_START
        hex
-       default "0xc000000002000000" if CRASH_DUMP
        default "0xc000000000000000"
 config PHYSICAL_START
        hex
-       default "0x02000000" if CRASH_DUMP
        default "0x00000000"
 endif
 
index aac1406ccba5cb6394cdacf4837d846e4d35e56a..8fc6d72849ae435c095ec75a94acb677f0815d5e 100644 (file)
@@ -68,7 +68,8 @@ src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c
                fixed-head.S ep88xc.c ep405.c cuboot-c2k.c \
                cuboot-katmai.c cuboot-rainier.c redboot-8xx.c ep8248e.c \
                cuboot-warp.c cuboot-85xx-cpm2.c cuboot-yosemite.c simpleboot.c \
-               virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c
+               virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c \
+               cuboot-acadia.c
 src-boot := $(src-wlib) $(src-plat) empty.c
 
 src-boot := $(addprefix $(obj)/, $(src-boot))
@@ -211,6 +212,7 @@ image-$(CONFIG_DEFAULT_UIMAGE)              += uImage
 # Board ports in arch/powerpc/platform/40x/Kconfig
 image-$(CONFIG_EP405)                  += dtbImage.ep405
 image-$(CONFIG_WALNUT)                 += treeImage.walnut
+image-$(CONFIG_ACADIA)                 += cuImage.acadia
 
 # Board ports in arch/powerpc/platform/44x/Kconfig
 image-$(CONFIG_EBONY)                  += treeImage.ebony cuImage.ebony
@@ -319,6 +321,9 @@ $(obj)/zImage.iseries: vmlinux
 $(obj)/uImage: vmlinux $(wrapperbits)
        $(call if_changed,wrap,uboot)
 
+$(obj)/cuImage.initrd.%: vmlinux $(obj)/%.dtb $(wrapperbits)
+       $(call if_changed,wrap,cuboot-$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz)
+
 $(obj)/cuImage.%: vmlinux $(obj)/%.dtb $(wrapperbits)
        $(call if_changed,wrap,cuboot-$*,,$(obj)/$*.dtb)
 
index dcc9ab2ca823fff000dccf638c3c7caab421500e..3091d1d21aefcadf34992ccff9a3ed02962db505 100644 (file)
@@ -11,7 +11,7 @@
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  *
- * Usage: addnote zImage [note.elf]
+ * Usage: addnote [-r realbase] zImage [note.elf]
  *
  * If note.elf is supplied, it is the name of an ELF file that contains
  * an RPA note to use instead of the built-in one.  Alternatively, the
@@ -153,18 +153,31 @@ unsigned char *read_rpanote(const char *fname, int *nnp)
 int
 main(int ac, char **av)
 {
-       int fd, n, i;
+       int fd, n, i, ai;
        int ph, ps, np;
        int nnote, nnote2, ns;
        unsigned char *rpap;
-
-       if (ac != 2 && ac != 3) {
-               fprintf(stderr, "Usage: %s elf-file [rpanote.elf]\n", av[0]);
+       char *p, *endp;
+
+       ai = 1;
+       if (ac >= ai + 2 && strcmp(av[ai], "-r") == 0) {
+               /* process -r realbase */
+               p = av[ai + 1];
+               descr[1] = strtol(p, &endp, 16);
+               if (endp == p || *endp != 0) {
+                       fprintf(stderr, "Can't parse -r argument '%s' as hex\n",
+                               p);
+                       exit(1);
+               }
+               ai += 2;
+       }
+       if (ac != ai + 1 && ac != ai + 2) {
+               fprintf(stderr, "Usage: %s [-r realbase] elf-file [rpanote.elf]\n", av[0]);
                exit(1);
        }
-       fd = open(av[1], O_RDWR);
+       fd = open(av[ai], O_RDWR);
        if (fd < 0) {
-               perror(av[1]);
+               perror(av[ai]);
                exit(1);
        }
 
@@ -184,12 +197,12 @@ main(int ac, char **av)
        if (buf[E_IDENT+EI_CLASS] != ELFCLASS32
            || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) {
                fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n",
-                       av[1]);
+                       av[ai]);
                exit(1);
        }
 
-       if (ac == 3)
-               rpap = read_rpanote(av[2], &nnote2);
+       if (ac == ai + 2)
+               rpap = read_rpanote(av[ai + 1], &nnote2);
 
        ph = GET_32BE(buf, E_PHOFF);
        ps = GET_16BE(buf, E_PHENTSIZE);
@@ -202,7 +215,7 @@ main(int ac, char **av)
        for (i = 0; i < np; ++i) {
                if (GET_32BE(buf, ph + PH_TYPE) == PT_NOTE) {
                        fprintf(stderr, "%s already has a note entry\n",
-                               av[1]);
+                               av[ai]);
                        exit(0);
                }
                ph += ps;
@@ -260,18 +273,18 @@ main(int ac, char **av)
                exit(1);
        }
        if (i < n) {
-               fprintf(stderr, "%s: write truncated\n", av[1]);
+               fprintf(stderr, "%s: write truncated\n", av[ai]);
                exit(1);
        }
 
        exit(0);
 
  notelf:
-       fprintf(stderr, "%s does not appear to be an ELF file\n", av[1]);
+       fprintf(stderr, "%s does not appear to be an ELF file\n", av[ai]);
        exit(1);
 
  nospace:
        fprintf(stderr, "sorry, I can't find space in %s to put the note\n",
-               av[1]);
+               av[ai]);
        exit(1);
 }
index a8611546a656338820ffb2d83448c03954f331cb..4c42ec8687be100c879242f6a3846640f1bc8b12 100644 (file)
@@ -37,6 +37,10 @@ static void platform_fixups(void)
         * this can do a simple path lookup.
         */
        soc = find_node_by_devtype(NULL, "soc");
+       if (!soc)
+               soc = find_node_by_compatible(NULL, "fsl,mpc5200-immr");
+       if (!soc)
+               soc = find_node_by_compatible(NULL, "fsl,mpc5200b-immr");
        if (soc) {
                setprop(soc, "bus-frequency", &bd.bi_ipbfreq,
                        sizeof(bd.bi_ipbfreq));
diff --git a/arch/powerpc/boot/cuboot-acadia.c b/arch/powerpc/boot/cuboot-acadia.c
new file mode 100644 (file)
index 0000000..0634aba
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Old U-boot compatibility for Acadia
+ *
+ * Author: Josh Boyer <jwboyer@linux.vnet.ibm.com>
+ *
+ * Copyright 2008 IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "ops.h"
+#include "io.h"
+#include "dcr.h"
+#include "stdio.h"
+#include "4xx.h"
+#include "44x.h"
+#include "cuboot.h"
+
+#define TARGET_4xx
+#include "ppcboot.h"
+
+static bd_t bd;
+
+#define CPR_PERD0_SPIDV_MASK   0x000F0000     /* SPI Clock Divider */
+
+#define PLLC_SRC_MASK         0x20000000     /* PLL feedback source */
+
+#define PLLD_FBDV_MASK        0x1F000000     /* PLL feedback divider value */
+#define PLLD_FWDVA_MASK        0x000F0000     /* PLL forward divider A value */
+#define PLLD_FWDVB_MASK        0x00000700     /* PLL forward divider B value */
+
+#define PRIMAD_CPUDV_MASK      0x0F000000     /* CPU Clock Divisor Mask */
+#define PRIMAD_PLBDV_MASK      0x000F0000     /* PLB Clock Divisor Mask */
+#define PRIMAD_OPBDV_MASK      0x00000F00     /* OPB Clock Divisor Mask */
+#define PRIMAD_EBCDV_MASK      0x0000000F     /* EBC Clock Divisor Mask */
+
+#define PERD0_PWMDV_MASK       0xFF000000     /* PWM Divider Mask */
+#define PERD0_SPIDV_MASK       0x000F0000     /* SPI Divider Mask */
+#define PERD0_U0DV_MASK        0x0000FF00     /* UART 0 Divider Mask */
+#define PERD0_U1DV_MASK        0x000000FF     /* UART 1 Divider Mask */
+
+static void get_clocks(void)
+{
+       unsigned long sysclk, cpr_plld, cpr_pllc, cpr_primad, plloutb, i;
+       unsigned long pllFwdDiv, pllFwdDivB, pllFbkDiv, pllPlbDiv, pllExtBusDiv;
+       unsigned long pllOpbDiv, freqEBC, freqUART, freqOPB;
+       unsigned long div;              /* total divisor udiv * bdiv */
+       unsigned long umin;             /* minimum udiv */
+       unsigned short diff;            /* smallest diff */
+       unsigned long udiv;             /* best udiv */
+       unsigned short idiff;           /* current diff */
+       unsigned short ibdiv;           /* current bdiv */
+       unsigned long est;              /* current estimate */
+       unsigned long baud;
+       void *np;
+
+       /* read the sysclk value from the CPLD */
+       sysclk = (in_8((unsigned char *)0x80000000) == 0xc) ? 66666666 : 33333000;
+
+       /*
+        * Read PLL Mode registers
+        */
+       cpr_plld = CPR0_READ(DCRN_CPR0_PLLD);
+       cpr_pllc = CPR0_READ(DCRN_CPR0_PLLC);
+
+       /*
+        * Determine forward divider A
+        */
+       pllFwdDiv = ((cpr_plld & PLLD_FWDVA_MASK) >> 16);
+
+       /*
+        * Determine forward divider B
+        */
+       pllFwdDivB = ((cpr_plld & PLLD_FWDVB_MASK) >> 8);
+       if (pllFwdDivB == 0)
+               pllFwdDivB = 8;
+
+       /*
+        * Determine FBK_DIV.
+        */
+       pllFbkDiv = ((cpr_plld & PLLD_FBDV_MASK) >> 24);
+       if (pllFbkDiv == 0)
+               pllFbkDiv = 256;
+
+       /*
+        * Read CPR_PRIMAD register
+        */
+       cpr_primad = CPR0_READ(DCRN_CPR0_PRIMAD);
+
+       /*
+        * Determine PLB_DIV.
+        */
+       pllPlbDiv = ((cpr_primad & PRIMAD_PLBDV_MASK) >> 16);
+       if (pllPlbDiv == 0)
+               pllPlbDiv = 16;
+
+       /*
+        * Determine EXTBUS_DIV.
+        */
+       pllExtBusDiv = (cpr_primad & PRIMAD_EBCDV_MASK);
+       if (pllExtBusDiv == 0)
+               pllExtBusDiv = 16;
+
+       /*
+        * Determine OPB_DIV.
+        */
+       pllOpbDiv = ((cpr_primad & PRIMAD_OPBDV_MASK) >> 8);
+       if (pllOpbDiv == 0)
+               pllOpbDiv = 16;
+
+       /* There is a bug in U-Boot that prevents us from using
+        * bd.bi_opbfreq because U-Boot doesn't populate it for
+        * 405EZ.  We get to calculate it, yay!
+        */
+       freqOPB = (sysclk *pllFbkDiv) /pllOpbDiv;
+
+       freqEBC = (sysclk * pllFbkDiv) / pllExtBusDiv;
+
+       plloutb = ((sysclk * ((cpr_pllc & PLLC_SRC_MASK) ?
+                                          pllFwdDivB : pllFwdDiv) *
+                   pllFbkDiv) / pllFwdDivB);
+
+       np = find_node_by_alias("serial0");
+       if (getprop(np, "current-speed", &baud, sizeof(baud)) != sizeof(baud))
+               fatal("no current-speed property\n\r");
+
+       udiv = 256;                     /* Assume lowest possible serial clk */
+       div = plloutb / (16 * baud); /* total divisor */
+       umin = (plloutb / freqOPB) << 1;        /* 2 x OPB divisor */
+       diff = 256;                     /* highest possible */
+
+       /* i is the test udiv value -- start with the largest
+        * possible (256) to minimize serial clock and constrain
+        * search to umin.
+        */
+       for (i = 256; i > umin; i--) {
+               ibdiv = div / i;
+               est = i * ibdiv;
+               idiff = (est > div) ? (est-div) : (div-est);
+               if (idiff == 0) {
+                       udiv = i;
+                       break;      /* can't do better */
+               } else if (idiff < diff) {
+                       udiv = i;       /* best so far */
+                       diff = idiff;   /* update lowest diff*/
+               }
+       }
+       freqUART = plloutb / udiv;
+
+       dt_fixup_cpu_clocks(bd.bi_procfreq, bd.bi_intfreq, bd.bi_plb_busfreq);
+       dt_fixup_clock("/plb/ebc", freqEBC);
+       dt_fixup_clock("/plb/opb", freqOPB);
+       dt_fixup_clock("/plb/opb/serial@ef600300", freqUART);
+       dt_fixup_clock("/plb/opb/serial@ef600400", freqUART);
+}
+
+static void acadia_fixups(void)
+{
+       dt_fixup_memory(bd.bi_memstart, bd.bi_memsize);
+       get_clocks();
+       dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr);
+}
+       
+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+               unsigned long r6, unsigned long r7)
+{
+       CUBOOT_INIT();
+       platform_ops.fixups = acadia_fixups;
+       platform_ops.exit = ibm40x_dbcr_reset;
+       fdt_init(_dtb_start);
+       serial_console_init();
+}
diff --git a/arch/powerpc/boot/dts/acadia.dts b/arch/powerpc/boot/dts/acadia.dts
new file mode 100644 (file)
index 0000000..57291f6
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Device Tree Source for AMCC Acadia (405EZ)
+ *
+ * Copyright IBM Corp. 2008
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       model = "amcc,acadia";
+       compatible = "amcc,acadia";
+       dcr-parent = <&{/cpus/cpu@0}>;
+
+       aliases {
+               ethernet0 = &EMAC0;
+               serial0 = &UART0;
+               serial1 = &UART1;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       model = "PowerPC,405EZ";
+                       reg = <0x0>;
+                       clock-frequency = <0>; /* Filled in by wrapper */
+                       timebase-frequency = <0>; /* Filled in by wrapper */
+                       i-cache-line-size = <32>;
+                       d-cache-line-size = <32>;
+                       i-cache-size = <16384>;
+                       d-cache-size = <16384>;
+                       dcr-controller;
+                       dcr-access-method = "native";
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x0 0x0>; /* Filled in by wrapper */
+       };
+
+       UIC0: interrupt-controller {
+               compatible = "ibm,uic-405ez", "ibm,uic";
+               interrupt-controller;
+               dcr-reg = <0x0c0 0x009>;
+               cell-index = <0>;
+               #address-cells = <0>;
+               #size-cells = <0>;
+               #interrupt-cells = <2>;
+       };
+
+       plb {
+               compatible = "ibm,plb-405ez", "ibm,plb3";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+               clock-frequency = <0>; /* Filled in by wrapper */
+
+               MAL0: mcmal {
+                       compatible = "ibm,mcmal-405ez", "ibm,mcmal";
+                       dcr-reg = <0x380 0x62>;
+                       num-tx-chans = <1>;
+                       num-rx-chans = <1>;
+                       interrupt-parent = <&UIC0>;
+                       /* 405EZ has only 3 interrupts to the UIC, as
+                        * SERR, TXDE, and RXDE are or'd together into
+                        * one UIC bit
+                        */
+                       interrupts = <
+                               0x13 0x4 /* TXEOB */
+                               0x15 0x4 /* RXEOB */
+                               0x12 0x4 /* SERR, TXDE, RXDE */>;
+               };
+
+               POB0: opb {
+                       compatible = "ibm,opb-405ez", "ibm,opb";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+                       dcr-reg = <0x0a 0x05>;
+                       clock-frequency = <0>; /* Filled in by wrapper */
+
+                       UART0: serial@ef600300 {
+                               device_type = "serial";
+                               compatible = "ns16550";
+                               reg = <0xef600300 0x8>;
+                               virtual-reg = <0xef600300>;
+                               clock-frequency = <0>; /* Filled in by wrapper */
+                               current-speed = <115200>;
+                               interrupt-parent = <&UIC0>;
+                               interrupts = <0x5 0x4>;
+                       };
+
+                       UART1: serial@ef600400 {
+                               device_type = "serial";
+                               compatible = "ns16550";
+                               reg = <0xef600400 0x8>;
+                               clock-frequency = <0>; /* Filled in by wrapper */
+                               current-speed = <115200>;
+                               interrupt-parent = <&UIC0>;
+                               interrupts = <0x6 0x4>;
+                       };
+
+                       IIC: i2c@ef600500 {
+                               compatible = "ibm,iic-405ez", "ibm,iic";
+                               reg = <0xef600500 0x11>;
+                               interrupt-parent = <&UIC0>;
+                               interrupts = <0xa 0x4>;
+                       };
+
+                       GPIO0: gpio@ef600700 {
+                               compatible = "ibm,gpio-405ez";
+                               reg = <0xef600700 0x20>;
+                       };
+
+                       GPIO1: gpio@ef600800 {
+                               compatible = "ibm,gpio-405ez";
+                               reg = <0xef600800 0x20>;
+                       };
+
+                       EMAC0: ethernet@ef600900 {
+                               device_type = "network";
+                               compatible = "ibm,emac-405ez", "ibm,emac";
+                               interrupt-parent = <&UIC0>;
+                               interrupts = <
+                                       0x10 0x4 /* Ethernet */
+                                       0x11 0x4 /* Ethernet Wake up */>;
+                               local-mac-address = [000000000000]; /* Filled in by wrapper */
+                               reg = <0xef600900 0x70>;
+                               mal-device = <&MAL0>;
+                               mal-tx-channel = <0>;
+                               mal-rx-channel = <0>;
+                               cell-index = <0>;
+                               max-frame-size = <1500>;
+                               rx-fifo-size = <4096>;
+                               tx-fifo-size = <2048>;
+                               phy-mode = "mii";
+                               phy-map = <0x0>;
+                       };
+
+                       CAN0: can@ef601000 {
+                               compatible = "amcc,can-405ez";
+                               reg = <0xef601000 0x620>;
+                               interrupt-parent = <&UIC0>;
+                               interrupts = <0x7 0x4>;
+                       };
+
+                       CAN1: can@ef601800 {
+                               compatible = "amcc,can-405ez";
+                               reg = <0xef601800 0x620>;
+                               interrupt-parent = <&UIC0>;
+                               interrupts = <0x8 0x4>;
+                       };
+
+                       cameleon@ef602000 {
+                               compatible = "amcc,cameleon-405ez";
+                               reg = <0xef602000 0x800>;
+                               interrupt-parent = <&UIC0>;
+                               interrupts = <0xb 0x4 0xc 0x4>;
+                       };
+
+                       ieee1588@ef602800 {
+                               compatible = "amcc,ieee1588-405ez";
+                               reg = <0xef602800 0x60>;
+                               interrupt-parent = <&UIC0>;
+                               interrupts = <0x4 0x4>;
+                               /* This thing is a bit weird.  It has it's own UIC
+                                * that it uses to generate snapshot triggers.  We
+                                * don't really support this device yet, and it needs
+                                * work to figure this out.
+                                */
+                               dcr-reg = <0xe0 0x9>;
+                       };
+
+                       usb@ef603000 {
+                               compatible = "ohci-be";
+                               reg = <0xef603000 0x80>;
+                               interrupts-parent = <&UIC0>;
+                               interrupts = <0xd 0x4 0xe 0x4>;
+                       };
+
+                       dac@ef603300 {
+                               compatible = "amcc,dac-405ez";
+                               reg = <0xef603300 0x40>;
+                               interrupt-parent = <&UIC0>;
+                               interrupts = <0x18 0x4>;
+                       };
+
+                       adc@ef603400 {
+                               compatible = "amcc,adc-405ez";
+                               reg = <0xef603400 0x40>;
+                               interrupt-parent = <&UIC0>;
+                               interrupts = <0x17 0x4>;
+                       };
+
+                       spi@ef603500 {
+                               compatible = "amcc,spi-405ez";
+                               reg = <0xef603500 0x100>;
+                               interrupt-parent = <&UIC0>;
+                               interrupts = <0x9 0x4>;
+                       };
+               };
+
+               EBC0: ebc {
+                       compatible = "ibm,ebc-405ez", "ibm,ebc";
+                       dcr-reg = <0x12 0x2>;
+                       #address-cells = <2>;
+                       #size-cells = <1>;
+                       clock-frequency = <0>; /* Filled in by wrapper */
+               };
+       };
+
+       chosen {
+               linux,stdout-path = "/plb/opb/serial@ef600300";
+       };
+};
diff --git a/arch/powerpc/boot/dts/hcu4.dts b/arch/powerpc/boot/dts/hcu4.dts
new file mode 100644 (file)
index 0000000..7988598
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+* Device Tree Source for Netstal Maschinen HCU4
+* based on the IBM Walnut
+*
+* Copyright 2008
+* Niklaus Giger <niklaus.giger@member.fsf.org>
+*
+* Copyright 2007 IBM Corp.
+* Josh Boyer <jwboyer@linux.vnet.ibm.com>
+*
+* 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.
+*/
+
+/dts-v1/;
+
+/ {
+       #address-cells = <0x1>;
+       #size-cells = <0x1>;
+       model = "netstal,hcu4";
+       compatible = "netstal,hcu4";
+       dcr-parent = <0x1>;
+
+       aliases {
+               ethernet0 = "/plb/opb/ethernet@ef600800";
+               serial0 = "/plb/opb/serial@ef600300";
+       };
+
+       cpus {
+               #address-cells = <0x1>;
+               #size-cells = <0x0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       model = "PowerPC,405GPr";
+                       reg = <0x0>;
+                       clock-frequency = <0>;          /* Filled in by U-Boot */
+                       timebase-frequency = <0x0>;     /* Filled in by U-Boot */
+                       i-cache-line-size = <0x20>;
+                       d-cache-line-size = <0x20>;
+                       i-cache-size = <0x4000>;
+                       d-cache-size = <0x4000>;
+                       dcr-controller;
+                       dcr-access-method = "native";
+                       linux,phandle = <0x1>;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x0 0x0>;        /* Filled in by U-Boot */
+       };
+
+       UIC0: interrupt-controller {
+               compatible = "ibm,uic";
+               interrupt-controller;
+               cell-index = <0x0>;
+               dcr-reg = <0xc0 0x9>;
+               #address-cells = <0x0>;
+               #size-cells = <0x0>;
+               #interrupt-cells = <0x2>;
+               linux,phandle = <0x2>;
+       };
+
+       plb {
+               compatible = "ibm,plb3";
+               #address-cells = <0x1>;
+               #size-cells = <0x1>;
+               ranges;
+               clock-frequency = <0x0>;        /* Filled in by U-Boot */
+
+               SDRAM0: memory-controller {
+                       compatible = "ibm,sdram-405gp";
+                       dcr-reg = <0x10 0x2>;
+               };
+
+               MAL: mcmal {
+                       compatible = "ibm,mcmal-405gp", "ibm,mcmal";
+                       dcr-reg = <0x180 0x62>;
+                       num-tx-chans = <0x1>;
+                       num-rx-chans = <0x1>;
+                       interrupt-parent = <0x2>;
+                       interrupts = <0xb 0x4 0xc 0x4 0xa 0x4 0xd 0x4 0xe 0x4>;
+                       linux,phandle = <0x3>;
+               };
+
+               POB0: opb {
+                       compatible = "ibm,opb-405gp", "ibm,opb";
+                       #address-cells = <0x1>;
+                       #size-cells = <0x1>;
+                       ranges = <0xef600000 0xef600000 0xa00000>;
+                       dcr-reg = <0xa0 0x5>;
+                       clock-frequency = <0x0>;        /* Filled in by U-Boot */
+
+                       UART0: serial@ef600300 {
+                               device_type = "serial";
+                               compatible = "ns16550";
+                               reg = <0xef600300 0x8>;
+                               virtual-reg = <0xef600300>;
+                               clock-frequency = <0x0>;/* Filled in by U-Boot */
+                               current-speed = <0>;    /* Filled in by U-Boot */
+                               interrupt-parent = <0x2>;
+                               interrupts = <0x0 0x4>;
+                       };
+
+                       IIC: i2c@ef600500 {
+                               compatible = "ibm,iic-405gp", "ibm,iic";
+                               reg = <0xef600500 0x11>;
+                               interrupt-parent = <0x2>;
+                               interrupts = <0x2 0x4>;
+                       };
+
+                       GPIO: gpio@ef600700 {
+                               compatible = "ibm,gpio-405gp";
+                               reg = <0xef600700 0x20>;
+                       };
+
+                       EMAC: ethernet@ef600800 {
+                               device_type = "network";
+                               compatible = "ibm,emac-405gp", "ibm,emac";
+                               interrupt-parent = <0x2>;
+                               interrupts = <0xf 0x4 0x9 0x4>;
+                               local-mac-address = [00 00 00 00 00 00];
+                               reg = <0xef600800 0x70>;
+                               mal-device = <0x3>;
+                               mal-tx-channel = <0x0>;
+                               mal-rx-channel = <0x0>;
+                               cell-index = <0x0>;
+                               max-frame-size = <0x5dc>;
+                               rx-fifo-size = <0x1000>;
+                               tx-fifo-size = <0x800>;
+                               phy-mode = "rmii";
+                               phy-map = <0x1>;
+                       };
+               };
+
+               EBC0: ebc {
+                       compatible = "ibm,ebc-405gp", "ibm,ebc";
+                       dcr-reg = <0x12 0x2>;
+                       #address-cells = <0x2>;
+                       #size-cells = <0x1>;
+                       clock-frequency = <0x0>;        /* Filled in by U-Boot */
+
+                       sram@0,0 {
+                               reg = <0x0 0x0 0x80000>;
+                       };
+
+                       flash@0,80000 {
+                               compatible = "jedec-flash";
+                               bank-width = <0x1>;
+                               reg = <0x0 0x80000 0x80000>;
+                               #address-cells = <0x1>;
+                               #size-cells = <0x1>;
+
+                               partition@0 {
+                                       label = "OpenBIOS";
+                                       reg = <0x0 0x80000>;
+                                       read-only;
+                               };
+                       };
+               };
+       };
+
+       chosen {
+               linux,stdout-path = "/plb/opb/serial@ef600300";
+       };
+};
index 7449e54c1a908d46e780aa5815c4ef83b71551bb..6b850670de1df9da01b043dac83dea9c3afa550d 100644 (file)
                                compatible = "dallas,ds1339";
                                reg = <0x68>;
                        };
+
+                       mcu_pio: mcu@a {
+                               #gpio-cells = <2>;
+                               compatible = "fsl,mc9s08qg8-mpc8315erdb",
+                                            "fsl,mcu-mpc8349emitx";
+                               reg = <0x0a>;
+                               gpio-controller;
+                       };
                };
 
                spi@7000 {
index e4cc1768f24165b56446ce5b06a0d4d422f64bbf..57c595bf10717f23036a9d292b6025c26f273afa 100644 (file)
@@ -60,7 +60,7 @@
        };
 
        bcsr@f8000000 {
-               device_type = "board-control";
+               compatible = "fsl,mpc8323mds-bcsr";
                reg = <0xf8000000 0x8000>;
        };
 
index 5cedf373a1d802e39aba5c21e232b49db2ed71a6..2c9d54a35bc312e8286812a67507e7a71e9f9141 100644 (file)
                        interrupts = <15 0x8>;
                        interrupt-parent = <&ipic>;
                        dfsrr;
+
+                       rtc@68 {
+                               device_type = "rtc";
+                               compatible = "dallas,ds1339";
+                               reg = <0x68>;
+                               interrupts = <18 0x8>;
+                               interrupt-parent = <&ipic>;
+                       };
                };
 
                spi@7000 {
                                interrupt-parent = <&ipic>;
                                interrupts = <71 8>;
                        };
+
+                       mcu_pio: mcu@a {
+                               #gpio-cells = <2>;
+                               compatible = "fsl,mc9s08qg8-mpc8349emitx",
+                                            "fsl,mcu-mpc8349emitx";
+                               reg = <0x0a>;
+                               gpio-controller;
+                       };
                };
 
                usb@22000 {
index 81ae1d3e9440ad06be3e14eeb9cb10ce544ae659..fa40647ee62e9bb74ef363ff6c2c9962b8a6dac2 100644 (file)
                        interrupts = <15 0x8>;
                        interrupt-parent = <&ipic>;
                        dfsrr;
+
+                       rtc@68 {
+                               device_type = "rtc";
+                               compatible = "dallas,ds1339";
+                               reg = <0x68>;
+                               interrupts = <18 0x8>;
+                               interrupt-parent = <&ipic>;
+                       };
                };
 
                spi@7000 {
index 04bfde3ea605b2ec64cc528c0e64341e89ff8c33..c986c541e9bba8b9d013ede8db8e2017dc9ee6ee 100644 (file)
@@ -49,7 +49,7 @@
        };
 
        bcsr@e2400000 {
-               device_type = "board-control";
+               compatible = "fsl,mpc8349mds-bcsr";
                reg = <0xe2400000 0x8000>;
        };
 
index 66a12d2631fbd4e39b93e3d6c351ed820703d6c9..14534d04e4db1cf1e9709184754e9278011c0531 100644 (file)
@@ -69,7 +69,7 @@
                };
 
                bcsr@1,0 {
-                       device_type = "board-control";
+                       compatible = "fsl,mpc8360mds-bcsr";
                        reg = <1 0 0x8000>;
                };
        };
index 53191ba67aaa3a1d2493fb8a251b0f437efff167..435ef3dd022d0f3614f85e7bbcffced5c0102cd7 100644 (file)
                                compatible = "dallas,ds1339";
                                reg = <0x68>;
                        };
+
+                       mcu_pio: mcu@a {
+                               #gpio-cells = <2>;
+                               compatible = "fsl,mc9s08qg8-mpc8377erdb",
+                                            "fsl,mcu-mpc8349emitx";
+                               reg = <0x0a>;
+                               gpio-controller;
+                       };
                };
 
                i2c@3100 {
index 4a09153d160c90967b5b27a0bcfe52cc49561251..b11e68f56a0612d302ce61bee6d2c56f03f01f3b 100644 (file)
                                compatible = "dallas,ds1339";
                                reg = <0x68>;
                        };
+
+                       mcu_pio: mcu@a {
+                               #gpio-cells = <2>;
+                               compatible = "fsl,mc9s08qg8-mpc8378erdb",
+                                            "fsl,mcu-mpc8349emitx";
+                               reg = <0x0a>;
+                               gpio-controller;
+                       };
                };
 
                i2c@3100 {
index bbd884ac9dc0e3f84a487f2edb6277416b008cd8..337af6ea26d3817247543fa94ddddba9ee135ee9 100644 (file)
                                compatible = "dallas,ds1339";
                                reg = <0x68>;
                        };
+
+                       mcu_pio: mcu@a {
+                               #gpio-cells = <2>;
+                               compatible = "fsl,mc9s08qg8-mpc8379erdb",
+                                            "fsl,mcu-mpc8349emitx";
+                               reg = <0x0a>;
+                               gpio-controller;
+                       };
                };
 
                i2c@3100 {
index 93fdd99901b6e61c9909542ec30338df5b0d8cd8..35db1e5440c7631928562337ac2f043f82e6f55a 100644 (file)
                                reg = <0x0 0x80>;
                                cell-index = <0>;
                                interrupt-parent = <&mpic>;
-                               interrupts = <14 0x2>;
+                               interrupts = <20 2>;
                        };
                        dma-channel@80 {
                                compatible = "fsl,mpc8536-dma-channel",
                                reg = <0x80 0x80>;
                                cell-index = <1>;
                                interrupt-parent = <&mpic>;
-                               interrupts = <15 0x2>;
+                               interrupts = <21 2>;
                        };
                        dma-channel@100 {
                                compatible = "fsl,mpc8536-dma-channel",
                                reg = <0x100 0x80>;
                                cell-index = <2>;
                                interrupt-parent = <&mpic>;
-                               interrupts = <16 0x2>;
+                               interrupts = <22 2>;
                        };
                        dma-channel@180 {
                                compatible = "fsl,mpc8536-dma-channel",
                                reg = <0x180 0x80>;
                                cell-index = <3>;
                                interrupt-parent = <&mpic>;
-                               interrupts = <17 0x2>;
+                               interrupts = <23 2>;
                        };
                };
 
                enet0: ethernet@24000 {
                        cell-index = <0>;
                        device_type = "network";
-                       model = "TSEC";
+                       model = "eTSEC";
                        compatible = "gianfar";
                        reg = <0x24000 0x1000>;
                        local-mac-address = [ 00 00 00 00 00 00 ];
                enet1: ethernet@26000 {
                        cell-index = <1>;
                        device_type = "network";
-                       model = "TSEC";
+                       model = "eTSEC";
                        compatible = "gianfar";
                        reg = <0x26000 0x1000>;
                        local-mac-address = [ 00 00 00 00 00 00 ];
index a15f10343f53fa4238b9e0d9d4169a4e9388450d..c80158f7741db22f93c3f969492c10c706e18bb1 100644 (file)
@@ -52,7 +52,7 @@
        };
 
        bcsr@f8000000 {
-               device_type = "board-control";
+               compatible = "fsl,mpc8568mds-bcsr";
                reg = <0xf8000000 0x8000>;
        };
 
index e124dd18fb5aec09d5d26074e1887729d491e1aa..cadd4652a69556a8eb496449b3d3f15e0d4928fb 100644 (file)
@@ -13,8 +13,8 @@
 / {
        model = "fsl,MPC8572DS";
        compatible = "fsl,MPC8572DS";
-       #address-cells = <1>;
-       #size-cells = <1>;
+       #address-cells = <2>;
+       #size-cells = <2>;
 
        aliases {
                ethernet0 = &enet0;
@@ -61,7 +61,6 @@
 
        memory {
                device_type = "memory";
-               reg = <0x0 0x0>;        // Filled by U-Boot
        };
 
        soc8572@ffe00000 {
@@ -69,8 +68,8 @@
                #size-cells = <1>;
                device_type = "soc";
                compatible = "simple-bus";
-               ranges = <0x0 0xffe00000 0x100000>;
-               reg = <0xffe00000 0x1000>;      // CCSRBAR & soc regs, remove once parse code for immrbase fixed
+               ranges = <0x0 0 0xffe00000 0x100000>;
+               reg = <0 0xffe00000 0 0x1000>;  // CCSRBAR & soc regs, remove once parse code for immrbase fixed
                bus-frequency = <0>;            // Filled out by uboot.
 
                memory-controller@2000 {
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
-               reg = <0xffe08000 0x1000>;
+               reg = <0 0xffe08000 0 0x1000>;
                bus-range = <0 255>;
-               ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x20000000
-                         0x1000000 0x0 0x0 0xffc00000 0x0 0x10000>;
+               ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
+                         0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x00010000>;
                clock-frequency = <33333333>;
                interrupt-parent = <&mpic>;
                interrupts = <24 2>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
-               reg = <0xffe09000 0x1000>;
+               reg = <0 0xffe09000 0 0x1000>;
                bus-range = <0 255>;
-               ranges = <0x2000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000
-                         0x1000000 0x0 0x0 0xffc10000 0x0 0x10000>;
+               ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+                         0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x00010000>;
                clock-frequency = <33333333>;
                interrupt-parent = <&mpic>;
                interrupts = <26 2>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
-               reg = <0xffe0a000 0x1000>;
+               reg = <0 0xffe0a000 0 0x1000>;
                bus-range = <0 255>;
-               ranges = <0x2000000 0x0 0xc0000000 0xc0000000 0x0 0x20000000
-                         0x1000000 0x0 0x0 0xffc20000 0x0 0x10000>;
+               ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+                         0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x00010000>;
                clock-frequency = <33333333>;
                interrupt-parent = <&mpic>;
                interrupts = <27 2>;
index c541fd8a95d4966369aa79fbc3557122fd7a36d8..9276327bc2bb1995343dabf417f2c3927386cd95 100644 (file)
@@ -105,6 +105,11 @@ static int fdt_wrapper_setprop(const void *devp, const char *name,
        return check_err(rc);
 }
 
+static int fdt_wrapper_del_node(const void *devp)
+{
+       return fdt_del_node(fdt, devp_offset(devp));
+}
+
 static void *fdt_wrapper_get_parent(const void *devp)
 {
        return offset_devp(fdt_parent_offset(fdt, devp_offset(devp)));
@@ -165,6 +170,7 @@ static unsigned long fdt_wrapper_finalize(void)
 void fdt_init(void *blob)
 {
        int err;
+       int bufsize;
 
        dt_ops.finddevice = fdt_wrapper_finddevice;
        dt_ops.getprop = fdt_wrapper_getprop;
@@ -173,21 +179,21 @@ void fdt_init(void *blob)
        dt_ops.create_node = fdt_wrapper_create_node;
        dt_ops.find_node_by_prop_value = fdt_wrapper_find_node_by_prop_value;
        dt_ops.find_node_by_compatible = fdt_wrapper_find_node_by_compatible;
+       dt_ops.del_node = fdt_wrapper_del_node;
        dt_ops.get_path = fdt_wrapper_get_path;
        dt_ops.finalize = fdt_wrapper_finalize;
 
        /* Make sure the dt blob is the right version and so forth */
        fdt = blob;
-       err = fdt_open_into(fdt, fdt, fdt_totalsize(blob));
-       if (err == -FDT_ERR_NOSPACE) {
-               int bufsize = fdt_totalsize(fdt) + 4;
-               buf = malloc(bufsize);
-               err = fdt_open_into(fdt, buf, bufsize);
-       }
+       bufsize = fdt_totalsize(fdt) + 4;
+       buf = malloc(bufsize);
+       if(!buf)
+               fatal("malloc failed. can't relocate the device tree\n\r");
+
+       err = fdt_open_into(fdt, buf, bufsize);
 
        if (err != 0)
                fatal("fdt_init(): %s\n\r", fdt_strerror(err));
 
-       if (buf)
-               fdt = buf;
+       fdt = buf;
 }
index 9e7f3ddd99131523c275f468ea26cc3f974a2e83..ae32801ebd69de64fee9e4946f569ebb81813b95 100644 (file)
@@ -56,9 +56,19 @@ static struct addr_range prep_kernel(void)
        if (platform_ops.vmlinux_alloc) {
                addr = platform_ops.vmlinux_alloc(ei.memsize);
        } else {
-               if ((unsigned long)_start < ei.memsize)
+               /*
+                * Check if the kernel image (without bss) would overwrite the
+                * bootwrapper. The device tree has been moved in fdt_init()
+                * to an area allocated with malloc() (somewhere past _end).
+                */
+               if ((unsigned long)_start < ei.loadsize)
                        fatal("Insufficient memory for kernel at address 0!"
-                              " (_start=%p)\n\r", _start);
+                              " (_start=%p, uncomressed size=%08x)\n\r",
+                              _start, ei.loadsize);
+
+               if ((unsigned long)_end < ei.memsize)
+                       fatal("The final kernel image would overwrite the "
+                                       "device tree\n\r");
        }
 
        /* Finally, gunzip the kernel */
index 321e2f5afe714007443e4c8a39bad2f011c7e04e..b3218ce451bb9be8081dd77cc75f0a3114468be1 100644 (file)
@@ -40,6 +40,7 @@ struct dt_ops {
                        const int buflen);
        int     (*setprop)(const void *phandle, const char *name,
                        const void *buf, const int buflen);
+       int (*del_node)(const void *phandle);
        void *(*get_parent)(const void *phandle);
        /* The node must not already exist. */
        void *(*create_node)(const void *parent, const char *name);
@@ -126,6 +127,11 @@ static inline int setprop_str(void *devp, const char *name, const char *buf)
        return -1;
 }
 
+static inline int del_node(const void *devp)
+{
+       return dt_ops.del_node ? dt_ops.del_node(devp) : -1;
+}
+
 static inline void *get_parent(const char *devp)
 {
        return dt_ops.get_parent ? dt_ops.get_parent(devp) : NULL;
index 643e4cb2f11da67f3c55f237ff68fbda5b07687f..acc9428f27897d80db4cd65430fedf1069adbe6c 100644 (file)
@@ -235,7 +235,7 @@ memchr:
        .globl  memcmp
 memcmp:
        cmpwi   0,r5,0
-       blelr
+       ble     2f
        mtctr   r5
        addi    r6,r3,-1
        addi    r4,r4,-1
@@ -244,6 +244,8 @@ memcmp:
        subf.   r3,r0,r3
        bdnzt   2,1b
        blr
+2:     li      r3,0
+       blr
 
 
 /*
index ee0dc41d7c5659bb063e37b23bf180b2c8ba578b..f39073511a49ada9b2597a641b70e7fd1477cbb5 100755 (executable)
@@ -306,11 +306,14 @@ fi
 
 # post-processing needed for some platforms
 case "$platform" in
-pseries|chrp)
+pseries)
     ${CROSS}objcopy -O binary -j .fakeelf "$kernel" "$ofile".rpanote
     $objbin/addnote "$ofile" "$ofile".rpanote
     rm -r "$ofile".rpanote
     ;;
+chrp)
+    $objbin/addnote -r c00000 "$ofile"
+    ;;
 coff)
     ${CROSS}objcopy -O aixcoff-rs6000 --set-start "$entry" "$ofile"
     $objbin/hack-coff "$ofile"
diff --git a/arch/powerpc/configs/40x/acadia_defconfig b/arch/powerpc/configs/40x/acadia_defconfig
new file mode 100644 (file)
index 0000000..39bd9eb
--- /dev/null
@@ -0,0 +1,921 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27-rc5
+# Mon Oct 13 13:47:16 2008
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+# CONFIG_6xx is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+CONFIG_40x=y
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_4xx=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+# CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_PPC_DCR_NATIVE=y
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_PPC_DCR=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
+# CONFIG_FAIR_GROUP_SCHED is not set
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
+CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PPC4xx_PCI_EXPRESS is not set
+
+#
+# Platform support
+#
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+CONFIG_ACADIA=y
+# CONFIG_EP405 is not set
+# CONFIG_KILAUEA is not set
+# CONFIG_MAKALU is not set
+# CONFIG_WALNUT is not set
+# CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set
+CONFIG_PPC40x_SIMPLE=y
+CONFIG_405EZ=y
+# CONFIG_IPIC is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_FSL_ULI1575 is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_4xx_SOC=y
+CONFIG_PPC_PCI_CHOICE=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0xc0000000
+CONFIG_CONSISTENT_START=0xff100000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=m
+CONFIG_MTD_BLOCK=m
+# CONFIG_MTD_BLOCK_RO is not set
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+CONFIG_OF_DEVICE=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=35000
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_XILINX_SYSACE is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS 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_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_IBM_NEW_EMAC=y
+CONFIG_IBM_NEW_EMAC_RXB=256
+CONFIG_IBM_NEW_EMAC_TXB=256
+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
+CONFIG_IBM_NEW_EMAC_DEBUG=y
+# 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=y
+CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT=y
+CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR=y
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_I2C is not set
+# CONFIG_SPI 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=y
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO 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
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL 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 is not set
+# CONFIG_DLM is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+
+#
+# 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=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER 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_PAGEALLOC is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+# CONFIG_XMON is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_VIRQ_DEBUG is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# 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=y
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/powerpc/configs/40x/hcu4_defconfig b/arch/powerpc/configs/40x/hcu4_defconfig
new file mode 100644 (file)
index 0000000..682fce0
--- /dev/null
@@ -0,0 +1,929 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.26.5
+# Tue Sep 16 00:44:33 2008
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+# CONFIG_6xx is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+CONFIG_40x=y
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_4xx=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+# CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_PPC_DCR_NATIVE=y
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_PPC_DCR=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+# CONFIG_LOGBUFFER is not set
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_DMA_ATTRS is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_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_KMOD=y
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PPC4xx_PCI_EXPRESS is not set
+
+#
+# Platform support
+#
+# CONFIG_PPC_MPC512x is not set
+# CONFIG_PPC_MPC5121 is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_EP405 is not set
+CONFIG_HCU4=y
+# CONFIG_KILAUEA is not set
+# CONFIG_MAKALU is not set
+# CONFIG_WALNUT is not set
+# CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set
+# CONFIG_IPIC is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_FSL_ULI1575 is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_4xx_SOC=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
+# CONFIG_PCI_LEGACY is not set
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0xc0000000
+CONFIG_CONSISTENT_START=0xff100000
+CONFIG_CONSISTENT_SIZE=0x00200000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=m
+CONFIG_MTD_BLOCK=m
+# CONFIG_MTD_BLOCK_RO is not set
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+CONFIG_OF_DEVICE=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=35000
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_XILINX_SYSACE is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_IBM_NEW_EMAC=y
+CONFIG_IBM_NEW_EMAC_RXB=128
+CONFIG_IBM_NEW_EMAC_TXB=64
+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
+# CONFIG_IBM_NEW_EMAC_DEBUG is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_E1000E_ENABLED is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+CONFIG_NETDEV_10000=y
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
+# CONFIG_SFC is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_I2C is not set
+# CONFIG_SPI 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
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# 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
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_YAFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+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_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+
+#
+# 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=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUGGER is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_VIRQ_DEBUG is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# 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=y
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_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=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
index f6c93c7168988664ad6144d06936ac3ebfc964ca..a503da9d56f38712786a6757fb223dfaf9c70b1b 100644 (file)
@@ -9,6 +9,12 @@
  * Reserve to the end of the FWNMI area, see head_64.S */
 #define KDUMP_RESERVE_LIMIT    0x10000 /* 64K */
 
+/*
+ * Used to differentiate between relocatable kdump kernel and other
+ * kernels
+ */
+#define KDUMP_SIGNATURE        0xfeed1234
+
 #ifdef CONFIG_CRASH_DUMP
 
 #define KDUMP_TRAMPOLINE_START 0x0100
 #endif /* CONFIG_CRASH_DUMP */
 
 #ifndef __ASSEMBLY__
-#ifdef CONFIG_CRASH_DUMP
 
+extern unsigned long __kdump_flag;
+
+#if defined(CONFIG_CRASH_DUMP) && !defined(CONFIG_RELOCATABLE)
 extern void reserve_kdump_trampoline(void);
 extern void setup_kdump_trampoline(void);
-
-#else /* !CONFIG_CRASH_DUMP */
-
+#else
+/* !CRASH_DUMP || RELOCATABLE */
 static inline void reserve_kdump_trampoline(void) { ; }
 static inline void setup_kdump_trampoline(void) { ; }
+#endif
 
-#endif /* CONFIG_CRASH_DUMP */
 #endif /* __ASSEMBLY__ */
 
 #endif /* __PPC64_KDUMP_H */
index 64e144505f653e0ae1d4f190690ef458e9aad5e7..c0b8d4a29a91cd34c7e10bb45608d7e9fe83fee0 100644 (file)
  * 2 of the License, or (at your option) any later version.
  */
 
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+#else
+#include <asm/types.h>
+#endif
 #include <asm/asm-compat.h>
 #include <asm/kdump.h>
-#include <asm/types.h>
 
 /*
  * On PPC32 page size is 4K. For PPC64 we support either 4K or 64K software
@@ -73,6 +77,7 @@
 
 #if defined(CONFIG_RELOCATABLE)
 #ifndef __ASSEMBLY__
+
 extern phys_addr_t memstart_addr;
 extern phys_addr_t kernstart_addr;
 #endif
index ae2ea803a0f2502daff6e2ffcd24359c1f602675..9047af7baa697afad42e89b19f2cfdd893ad7430 100644 (file)
@@ -74,6 +74,13 @@ struct pci_controller {
        unsigned long pci_io_size;
 #endif
 
+       /* 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;
index 0e52c7828ea498d48c34a37155dba0f57b39a349..39d547fde956a66f9dc3cb5d26914c3e01cb387b 100644 (file)
@@ -123,6 +123,16 @@ int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
 /* 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
+
 #if defined(CONFIG_PPC64) || defined(CONFIG_NOT_COHERENT_CACHE)
 /*
  * For 64-bit kernels, pci_unmap_{single,page} is not a nop.
@@ -226,5 +236,6 @@ extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
 extern void pcibios_do_bus_setup(struct pci_bus *bus);
 extern void pcibios_fixup_of_probed_bus(struct pci_bus *bus);
 
+
 #endif /* __KERNEL__ */
 #endif /* __ASM_POWERPC_PCI_H */
index 734e0754fb9bec39a0d8533d77c30ad1c02d1103..280a90cc9894c6ed3f6a2e2611b9d53623218a2f 100644 (file)
@@ -129,7 +129,7 @@ extern int ptrace_put_reg(struct task_struct *task, int regno,
 #define CHECK_FULL_REGS(regs)                                                \
 do {                                                                         \
        if ((regs)->trap & 1)                                                 \
-               printk(KERN_CRIT "%s: partial register set\n", __FUNCTION__); \
+               printk(KERN_CRIT "%s: partial register set\n", __func__); \
 } while (0)
 #endif /* __powerpc64__ */
 
index a7360cdd99eb783b6249c58428ffb744d46007d3..69f709d8e8e750f781c3b7f2a507dd4043ef49d5 100644 (file)
@@ -122,7 +122,6 @@ typedef struct sigaltstack {
 
 #ifdef __KERNEL__
 struct pt_regs;
-extern void do_signal(struct pt_regs *regs, unsigned long thread_info_flags);
 #define ptrace_signal_deliver(regs, cookie) do { } while (0)
 #endif /* __KERNEL__ */
 
index e70d0483fb4e55494c87f4d97d33b120336deed0..b1eb834bc0fcd00ba563ca8d60287d912a9fdc80 100644 (file)
@@ -1277,6 +1277,19 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .machine_check          = machine_check_4xx,
                .platform               = "ppc405",
        },
+       {
+               /* 405EZ */
+               .pvr_mask               = 0xffff0000,
+               .pvr_value              = 0x41510000,
+               .cpu_name               = "405EZ",
+               .cpu_features           = CPU_FTRS_40X,
+               .cpu_user_features      = PPC_FEATURE_32 |
+                       PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+               .icache_bsize           = 32,
+               .dcache_bsize           = 32,
+               .machine_check          = machine_check_4xx,
+               .platform               = "ppc405",
+       },
        {       /* default match */
                .pvr_mask               = 0x00000000,
                .pvr_value              = 0x00000000,
index 97e056379728c5f936aba586c0f9cf2acf044e34..19671aca659137ca8a6f62ac80585d969203a6f9 100644 (file)
@@ -30,6 +30,7 @@
 /* Stores the physical address of elf header of crash image. */
 unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
 
+#ifndef CONFIG_RELOCATABLE
 void __init reserve_kdump_trampoline(void)
 {
        lmb_reserve(0, KDUMP_RESERVE_LIMIT);
@@ -68,6 +69,7 @@ void __init setup_kdump_trampoline(void)
 
        DBG(" <- setup_kdump_trampoline()\n");
 }
+#endif /* CONFIG_RELOCATABLE */
 
 /*
  * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by
index 84856bee33a54a5bc58d7c99edf67286ddd281e0..69489bd3210c03ecf9c6d5e36fe5bee1c23e8871 100644 (file)
@@ -97,6 +97,12 @@ __secondary_hold_spinloop:
 __secondary_hold_acknowledge:
        .llong  0x0
 
+       /* This flag is set by purgatory if we should be a kdump kernel. */
+       /* Do not move this variable as purgatory knows about it. */
+       .globl  __kdump_flag
+__kdump_flag:
+       .llong  0x0
+
 #ifdef CONFIG_PPC_ISERIES
        /*
         * At offset 0x20, there is a pointer to iSeries LPAR data.
@@ -1384,7 +1390,13 @@ _STATIC(__after_prom_start)
        /* process relocations for the final address of the kernel */
        lis     r25,PAGE_OFFSET@highest /* compute virtual base of kernel */
        sldi    r25,r25,32
-       mr      r3,r25
+#ifdef CONFIG_CRASH_DUMP
+       ld      r7,__kdump_flag-_stext(r26)
+       cmpldi  cr0,r7,1        /* kdump kernel ? - stay where we are */
+       bne     1f
+       add     r25,r25,r26
+#endif
+1:     mr      r3,r25
        bl      .relocate
 #endif
 
@@ -1398,11 +1410,26 @@ _STATIC(__after_prom_start)
        li      r3,0                    /* target addr */
        mr.     r4,r26                  /* In some cases the loader may  */
        beq     9f                      /* have already put us at zero */
-       lis     r5,(copy_to_here - _stext)@ha
-       addi    r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */
        li      r6,0x100                /* Start offset, the first 0x100 */
                                        /* bytes were copied earlier.    */
 
+#ifdef CONFIG_CRASH_DUMP
+/*
+ * Check if the kernel has to be running as relocatable kernel based on the
+ * variable __kdump_flag, if it is set the kernel is treated as relocatable
+ * kernel, otherwise it will be moved to PHYSICAL_START
+ */
+       ld      r7,__kdump_flag-_stext(r26)
+       cmpldi  cr0,r7,1
+       bne     3f
+
+       li      r5,__end_interrupts - _stext    /* just copy interrupts */
+       b       5f
+3:
+#endif
+       lis     r5,(copy_to_here - _stext)@ha
+       addi    r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */
+
        bl      .copy_and_flush         /* copy the first n bytes        */
                                        /* this includes the code being  */
                                        /* executed here.                */
@@ -1411,15 +1438,15 @@ _STATIC(__after_prom_start)
        mtctr   r8
        bctr
 
+p_end: .llong  _end - _stext
+
 4:     /* Now copy the rest of the kernel up to _end */
        addis   r5,r26,(p_end - _stext)@ha
        ld      r5,(p_end - _stext)@l(r5)       /* get _end */
-       bl      .copy_and_flush         /* copy the rest */
+5:     bl      .copy_and_flush         /* copy the rest */
 
 9:     b       .start_here_multiplatform
 
-p_end: .llong  _end - _stext
-
 /*
  * Copy routine used to copy the kernel to start at physical address 0
  * and flush and invalidate the caches as needed.
index ea1ba89f9c9001ccff8b2d5256d09fe17dafd4c7..3857d7e2af0cab9513c72262f2e6372c66bf31c9 100644 (file)
@@ -458,6 +458,42 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
        spin_unlock_irqrestore(&(tbl->it_lock), flags);
 }
 
+static void iommu_table_clear(struct iommu_table *tbl)
+{
+       if (!__kdump_flag) {
+               /* Clear the table in case firmware left allocations in it */
+               ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size);
+               return;
+       }
+
+#ifdef CONFIG_CRASH_DUMP
+       if (ppc_md.tce_get) {
+               unsigned long index, tceval, tcecount = 0;
+
+               /* Reserve the existing mappings left by the first kernel. */
+               for (index = 0; index < tbl->it_size; index++) {
+                       tceval = ppc_md.tce_get(tbl, index + tbl->it_offset);
+                       /*
+                        * Freed TCE entry contains 0x7fffffffffffffff on JS20
+                        */
+                       if (tceval && (tceval != 0x7fffffffffffffffUL)) {
+                               __set_bit(index, tbl->it_map);
+                               tcecount++;
+                       }
+               }
+
+               if ((tbl->it_size - tcecount) < KDUMP_MIN_TCE_ENTRIES) {
+                       printk(KERN_WARNING "TCE table is full; freeing ");
+                       printk(KERN_WARNING "%d entries for the kdump boot\n",
+                               KDUMP_MIN_TCE_ENTRIES);
+                       for (index = tbl->it_size - KDUMP_MIN_TCE_ENTRIES;
+                               index < tbl->it_size; index++)
+                               __clear_bit(index, tbl->it_map);
+               }
+       }
+#endif
+}
+
 /*
  * Build a iommu_table structure.  This contains a bit map which
  * is used to manage allocation of the tce space.
@@ -484,38 +520,7 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
        tbl->it_largehint = tbl->it_halfpoint;
        spin_lock_init(&tbl->it_lock);
 
-#ifdef CONFIG_CRASH_DUMP
-       if (ppc_md.tce_get) {
-               unsigned long index;
-               unsigned long tceval;
-               unsigned long tcecount = 0;
-
-               /*
-                * Reserve the existing mappings left by the first kernel.
-                */
-               for (index = 0; index < tbl->it_size; index++) {
-                       tceval = ppc_md.tce_get(tbl, index + tbl->it_offset);
-                       /*
-                        * Freed TCE entry contains 0x7fffffffffffffff on JS20
-                        */
-                       if (tceval && (tceval != 0x7fffffffffffffffUL)) {
-                               __set_bit(index, tbl->it_map);
-                               tcecount++;
-                       }
-               }
-               if ((tbl->it_size - tcecount) < KDUMP_MIN_TCE_ENTRIES) {
-                       printk(KERN_WARNING "TCE table is full; ");
-                       printk(KERN_WARNING "freeing %d entries for the kdump boot\n",
-                               KDUMP_MIN_TCE_ENTRIES);
-                       for (index = tbl->it_size - KDUMP_MIN_TCE_ENTRIES;
-                               index < tbl->it_size; index++)
-                               __clear_bit(index, tbl->it_map);
-               }
-       }
-#else
-       /* Clear the hardware table in case firmware left allocations in it */
-       ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size);
-#endif
+       iommu_table_clear(tbl);
 
        if (!welcomed) {
                printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n",
index aab76887a842c7dfa667141fe9467551338cf0ca..ac2a21f45c757a41f8ab639abca5a449d6576207 100644 (file)
@@ -88,11 +88,13 @@ void __init reserve_crashkernel(void)
 
        crash_size = crashk_res.end - crashk_res.start + 1;
 
+#ifndef CONFIG_RELOCATABLE
        if (crashk_res.start != KDUMP_KERNELBASE)
                printk("Crash kernel location must be 0x%x\n",
                                KDUMP_KERNELBASE);
 
        crashk_res.start = KDUMP_KERNELBASE;
+#endif
        crash_size = PAGE_ALIGN(crash_size);
        crashk_res.end = crashk_res.start + crash_size - 1;
 
index a168514d8609652335269211c723fb795a2f4865..e6efec788c4d0d98706c729666e1ab779feee6f9 100644 (file)
@@ -255,11 +255,14 @@ static union thread_union kexec_stack
 /* Our assembly helper, in kexec_stub.S */
 extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start,
                                        void *image, void *control,
-                                       void (*clear_all)(void)) ATTRIB_NORET;
+                                       void (*clear_all)(void),
+                                       unsigned long kdump_flag) ATTRIB_NORET;
 
 /* too late to fail here */
 void default_machine_kexec(struct kimage *image)
 {
+       unsigned long kdump_flag = 0;
+
        /* prepare control code if any */
 
        /*
@@ -270,8 +273,10 @@ void default_machine_kexec(struct kimage *image)
         * using debugger IPI.
         */
 
-       if (crashing_cpu == -1)
-               kexec_prepare_cpus();
+       if (crashing_cpu == -1)
+               kexec_prepare_cpus();
+       else
+               kdump_flag = KDUMP_SIGNATURE;
 
        /* switch to a staticly allocated stack.  Based on irq stack code.
         * XXX: the task struct will likely be invalid once we do the copy!
@@ -284,7 +289,7 @@ void default_machine_kexec(struct kimage *image)
         */
        kexec_sequence(&kexec_stack, image->start, image,
                        page_address(image->control_code_page),
-                       ppc_md.hpte_clear_all);
+                       ppc_md.hpte_clear_all, kdump_flag);
        /* NOTREACHED */
 }
 
@@ -312,11 +317,24 @@ static struct property kernel_end_prop = {
 static void __init export_htab_values(void)
 {
        struct device_node *node;
+       struct property *prop;
 
        node = of_find_node_by_path("/chosen");
        if (!node)
                return;
 
+       /* remove any stale propertys so ours can be found */
+       prop = of_find_property(node, kernel_end_prop.name, NULL);
+       if (prop)
+               prom_remove_property(node, prop);
+       prop = of_find_property(node, htab_base_prop.name, NULL);
+       if (prop)
+               prom_remove_property(node, prop);
+       prop = of_find_property(node, htab_size_prop.name, NULL);
+       if (prop)
+               prom_remove_property(node, prop);
+
+       /* information needed by userspace when using default_machine_kexec */
        kernel_end = __pa(_end);
        prom_add_property(node, &kernel_end_prop);
 
index 3053fe5c62f2a67694d430187df900495c19531b..a243fd072a77b08e70f99fa5d41a33ee9943619a 100644 (file)
@@ -611,10 +611,12 @@ real_mode:        /* assume normal blr return */
 
 
 /*
- * kexec_sequence(newstack, start, image, control, clear_all())
+ * kexec_sequence(newstack, start, image, control, clear_all(), kdump_flag)
  *
  * does the grungy work with stack switching and real mode switches
  * also does simple calls to other code
+ *
+ * kdump_flag says whether the next kernel should be a kdump kernel.
  */
 
 _GLOBAL(kexec_sequence)
@@ -647,7 +649,7 @@ _GLOBAL(kexec_sequence)
        mr      r29,r5                  /* image (virt) */
        mr      r28,r6                  /* control, unused */
        mr      r27,r7                  /* clear_all() fn desc */
-       mr      r26,r8                  /* spare */
+       mr      r26,r8                  /* kdump flag */
        lhz     r25,PACAHWCPUID(r13)    /* get our phys cpu from paca */
 
        /* disable interrupts, we are overwriting kernel data next */
@@ -709,5 +711,6 @@ _GLOBAL(kexec_sequence)
        mr      r4,r30  # start, aka phys mem offset
        mtlr    4
        li      r5,0
-       blr     /* image->start(physid, image->start, 0); */
+       mr      r6,r26                  /* kdump_flag */
+       blr     /* image->start(physid, image->start, 0, kdump_flag); */
 #endif /* CONFIG_KEXEC */
index 01ce8c38bae635334b6b3b9d104f0bb26d5861fe..1ec73938a00f122c7685c713aefb383934728b30 100644 (file)
@@ -451,7 +451,8 @@ pgprot_t pci_phys_mem_access_prot(struct file *file,
                pci_dev_put(pdev);
        }
 
-       DBG("non-PCI map for %lx, prot: %lx\n", offset, prot);
+       DBG("non-PCI map for %llx, prot: %lx\n",
+           (unsigned long long)offset, prot);
 
        return __pgprot(prot);
 }
@@ -490,6 +491,132 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
        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) {
+               if ((offset + size) > hose->isa_mem_size)
+                       return -ENXIO;
+               offset += hose->isa_mem_phys;
+       } else {
+               unsigned long io_offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+               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(pgprot_val(vma->vm_page_prot)
+                                    | _PAGE_NO_CACHE | _PAGE_GUARDED);
+       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)
@@ -592,6 +719,12 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
                cpu_addr = of_translate_address(dev, ranges + 3);
                size = of_read_number(ranges + pna + 3, 2);
                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;
 
@@ -665,6 +798,8 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
                                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
index 2fdbc18ae94afe3ef27c0a32debbca2535767b7a..23e0db203329cdfeeea7312e4c2b502c23fcaf1e 100644 (file)
@@ -487,67 +487,6 @@ static int __init prom_setprop(phandle node, const char *nodename,
        return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd);
 }
 
-/* We can't use the standard versions because of RELOC headaches. */
-#define isxdigit(c)    (('0' <= (c) && (c) <= '9') \
-                        || ('a' <= (c) && (c) <= 'f') \
-                        || ('A' <= (c) && (c) <= 'F'))
-
-#define isdigit(c)     ('0' <= (c) && (c) <= '9')
-#define islower(c)     ('a' <= (c) && (c) <= 'z')
-#define toupper(c)     (islower(c) ? ((c) - 'a' + 'A') : (c))
-
-unsigned long prom_strtoul(const char *cp, const char **endp)
-{
-       unsigned long result = 0, base = 10, value;
-
-       if (*cp == '0') {
-               base = 8;
-               cp++;
-               if (toupper(*cp) == 'X') {
-                       cp++;
-                       base = 16;
-               }
-       }
-
-       while (isxdigit(*cp) &&
-              (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
-               result = result * base + value;
-               cp++;
-       }
-
-       if (endp)
-               *endp = cp;
-
-       return result;
-}
-
-unsigned long prom_memparse(const char *ptr, const char **retptr)
-{
-       unsigned long ret = prom_strtoul(ptr, retptr);
-       int shift = 0;
-
-       /*
-        * We can't use a switch here because GCC *may* generate a
-        * jump table which won't work, because we're not running at
-        * the address we're linked at.
-        */
-       if ('G' == **retptr || 'g' == **retptr)
-               shift = 30;
-
-       if ('M' == **retptr || 'm' == **retptr)
-               shift = 20;
-
-       if ('K' == **retptr || 'k' == **retptr)
-               shift = 10;
-
-       if (shift) {
-               ret <<= shift;
-               (*retptr)++;
-       }
-
-       return ret;
-}
-
 /*
  * Early parsing of the command line passed to the kernel, used for
  * "mem=x" and the options that affect the iommu
index 2c7e8e87f770e604a6992babb938d6cfac706211..ea3a2ec03ffafe1a00a946895ee77db5c39b650d 100644 (file)
@@ -20,7 +20,7 @@ WHITELIST="add_reloc_offset __bss_start __bss_stop copy_and_flush
 _end enter_prom memcpy memset reloc_offset __secondary_hold
 __secondary_hold_acknowledge __secondary_hold_spinloop __start
 strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224
-reloc_got2 kernstart_addr"
+reloc_got2 kernstart_addr memstart_addr"
 
 NM="$1"
 OBJ="$2"
index 5ec56ff03e8621584cf026b2fdbb0405dddd84b0..705fc4bf3800af690b9d3edff25c915b52d811c6 100644 (file)
@@ -59,6 +59,7 @@
 #include <asm/mmu.h>
 #include <asm/xmon.h>
 #include <asm/cputhreads.h>
+#include <mm/mmu_decl.h>
 
 #include "setup.h"
 
@@ -190,6 +191,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                if (ppc_md.show_cpuinfo != NULL)
                        ppc_md.show_cpuinfo(m);
 
+#ifdef CONFIG_PPC32
+               /* Display the amount of memory */
+               seq_printf(m, "Memory\t\t: %d MB\n",
+                          (unsigned int)(total_memory / (1024 * 1024)));
+#endif
+
                return 0;
        }
 
index 28f4b9f5fe5e970a505940acd4268ce355be48c3..b427bf8e1d8fa440b714f730240ceca78ef7b850 100644 (file)
@@ -12,6 +12,8 @@
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
+extern void do_signal(struct pt_regs *regs, unsigned long thread_info_flags);
+
 extern void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
                                  size_t frame_size);
 extern void restore_sigmask(sigset_t *set);
index 65ad925c3a8f2e1ece221f7c709619c0a7cc4199..c6a8f2326b6f246fc077b25c2b7b1d9460f9e6cc 100644 (file)
@@ -235,8 +235,6 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
        else
                for (i = 0; i < 32 ; i++)
                        current->thread.fpr[i][TS_VSRLOWOFFSET] = 0;
-
-#else
 #endif
        return err;
 }
index cb01ebc593876b5736cc96640904a8117a5da3c6..7b7da8cfd5e862364feb391e4a3cc68447cfdec2 100644 (file)
@@ -142,7 +142,7 @@ unsigned int udbg_probe_uart_speed(void __iomem *comport, unsigned int clock)
        speed = (clock / prescaler) / (divisor * 16);
 
        /* sanity check */
-       if (speed < 0 || speed > (clock / 16))
+       if (speed > (clock / 16))
                speed = 9600;
 
        return speed;
index 5c64af1747525d7b7b5fd0adbae202845564f9e1..8d5b4758c13a5f47508c814ed9e279266bffead3 100644 (file)
@@ -382,8 +382,10 @@ static int __init htab_dt_scan_hugepage_blocks(unsigned long node,
        printk(KERN_INFO "Huge page(16GB) memory: "
                        "addr = 0x%lX size = 0x%lX pages = %d\n",
                        phys_addr, block_size, expected_pages);
-       lmb_reserve(phys_addr, block_size * expected_pages);
-       add_gpage(phys_addr, block_size, expected_pages);
+       if (phys_addr + (16 * GB) <= lmb_end_of_DRAM()) {
+               lmb_reserve(phys_addr, block_size * expected_pages);
+               add_gpage(phys_addr, block_size, expected_pages);
+       }
        return 0;
 }
 #endif /* CONFIG_HUGETLB_PAGE */
index 6cf5c71c431fddc43d33ba920753023d847a991e..eb505ad34a857421b2deb85bbedd7b4c6ba99777 100644 (file)
@@ -116,6 +116,7 @@ static int __init get_active_region_work_fn(unsigned long start_pfn,
 
 /*
  * get_node_active_region - Return active region containing start_pfn
+ * Active range returned is empty if none found.
  * @start_pfn: The page to return the region for.
  * @node_ar: Returned set to the active region containing start_pfn
  */
@@ -126,6 +127,7 @@ static void __init get_node_active_region(unsigned long start_pfn,
 
        node_ar->nid = nid;
        node_ar->start_pfn = start_pfn;
+       node_ar->end_pfn = start_pfn;
        work_with_active_regions(nid, get_active_region_work_fn, node_ar);
 }
 
@@ -526,12 +528,10 @@ static unsigned long __init numa_enforce_memory_limit(unsigned long start,
        /*
         * We use lmb_end_of_DRAM() in here instead of memory_limit because
         * we've already adjusted it for the limit and it takes care of
-        * having memory holes below the limit.
+        * having memory holes below the limit.  Also, in the case of
+        * iommu_is_off, memory_limit is not set but is implicitly enforced.
         */
 
-       if (! memory_limit)
-               return size;
-
        if (start + size <= lmb_end_of_DRAM())
                return size;
 
@@ -933,18 +933,20 @@ void __init do_init_bootmem(void)
                struct node_active_region node_ar;
 
                get_node_active_region(start_pfn, &node_ar);
-               while (start_pfn < end_pfn) {
+               while (start_pfn < end_pfn &&
+                       node_ar.start_pfn < node_ar.end_pfn) {
+                       unsigned long reserve_size = size;
                        /*
                         * if reserved region extends past active region
                         * then trim size to active region
                         */
                        if (end_pfn > node_ar.end_pfn)
-                               size = (node_ar.end_pfn << PAGE_SHIFT)
+                               reserve_size = (node_ar.end_pfn << PAGE_SHIFT)
                                        - (start_pfn << PAGE_SHIFT);
-                       dbg("reserve_bootmem %lx %lx nid=%d\n", physbase, size,
-                               node_ar.nid);
+                       dbg("reserve_bootmem %lx %lx nid=%d\n", physbase,
+                               reserve_size, node_ar.nid);
                        reserve_bootmem_node(NODE_DATA(node_ar.nid), physbase,
-                                               size, BOOTMEM_DEFAULT);
+                                               reserve_size, BOOTMEM_DEFAULT);
                        /*
                         * if reserved region is contained in the active region
                         * then done.
@@ -959,6 +961,7 @@ void __init do_init_bootmem(void)
                         */
                        start_pfn = node_ar.end_pfn;
                        physbase = start_pfn << PAGE_SHIFT;
+                       size = size - reserve_size;
                        get_node_active_region(start_pfn, &node_ar);
                }
 
index 22e4e8d4eb2c706daa7ad3481e87e4cc10afaf2b..628009c01958fc261ed1d14b3ff6e1352fa9afa5 100644 (file)
 #define SKIP_GENERIC_SYNC 0
 #define SYNC_START_ERROR -1
 #define DO_GENERIC_SYNC 1
+#define SPUS_PER_NODE   8
+#define DEFAULT_TIMER_EXPIRE  (HZ / 10)
+
+extern struct delayed_work spu_work;
+extern int spu_prof_running;
 
 struct spu_overlay_info {      /* map of sections within an SPU overlay */
        unsigned int vma;       /* SPU virtual memory address from elf */
@@ -62,6 +67,14 @@ struct vma_to_fileoffset_map {       /* map of sections within an SPU program */
 
 };
 
+struct spu_buffer {
+       int last_guard_val;
+       int ctx_sw_seen;
+       unsigned long *buff;
+       unsigned int head, tail;
+};
+
+
 /* The three functions below are for maintaining and accessing
  * the vma-to-fileoffset map.
  */
index 380d7e21753139a0eb72010daa48cca7ad92d869..dd499c3e9da769cb87109b910d3b8b36c79137a1 100644 (file)
 
 static u32 *samples;
 
-static int spu_prof_running;
+int spu_prof_running;
 static unsigned int profiling_interval;
 
 #define NUM_SPU_BITS_TRBUF 16
 #define SPUS_PER_TB_ENTRY   4
-#define SPUS_PER_NODE       8
 
 #define SPU_PC_MASK         0xFFFF
 
@@ -196,7 +195,7 @@ int start_spu_profiling(unsigned int cycles_reset)
        pr_debug("timer resolution: %lu\n", TICK_NSEC);
        kt = ktime_set(0, profiling_interval);
        hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-       timer.expires = kt;
+       hrtimer_set_expires(&timer, kt);
        timer.function = profile_spus;
 
        /* Allocate arrays for collecting SPU PC samples */
@@ -208,6 +207,7 @@ int start_spu_profiling(unsigned int cycles_reset)
 
        spu_prof_running = 1;
        hrtimer_start(&timer, kt, HRTIMER_MODE_REL);
+       schedule_delayed_work(&spu_work, DEFAULT_TIMER_EXPIRE);
 
        return 0;
 }
index 2a9b4a0493294b881ae75c0d9e7b4bf2a7823528..2949126d28d1f8c9f45bef32d45b96df86f959fa 100644 (file)
@@ -35,7 +35,102 @@ static DEFINE_SPINLOCK(buffer_lock);
 static DEFINE_SPINLOCK(cache_lock);
 static int num_spu_nodes;
 int spu_prof_num_nodes;
-int last_guard_val[MAX_NUMNODES * 8];
+
+struct spu_buffer spu_buff[MAX_NUMNODES * SPUS_PER_NODE];
+struct delayed_work spu_work;
+static unsigned max_spu_buff;
+
+static void spu_buff_add(unsigned long int value, int spu)
+{
+       /* spu buff is a circular buffer.  Add entries to the
+        * head.  Head is the index to store the next value.
+        * The buffer is full when there is one available entry
+        * in the queue, i.e. head and tail can't be equal.
+        * That way we can tell the difference between the
+        * buffer being full versus empty.
+        *
+        *  ASSUPTION: the buffer_lock is held when this function
+        *             is called to lock the buffer, head and tail.
+        */
+       int full = 1;
+
+       if (spu_buff[spu].head >= spu_buff[spu].tail) {
+               if ((spu_buff[spu].head - spu_buff[spu].tail)
+                   <  (max_spu_buff - 1))
+                       full = 0;
+
+       } else if (spu_buff[spu].tail > spu_buff[spu].head) {
+               if ((spu_buff[spu].tail - spu_buff[spu].head)
+                   > 1)
+                       full = 0;
+       }
+
+       if (!full) {
+               spu_buff[spu].buff[spu_buff[spu].head] = value;
+               spu_buff[spu].head++;
+
+               if (spu_buff[spu].head >= max_spu_buff)
+                       spu_buff[spu].head = 0;
+       } else {
+               /* From the user's perspective make the SPU buffer
+                * size management/overflow look like we are using
+                * per cpu buffers.  The user uses the same
+                * per cpu parameter to adjust the SPU buffer size.
+                * Increment the sample_lost_overflow to inform
+                * the user the buffer size needs to be increased.
+                */
+               oprofile_cpu_buffer_inc_smpl_lost();
+       }
+}
+
+/* This function copies the per SPU buffers to the
+ * OProfile kernel buffer.
+ */
+void sync_spu_buff(void)
+{
+       int spu;
+       unsigned long flags;
+       int curr_head;
+
+       for (spu = 0; spu < num_spu_nodes; spu++) {
+               /* In case there was an issue and the buffer didn't
+                * get created skip it.
+                */
+               if (spu_buff[spu].buff == NULL)
+                       continue;
+
+               /* Hold the lock to make sure the head/tail
+                * doesn't change while spu_buff_add() is
+                * deciding if the buffer is full or not.
+                * Being a little paranoid.
+                */
+               spin_lock_irqsave(&buffer_lock, flags);
+               curr_head = spu_buff[spu].head;
+               spin_unlock_irqrestore(&buffer_lock, flags);
+
+               /* Transfer the current contents to the kernel buffer.
+                * data can still be added to the head of the buffer.
+                */
+               oprofile_put_buff(spu_buff[spu].buff,
+                                 spu_buff[spu].tail,
+                                 curr_head, max_spu_buff);
+
+               spin_lock_irqsave(&buffer_lock, flags);
+               spu_buff[spu].tail = curr_head;
+               spin_unlock_irqrestore(&buffer_lock, flags);
+       }
+
+}
+
+static void wq_sync_spu_buff(struct work_struct *work)
+{
+       /* move data from spu buffers to kernel buffer */
+       sync_spu_buff();
+
+       /* only reschedule if profiling is not done */
+       if (spu_prof_running)
+               schedule_delayed_work(&spu_work, DEFAULT_TIMER_EXPIRE);
+}
 
 /* Container for caching information about an active SPU task. */
 struct cached_info {
@@ -305,14 +400,21 @@ static int process_context_switch(struct spu *spu, unsigned long objectId)
 
        /* Record context info in event buffer */
        spin_lock_irqsave(&buffer_lock, flags);
-       add_event_entry(ESCAPE_CODE);
-       add_event_entry(SPU_CTX_SWITCH_CODE);
-       add_event_entry(spu->number);
-       add_event_entry(spu->pid);
-       add_event_entry(spu->tgid);
-       add_event_entry(app_dcookie);
-       add_event_entry(spu_cookie);
-       add_event_entry(offset);
+       spu_buff_add(ESCAPE_CODE, spu->number);
+       spu_buff_add(SPU_CTX_SWITCH_CODE, spu->number);
+       spu_buff_add(spu->number, spu->number);
+       spu_buff_add(spu->pid, spu->number);
+       spu_buff_add(spu->tgid, spu->number);
+       spu_buff_add(app_dcookie, spu->number);
+       spu_buff_add(spu_cookie, spu->number);
+       spu_buff_add(offset, spu->number);
+
+       /* Set flag to indicate SPU PC data can now be written out.  If
+        * the SPU program counter data is seen before an SPU context
+        * record is seen, the postprocessing will fail.
+        */
+       spu_buff[spu->number].ctx_sw_seen = 1;
+
        spin_unlock_irqrestore(&buffer_lock, flags);
        smp_wmb();      /* insure spu event buffer updates are written */
                        /* don't want entries intermingled... */
@@ -360,6 +462,47 @@ static int number_of_online_nodes(void)
         return nodes;
 }
 
+static int oprofile_spu_buff_create(void)
+{
+       int spu;
+
+       max_spu_buff = oprofile_get_cpu_buffer_size();
+
+       for (spu = 0; spu < num_spu_nodes; spu++) {
+               /* create circular buffers to store the data in.
+                * use locks to manage accessing the buffers
+                */
+               spu_buff[spu].head = 0;
+               spu_buff[spu].tail = 0;
+
+               /*
+                * Create a buffer for each SPU.  Can't reliably
+                * create a single buffer for all spus due to not
+                * enough contiguous kernel memory.
+                */
+
+               spu_buff[spu].buff = kzalloc((max_spu_buff
+                                             * sizeof(unsigned long)),
+                                            GFP_KERNEL);
+
+               if (!spu_buff[spu].buff) {
+                       printk(KERN_ERR "SPU_PROF: "
+                              "%s, line %d:  oprofile_spu_buff_create "
+                      "failed to allocate spu buffer %d.\n",
+                              __func__, __LINE__, spu);
+
+                       /* release the spu buffers that have been allocated */
+                       while (spu >= 0) {
+                               kfree(spu_buff[spu].buff);
+                               spu_buff[spu].buff = 0;
+                               spu--;
+                       }
+                       return -ENOMEM;
+               }
+       }
+       return 0;
+}
+
 /* The main purpose of this function is to synchronize
  * OProfile with SPUFS by registering to be notified of
  * SPU task switches.
@@ -372,20 +515,35 @@ static int number_of_online_nodes(void)
  */
 int spu_sync_start(void)
 {
-       int k;
+       int spu;
        int ret = SKIP_GENERIC_SYNC;
        int register_ret;
        unsigned long flags = 0;
 
        spu_prof_num_nodes = number_of_online_nodes();
        num_spu_nodes = spu_prof_num_nodes * 8;
+       INIT_DELAYED_WORK(&spu_work, wq_sync_spu_buff);
+
+       /* create buffer for storing the SPU data to put in
+        * the kernel buffer.
+        */
+       ret = oprofile_spu_buff_create();
+       if (ret)
+               goto out;
 
        spin_lock_irqsave(&buffer_lock, flags);
-       add_event_entry(ESCAPE_CODE);
-       add_event_entry(SPU_PROFILING_CODE);
-       add_event_entry(num_spu_nodes);
+       for (spu = 0; spu < num_spu_nodes; spu++) {
+               spu_buff_add(ESCAPE_CODE, spu);
+               spu_buff_add(SPU_PROFILING_CODE, spu);
+               spu_buff_add(num_spu_nodes, spu);
+       }
        spin_unlock_irqrestore(&buffer_lock, flags);
 
+       for (spu = 0; spu < num_spu_nodes; spu++) {
+               spu_buff[spu].ctx_sw_seen = 0;
+               spu_buff[spu].last_guard_val = 0;
+       }
+
        /* Register for SPU events  */
        register_ret = spu_switch_event_register(&spu_active);
        if (register_ret) {
@@ -393,8 +551,6 @@ int spu_sync_start(void)
                goto out;
        }
 
-       for (k = 0; k < (MAX_NUMNODES * 8); k++)
-               last_guard_val[k] = 0;
        pr_debug("spu_sync_start -- running.\n");
 out:
        return ret;
@@ -446,13 +602,20 @@ void spu_sync_buffer(int spu_num, unsigned int *samples,
                 * use.  We need to discard samples taken during the time
                 * period which an overlay occurs (i.e., guard value changes).
                 */
-               if (grd_val && grd_val != last_guard_val[spu_num]) {
-                       last_guard_val[spu_num] = grd_val;
+               if (grd_val && grd_val != spu_buff[spu_num].last_guard_val) {
+                       spu_buff[spu_num].last_guard_val = grd_val;
                        /* Drop the rest of the samples. */
                        break;
                }
 
-               add_event_entry(file_offset | spu_num_shifted);
+               /* We must ensure that the SPU context switch has been written
+                * out before samples for the SPU.  Otherwise, the SPU context
+                * information is not available and the postprocessing of the
+                * SPU PC will fail with no available anonymous map information.
+                */
+               if (spu_buff[spu_num].ctx_sw_seen)
+                       spu_buff_add((file_offset | spu_num_shifted),
+                                        spu_num);
        }
        spin_unlock(&buffer_lock);
 out:
@@ -463,20 +626,41 @@ out:
 int spu_sync_stop(void)
 {
        unsigned long flags = 0;
-       int ret = spu_switch_event_unregister(&spu_active);
-       if (ret) {
+       int ret;
+       int k;
+
+       ret = spu_switch_event_unregister(&spu_active);
+
+       if (ret)
                printk(KERN_ERR "SPU_PROF: "
-                       "%s, line %d: spu_switch_event_unregister returned %d\n",
-                       __func__, __LINE__, ret);
-               goto out;
-       }
+                      "%s, line %d: spu_switch_event_unregister "      \
+                      "returned %d\n",
+                      __func__, __LINE__, ret);
+
+       /* flush any remaining data in the per SPU buffers */
+       sync_spu_buff();
 
        spin_lock_irqsave(&cache_lock, flags);
        ret = release_cached_info(RELEASE_ALL);
        spin_unlock_irqrestore(&cache_lock, flags);
-out:
+
+       /* remove scheduled work queue item rather then waiting
+        * for every queued entry to execute.  Then flush pending
+        * system wide buffer to event buffer.
+        */
+       cancel_delayed_work(&spu_work);
+
+       for (k = 0; k < num_spu_nodes; k++) {
+               spu_buff[k].ctx_sw_seen = 0;
+
+               /*
+                * spu_sys_buff will be null if there was a problem
+                * allocating the buffer.  Only delete if it exists.
+                */
+               kfree(spu_buff[k].buff);
+               spu_buff[k].buff = 0;
+       }
        pr_debug("spu_sync_stop -- done.\n");
        return ret;
 }
 
-
index 5ff4de3eb3be335ccdad62f4c208415c25a4bf88..35141a8bc3d94691acdfd2b4833b9bf386f45c60 100644 (file)
@@ -404,7 +404,7 @@ set_count_mode(u32 kernel, u32 user)
        }
 }
 
-static inline void enable_ctr(u32 cpu, u32 ctr, u32 * pm07_cntrl)
+static inline void enable_ctr(u32 cpu, u32 ctr, u32 *pm07_cntrl)
 {
 
        pm07_cntrl[ctr] |= CBE_PM_CTR_ENABLE;
index a9260e21451e5b884cc3affe056945eaf2fd049f..65730275e0122b15184f6bec331e2679130dfa82 100644 (file)
 #      help
 #        This option enables support for the CPCI405 board.
 
+config ACADIA
+       bool "Acadia"
+       depends on 40x
+       default n
+       select PPC40x_SIMPLE
+       select 405EZ
+       help
+         This option enables support for the AMCC 405EZ Acadia evaluation board.
+
 config EP405
        bool "EP405/EP405PC"
        depends on 40x
@@ -23,6 +32,14 @@ config EP405
        help
          This option enables support for the EP405/EP405PC boards.
 
+config HCU4
+       bool "Hcu4"
+       depends on 40x
+       default y
+       select 405GPR
+       help
+         This option enables support for the Nestal Maschinen HCU4 board.
+
 config KILAUEA
        bool "Kilauea"
        depends on 40x
@@ -93,6 +110,13 @@ config XILINX_VIRTEX_GENERIC_BOARD
          Most Virtex designs should use this unless it needs to do some
          special configuration at board probe time.
 
+config PPC40x_SIMPLE
+       bool "Simple PowerPC 40x board support"
+       depends on 40x
+       default n
+       help
+         This option enables the simple PowerPC 40x platform support.
+
 # 40x specific CPU modules, selected based on the board above.
 config NP405H
        bool
@@ -118,6 +142,12 @@ config 405EX
        select IBM_NEW_EMAC_EMAC4
        select IBM_NEW_EMAC_RGMII
 
+config 405EZ
+       bool
+       select IBM_NEW_EMAC_NO_FLOW_CTRL
+       select IBM_NEW_EMAC_MAL_CLR_ICINTSTAT
+       select IBM_NEW_EMAC_MAL_COMMON_ERR
+
 config 405GPR
        bool
 
@@ -139,6 +169,14 @@ config STB03xxx
        select IBM405_ERR77
        select IBM405_ERR51
 
+config PPC4xx_GPIO
+       bool "PPC4xx GPIO support"
+       depends on 40x
+       select ARCH_REQUIRE_GPIOLIB
+       select GENERIC_GPIO
+       help
+         Enable gpiolib support for ppc40x based boards
+
 # 40x errata/workaround config symbols, selected by the CPU models above
 
 # All 405-based cores up until the 405GPR and 405EP have this errata.
index 5533a5c8ce4e59f36bd3d586d25f2b37f301f799..9bab76a652a61e097ce0b9888307707523e2d640 100644 (file)
@@ -1,5 +1,7 @@
 obj-$(CONFIG_KILAUEA)                          += kilauea.o
+obj-$(CONFIG_HCU4)                             += hcu4.o
 obj-$(CONFIG_MAKALU)                           += makalu.o
 obj-$(CONFIG_WALNUT)                           += walnut.o
 obj-$(CONFIG_XILINX_VIRTEX_GENERIC_BOARD)      += virtex.o
 obj-$(CONFIG_EP405)                            += ep405.o
+obj-$(CONFIG_PPC40x_SIMPLE)            += ppc40x_simple.o
diff --git a/arch/powerpc/platforms/40x/hcu4.c b/arch/powerpc/platforms/40x/hcu4.c
new file mode 100644 (file)
index 0000000..60b2afe
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Architecture- / platform-specific boot-time initialization code for
+ * IBM PowerPC 4xx based boards. Adapted from original
+ * code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek
+ * <dan@net4x.com>.
+ *
+ * Copyright(c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
+ *
+ * Rewritten and ported to the merged powerpc tree:
+ * Copyright 2007 IBM Corporation
+ * Josh Boyer <jwboyer@linux.vnet.ibm.com>
+ *
+ * 2002 (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.
+ */
+
+#include <linux/init.h>
+#include <linux/of_platform.h>
+
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/time.h>
+#include <asm/uic.h>
+#include <asm/ppc4xx.h>
+
+static __initdata struct of_device_id hcu4_of_bus[] = {
+       { .compatible = "ibm,plb3", },
+       { .compatible = "ibm,opb", },
+       { .compatible = "ibm,ebc", },
+       {},
+};
+
+static int __init hcu4_device_probe(void)
+{
+       of_platform_bus_probe(NULL, hcu4_of_bus, NULL);
+       return 0;
+}
+machine_device_initcall(hcu4, hcu4_device_probe);
+
+static int __init hcu4_probe(void)
+{
+       unsigned long root = of_get_flat_dt_root();
+
+       if (!of_flat_dt_is_compatible(root, "netstal,hcu4"))
+               return 0;
+
+       return 1;
+}
+
+define_machine(hcu4) {
+       .name                   = "HCU4",
+       .probe                  = hcu4_probe,
+       .progress               = udbg_progress,
+       .init_IRQ               = uic_init_tree,
+       .get_irq                = uic_get_irq,
+       .restart                = ppc4xx_reset_system,
+       .calibrate_decr         = generic_calibrate_decr,
+};
diff --git a/arch/powerpc/platforms/40x/ppc40x_simple.c b/arch/powerpc/platforms/40x/ppc40x_simple.c
new file mode 100644 (file)
index 0000000..4498a86
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Generic PowerPC 40x platform support
+ *
+ * Copyright 2008 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; version 2 of the License.
+ *
+ * This implements simple platform support for PowerPC 44x chips.  This is
+ * mostly used for eval boards or other simple and "generic" 44x boards.  If
+ * your board has custom functions or hardware, then you will likely want to
+ * implement your own board.c file to accommodate it.
+ */
+
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/ppc4xx.h>
+#include <asm/prom.h>
+#include <asm/time.h>
+#include <asm/udbg.h>
+#include <asm/uic.h>
+
+#include <linux/init.h>
+#include <linux/of_platform.h>
+
+static __initdata struct of_device_id ppc40x_of_bus[] = {
+       { .compatible = "ibm,plb3", },
+       { .compatible = "ibm,plb4", },
+       { .compatible = "ibm,opb", },
+       { .compatible = "ibm,ebc", },
+       { .compatible = "simple-bus", },
+       {},
+};
+
+static int __init ppc40x_device_probe(void)
+{
+       of_platform_bus_probe(NULL, ppc40x_of_bus, NULL);
+
+       return 0;
+}
+machine_device_initcall(ppc40x_simple, ppc40x_device_probe);
+
+/* This is the list of boards that can be supported by this simple
+ * platform code.  This does _not_ mean the boards are compatible,
+ * as they most certainly are not from a device tree perspective.
+ * However, their differences are handled by the device tree and the
+ * drivers and therefore they don't need custom board support files.
+ *
+ * Again, if your board needs to do things differently then create a
+ * board.c file for it rather than adding it to this list.
+ */
+static char *board[] __initdata = {
+       "amcc,acadia"
+};
+
+static int __init ppc40x_probe(void)
+{
+       unsigned long root = of_get_flat_dt_root();
+       int i = 0;
+
+       for (i = 0; i < ARRAY_SIZE(board); i++) {
+               if (of_flat_dt_is_compatible(root, board[i])) {
+                       ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+define_machine(ppc40x_simple) {
+       .name = "PowerPC 40x Platform",
+       .probe = ppc40x_probe,
+       .progress = udbg_progress,
+       .init_IRQ = uic_init_tree,
+       .get_irq = uic_get_irq,
+       .restart = ppc4xx_reset_system,
+       .calibrate_decr = generic_calibrate_decr,
+};
index 79c1154f88d42464796c3dd0d5ce8194a8c7862c..3496bc05058ed63bef9773f843b97fb4b16fd642 100644 (file)
@@ -167,6 +167,14 @@ config PPC44x_SIMPLE
        help
          This option enables the simple PowerPC 44x platform support.
 
+config PPC4xx_GPIO
+       bool "PPC4xx GPIO support"
+       depends on 44x
+       select ARCH_REQUIRE_GPIOLIB
+       select GENERIC_GPIO
+       help
+         Enable gpiolib support for ppc440 based boards
+
 # 44x specific CPU modules, selected based on the board above.
 config 440EP
        bool
index 044b4e6e874383a77e31fe5e80d8737a465865c5..ae7c34f37e1c2cca2d4b6885b61e24ddfa434386 100644 (file)
@@ -99,11 +99,14 @@ mpc5200_setup_xlb_arbiter(void)
        out_be32(&xlb->master_pri_enable, 0xff);
        out_be32(&xlb->master_priority, 0x11111111);
 
-       /* Disable XLB pipelining
+       /*
+        * Disable XLB pipelining
         * (cfr errate 292. We could do this only just before ATA PIO
         *  transaction and re-enable it afterwards ...)
+        * Not needed on MPC5200B.
         */
-       out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS);
+       if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR)
+               out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS);
 
        iounmap(xlb);
 }
index 8a3b117b6ce2069c75eba6e427f93093c83d6770..81cee7bbf2d231b2a35bdc963e7e7df71b79d2b3 100644 (file)
@@ -193,7 +193,6 @@ static void __init ksi8560_setup_arch(void)
 static void ksi8560_show_cpuinfo(struct seq_file *m)
 {
        uint pvid, svid, phid1;
-       uint memsize = total_memory;
 
        pvid = mfspr(SPRN_PVR);
        svid = mfspr(SPRN_SVR);
@@ -215,9 +214,6 @@ static void ksi8560_show_cpuinfo(struct seq_file *m)
        /* Display cpu Pll setting */
        phid1 = mfspr(SPRN_HID1);
        seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
-
-       /* Display the amount of memory */
-       seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
 }
 
 static struct of_device_id __initdata of_bus_ids[] = {
index 0293e3d3580f4bd950835cd18ce0f08455a58644..21f009023e2611b4b98c4ac06eff94da05b44eef 100644 (file)
@@ -207,7 +207,6 @@ static void __init mpc85xx_ads_setup_arch(void)
 static void mpc85xx_ads_show_cpuinfo(struct seq_file *m)
 {
        uint pvid, svid, phid1;
-       uint memsize = total_memory;
 
        pvid = mfspr(SPRN_PVR);
        svid = mfspr(SPRN_SVR);
@@ -219,9 +218,6 @@ static void mpc85xx_ads_show_cpuinfo(struct seq_file *m)
        /* Display cpu Pll setting */
        phid1 = mfspr(SPRN_HID1);
        seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
-
-       /* Display the amount of memory */
-       seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
 }
 
 static struct of_device_id __initdata of_bus_ids[] = {
index 50d7ea8f922b4d0addd159af5e518f6cb05b2f30..aeb6a5bc55222a26ed4333cb503adf7f0cfc3846 100644 (file)
@@ -307,7 +307,6 @@ static void __init mpc85xx_cds_setup_arch(void)
 static void mpc85xx_cds_show_cpuinfo(struct seq_file *m)
 {
        uint pvid, svid, phid1;
-       uint memsize = total_memory;
 
        pvid = mfspr(SPRN_PVR);
        svid = mfspr(SPRN_SVR);
@@ -320,9 +319,6 @@ static void mpc85xx_cds_show_cpuinfo(struct seq_file *m)
        /* Display cpu Pll setting */
        phid1 = mfspr(SPRN_HID1);
        seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
-
-       /* Display the amount of memory */
-       seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
 }
 
 
index b9246ea0928a6c699703bd4993f71da311418e89..7ec77ce12dadb632f912eac544e7dc03b34bcf82 100644 (file)
@@ -136,7 +136,6 @@ static void __init sbc8548_setup_arch(void)
 static void sbc8548_show_cpuinfo(struct seq_file *m)
 {
        uint pvid, svid, phid1;
-       uint memsize = total_memory;
 
        pvid = mfspr(SPRN_PVR);
        svid = mfspr(SPRN_SVR);
@@ -149,9 +148,6 @@ static void sbc8548_show_cpuinfo(struct seq_file *m)
        /* Display cpu Pll setting */
        phid1 = mfspr(SPRN_HID1);
        seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
-
-       /* Display the amount of memory */
-       seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
 }
 
 static struct of_device_id __initdata of_bus_ids[] = {
index 0c9a856f66b6f7e2c4c918574e958e804d37292d..472f254a19d2480e32c84f22aa7b85cdb420ec25 100644 (file)
@@ -194,7 +194,6 @@ static void __init sbc8560_setup_arch(void)
 static void sbc8560_show_cpuinfo(struct seq_file *m)
 {
        uint pvid, svid, phid1;
-       uint memsize = total_memory;
 
        pvid = mfspr(SPRN_PVR);
        svid = mfspr(SPRN_SVR);
@@ -206,9 +205,6 @@ static void sbc8560_show_cpuinfo(struct seq_file *m)
        /* Display cpu Pll setting */
        phid1 = mfspr(SPRN_HID1);
        seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
-
-       /* Display the amount of memory */
-       seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
 }
 
 static struct of_device_id __initdata of_bus_ids[] = {
index 18499d7c9d9ef36b7e95d2b446de925256a95b29..0cca8f5cb272534e326db9cc1cf8d450c8d1a04a 100644 (file)
@@ -130,7 +130,6 @@ static void __init stx_gp3_setup_arch(void)
 static void stx_gp3_show_cpuinfo(struct seq_file *m)
 {
        uint pvid, svid, phid1;
-       uint memsize = total_memory;
 
        pvid = mfspr(SPRN_PVR);
        svid = mfspr(SPRN_SVR);
@@ -142,9 +141,6 @@ static void stx_gp3_show_cpuinfo(struct seq_file *m)
        /* Display cpu Pll setting */
        phid1 = mfspr(SPRN_HID1);
        seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
-
-       /* Display the amount of memory */
-       seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
 }
 
 static struct of_device_id __initdata of_bus_ids[] = {
index d850880d6964b12d6b620746cb5f73e24945a4fe..2933a8e827d9a5c8bbd259e41864fa158fa43cd7 100644 (file)
@@ -138,7 +138,6 @@ static void __init tqm85xx_setup_arch(void)
 static void tqm85xx_show_cpuinfo(struct seq_file *m)
 {
        uint pvid, svid, phid1;
-       uint memsize = total_memory;
 
        pvid = mfspr(SPRN_PVR);
        svid = mfspr(SPRN_SVR);
@@ -150,9 +149,6 @@ static void tqm85xx_show_cpuinfo(struct seq_file *m)
        /* Display cpu Pll setting */
        phid1 = mfspr(SPRN_HID1);
        seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
-
-       /* Display the amount of memory */
-       seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
 }
 
 static struct of_device_id __initdata of_bus_ids[] = {
index 821c45fac18bc11b71351ce64baf79ab98748851..fb371f5ce132c657ab910824d6d4c998b59c574d 100644 (file)
@@ -127,7 +127,6 @@ static unsigned int gef_sbc610_get_fpga_rev(void)
 
 static void gef_sbc610_show_cpuinfo(struct seq_file *m)
 {
-       uint memsize = total_memory;
        uint svid = mfspr(SPRN_SVR);
 
        seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n");
@@ -137,7 +136,6 @@ static void gef_sbc610_show_cpuinfo(struct seq_file *m)
        seq_printf(m, "FPGA Revision\t: %u\n", gef_sbc610_get_fpga_rev());
 
        seq_printf(m, "SVR\t\t: 0x%x\n", svid);
-       seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
 }
 
 static void __init gef_sbc610_nec_fixup(struct pci_dev *pdev)
index 2672829a71dc400397d3adefc84cb5dcbc15ffd5..27e0e682d8e1231949d94e5f9cfaa12b1b8b7b36 100644 (file)
@@ -101,13 +101,11 @@ mpc86xx_hpcn_setup_arch(void)
 static void
 mpc86xx_hpcn_show_cpuinfo(struct seq_file *m)
 {
-       uint memsize = total_memory;
        uint svid = mfspr(SPRN_SVR);
 
        seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
 
        seq_printf(m, "SVR\t\t: 0x%x\n", svid);
-       seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
 }
 
 
index da677a74e2d110068ca8608cc064645be0625e88..5fd7ed40986f58d6ecdac6ad31b52bc0029e6de7 100644 (file)
@@ -63,13 +63,11 @@ sbc8641_setup_arch(void)
 static void
 sbc8641_show_cpuinfo(struct seq_file *m)
 {
-       uint memsize = total_memory;
        uint svid = mfspr(SPRN_SVR);
 
        seq_printf(m, "Vendor\t\t: Wind River Systems\n");
 
        seq_printf(m, "SVR\t\t: 0x%x\n", svid);
-       seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
 }
 
 
index 2a14b052abcd7617b251d1e69555e0233b773d3d..665af1c4195b87ececd6b0b309eafa6242767be1 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/machdep.h>
 #include <asm/rtas.h>
 #include <asm/cell-regs.h>
+#include <asm/kdump.h>
 
 #include "ras.h"
 
@@ -111,9 +112,8 @@ static int __init cbe_ptcal_enable_on_node(int nid, int order)
        int ret = -ENOMEM;
        unsigned long addr;
 
-#ifdef CONFIG_CRASH_DUMP
-       rtas_call(ptcal_stop_tok, 1, 1, NULL, nid);
-#endif
+       if (__kdump_flag)
+               rtas_call(ptcal_stop_tok, 1, 1, NULL, nid);
 
        area = kmalloc(sizeof(*area), GFP_KERNEL);
        if (!area)
index efb3964457b1db4451c1c75d97dbf03e2c40ca0b..c0d86e1f56ea54d3eb6cb8ac70a3f71a19dc6df0 100644 (file)
@@ -54,8 +54,8 @@
 #endif
 
 /*
- * The primary thread of each non-boot processor is recorded here before
- * smp init.
+ * The Primary thread of each non-boot processor was started from the OF client
+ * interface by prom_hold_cpus and is spinning on secondary_hold_spinloop.
  */
 static cpumask_t of_spin_map;
 
@@ -208,11 +208,7 @@ void __init smp_init_cell(void)
        /* Mark threads which are still spinning in hold loops. */
        if (cpu_has_feature(CPU_FTR_SMT)) {
                for_each_present_cpu(i) {
-                       if (i % 2 == 0)
-                               /*
-                                * Even-numbered logical cpus correspond to
-                                * primary threads.
-                                */
+                       if (cpu_thread_in_core(i) == 0)
                                cpu_set(i, of_spin_map);
                }
        } else {
index 010a51f59796b7a9068103bb6598843f9195fff4..b73c369cc6f167a4fa52c9162cfed557c9c1bba0 100644 (file)
@@ -548,6 +548,11 @@ spufs_regs_read(struct file *file, char __user *buffer,
        int ret;
        struct spu_context *ctx = file->private_data;
 
+       /* pre-check for file position: if we'd return EOF, there's no point
+        * causing a deschedule */
+       if (*pos >= sizeof(ctx->csa.lscsa->gprs))
+               return 0;
+
        ret = spu_acquire_saved(ctx);
        if (ret)
                return ret;
@@ -2426,38 +2431,49 @@ static inline int spufs_switch_log_avail(struct spu_context *ctx)
 static int spufs_switch_log_open(struct inode *inode, struct file *file)
 {
        struct spu_context *ctx = SPUFS_I(inode)->i_ctx;
+       int rc;
+
+       rc = spu_acquire(ctx);
+       if (rc)
+               return rc;
 
-       /*
-        * We (ab-)use the mapping_lock here because it serves the similar
-        * purpose for synchronizing open/close elsewhere.  Maybe it should
-        * be renamed eventually.
-        */
-       mutex_lock(&ctx->mapping_lock);
        if (ctx->switch_log) {
-               spin_lock(&ctx->switch_log->lock);
-               ctx->switch_log->head = 0;
-               ctx->switch_log->tail = 0;
-               spin_unlock(&ctx->switch_log->lock);
-       } else {
-               /*
-                * We allocate the switch log data structures on first open.
-                * They will never be free because we assume a context will
-                * be traced until it goes away.
-                */
-               ctx->switch_log = kzalloc(sizeof(struct switch_log) +
-                       SWITCH_LOG_BUFSIZE * sizeof(struct switch_log_entry),
-                       GFP_KERNEL);
-               if (!ctx->switch_log)
-                       goto out;
-               spin_lock_init(&ctx->switch_log->lock);
-               init_waitqueue_head(&ctx->switch_log->wait);
+               rc = -EBUSY;
+               goto out;
        }
-       mutex_unlock(&ctx->mapping_lock);
+
+       ctx->switch_log = kmalloc(sizeof(struct switch_log) +
+               SWITCH_LOG_BUFSIZE * sizeof(struct switch_log_entry),
+               GFP_KERNEL);
+
+       if (!ctx->switch_log) {
+               rc = -ENOMEM;
+               goto out;
+       }
+
+       ctx->switch_log->head = ctx->switch_log->tail = 0;
+       init_waitqueue_head(&ctx->switch_log->wait);
+       rc = 0;
+
+out:
+       spu_release(ctx);
+       return rc;
+}
+
+static int spufs_switch_log_release(struct inode *inode, struct file *file)
+{
+       struct spu_context *ctx = SPUFS_I(inode)->i_ctx;
+       int rc;
+
+       rc = spu_acquire(ctx);
+       if (rc)
+               return rc;
+
+       kfree(ctx->switch_log);
+       ctx->switch_log = NULL;
+       spu_release(ctx);
 
        return 0;
- out:
-       mutex_unlock(&ctx->mapping_lock);
-       return -ENOMEM;
 }
 
 static int switch_log_sprint(struct spu_context *ctx, char *tbuf, int n)
@@ -2485,42 +2501,54 @@ static ssize_t spufs_switch_log_read(struct file *file, char __user *buf,
        if (!buf || len < 0)
                return -EINVAL;
 
+       error = spu_acquire(ctx);
+       if (error)
+               return error;
+
        while (cnt < len) {
                char tbuf[128];
                int width;
 
-               if (file->f_flags & O_NONBLOCK) {
-                       if (spufs_switch_log_used(ctx) <= 0)
-                               return cnt ? cnt : -EAGAIN;
-               } else {
-                       /* Wait for data in buffer */
-                       error = wait_event_interruptible(ctx->switch_log->wait,
-                                       spufs_switch_log_used(ctx) > 0);
-                       if (error)
+               if (spufs_switch_log_used(ctx) == 0) {
+                       if (cnt > 0) {
+                               /* If there's data ready to go, we can
+                                * just return straight away */
+                               break;
+
+                       } else if (file->f_flags & O_NONBLOCK) {
+                               error = -EAGAIN;
                                break;
-               }
 
-               spin_lock(&ctx->switch_log->lock);
-               if (ctx->switch_log->head == ctx->switch_log->tail) {
-                       /* multiple readers race? */
-                       spin_unlock(&ctx->switch_log->lock);
-                       continue;
+                       } else {
+                               /* spufs_wait will drop the mutex and
+                                * re-acquire, but since we're in read(), the
+                                * file cannot be _released (and so
+                                * ctx->switch_log is stable).
+                                */
+                               error = spufs_wait(ctx->switch_log->wait,
+                                               spufs_switch_log_used(ctx) > 0);
+
+                               /* On error, spufs_wait returns without the
+                                * state mutex held */
+                               if (error)
+                                       return error;
+
+                               /* We may have had entries read from underneath
+                                * us while we dropped the mutex in spufs_wait,
+                                * so re-check */
+                               if (spufs_switch_log_used(ctx) == 0)
+                                       continue;
+                       }
                }
 
                width = switch_log_sprint(ctx, tbuf, sizeof(tbuf));
-               if (width < len) {
+               if (width < len)
                        ctx->switch_log->tail =
                                (ctx->switch_log->tail + 1) %
                                 SWITCH_LOG_BUFSIZE;
-               }
-
-               spin_unlock(&ctx->switch_log->lock);
-
-               /*
-                * If the record is greater than space available return
-                * partial buffer (so far)
-                */
-               if (width >= len)
+               else
+                       /* If the record is greater than space available return
+                        * partial buffer (so far) */
                        break;
 
                error = copy_to_user(buf + cnt, tbuf, width);
@@ -2529,6 +2557,8 @@ static ssize_t spufs_switch_log_read(struct file *file, char __user *buf,
                cnt += width;
        }
 
+       spu_release(ctx);
+
        return cnt == 0 ? error : cnt;
 }
 
@@ -2537,29 +2567,41 @@ static unsigned int spufs_switch_log_poll(struct file *file, poll_table *wait)
        struct inode *inode = file->f_path.dentry->d_inode;
        struct spu_context *ctx = SPUFS_I(inode)->i_ctx;
        unsigned int mask = 0;
+       int rc;
 
        poll_wait(file, &ctx->switch_log->wait, wait);
 
+       rc = spu_acquire(ctx);
+       if (rc)
+               return rc;
+
        if (spufs_switch_log_used(ctx) > 0)
                mask |= POLLIN;
 
+       spu_release(ctx);
+
        return mask;
 }
 
 static const struct file_operations spufs_switch_log_fops = {
-       .owner  = THIS_MODULE,
-       .open   = spufs_switch_log_open,
-       .read   = spufs_switch_log_read,
-       .poll   = spufs_switch_log_poll,
+       .owner          = THIS_MODULE,
+       .open           = spufs_switch_log_open,
+       .read           = spufs_switch_log_read,
+       .poll           = spufs_switch_log_poll,
+       .release        = spufs_switch_log_release,
 };
 
+/**
+ * Log a context switch event to a switch log reader.
+ *
+ * Must be called with ctx->state_mutex held.
+ */
 void spu_switch_log_notify(struct spu *spu, struct spu_context *ctx,
                u32 type, u32 val)
 {
        if (!ctx->switch_log)
                return;
 
-       spin_lock(&ctx->switch_log->lock);
        if (spufs_switch_log_avail(ctx) > 1) {
                struct switch_log_entry *p;
 
@@ -2573,7 +2615,6 @@ void spu_switch_log_notify(struct spu *spu, struct spu_context *ctx,
                ctx->switch_log->head =
                        (ctx->switch_log->head + 1) % SWITCH_LOG_BUFSIZE;
        }
-       spin_unlock(&ctx->switch_log->lock);
 
        wake_up(&ctx->switch_log->wait);
 }
index c9bb7cfd3dca8069434a9071860a6b99cff19022..c58bd36b0c5b1045c170c7135a2e30f884f204fa 100644 (file)
@@ -249,6 +249,7 @@ static int spu_run_fini(struct spu_context *ctx, u32 *npc,
 
        spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED);
        clear_bit(SPU_SCHED_SPU_RUN, &ctx->sched_flags);
+       spu_switch_log_notify(NULL, ctx, SWITCH_LOG_EXIT, *status);
        spu_release(ctx);
 
        if (signal_pending(current))
@@ -417,8 +418,6 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event)
        ret = spu_run_fini(ctx, npc, &status);
        spu_yield(ctx);
 
-       spu_switch_log_notify(NULL, ctx, SWITCH_LOG_EXIT, status);
-
        if ((status & SPU_STATUS_STOPPED_BY_STOP) &&
            (((status >> SPU_STOP_STATUS_SHIFT) & 0x3f00) == 0x2100))
                ctx->stats.libassist++;
index 67595bc380dc154465682f9be7f9c203d283bfe5..2ad914c47493fbd870cc6eaf1acd70991f256440 100644 (file)
@@ -312,6 +312,15 @@ static struct spu *aff_ref_location(struct spu_context *ctx, int mem_aff,
         */
        node = cpu_to_node(raw_smp_processor_id());
        for (n = 0; n < MAX_NUMNODES; n++, node++) {
+               /*
+                * "available_spus" counts how many spus are not potentially
+                * going to be used by other affinity gangs whose reference
+                * context is already in place. Although this code seeks to
+                * avoid having affinity gangs with a summed amount of
+                * contexts bigger than the amount of spus in the node,
+                * this may happen sporadically. In this case, available_spus
+                * becomes negative, which is harmless.
+                */
                int available_spus;
 
                node = (node < MAX_NUMNODES) ? node : 0;
@@ -321,12 +330,10 @@ static struct spu *aff_ref_location(struct spu_context *ctx, int mem_aff,
                available_spus = 0;
                mutex_lock(&cbe_spu_info[node].list_mutex);
                list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) {
-                       if (spu->ctx && spu->ctx->gang
-                                       && spu->ctx->aff_offset == 0)
-                               available_spus -=
-                                       (spu->ctx->gang->contexts - 1);
-                       else
-                               available_spus++;
+                       if (spu->ctx && spu->ctx->gang && !spu->ctx->aff_offset
+                                       && spu->ctx->gang->aff_ref_spu)
+                               available_spus -= spu->ctx->gang->contexts;
+                       available_spus++;
                }
                if (available_spus < ctx->gang->contexts) {
                        mutex_unlock(&cbe_spu_info[node].list_mutex);
@@ -437,6 +444,11 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
                atomic_dec(&cbe_spu_info[spu->node].reserved_spus);
 
        if (ctx->gang)
+               /*
+                * If ctx->gang->aff_sched_count is positive, SPU affinity is
+                * being considered in this gang. Using atomic_dec_if_positive
+                * allow us to skip an explicit check for affinity in this gang
+                */
                atomic_dec_if_positive(&ctx->gang->aff_sched_count);
 
        spu_switch_notify(spu, NULL);
index 8ae8ef9dfc22dd5a73bfba0899ddffa7d375b693..15c62d3ca129f55d6ebfe56fe7b93fcb8939f42c 100644 (file)
@@ -65,7 +65,6 @@ enum {
 };
 
 struct switch_log {
-       spinlock_t              lock;
        wait_queue_head_t       wait;
        unsigned long           head;
        unsigned long           tail;
index 92d20e993ede097d5e732a2bf0b751f9931eb7d1..d0b1f3f4d9c887de9a902b4e511c0a2940a4aa02 100644 (file)
@@ -40,6 +40,7 @@ static DECLARE_WAIT_QUEUE_HEAD(sputrace_wait);
 static ktime_t sputrace_start;
 static unsigned long sputrace_head, sputrace_tail;
 static struct sputrace *sputrace_log;
+static int sputrace_logging;
 
 static int sputrace_used(void)
 {
@@ -79,6 +80,11 @@ static ssize_t sputrace_read(struct file *file, char __user *buf,
                char tbuf[128];
                int width;
 
+               /* If we have data ready to return, don't block waiting
+                * for more */
+               if (cnt > 0 && sputrace_used() == 0)
+                       break;
+
                error = wait_event_interruptible(sputrace_wait,
                                                 sputrace_used() > 0);
                if (error)
@@ -109,24 +115,49 @@ static ssize_t sputrace_read(struct file *file, char __user *buf,
 
 static int sputrace_open(struct inode *inode, struct file *file)
 {
+       int rc;
+
        spin_lock(&sputrace_lock);
+       if (sputrace_logging) {
+               rc = -EBUSY;
+               goto out;
+       }
+
+       sputrace_logging = 1;
        sputrace_head = sputrace_tail = 0;
        sputrace_start = ktime_get();
+       rc = 0;
+
+out:
        spin_unlock(&sputrace_lock);
+       return rc;
+}
 
+static int sputrace_release(struct inode *inode, struct file *file)
+{
+       spin_lock(&sputrace_lock);
+       sputrace_logging = 0;
+       spin_unlock(&sputrace_lock);
        return 0;
 }
 
 static const struct file_operations sputrace_fops = {
-       .owner  = THIS_MODULE,
-       .open   = sputrace_open,
-       .read   = sputrace_read,
+       .owner   = THIS_MODULE,
+       .open    = sputrace_open,
+       .read    = sputrace_read,
+       .release = sputrace_release,
 };
 
 static void sputrace_log_item(const char *name, struct spu_context *ctx,
                struct spu *spu)
 {
        spin_lock(&sputrace_lock);
+
+       if (!sputrace_logging) {
+               spin_unlock(&sputrace_lock);
+               return;
+       }
+
        if (sputrace_avail() > 1) {
                struct sputrace *t = sputrace_log + sputrace_head;
 
@@ -232,6 +263,7 @@ static void __exit sputrace_exit(void)
 
        remove_proc_entry("sputrace", NULL);
        kfree(sputrace_log);
+       marker_synchronize_unregister();
 }
 
 module_init(sputrace_init);
index 49c87769b1f8f96936ac713be1b42014062adf51..c23617c6baf39ed1f4854f1f2ed2fde10ebd8e33 100644 (file)
@@ -69,9 +69,9 @@ static long do_spu_create(const char __user *pathname, unsigned int flags,
        if (!IS_ERR(tmp)) {
                struct nameidata nd;
 
-               ret = path_lookup(tmp, LOOKUP_PARENT|
-                               LOOKUP_OPEN|LOOKUP_CREATE, &nd);
+               ret = path_lookup(tmp, LOOKUP_PARENT, &nd);
                if (!ret) {
+                       nd.flags |= LOOKUP_OPEN | LOOKUP_CREATE;
                        ret = spufs_create(&nd, flags, mode, neighbor);
                        path_put(&nd.path);
                }
index d0b25b8c39d11bdaab0db206266af0d77beb944a..32ba0fa0ad032fcac7b06d62f4bc87b99537acb9 100644 (file)
@@ -116,10 +116,7 @@ static void c2k_restart(char *cmd)
 
 void c2k_show_cpuinfo(struct seq_file *m)
 {
-       uint memsize = total_memory;
-
        seq_printf(m, "Vendor\t\t: GEFanuc\n");
-       seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
        seq_printf(m, "coherency\t: %s\n", COHERENCY_SETTING);
 }
 
index 5a19b9a1457ca3829070faae3d29786fdc0a7067..4c485e984236d57ed2ae012efbe3ca55df9dad55 100644 (file)
@@ -119,10 +119,7 @@ static void prpmc2800_restart(char *cmd)
 
 void prpmc2800_show_cpuinfo(struct seq_file *m)
 {
-       uint memsize = total_memory;
-
        seq_printf(m, "Vendor\t\t: Motorola\n");
-       seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
        seq_printf(m, "coherency\t: %s\n", PPRPM2800_COHERENCY_SETTING);
 }
 
index 140d02a5232af273b617a464fa08052438266262..a623ad256e9e500684cd972ccae1be3b4866c62e 100644 (file)
@@ -22,6 +22,12 @@ static int pseries_remove_lmb(unsigned long base, unsigned int lmb_size)
        int ret;
 
        start_pfn = base >> PAGE_SHIFT;
+
+       if (!pfn_valid(start_pfn)) {
+               lmb_remove(base, lmb_size);
+               return 0;
+       }
+
        zone = page_zone(pfn_to_page(start_pfn));
 
        /*
index a8c446697f9e3b0e737b418f1f966fbec3bd1f49..d56491d182d399e1f3fd2aa58bb98fe3a99609e4 100644 (file)
@@ -44,6 +44,7 @@
 #include <asm/tce.h>
 #include <asm/ppc-pci.h>
 #include <asm/udbg.h>
+#include <asm/kdump.h>
 
 #include "plpar_wrappers.h"
 
@@ -291,9 +292,8 @@ static void iommu_table_setparms(struct pci_controller *phb,
 
        tbl->it_base = (unsigned long)__va(*basep);
 
-#ifndef CONFIG_CRASH_DUMP
-       memset((void *)tbl->it_base, 0, *sizep);
-#endif
+       if (!__kdump_flag)
+               memset((void *)tbl->it_base, 0, *sizep);
 
        tbl->it_busno = phb->bus->number;
 
index e00f96baa38160f3b9e5773e88d5d04ab2da7df7..1a231c389ba0122ce7f55419962af8a1bbdab25f 100644 (file)
@@ -52,8 +52,8 @@
 
 
 /*
- * The primary thread of each non-boot processor is recorded here before
- * smp init.
+ * The Primary thread of each non-boot processor was started from the OF client
+ * interface by prom_hold_cpus and is spinning on secondary_hold_spinloop.
  */
 static cpumask_t of_spin_map;
 
@@ -161,8 +161,7 @@ static void __devinit smp_pSeries_kick_cpu(int nr)
 static int smp_pSeries_cpu_bootable(unsigned int nr)
 {
        /* Special case - we inhibit secondary thread startup
-        * during boot if the user requests it.  Odd-numbered
-        * cpus are assumed to be secondary threads.
+        * during boot if the user requests it.
         */
        if (system_state < SYSTEM_RUNNING &&
            cpu_has_feature(CPU_FTR_SMT) &&
@@ -199,11 +198,7 @@ static void __init smp_init_pseries(void)
        /* Mark threads which are still spinning in hold loops. */
        if (cpu_has_feature(CPU_FTR_SMT)) {
                for_each_present_cpu(i) { 
-                       if (i % 2 == 0)
-                               /*
-                                * Even-numbered logical cpus correspond to
-                                * primary threads.
-                                */
+                       if (cpu_thread_in_core(i) == 0)
                                cpu_set(i, of_spin_map);
                }
        } else {
index a44709a94f9734e0b51981a06a32f1550c19194f..5afce115ab1f8533d25d7d3c3a8e4ff304ec51e0 100644 (file)
@@ -37,6 +37,7 @@ obj-$(CONFIG_OF_RTC)          += of_rtc.o
 ifeq ($(CONFIG_PCI),y)
 obj-$(CONFIG_4xx)              += ppc4xx_pci.o
 endif
+obj-$(CONFIG_PPC4xx_GPIO)      += ppc4xx_gpio.o
 
 obj-$(CONFIG_CPM)              += cpm_common.o
 obj-$(CONFIG_CPM2)             += cpm2.o cpm2_pic.o
diff --git a/arch/powerpc/sysdev/ppc4xx_gpio.c b/arch/powerpc/sysdev/ppc4xx_gpio.c
new file mode 100644 (file)
index 0000000..110efe2
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * PPC4xx gpio driver
+ *
+ * Copyright (c) 2008 Harris Corporation
+ * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ * Copyright (c) MontaVista Software, Inc. 2008.
+ *
+ * Author: Steve Falco <sfalco@harris.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
+#include <linux/types.h>
+
+#define GPIO_MASK(gpio)                (0x80000000 >> (gpio))
+#define GPIO_MASK2(gpio)       (0xc0000000 >> ((gpio) * 2))
+
+/* Physical GPIO register layout */
+struct ppc4xx_gpio {
+       __be32 or;
+       __be32 tcr;
+       __be32 osrl;
+       __be32 osrh;
+       __be32 tsrl;
+       __be32 tsrh;
+       __be32 odr;
+       __be32 ir;
+       __be32 rr1;
+       __be32 rr2;
+       __be32 rr3;
+       __be32 reserved1;
+       __be32 isr1l;
+       __be32 isr1h;
+       __be32 isr2l;
+       __be32 isr2h;
+       __be32 isr3l;
+       __be32 isr3h;
+};
+
+struct ppc4xx_gpio_chip {
+       struct of_mm_gpio_chip mm_gc;
+       spinlock_t lock;
+};
+
+/*
+ * GPIO LIB API implementation for GPIOs
+ *
+ * There are a maximum of 32 gpios in each gpio controller.
+ */
+
+static inline struct ppc4xx_gpio_chip *
+to_ppc4xx_gpiochip(struct of_mm_gpio_chip *mm_gc)
+{
+       return container_of(mm_gc, struct ppc4xx_gpio_chip, mm_gc);
+}
+
+static int ppc4xx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
+{
+       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+       struct ppc4xx_gpio __iomem *regs = mm_gc->regs;
+
+       return in_be32(&regs->ir) & GPIO_MASK(gpio);
+}
+
+static inline void
+__ppc4xx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+       struct ppc4xx_gpio __iomem *regs = mm_gc->regs;
+
+       if (val)
+               setbits32(&regs->or, GPIO_MASK(gpio));
+       else
+               clrbits32(&regs->or, GPIO_MASK(gpio));
+}
+
+static void
+ppc4xx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+       struct ppc4xx_gpio_chip *chip = to_ppc4xx_gpiochip(mm_gc);
+       unsigned long flags;
+
+       spin_lock_irqsave(&chip->lock, flags);
+
+       __ppc4xx_gpio_set(gc, gpio, val);
+
+       spin_unlock_irqrestore(&chip->lock, flags);
+
+       pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
+}
+
+static int ppc4xx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
+{
+       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+       struct ppc4xx_gpio_chip *chip = to_ppc4xx_gpiochip(mm_gc);
+       struct ppc4xx_gpio __iomem *regs = mm_gc->regs;
+       unsigned long flags;
+
+       spin_lock_irqsave(&chip->lock, flags);
+
+       /* Disable open-drain function */
+       clrbits32(&regs->odr, GPIO_MASK(gpio));
+
+       /* Float the pin */
+       clrbits32(&regs->tcr, GPIO_MASK(gpio));
+
+       /* Bits 0-15 use TSRL/OSRL, bits 16-31 use TSRH/OSRH */
+       if (gpio < 16) {
+               clrbits32(&regs->osrl, GPIO_MASK2(gpio));
+               clrbits32(&regs->tsrl, GPIO_MASK2(gpio));
+       } else {
+               clrbits32(&regs->osrh, GPIO_MASK2(gpio));
+               clrbits32(&regs->tsrh, GPIO_MASK2(gpio));
+       }
+
+       spin_unlock_irqrestore(&chip->lock, flags);
+
+       return 0;
+}
+
+static int
+ppc4xx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+       struct ppc4xx_gpio_chip *chip = to_ppc4xx_gpiochip(mm_gc);
+       struct ppc4xx_gpio __iomem *regs = mm_gc->regs;
+       unsigned long flags;
+
+       spin_lock_irqsave(&chip->lock, flags);
+
+       /* First set initial value */
+       __ppc4xx_gpio_set(gc, gpio, val);
+
+       /* Disable open-drain function */
+       clrbits32(&regs->odr, GPIO_MASK(gpio));
+
+       /* Drive the pin */
+       setbits32(&regs->tcr, GPIO_MASK(gpio));
+
+       /* Bits 0-15 use TSRL, bits 16-31 use TSRH */
+       if (gpio < 16) {
+               clrbits32(&regs->osrl, GPIO_MASK2(gpio));
+               clrbits32(&regs->tsrl, GPIO_MASK2(gpio));
+       } else {
+               clrbits32(&regs->osrh, GPIO_MASK2(gpio));
+               clrbits32(&regs->tsrh, GPIO_MASK2(gpio));
+       }
+
+       spin_unlock_irqrestore(&chip->lock, flags);
+
+       pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
+
+       return 0;
+}
+
+static int __init ppc4xx_add_gpiochips(void)
+{
+       struct device_node *np;
+
+       for_each_compatible_node(np, NULL, "ibm,ppc4xx-gpio") {
+               int ret;
+               struct ppc4xx_gpio_chip *ppc4xx_gc;
+               struct of_mm_gpio_chip *mm_gc;
+               struct of_gpio_chip *of_gc;
+               struct gpio_chip *gc;
+
+               ppc4xx_gc = kzalloc(sizeof(*ppc4xx_gc), GFP_KERNEL);
+               if (!ppc4xx_gc) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
+
+               spin_lock_init(&ppc4xx_gc->lock);
+
+               mm_gc = &ppc4xx_gc->mm_gc;
+               of_gc = &mm_gc->of_gc;
+               gc = &of_gc->gc;
+
+               of_gc->gpio_cells = 2;
+               gc->ngpio = 32;
+               gc->direction_input = ppc4xx_gpio_dir_in;
+               gc->direction_output = ppc4xx_gpio_dir_out;
+               gc->get = ppc4xx_gpio_get;
+               gc->set = ppc4xx_gpio_set;
+
+               ret = of_mm_gpiochip_add(np, mm_gc);
+               if (ret)
+                       goto err;
+               continue;
+err:
+               pr_err("%s: registration failed with status %d\n",
+                      np->full_name, ret);
+               kfree(ppc4xx_gc);
+               /* try others anyway */
+       }
+       return 0;
+}
+arch_initcall(ppc4xx_add_gpiochips);
index 7c7874e6ac36c744b508b523201bfc87a68fe64f..8881a643ac320c86cb3b2473b4e466e27c7151ae 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/physmap.h>
+#include <linux/mtd/sh_flctl.h>
 #include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/smc911x.h>
@@ -108,10 +109,45 @@ static struct platform_device ap325rxa_nor_flash_device = {
        },
 };
 
+static struct mtd_partition nand_partition_info[] = {
+       {
+               .name   = "nand_data",
+               .offset = 0,
+               .size   = MTDPART_SIZ_FULL,
+       },
+};
+
+static struct resource nand_flash_resources[] = {
+       [0] = {
+               .start  = 0xa4530000,
+               .end    = 0xa45300ff,
+               .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    = FCKSEL_E | TYPESEL_SET | NANWF_E,
+       .has_hwecc      = 1,
+};
+
+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,
+       },
+};
+
 #define FPGA_LCDREG    0xB4100180
 #define FPGA_BKLREG    0xB4100212
 #define FPGA_LCDREG_VAL        0x0018
 #define PORT_MSELCRB   0xA4050182
+#define PORT_HIZCRC    0xA405015C
+#define PORT_DRVCRA    0xA405018A
+#define PORT_DRVCRB    0xA405018C
 
 static void ap320_wvga_power_on(void *board_data)
 {
@@ -282,6 +318,7 @@ static struct platform_device *ap325rxa_devices[] __initdata = {
 #ifdef CONFIG_I2C
        &camera_device,
 #endif
+       &nand_flash_device,
 };
 
 static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = {
@@ -364,21 +401,36 @@ static int __init ap325rxa_devices_setup(void)
 
        ctrl_outw(ctrl_inw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
 
+       /* FLCTL */
+       gpio_request(GPIO_FN_FCE, NULL);
+       gpio_request(GPIO_FN_NAF7, NULL);
+       gpio_request(GPIO_FN_NAF6, NULL);
+       gpio_request(GPIO_FN_NAF5, NULL);
+       gpio_request(GPIO_FN_NAF4, NULL);
+       gpio_request(GPIO_FN_NAF3, NULL);
+       gpio_request(GPIO_FN_NAF2, NULL);
+       gpio_request(GPIO_FN_NAF1, NULL);
+       gpio_request(GPIO_FN_NAF0, NULL);
+       gpio_request(GPIO_FN_FCDE, NULL);
+       gpio_request(GPIO_FN_FOE, NULL);
+       gpio_request(GPIO_FN_FSC, NULL);
+       gpio_request(GPIO_FN_FWE, NULL);
+       gpio_request(GPIO_FN_FRB, NULL);
+
+       ctrl_outw(0, PORT_HIZCRC);
+       ctrl_outw(0xFFFF, PORT_DRVCRA);
+       ctrl_outw(0xFFFF, PORT_DRVCRB);
+
        platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20);
 
        i2c_register_board_info(0, ap325rxa_i2c_devices,
                                ARRAY_SIZE(ap325rxa_i2c_devices));
+
        return platform_add_devices(ap325rxa_devices,
                                ARRAY_SIZE(ap325rxa_devices));
 }
 device_initcall(ap325rxa_devices_setup);
 
-static void __init ap325rxa_setup(char **cmdline_p)
-{
-}
-
 static struct sh_machine_vector mv_ap325rxa __initmv = {
        .mv_name = "AP-325RXA",
-       .mv_setup = ap325rxa_setup,
 };
index ded799cf3eae6f3099d0ef158a8824fc95549f04..58266f06134ae5a187673e23eb89765a3c171510 100644 (file)
 #include <linux/mtd/map.h>
 #include <linux/smc911x.h>
 #include <linux/gpio.h>
+#include <linux/leds.h>
 #include <asm/machvec.h>
 #include <asm/io.h>
-#include <asm/sh7203.h>
+#include <cpu/sh7203.h>
 
 static struct smc911x_platdata smc911x_info = {
        .flags          = SMC911X_USE_16BIT,
@@ -116,10 +117,46 @@ static void __init set_mtd_partitions(void)
        }
 }
 
+static struct gpio_led rsk7203_gpio_leds[] = {
+       {
+               .name                   = "green",
+               .gpio                   = GPIO_PE10,
+               .active_low             = 1,
+       }, {
+               .name                   = "orange",
+               .default_trigger        = "nand-disk",
+               .gpio                   = GPIO_PE12,
+               .active_low             = 1,
+       }, {
+               .name                   = "red:timer",
+               .default_trigger        = "timer",
+               .gpio                   = GPIO_PC14,
+               .active_low             = 1,
+       }, {
+               .name                   = "red:heartbeat",
+               .default_trigger        = "heartbeat",
+               .gpio                   = GPIO_PE11,
+               .active_low             = 1,
+       },
+};
+
+static struct gpio_led_platform_data rsk7203_gpio_leds_info = {
+       .leds           = rsk7203_gpio_leds,
+       .num_leds       = ARRAY_SIZE(rsk7203_gpio_leds),
+};
+
+static struct platform_device led_device = {
+       .name           = "leds-gpio",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &rsk7203_gpio_leds_info,
+       },
+};
 
 static struct platform_device *rsk7203_devices[] __initdata = {
        &smc911x_device,
        &flash_device,
+       &led_device,
 };
 
 static int __init rsk7203_devices_setup(void)
@@ -128,11 +165,6 @@ static int __init rsk7203_devices_setup(void)
        gpio_request(GPIO_FN_TXD0, NULL);
        gpio_request(GPIO_FN_RXD0, NULL);
 
-       /* Lit LED0 */
-       gpio_request(GPIO_PE10, NULL);
-       gpio_direction_output(GPIO_PE10, 0);
-       gpio_export(GPIO_PE10, 0);
-
        set_mtd_partitions();
        return platform_add_devices(rsk7203_devices,
                                    ARRAY_SIZE(rsk7203_devices));
index fc8f28e04ba3d306a362e191fd6440b4b6416110..08057f62687b7bcc3e3687dabf4b53554500d080 100644 (file)
@@ -18,6 +18,7 @@ config SH_R7780MP
 config SH_R7785RP
        bool "R7785RP board support"
        depends on CPU_SUBTYPE_SH7785
+       select GENERIC_GPIO
 
 endchoice
 
index 20a10080b11fefbb430ed4f8470eda59d9890f94..d93aaf88013447338c36d4c4e2143a800f720db3 100644 (file)
@@ -1,10 +1,10 @@
 #
-# Makefile for the R7780RP-1 specific parts of the kernel
+# Makefile for the Highlander specific parts of the kernel
 #
-irqinit-$(CONFIG_SH_R7780MP)   := irq-r7780mp.o
-irqinit-$(CONFIG_SH_R7785RP)   := irq-r7785rp.o
-irqinit-$(CONFIG_SH_R7780RP)   := irq-r7780rp.o
-obj-y                          := setup.o $(irqinit-y)
+obj-y                          := setup.o
+obj-$(CONFIG_SH_R7780RP)       += irq-r7780rp.o
+obj-$(CONFIG_SH_R7780MP)       += irq-r7780mp.o
+obj-$(CONFIG_SH_R7785RP)       += irq-r7785rp.o pinmux-r7785rp.o
 
 ifneq ($(CONFIG_SH_R7785RP),y)
 obj-$(CONFIG_PUSH_SWITCH)      += psw.o
diff --git a/arch/sh/boards/mach-highlander/pinmux-r7785rp.c b/arch/sh/boards/mach-highlander/pinmux-r7785rp.c
new file mode 100644 (file)
index 0000000..c77a2be
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2008 Paul Mundt
+ *
+ * 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/gpio.h>
+#include <cpu/sh7785.h>
+
+void __init highlander_plat_pinmux_setup(void)
+{
+       /* SCIF0 */
+       gpio_request(GPIO_FN_SCIF0_CTS, NULL);
+       gpio_request(GPIO_FN_SCIF0_RTS, NULL);
+       gpio_request(GPIO_FN_SCIF0_SCK, NULL);
+       gpio_request(GPIO_FN_SCIF0_RXD, NULL);
+       gpio_request(GPIO_FN_SCIF0_TXD, NULL);
+}
index c5a40f7906d789b453ff9e8a4e1fc2961b345fc8..806438b42cacbf68f2748c7a1ed3c04a4df82a98 100644 (file)
@@ -294,6 +294,8 @@ static void __init highlander_setup(char **cmdline_p)
                         (ver >> 12) & 0xf, (ver >> 8) & 0xf,
                         (ver >>  4) & 0xf, ver & 0xf);
 
+       highlander_plat_pinmux_setup();
+
        /*
         * Enable the important clocks right away..
         */
index 769d630434248ff5a92acc40c4210cfb22dae042..97528198029997ba34f814b35d8aa7f63cbf8f22 100644 (file)
@@ -288,8 +288,11 @@ static struct clk *camera_clk;
 
 static void camera_power_on(void)
 {
+       /* Use 10 MHz VIO_CKO instead of 24 MHz to work
+        * around signal quality issues on Panel Board V2.1.
+        */
        camera_clk = clk_get(NULL, "video_clk");
-       clk_set_rate(camera_clk, 24000000);
+       clk_set_rate(camera_clk, 10000000);
        clk_enable(camera_clk); /* start VIO_CKO */
 
        /* use VIO_RST to take camera out of reset */
@@ -307,10 +310,18 @@ static void camera_power_off(void)
        gpio_set_value(GPIO_PTT3, 0);
 }
 
+static void camera_power(int mode)
+{
+       if (mode)
+               camera_power_on();
+       else
+               camera_power_off();
+}
+
 #ifdef CONFIG_I2C
 static unsigned char camera_ov772x_magic[] =
 {
-       0x09, 0x01, 0x0c, 0x10, 0x0d, 0x41, 0x0e, 0x01,
+       0x09, 0x01, 0x0c, 0x20, 0x0d, 0x41, 0x0e, 0x01,
        0x12, 0x00, 0x13, 0x8F, 0x14, 0x4A, 0x15, 0x00,
        0x16, 0x00, 0x17, 0x23, 0x18, 0xa0, 0x19, 0x07,
        0x1a, 0xf0, 0x1b, 0x40, 0x1f, 0x00, 0x20, 0x10,
@@ -386,6 +397,7 @@ static struct soc_camera_platform_info ov772x_info = {
        },
        .bus_param =  SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
        SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
+       .power = camera_power,
        .set_capture = ov772x_set_capture,
 };
 
@@ -400,8 +412,6 @@ static struct platform_device migor_camera_device = {
 static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
        .flags = SOCAM_MASTER | SOCAM_DATAWIDTH_8 | SOCAM_PCLK_SAMPLE_RISING \
        | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH,
-       .enable_camera = camera_power_on,
-       .disable_camera = camera_power_off,
 };
 
 static struct resource migor_ceu_resources[] = {
index 851c870adf3b0a1447270f9cd5033fe49e8bd45c..874dd9726e520ab45e5acf5db31c546fc32b1359 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc4
-# Tue Aug 26 14:21:17 2008
+# Linux kernel version: 2.6.27
+# Tue Oct 21 18:20:06 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,11 +13,12 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
@@ -72,22 +73,20 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
-CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -120,6 +119,7 @@ CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -190,12 +190,13 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 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=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -289,6 +290,8 @@ CONFIG_CMDLINE="console=tty1 console=ttySC5,38400 root=/dev/nfs ip=dhcp"
 # 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_NET=y
 
@@ -339,6 +342,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -359,11 +363,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
@@ -455,7 +458,15 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=0
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_NAND is not set
+CONFIG_MTD_NAND=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_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_NAND_SH_FLCTL=y
 # CONFIG_MTD_ONENAND is not set
 
 #
@@ -541,6 +552,9 @@ CONFIG_SMC911X=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
@@ -645,6 +659,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_WM8400 is not set
 
 #
 # Multimedia devices
@@ -692,6 +707,8 @@ 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
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -705,12 +722,13 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT3_FS_SECURITY=y
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_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=y
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_DNOTIFY=y
@@ -743,6 +761,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
@@ -785,6 +804,7 @@ CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -855,7 +875,12 @@ CONFIG_FRAME_WARN=1024
 # 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
+# CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -866,14 +891,19 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
 CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_RNG=y
 CONFIG_CRYPTO_MANAGER=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -946,13 +976,17 @@ CONFIG_CRYPTO_CBC=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC_T10DIF=y
index a05b278d72f5681c3d2808ef36ab6fedc6a75595..e21c0e8e22d9029f7d92a34a343d54eb6b88d52d 100644 (file)
@@ -1,22 +1,25 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc3
-# Fri Nov 23 14:15:55 2007
+# Linux kernel version: 2.6.27
+# Wed Oct 22 18:04:52 2008
 #
 CONFIG_SUPERH=y
 # CONFIG_SUPERH32 is not set
 CONFIG_SUPERH64=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/cayman_defconfig"
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 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_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 # CONFIG_GENERIC_TIME is not set
 # CONFIG_GENERIC_CLOCKEVENTS is not set
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
@@ -36,17 +39,15 @@ CONFIG_SWAP=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_PID_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CGROUPS is not set
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
+# CONFIG_GROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
@@ -60,21 +61,33 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_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_IOREMAP_PROT=y
+CONFIG_HAVE_CLK=y
+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
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
@@ -85,6 +98,7 @@ CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -98,13 +112,18 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
 #
 CONFIG_CPU_SH5=y
 # CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
 # CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
 # CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
@@ -113,6 +132,7 @@ CONFIG_CPU_SH5=y
 # CONFIG_CPU_SUBTYPE_SH7710 is not set
 # CONFIG_CPU_SUBTYPE_SH7712 is not set
 # CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
 # CONFIG_CPU_SUBTYPE_SH7091 is not set
 # CONFIG_CPU_SUBTYPE_SH7750R is not set
@@ -121,12 +141,15 @@ CONFIG_CPU_SH5=y
 # CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
 # CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
 CONFIG_CPU_SUBTYPE_SH5_101=y
 # CONFIG_CPU_SUBTYPE_SH5_103 is not set
 
@@ -147,7 +170,9 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_HUGETLB_PAGE_SIZE_64K=y
 # CONFIG_HUGETLB_PAGE_SIZE_256K is not set
 # CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
@@ -161,11 +186,13 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# 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 is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -196,7 +223,6 @@ CONFIG_SH_CAYMAN=y
 #
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=50000000
-# CONFIG_TICK_ONESHOT is not set
 
 #
 # CPU Frequency scaling
@@ -225,13 +251,12 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
-# CONFIG_KEXEC is not set
-# CONFIG_CRASH_DUMP is not set
+# CONFIG_SCHED_HRTICK is not set
+# CONFIG_SECCOMP is not set
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
-CONFIG_PREEMPT_BKL=y
-CONFIG_GUSA=y
+# CONFIG_PREEMPT_RCU is not set
 
 #
 # Boot options
@@ -257,11 +282,9 @@ CONFIG_PCI_LEGACY=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
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -274,6 +297,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -303,8 +327,6 @@ CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
@@ -312,6 +334,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -328,14 +351,14 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
@@ -371,14 +394,18 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
 #
@@ -438,6 +465,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_MVSAS is not set
 # CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
@@ -449,6 +477,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_DH is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 # CONFIG_FUSION is not set
@@ -456,18 +485,20 @@ CONFIG_SCSI_LOWLEVEL=y
 #
 # IEEE 1394 (FireWire) support
 #
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
-# CONFIG_IP1000 is not set
 # CONFIG_ARCNET is not set
 # CONFIG_PHYLIB is not set
 CONFIG_NET_ETHERNET=y
@@ -486,13 +517,19 @@ CONFIG_NET_ETHERNET=y
 # 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_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_IP1000 is not set
+# CONFIG_IGB is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -500,15 +537,17 @@ CONFIG_NETDEV_1000=y
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
 # CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_CHELSIO_T3 is not set
+# CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
@@ -517,6 +556,9 @@ CONFIG_NETDEV_10000=y
 # CONFIG_NIU is not set
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
+# CONFIG_QLGE is not set
+# CONFIG_SFC is not set
 # CONFIG_TR is not set
 
 #
@@ -524,13 +566,13 @@ CONFIG_NETDEV_10000=y
 #
 # 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
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
 # CONFIG_NET_FC is not set
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
@@ -575,10 +617,13 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 # CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
 
 #
 # Serial drivers
@@ -603,16 +648,14 @@ CONFIG_DEVPORT=y
 CONFIG_I2C=m
 CONFIG_I2C_BOARDINFO=y
 # CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
 
 #
-# I2C Algorithms
+# I2C Hardware Bus support
 #
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
 
 #
-# I2C Hardware Bus support
+# PC SMBus host controller drivers
 #
 # CONFIG_I2C_ALI1535 is not set
 # CONFIG_I2C_ALI1563 is not set
@@ -620,31 +663,47 @@ CONFIG_I2C_BOARDINFO=y
 # 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_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
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SH_MOBILE 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
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
 # CONFIG_I2C_VOODOO3 is not set
 
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
 # CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
@@ -653,16 +712,12 @@ CONFIG_I2C_BOARDINFO=y
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# SPI support
-#
 # CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
@@ -671,6 +726,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -700,6 +756,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VT1211 is not set
@@ -709,9 +766,12 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83792D is not set
 # CONFIG_SENSORS_W83793 is not set
 # CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -719,6 +779,7 @@ CONFIG_WATCHDOG=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ALIM7101_WDT is not set
 
 #
 # PCI-based Watchdog Cards
@@ -735,35 +796,71 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
 
 #
 # Multimedia devices
 #
+
+#
+# Multimedia core support
+#
 CONFIG_VIDEO_DEV=m
-# CONFIG_VIDEO_V4L1 is not set
-# CONFIG_VIDEO_V4L1_COMPAT is not set
-CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_V4L2_COMMON=m
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_DVB_CORE=y
+CONFIG_VIDEO_MEDIA=m
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=m
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=m
+CONFIG_MEDIA_TUNER_TDA8290=m
+CONFIG_MEDIA_TUNER_TDA9887=m
+CONFIG_MEDIA_TUNER_TEA5761=m
+CONFIG_MEDIA_TUNER_TEA5767=m
+CONFIG_MEDIA_TUNER_MT20XX=m
+CONFIG_MEDIA_TUNER_XC2028=m
+CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_VIDEO_V4L2=m
+CONFIG_VIDEO_V4L1=m
 CONFIG_VIDEO_CAPTURE_DRIVERS=y
 # CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
 CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
 # CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_BT848 is not set
+# CONFIG_VIDEO_CPIA is not set
 # CONFIG_VIDEO_SAA5246A is not set
 # CONFIG_VIDEO_SAA5249 is not set
 # CONFIG_VIDEO_SAA7134 is not set
+# CONFIG_VIDEO_MXB is not set
 # CONFIG_VIDEO_HEXIUM_ORION is not set
 # CONFIG_VIDEO_HEXIUM_GEMINI is not set
 # CONFIG_VIDEO_CX88 is not set
 # CONFIG_VIDEO_CX23885 is not set
+# CONFIG_VIDEO_IVTV is not set
+# CONFIG_VIDEO_CX18 is not set
 # CONFIG_VIDEO_CAFE_CCIC is not set
+# CONFIG_SOC_CAMERA is not set
 # CONFIG_RADIO_ADAPTERS is not set
-CONFIG_DVB_CORE=y
-# CONFIG_DVB_CORE_ATTACH is not set
 CONFIG_DVB_CAPTURE_DRIVERS=y
 
 #
 # Supported SAA7146 based PCI Adapters
 #
+# CONFIG_TTPCI_EEPROM is not set
+# CONFIG_DVB_AV7110 is not set
+# CONFIG_DVB_BUDGET_CORE is not set
 
 #
 # Supported FlexCopII (B2C2) Adapters
@@ -779,6 +876,11 @@ CONFIG_DVB_CAPTURE_DRIVERS=y
 #
 # CONFIG_DVB_PLUTO2 is not set
 
+#
+# Supported SDMC DM1105 Adapters
+#
+# CONFIG_DVB_DM1105 is not set
+
 #
 # Supported DVB Frontends
 #
@@ -791,14 +893,21 @@ CONFIG_DVB_CAPTURE_DRIVERS=y
 #
 # DVB-S (satellite) frontends
 #
-# CONFIG_DVB_STV0299 is not set
 # CONFIG_DVB_CX24110 is not set
 # CONFIG_DVB_CX24123 is not set
-# CONFIG_DVB_TDA8083 is not set
 # CONFIG_DVB_MT312 is not set
-# CONFIG_DVB_VES1X93 is not set
 # CONFIG_DVB_S5H1420 is not set
+# CONFIG_DVB_STV0288 is not set
+# CONFIG_DVB_STB6000 is not set
+# CONFIG_DVB_STV0299 is not set
+# CONFIG_DVB_TDA8083 is not set
 # CONFIG_DVB_TDA10086 is not set
+# CONFIG_DVB_VES1X93 is not set
+# CONFIG_DVB_TUNER_ITD1000 is not set
+# CONFIG_DVB_TDA826X is not set
+# CONFIG_DVB_TUA6100 is not set
+# CONFIG_DVB_CX24116 is not set
+# CONFIG_DVB_SI21XX is not set
 
 #
 # DVB-T (terrestrial) frontends
@@ -807,6 +916,7 @@ CONFIG_DVB_CAPTURE_DRIVERS=y
 # CONFIG_DVB_SP887X is not set
 # CONFIG_DVB_CX22700 is not set
 # CONFIG_DVB_CX22702 is not set
+# CONFIG_DVB_DRX397XD is not set
 # CONFIG_DVB_L64781 is not set
 # CONFIG_DVB_TDA1004X is not set
 # CONFIG_DVB_NXT6000 is not set
@@ -816,6 +926,7 @@ CONFIG_DVB_CAPTURE_DRIVERS=y
 # CONFIG_DVB_DIB3000MC is not set
 # CONFIG_DVB_DIB7000M is not set
 # CONFIG_DVB_DIB7000P is not set
+# CONFIG_DVB_TDA10048 is not set
 
 #
 # DVB-C (cable) frontends
@@ -834,25 +945,28 @@ CONFIG_DVB_CAPTURE_DRIVERS=y
 # CONFIG_DVB_BCM3510 is not set
 # CONFIG_DVB_LGDT330X is not set
 # CONFIG_DVB_S5H1409 is not set
+# CONFIG_DVB_AU8522 is not set
+# CONFIG_DVB_S5H1411 is not set
 
 #
-# Tuners/PLL support
+# Digital terrestrial only tuners/PLL
 #
 # CONFIG_DVB_PLL is not set
-# CONFIG_DVB_TDA826X is not set
-# CONFIG_DVB_TDA827X is not set
-# CONFIG_DVB_TUNER_QT1010 is not set
-# CONFIG_DVB_TUNER_MT2060 is not set
-# CONFIG_DVB_TUNER_MT2266 is not set
-# CONFIG_DVB_TUNER_MT2131 is not set
 # CONFIG_DVB_TUNER_DIB0070 is not set
 
 #
-# Miscellaneous devices
+# SEC control devices for DVB-S
 #
 # CONFIG_DVB_LNBP21 is not set
+# CONFIG_DVB_ISL6405 is not set
 # CONFIG_DVB_ISL6421 is not set
-# CONFIG_DVB_TUA6100 is not set
+# CONFIG_DVB_LGS8GL5 is not set
+
+#
+# Tools to develop new frontends
+#
+# CONFIG_DVB_DUMMY_FE is not set
+# CONFIG_DVB_AF9013 is not set
 CONFIG_DAB=y
 
 #
@@ -864,15 +978,16 @@ CONFIG_VIDEO_OUTPUT_CONTROL=y
 CONFIG_FB=y
 CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB_DDC is not set
-# CONFIG_FB_CFB_FILLRECT is not set
-# CONFIG_FB_CFB_COPYAREA is not set
-# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=m
+CONFIG_FB_CFB_COPYAREA=m
+CONFIG_FB_CFB_IMAGEBLIT=m
 # 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_DEFERRED_IO=y
 # CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
@@ -897,6 +1012,7 @@ CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
@@ -905,7 +1021,10 @@ CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_ARK is not set
 # CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+CONFIG_FB_SH_MOBILE_LCDC=m
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -938,38 +1057,42 @@ CONFIG_LOGO=y
 # CONFIG_LOGO_SUPERH_MONO is not set
 # CONFIG_LOGO_SUPERH_VGA16 is not set
 CONFIG_LOGO_SUPERH_CLUT224=y
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# 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
 #
 
 #
-# USB Gadget Support
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 # CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
 # CONFIG_RTC_CLASS is not set
-
-#
-# Userspace I/O
-#
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -981,22 +1104,20 @@ CONFIG_EXT3_FS=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_EXT4_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # 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_MINIX_FS=y
-CONFIG_ROMFS_FS=y
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
@@ -1020,6 +1141,7 @@ CONFIG_DNOTIFY=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
@@ -1039,8 +1161,11 @@ CONFIG_HUGETLB_PAGE=y
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
+CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
@@ -1048,14 +1173,13 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_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_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1087,9 +1211,6 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
-CONFIG_INSTRUMENTATION=y
-# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 
 #
 # Kernel hacking
@@ -1098,6 +1219,7 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
@@ -1105,9 +1227,12 @@ CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 CONFIG_SCHEDSTATS=y
 # CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_DEBUG_SLAB is not set
 CONFIG_DEBUG_PREEMPT=y
 # CONFIG_DEBUG_RT_MUTEXES is not set
@@ -1123,15 +1248,20 @@ CONFIG_DEBUG_PREEMPT=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 CONFIG_FRAME_POINTER=y
-CONFIG_FORCED_INLINING=y
-# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
-# CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DEBUG_BOOTMEM is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
@@ -1147,8 +1277,93 @@ CONFIG_SH64_SR_WATCH=y
 #
 # 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_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
 
 #
 # Library routines
@@ -1156,6 +1371,7 @@ CONFIG_SH64_SR_WATCH=y
 CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index 3dc1cbd8a98151bfcad1a57f328b967ce9a2fff9..be4c2e0dbb260b9d21a40a7acc19d674367b48d5 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc1
-# Mon Aug  4 16:49:13 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 18:18:02 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,12 +13,13 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
@@ -70,7 +71,9 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -78,15 +81,12 @@ CONFIG_PROFILING=y
 # CONFIG_MARKERS is not set
 # CONFIG_OPROFILE is not set
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
-CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -119,6 +119,7 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -192,12 +193,13 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 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=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -230,7 +232,6 @@ CONFIG_SH_DREAMCAST=y
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=49876504
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -318,6 +319,8 @@ CONFIG_PCI_LEGACY=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_NET=y
 
@@ -365,6 +368,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -385,11 +389,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
@@ -480,6 +483,9 @@ CONFIG_MII=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
@@ -504,6 +510,7 @@ CONFIG_8139TOO=y
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_SC92031 is not set
+# CONFIG_ATL2 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
@@ -559,6 +566,7 @@ CONFIG_INPUT_MOUSE=y
 # CONFIG_MOUSE_PS2 is not set
 # CONFIG_MOUSE_SERIAL is not set
 # CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
@@ -626,6 +634,7 @@ CONFIG_WATCHDOG=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ALIM7101_WDT is not set
 CONFIG_SH_WDT=y
 # CONFIG_SH_WDT_MMAP is not set
 
@@ -647,6 +656,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # Multimedia devices
@@ -673,6 +684,7 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
 CONFIG_FB=y
 CONFIG_FIRMWARE_EDID=y
 # 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
@@ -707,6 +719,7 @@ CONFIG_FB_PVR2=y
 # CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
@@ -718,6 +731,7 @@ CONFIG_FB_PVR2=y
 # CONFIG_FB_CARMINE is not set
 # CONFIG_FB_SH_MOBILE_LCDC is not set
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -755,6 +769,12 @@ 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=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -763,6 +783,10 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
 
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
@@ -775,16 +799,18 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_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_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_DNOTIFY is not set
@@ -814,6 +840,7 @@ CONFIG_INOTIFY_USER=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
@@ -872,6 +899,11 @@ CONFIG_FRAME_WARN=1024
 # 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
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -882,12 +914,14 @@ CONFIG_FRAME_WARN=1024
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 # CONFIG_CRYPTO_MANAGER is not set
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -960,6 +994,11 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
 
@@ -967,7 +1006,6 @@ CONFIG_CRYPTO_HW=y
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
index bef07fa8d858b57170b895f76cd449e90ff3d69c..158006847ad61935e4f44bb7cc21530b9d8e5c38 100644 (file)
@@ -1,25 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26
-# Tue Aug 26 11:36:09 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 18:20:09 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_BUG=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -55,7 +57,6 @@ CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -72,7 +73,9 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
@@ -80,10 +83,13 @@ CONFIG_SLUB=y
 # 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_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -100,6 +106,7 @@ CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -114,6 +121,7 @@ CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -171,7 +179,9 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -179,12 +189,13 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 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=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -254,9 +265,10 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
-# CONFIG_SCHED_HRTICK is not set
+CONFIG_SCHED_HRTICK=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
@@ -283,11 +295,9 @@ CONFIG_CMDLINE="mem=64M console=ttySC2,115200 root=/dev/nfs rw nfsroot=192.168.0
 # 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
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -332,6 +342,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -352,11 +363,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
@@ -472,6 +482,7 @@ CONFIG_BLK_DEV_RAM_SIZE=26000
 # 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 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
@@ -486,7 +497,6 @@ CONFIG_HAVE_IDE=y
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -498,12 +508,15 @@ CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
-# CONFIG_SMC9194 is not set
 CONFIG_SMC91X=y
+# CONFIG_SMC911X is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
@@ -558,6 +571,7 @@ CONFIG_INPUT=y
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 # CONFIG_VT_HW_CONSOLE_BINDING is not set
@@ -588,26 +602,41 @@ CONFIG_HW_RANDOM=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=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_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
+CONFIG_I2C_SH7760=y
+# CONFIG_I2C_SH_MOBILE 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_STUB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
 # CONFIG_I2C_PCA_PLATFORM is not set
-CONFIG_I2C_SH7760=y
-# CONFIG_I2C_SH_MOBILE is not set
+# CONFIG_I2C_STUB is not set
 
 #
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
@@ -632,8 +661,12 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
 
 #
 # Multimedia devices
@@ -659,6 +692,7 @@ CONFIG_SSB_POSSIBLE=y
 CONFIG_FB=m
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
 CONFIG_FB_CFB_FILLRECT=m
 CONFIG_FB_CFB_COPYAREA=m
 CONFIG_FB_CFB_IMAGEBLIT=m
@@ -677,9 +711,11 @@ CONFIG_FB_TILEBLITTING=y
 #
 # Frame buffer hardware drivers
 #
-# CONFIG_FB_MB86290_640X480_16BPP is not set
 # CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_SH_MOBILE_LCDC=m
+# CONFIG_FB_SH7760 is not set
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -693,15 +729,8 @@ CONFIG_FB_TILEBLITTING=y
 CONFIG_DUMMY_CONSOLE=y
 # CONFIG_FRAMEBUFFER_CONSOLE is not set
 # CONFIG_LOGO is not set
-
-#
-# Sound
-#
 CONFIG_SOUND=y
-
-#
-# Advanced Linux Sound Architecture
-#
+# CONFIG_SOUND_OSS_CORE is not set
 CONFIG_SND=y
 CONFIG_SND_TIMER=y
 CONFIG_SND_PCM=y
@@ -713,39 +742,18 @@ CONFIG_SND_PCM=y
 # CONFIG_SND_VERBOSE_PROCFS is not set
 CONFIG_SND_VERBOSE_PRINTK=y
 # CONFIG_SND_DEBUG is not set
-
-#
-# Generic devices
-#
+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
-
-#
-# SUPERH devices
-#
-
-#
-# System on Chip audio support
-#
+CONFIG_SND_SUPERH=y
 CONFIG_SND_SOC=y
 
 #
 # SoC Audio support for SuperH
 #
-
-#
-# ALSA SoC audio for Freescale SOCs
-#
-
-#
-# SoC Audio for the Texas Instruments OMAP
-#
-
-#
-# Open Sound System
-#
+# CONFIG_SND_SOC_ALL_CODECS is not set
 # CONFIG_SOUND_PRIME is not set
 # CONFIG_HID_SUPPORT is not set
 # CONFIG_USB_SUPPORT is not set
@@ -754,7 +762,9 @@ CONFIG_SND_SOC=y
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -764,17 +774,18 @@ CONFIG_EXT2_FS_XATTR=y
 # CONFIG_EXT2_FS_POSIX_ACL is not set
 # CONFIG_EXT2_FS_SECURITY is not set
 CONFIG_EXT2_FS_XIP=y
-CONFIG_FS_XIP=y
 CONFIG_EXT3_FS=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_EXT4_FS is not set
+CONFIG_FS_XIP=y
 CONFIG_JBD=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_DNOTIFY=y
@@ -805,6 +816,7 @@ CONFIG_GENERIC_ACL=y
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
@@ -826,6 +838,7 @@ CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -835,12 +848,12 @@ CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 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_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -911,6 +924,8 @@ CONFIG_UNUSED_SYMBOLS=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_SCHED_DEBUG is not set
 # CONFIG_SCHEDSTATS is not set
 CONFIG_TIMER_STATS=y
@@ -932,13 +947,27 @@ 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_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_FRAME_POINTER is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 CONFIG_EARLY_SCIF_CONSOLE=y
@@ -956,12 +985,14 @@ CONFIG_DEBUG_STACKOVERFLOW=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 # CONFIG_CRYPTO_MANAGER is not set
 # CONFIG_CRYPTO_GF128MUL is not set
@@ -1001,6 +1032,10 @@ CONFIG_CRYPTO_ALGAPI=y
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 # CONFIG_CRYPTO_SHA1 is not set
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
@@ -1031,15 +1066,20 @@ CONFIG_CRYPTO_DES=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index 41e25b3a5b012ef39745bec8e75ad89a7015b025..1032b235f0801e17d64d8d5ffec1d8d34f0f680f 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26
-# Wed Jul 30 01:24:57 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 18:23:53 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -11,18 +11,19 @@ CONFIG_GENERIC_BUG=y
 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_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_SYS_SUPPORTS_PM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -67,22 +68,21 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -108,6 +108,7 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
 
 #
 # System type
@@ -175,12 +176,13 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 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=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -212,7 +214,6 @@ CONFIG_SH_HP6XX=y
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=22110000
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -257,6 +258,7 @@ CONFIG_HZ=250
 # CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
@@ -292,6 +294,8 @@ CONFIG_PCMCIA_PROBE=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
 
 #
@@ -304,10 +308,6 @@ CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 CONFIG_APM_EMULATION=y
-
-#
-# Networking
-#
 # CONFIG_NET is not set
 
 #
@@ -446,7 +446,6 @@ CONFIG_TOUCHSCREEN_HP600=y
 # CONFIG_TOUCHSCREEN_PENMOUNT is not set
 # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
 # CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-# CONFIG_TOUCHSCREEN_UCB1400 is not set
 # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
 # CONFIG_INPUT_MISC is not set
 
@@ -522,6 +521,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # Multimedia devices
@@ -546,6 +547,7 @@ CONFIG_VIDEO_OUTPUT_CONTROL=y
 CONFIG_FB=y
 CONFIG_FIRMWARE_EDID=y
 # 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
@@ -568,6 +570,7 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 CONFIG_FB_HIT=y
 CONFIG_FB_SH_MOBILE_LCDC=y
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
 # CONFIG_LCD_ILI9320 is not set
@@ -630,12 +633,15 @@ CONFIG_RTC_INTF_DEV=y
 #
 # 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
 
 #
@@ -644,6 +650,7 @@ CONFIG_RTC_INTF_DEV=y
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -652,10 +659,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_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_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
@@ -687,6 +695,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLBFS is not set
@@ -774,6 +783,11 @@ CONFIG_FRAME_WARN=1024
 # 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
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -784,14 +798,19 @@ CONFIG_FRAME_WARN=1024
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
 CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_RNG=y
 CONFIG_CRYPTO_MANAGER=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -863,13 +882,17 @@ CONFIG_CRYPTO_MD5=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC16=y
 CONFIG_CRC_T10DIF=y
index 99cc39c5c6ca7495bc06fc394b7a62048468dfce..b82dfb4da3aaec774725ebbe83f402a3e2941837 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26
-# Wed Jul 30 01:35:07 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 18:25:51 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -11,17 +11,18 @@ CONFIG_GENERIC_BUG=y
 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_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -68,22 +69,22 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -115,6 +116,7 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -182,12 +184,13 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 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=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -225,7 +228,6 @@ CONFIG_SH_LANDISK=y
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=33333333
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -261,6 +263,7 @@ CONFIG_HZ=250
 # CONFIG_SCHED_HRTICK is not set
 CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
@@ -309,11 +312,9 @@ CONFIG_PCCARD_NONSTATIC=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
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -360,7 +361,6 @@ CONFIG_INET_TCP_DIAG=y
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
-# CONFIG_IP_VS is not set
 # CONFIG_IPV6 is not set
 # CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
@@ -374,10 +374,12 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_NETFILTER_NETLINK_LOG is not set
 # CONFIG_NF_CONNTRACK is not set
 # CONFIG_NETFILTER_XTABLES is not set
+# CONFIG_IP_VS is not set
 
 #
 # IP: Netfilter Configuration
 #
+# CONFIG_NF_DEFRAG_IPV4 is not set
 CONFIG_IP_NF_QUEUE=m
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
@@ -386,6 +388,7 @@ CONFIG_IP_NF_QUEUE=m
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 CONFIG_LLC=m
@@ -408,11 +411,10 @@ CONFIG_ATALK=m
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
@@ -462,22 +464,20 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_HP_ILO 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_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_IDECS is not set
 # CONFIG_BLK_DEV_DELKIN is not set
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
 # CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
 CONFIG_BLK_DEV_IDESCSI=y
 # CONFIG_IDE_TASK_IOCTL is not set
 CONFIG_IDE_PROC_FS=y
@@ -640,6 +640,9 @@ CONFIG_MII=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
@@ -660,6 +663,7 @@ CONFIG_8139CP=y
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_SC92031 is not set
+# CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
@@ -680,9 +684,11 @@ CONFIG_NETDEV_1000=y
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_CHELSIO_T3 is not set
+# CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
@@ -692,6 +698,7 @@ CONFIG_NETDEV_10000=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_TR is not set
 
@@ -727,7 +734,7 @@ CONFIG_USB_RTL8150=m
 # Input device support
 #
 CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
 
 #
@@ -838,6 +845,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # Multimedia devices
@@ -861,10 +870,12 @@ CONFIG_VIDEO_V4L2=m
 CONFIG_VIDEO_V4L1=m
 CONFIG_VIDEO_CAPTURE_DRIVERS=y
 # CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
 CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
 # CONFIG_VIDEO_VIVI is not set
 # CONFIG_VIDEO_CPIA is not set
 # CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_SOC_CAMERA is not set
 CONFIG_V4L_USB_DRIVERS=y
 # CONFIG_USB_VIDEO_CLASS is not set
 # CONFIG_USB_GSPCA is not set
@@ -884,14 +895,13 @@ CONFIG_USB_PWC=m
 # CONFIG_USB_ZR364XX is not set
 # CONFIG_USB_STKWEBCAM is not set
 # CONFIG_USB_S2255 is not set
-# CONFIG_SOC_CAMERA is not set
-# CONFIG_VIDEO_SH_MOBILE_CEU is not set
 CONFIG_RADIO_ADAPTERS=y
 # CONFIG_RADIO_GEMTEK_PCI is not set
 # CONFIG_RADIO_MAXIRADIO is not set
 # CONFIG_RADIO_MAESTRO is not set
 CONFIG_USB_DSBR=m
 # CONFIG_USB_SI470X is not set
+# CONFIG_USB_MR800 is not set
 # CONFIG_DAB is not set
 
 #
@@ -914,6 +924,7 @@ CONFIG_USB_DSBR=m
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FONT_8x16=y
 CONFIG_SOUND=m
+CONFIG_SOUND_OSS_CORE=y
 # CONFIG_SND is not set
 CONFIG_SOUND_PRIME=m
 CONFIG_HID_SUPPORT=y
@@ -925,8 +936,7 @@ CONFIG_HID=y
 # USB Input Devices
 #
 CONFIG_USB_HID=m
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
+# CONFIG_HID_PID is not set
 # CONFIG_USB_HIDDEV is not set
 
 #
@@ -934,6 +944,34 @@ CONFIG_USB_HID=m
 #
 # CONFIG_USB_KBD is not set
 # CONFIG_USB_MOUSE is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=m
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_BRIGHT=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_DELL=m
+CONFIG_HID_EZKEY=m
+CONFIG_HID_GYRATION=m
+CONFIG_HID_LOGITECH=m
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+CONFIG_HID_PANTHERLORD=m
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+CONFIG_THRUSTMASTER_FF=m
+CONFIG_ZEROPLUS_FF=m
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -951,6 +989,7 @@ CONFIG_USB_DEVICE_CLASS=y
 # 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
 
 #
 # USB Host Controller Drivers
@@ -975,6 +1014,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_ACM is not set
 CONFIG_USB_PRINTER=m
 # CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -1004,7 +1044,6 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-CONFIG_USB_MON=y
 
 #
 # USB port drivers
@@ -1059,7 +1098,7 @@ CONFIG_USB_SERIAL_PL2303=m
 CONFIG_USB_EMI62=m
 CONFIG_USB_EMI26=m
 # CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_SEVSEG is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
@@ -1078,6 +1117,7 @@ CONFIG_USB_SISUSBVGA_CON=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_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1087,6 +1127,7 @@ CONFIG_USB_SISUSBVGA_CON=y
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -1098,7 +1139,7 @@ CONFIG_EXT3_FS=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_EXT4_FS is not set
 CONFIG_JBD=y
 CONFIG_FS_MBCACHE=y
 CONFIG_REISERFS_FS=y
@@ -1107,6 +1148,7 @@ CONFIG_REISERFS_FS=y
 # CONFIG_REISERFS_FS_XATTR 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_OCFS2_FS is not set
 CONFIG_DNOTIFY=y
@@ -1143,6 +1185,7 @@ CONFIG_NTFS_RW=y
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
@@ -1185,6 +1228,7 @@ CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 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,6 +1300,11 @@ CONFIG_FRAME_WARN=1024
 # 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
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -1267,12 +1316,14 @@ CONFIG_SH_STANDARD_BIOS=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 # CONFIG_CRYPTO_MANAGER is not set
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -1345,6 +1396,11 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
 
@@ -1352,7 +1408,6 @@ CONFIG_CRYPTO_HW=y
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC_T10DIF=y
index aecdfd33c695ae6b7ca38031e5e604e0fbe50d29..c3ecedfc1bc7d6f0595004efada5dc68426203cf 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26
-# Wed Jul 30 01:39:41 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 18:29:42 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -11,17 +11,18 @@ CONFIG_GENERIC_BUG=y
 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_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -68,22 +69,22 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -115,6 +116,7 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -182,12 +184,13 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 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=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -225,7 +228,6 @@ CONFIG_SH_LBOX_RE2=y
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=40000000
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -261,6 +263,7 @@ CONFIG_HZ=250
 # CONFIG_SCHED_HRTICK is not set
 CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
@@ -309,11 +312,9 @@ CONFIG_PCCARD_NONSTATIC=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
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -360,7 +361,6 @@ CONFIG_INET_TCP_DIAG=y
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
-# CONFIG_IP_VS is not set
 # CONFIG_IPV6 is not set
 # CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
@@ -374,10 +374,12 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_NETFILTER_NETLINK_LOG is not set
 # CONFIG_NF_CONNTRACK is not set
 # CONFIG_NETFILTER_XTABLES is not set
+# CONFIG_IP_VS is not set
 
 #
 # IP: Netfilter Configuration
 #
+# CONFIG_NF_DEFRAG_IPV4 is not set
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
@@ -386,6 +388,7 @@ CONFIG_NETFILTER_ADVANCED=y
 # 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
@@ -406,11 +409,10 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
@@ -631,6 +633,9 @@ CONFIG_MII=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
@@ -655,6 +660,7 @@ CONFIG_8139TOO_TUNE_TWISTER=y
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_SC92031 is not set
+# CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
@@ -675,9 +681,11 @@ CONFIG_NETDEV_1000=y
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_CHELSIO_T3 is not set
+# CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
@@ -687,6 +695,7 @@ CONFIG_NETDEV_10000=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_TR is not set
 
@@ -832,6 +841,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # Multimedia devices
@@ -872,6 +883,12 @@ 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=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -880,6 +897,10 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
 
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
@@ -911,12 +932,15 @@ CONFIG_RTC_INTF_DEV=y
 #
 # 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
 
 #
@@ -925,6 +949,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_SH is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -936,12 +961,13 @@ CONFIG_EXT3_FS=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_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_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_DNOTIFY=y
@@ -974,6 +1000,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
@@ -1071,6 +1098,11 @@ CONFIG_FRAME_WARN=1024
 # 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
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -1082,12 +1114,14 @@ CONFIG_SH_STANDARD_BIOS=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 # CONFIG_CRYPTO_MANAGER is not set
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -1160,6 +1194,11 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
 
@@ -1167,7 +1206,6 @@ CONFIG_CRYPTO_HW=y
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC_T10DIF=y
index a3a80f3d27c0592d10a85f499ab88c5d2ebd55f3..499ed7204385254dbf0d9059caa9efaf8790191c 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26
-# Wed Jul 30 01:41:08 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 18:32:23 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -11,16 +11,17 @@ CONFIG_GENERIC_BUG=y
 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_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -55,7 +56,6 @@ CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -72,22 +72,22 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -119,6 +119,7 @@ CONFIG_IOSCHED_NOOP=y
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -186,12 +187,13 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 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=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -229,7 +231,6 @@ CONFIG_SH_MAGIC_PANEL_R2_VERSION=3
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=24000000
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -268,6 +269,7 @@ CONFIG_HZ=250
 # CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
@@ -291,11 +293,9 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000
 # 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
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -340,6 +340,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -360,11 +361,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
@@ -513,6 +513,9 @@ CONFIG_SMC911X=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
@@ -560,11 +563,13 @@ CONFIG_KEYBOARD_ATKBD=y
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GPIO is not set
 # CONFIG_KEYBOARD_SH_KEYSC is not set
 CONFIG_INPUT_MOUSE=y
 # CONFIG_MOUSE_PS2 is not set
 # CONFIG_MOUSE_SERIAL is not set
 # CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
@@ -641,6 +646,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # Multimedia devices
@@ -703,12 +710,15 @@ CONFIG_RTC_INTF_DEV=y
 #
 # 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
 
 #
@@ -717,6 +727,7 @@ CONFIG_RTC_INTF_DEV=y
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -726,11 +737,12 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
 CONFIG_JBD=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_DNOTIFY is not set
@@ -759,6 +771,7 @@ CONFIG_JBD=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
@@ -806,6 +819,7 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -899,10 +913,22 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 CONFIG_FRAME_POINTER=y
-# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 CONFIG_EARLY_SCIF_CONSOLE=y
@@ -938,6 +964,7 @@ CONFIG_KGDB_DEFBITS_8=y
 #
 # 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
 
@@ -945,7 +972,6 @@ CONFIG_KGDB_DEFBITS_8=y
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
 # CONFIG_CRC_T10DIF is not set
index e4b900e72dcd95f19256ae0761e49714a9ba0397..b8ada8ce98d9476f7a81f5caf677ce89d2c9f091 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26
-# Wed Jul 30 01:47:16 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 18:37:41 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -11,16 +11,17 @@ CONFIG_GENERIC_BUG=y
 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_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -69,22 +70,21 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -110,6 +110,7 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -183,12 +184,13 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 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=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -221,7 +223,6 @@ CONFIG_SH_SH4202_MICRODEV=y
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=66000000
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -260,6 +261,7 @@ CONFIG_HZ=250
 # CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
@@ -287,11 +289,9 @@ CONFIG_SUPERHYWAY=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
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -340,6 +340,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -360,11 +361,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
@@ -402,19 +402,17 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=1
-CONFIG_BLK_DEV_IDE=y
 
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
 # 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 is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_IDE_TASK_IOCTL is not set
 CONFIG_IDE_PROC_FS=y
 
@@ -451,6 +449,9 @@ CONFIG_SMC91X=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
@@ -542,6 +543,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # Multimedia devices
@@ -580,6 +583,10 @@ CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
 
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
@@ -591,6 +598,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -602,12 +610,13 @@ CONFIG_EXT3_FS=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_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_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_DNOTIFY=y
@@ -640,6 +649,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
@@ -678,6 +688,7 @@ CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -748,6 +759,11 @@ CONFIG_FRAME_WARN=1024
 # 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
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -758,14 +774,19 @@ CONFIG_FRAME_WARN=1024
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
 CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_RNG=y
 CONFIG_CRYPTO_MANAGER=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -837,13 +858,17 @@ CONFIG_CRYPTO_DES=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
index 4f8b1974f2c7a5b3d4ba66b5daf962992519ed6b..624c47aa66d3cf7e4f9023e500d6f8b4e6d86181 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc4
-# Tue Aug 26 14:18:17 2008
+# Linux kernel version: 2.6.27
+# Tue Oct 21 12:57:28 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,12 +13,13 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
@@ -70,7 +71,9 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -78,15 +81,12 @@ CONFIG_PROFILING=y
 # CONFIG_MARKERS is not set
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
-CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -118,6 +118,7 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -179,6 +180,7 @@ CONFIG_MAX_ACTIVE_REGIONS=2
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -192,13 +194,14 @@ CONFIG_SPARSEMEM=y
 CONFIG_NEED_MULTIPLE_NODES=y
 CONFIG_HAVE_MEMORY_PRESENT=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 # CONFIG_MEMORY_HOTPLUG is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_MIGRATION is not set
 # CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -235,7 +238,6 @@ CONFIG_SH_MIGOR_QVGA=y
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=33333333
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -295,6 +297,8 @@ CONFIG_CMDLINE="console=ttySC0,115200 earlyprintk=serial ip=on"
 # 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_NET=y
 
@@ -345,6 +349,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -365,11 +370,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 CONFIG_WIRELESS_EXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_MAC80211 is not set
@@ -555,6 +559,9 @@ CONFIG_SMC91X=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
@@ -599,6 +606,7 @@ CONFIG_INPUT_KEYBOARD=y
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GPIO is not set
 CONFIG_KEYBOARD_SH_KEYSC=y
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
@@ -656,6 +664,7 @@ CONFIG_I2C_HELPER_AUTO=y
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
+# CONFIG_I2C_GPIO is not set
 # CONFIG_I2C_OCORES is not set
 CONFIG_I2C_SH_MOBILE=y
 # CONFIG_I2C_SIMTEC is not set
@@ -709,6 +718,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_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
 
 #
 # Multimedia devices
@@ -717,13 +728,44 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multimedia core support
 #
-# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+# CONFIG_VIDEO_ALLOW_V4L1 is not set
+CONFIG_VIDEO_V4L1_COMPAT=y
 # CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
+CONFIG_VIDEO_MEDIA=y
 
 #
 # Multimedia drivers
 #
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF_DMA_CONTIG=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+CONFIG_SOC_CAMERA=y
+# CONFIG_SOC_CAMERA_MT9M001 is not set
+# CONFIG_SOC_CAMERA_MT9M111 is not set
+# CONFIG_SOC_CAMERA_MT9V022 is not set
+CONFIG_SOC_CAMERA_PLATFORM=y
+CONFIG_VIDEO_SH_MOBILE_CEU=y
+# CONFIG_RADIO_ADAPTERS is not set
 # CONFIG_DAB is not set
 
 #
@@ -748,6 +790,12 @@ 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=y
 CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
@@ -755,7 +803,6 @@ CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
-# CONFIG_USB_MUSB_HDRC is not set
 # CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
@@ -764,21 +811,23 @@ CONFIG_USB_ARCH_HAS_HCD=y
 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_AMD5536UDC is not set
+# 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_NET2280 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_PXA27X is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
 CONFIG_USB_GADGET_M66592=y
 CONFIG_USB_M66592=y
 CONFIG_SUPERH_BUILT_IN_M66592=y
-# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_NET2280 is not set
 # CONFIG_USB_GADGET_GOKU is not set
-# CONFIG_USB_GADGET_LH7A40X is not set
-# CONFIG_USB_GADGET_OMAP is not set
-# CONFIG_USB_GADGET_S3C2410 is not set
-# CONFIG_USB_GADGET_AT91 is not set
 # CONFIG_USB_GADGET_DUMMY_HCD is not set
 CONFIG_USB_GADGET_DUALSPEED=y
 # CONFIG_USB_ZERO is not set
@@ -831,12 +880,15 @@ CONFIG_RTC_DRV_RS5C372=y
 #
 # 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
 
 #
@@ -848,16 +900,19 @@ 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
+# CONFIG_STAGING is not set
 
 #
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_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_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_DNOTIFY is not set
@@ -886,6 +941,7 @@ CONFIG_UIO_PDRV_GENIRQ=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
@@ -938,6 +994,11 @@ CONFIG_DEBUG_FS=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
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 CONFIG_EARLY_SCIF_CONSOLE=y
@@ -950,12 +1011,14 @@ CONFIG_EARLY_PRINTK=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 # CONFIG_CRYPTO_MANAGER is not set
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -1028,13 +1091,17 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC_T10DIF=y
index 57a300797584baa5656c25bb90e41641a17b0f96..2e65149e9502b156b54c27d96e92dc9c721fc45b 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26
-# Wed Jul 30 01:51:13 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 20:03:46 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -11,17 +11,18 @@ CONFIG_GENERIC_BUG=y
 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_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_IO_TRAPPED=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -77,7 +78,9 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -85,15 +88,13 @@ CONFIG_PROFILING=y
 # CONFIG_MARKERS is not set
 CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
@@ -124,6 +125,7 @@ CONFIG_IOSCHED_NOOP=y
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -199,12 +201,13 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 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=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -242,7 +245,6 @@ CONFIG_SH_R7780MP=y
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=28
 CONFIG_SH_PCLK_FREQ=32000000
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -278,6 +280,7 @@ CONFIG_HZ=250
 # CONFIG_SCHED_HRTICK is not set
 CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
@@ -309,11 +312,9 @@ CONFIG_PCI_LEGACY=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
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -369,6 +370,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ATM is not set
 CONFIG_STP=m
 CONFIG_BRIDGE=m
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 CONFIG_LLC=m
@@ -390,11 +392,10 @@ CONFIG_LLC=m
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 CONFIG_WIRELESS_EXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_MAC80211 is not set
@@ -616,6 +617,9 @@ CONFIG_AX88796_93CX6=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=m
 # CONFIG_AMD8111_ETH is not set
@@ -641,11 +645,11 @@ CONFIG_8139TOO_8129=y
 CONFIG_VIA_RHINE=m
 CONFIG_VIA_RHINE_MMIO=y
 # CONFIG_SC92031 is not set
+# CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 CONFIG_E1000=m
-# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_E1000E is not set
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
@@ -662,9 +666,11 @@ CONFIG_R8169=y
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_CHELSIO_T3 is not set
+# CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
@@ -674,6 +680,7 @@ CONFIG_NETDEV_10000=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_TR is not set
 
@@ -773,24 +780,129 @@ CONFIG_HW_RANDOM=y
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_DEVPORT=y
-# CONFIG_I2C is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=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_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_HIGHLANDER=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SH_MOBILE 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
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
 # CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
@@ -810,6 +922,9 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
 
 #
 # Multimedia devices
@@ -841,12 +956,19 @@ CONFIG_DAB=y
 #
 # CONFIG_DISPLAY_SUPPORT is not set
 CONFIG_SOUND=m
+CONFIG_SOUND_OSS_CORE=y
 # CONFIG_SND is not set
 CONFIG_SOUND_PRIME=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=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -855,6 +977,10 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
 
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
@@ -879,6 +1005,22 @@ 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=y
+# 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
+
 #
 # SPI RTC drivers
 #
@@ -886,12 +1028,15 @@ CONFIG_RTC_INTF_DEV=y
 #
 # 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
 
 #
@@ -900,6 +1045,7 @@ CONFIG_RTC_INTF_DEV=y
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -911,13 +1057,14 @@ CONFIG_EXT3_FS=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_EXT4_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_DNOTIFY=y
@@ -952,6 +1099,7 @@ 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
@@ -994,6 +1142,7 @@ CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1088,10 +1237,22 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_FRAME_POINTER is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -1108,15 +1269,19 @@ CONFIG_DEBUG_STACKOVERFLOW=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
 CONFIG_CRYPTO_BLKCIPHER=y
 CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_RNG=y
 CONFIG_CRYPTO_MANAGER=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -1189,6 +1354,11 @@ CONFIG_CRYPTO_DES=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
 
@@ -1196,7 +1366,6 @@ CONFIG_CRYPTO_HW=y
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC_T10DIF=y
index 1d09d24d429853890130f8c936d509e1b3e24e05..043a8a509e0912d75aaa90a08bb46fc6b4c9ba08 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26
-# Wed Jul 30 00:59:19 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 16:25:30 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -11,18 +11,19 @@ CONFIG_GENERIC_BUG=y
 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_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_IO_TRAPPED=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -38,11 +39,13 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_POSIX_MQUEUE is not set
+CONFIG_POSIX_MQUEUE=y
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_AUDIT is not set
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+CONFIG_AUDIT_TREE=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
@@ -67,31 +70,33 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
-# CONFIG_FUTEX is not set
+CONFIG_FUTEX=y
 CONFIG_ANON_INODES=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
 # CONFIG_MARKERS is not set
-CONFIG_OPROFILE=m
+CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_KPROBES=y
+CONFIG_KRETPROBES=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
-CONFIG_PROC_PAGE_MONITOR=y
+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
@@ -120,7 +125,8 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
+# CONFIG_CLASSIC_RCU is not set
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -182,6 +188,7 @@ CONFIG_MAX_ACTIVE_REGIONS=2
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -200,13 +207,15 @@ CONFIG_SPARSEMEM_MANUAL=y
 CONFIG_SPARSEMEM=y
 CONFIG_HAVE_MEMORY_PRESENT=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 # CONFIG_MEMORY_HOTPLUG is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
 # CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -243,15 +252,30 @@ CONFIG_SH_R7785RP=y
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=28
 CONFIG_SH_PCLK_FREQ=50000000
-# CONFIG_TICK_ONESHOT is not set
-# CONFIG_NO_HZ is not set
-# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 
 #
 # CPU Frequency scaling
 #
-# CONFIG_CPU_FREQ is not set
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_SH_CPU_FREQ=y
 
 #
 # DMA support
@@ -276,13 +300,15 @@ 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_SCHED_HRTICK=y
 CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_TRACE=y
 CONFIG_GUSA=y
 
 #
@@ -301,7 +327,7 @@ CONFIG_SH_PCIDMA_NONCOHERENT=y
 CONFIG_PCI_AUTO=y
 CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
@@ -310,11 +336,9 @@ CONFIG_PCI_LEGACY=y
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Networking
-#
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=m
 CONFIG_NET=y
 
 #
@@ -370,6 +394,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ATM is not set
 CONFIG_STP=m
 CONFIG_BRIDGE=m
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 CONFIG_LLC=m
@@ -386,16 +411,16 @@ CONFIG_LLC=m
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 CONFIG_WIRELESS_EXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_MAC80211 is not set
@@ -617,8 +642,12 @@ CONFIG_AX88796_93CX6=y
 # 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_ATL2 is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
@@ -639,9 +668,11 @@ CONFIG_R8169=y
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_CHELSIO_T3 is not set
+# CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
@@ -651,6 +682,7 @@ CONFIG_NETDEV_10000=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_TR is not set
 
@@ -750,24 +782,129 @@ CONFIG_HW_RANDOM=y
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_DEVPORT=y
-# CONFIG_I2C is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=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_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_HIGHLANDER=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SH_MOBILE 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
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
 # CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
@@ -787,6 +924,9 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
 
 #
 # Multimedia devices
@@ -813,6 +953,7 @@ CONFIG_SSB_POSSIBLE=y
 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=m
 CONFIG_FB_CFB_COPYAREA=m
 CONFIG_FB_CFB_IMAGEBLIT=m
@@ -846,6 +987,7 @@ CONFIG_FB_CFB_IMAGEBLIT=m
 # CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
@@ -857,6 +999,7 @@ CONFIG_FB_CFB_IMAGEBLIT=m
 # CONFIG_FB_CARMINE is not set
 CONFIG_FB_SH_MOBILE_LCDC=m
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -865,12 +1008,19 @@ CONFIG_FB_SH_MOBILE_LCDC=m
 # CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_LOGO is not set
 CONFIG_SOUND=m
+CONFIG_SOUND_OSS_CORE=y
 # CONFIG_SND is not set
 CONFIG_SOUND_PRIME=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=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -879,6 +1029,10 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
 
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
@@ -903,6 +1057,22 @@ 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=y
+# 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
+
 #
 # SPI RTC drivers
 #
@@ -910,12 +1080,15 @@ CONFIG_RTC_INTF_DEV=y
 #
 # 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
 
 #
@@ -924,6 +1097,7 @@ CONFIG_RTC_INTF_DEV=y
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -935,13 +1109,14 @@ CONFIG_EXT3_FS=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_EXT4_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_DNOTIFY=y
@@ -976,6 +1151,7 @@ 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
@@ -1018,6 +1194,7 @@ CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1094,6 +1271,8 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_MUTEXES=y
 CONFIG_DEBUG_LOCK_ALLOC=y
@@ -1113,10 +1292,23 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 CONFIG_FRAME_POINTER=y
-# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_KPROBES_SANITY_TEST is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -1133,15 +1325,19 @@ CONFIG_4KSTACKS=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
 CONFIG_CRYPTO_BLKCIPHER=y
 CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_RNG=y
 CONFIG_CRYPTO_MANAGER=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -1214,6 +1410,11 @@ CONFIG_CRYPTO_DES=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
 
@@ -1221,7 +1422,6 @@ CONFIG_CRYPTO_HW=y
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC_T10DIF=y
@@ -1229,6 +1429,8 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
+CONFIG_AUDIT_GENERIC=y
+CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
index 840fe3843ffae31ce0360cdc06fbbf09816f4456..85b0ac4fc66737944b912229a6b2e72d547a6e7a 100644 (file)
@@ -1,25 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26
-# Mon Jul 28 22:23:03 2008
+# Linux kernel version: 2.6.27
+# Tue Oct 21 12:58:47 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_BUG=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_GPIO=y
 # CONFIG_GENERIC_TIME is not set
 # CONFIG_GENERIC_CLOCKEVENTS is not set
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -56,7 +58,6 @@ CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -72,7 +73,9 @@ CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 # CONFIG_SLAB is not set
 # CONFIG_SLUB is not set
 CONFIG_SLOB=y
@@ -80,14 +83,12 @@ CONFIG_PROFILING=y
 # CONFIG_MARKERS is not set
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_RT_MUTEXES=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
@@ -117,6 +118,7 @@ CONFIG_IOSCHED_NOOP=y
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -183,10 +185,10 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 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=0
 CONFIG_NR_QUICK=2
 
@@ -219,7 +221,6 @@ CONFIG_SH_CMT=y
 CONFIG_SH_TIMER_IRQ=142
 CONFIG_SH_PCLK_FREQ=16670800
 CONFIG_SH_CLK_MD=0
-# CONFIG_TICK_ONESHOT is not set
 
 #
 # CPU Frequency scaling
@@ -266,6 +267,7 @@ CONFIG_HZ=1000
 # CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
@@ -292,11 +294,8 @@ CONFIG_BINFMT_ELF_FDPIC=y
 CONFIG_BINFMT_FLAT=y
 CONFIG_BINFMT_ZFLAT=y
 CONFIG_BINFMT_SHARED_FLAT=y
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -339,6 +338,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -359,11 +359,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
@@ -442,7 +441,6 @@ CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_PHYSMAP_START=0x0
 CONFIG_MTD_PHYSMAP_LEN=0x0
 CONFIG_MTD_PHYSMAP_BANKWIDTH=4
-# CONFIG_MTD_UCLINUX is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -509,6 +507,9 @@ CONFIG_SMC911X=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
@@ -541,7 +542,7 @@ CONFIG_SMC911X=y
 # Input device support
 #
 CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
 
 #
@@ -615,6 +616,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # Multimedia devices
@@ -655,9 +658,36 @@ CONFIG_HID=y
 # USB Input Devices
 #
 CONFIG_USB_HID=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
+# CONFIG_HID_PID is not set
 # CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_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_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_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_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
@@ -675,6 +705,7 @@ CONFIG_USB_DEVICE_CLASS=y
 # 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
 
 #
 # USB Host Controller Drivers
@@ -691,6 +722,7 @@ CONFIG_USB_R8A66597_HCD=y
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
 # CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -705,7 +737,6 @@ CONFIG_USB_R8A66597_HCD=y
 # USB Imaging devices
 #
 # CONFIG_USB_MDC800 is not set
-CONFIG_USB_MON=y
 
 #
 # USB port drivers
@@ -718,7 +749,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_SEVSEG is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
@@ -735,6 +766,7 @@ CONFIG_USB_MON=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_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -762,12 +794,15 @@ CONFIG_RTC_INTF_DEV=y
 #
 # 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
 
 #
@@ -776,16 +811,18 @@ CONFIG_RTC_INTF_DEV=y
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_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_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_DNOTIFY is not set
@@ -847,6 +884,7 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -905,10 +943,21 @@ CONFIG_DEBUG_WRITECOUNT=y
 CONFIG_DEBUG_LIST=y
 CONFIG_DEBUG_SG=y
 CONFIG_FRAME_POINTER=y
-# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 CONFIG_EARLY_SCIF_CONSOLE=y
@@ -924,6 +973,7 @@ CONFIG_DEBUG_STACK_USAGE=y
 #
 # 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
 
@@ -931,7 +981,6 @@ CONFIG_DEBUG_STACK_USAGE=y
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
index 8413236c1b37399783141d097b9de2b78e100a21..7d2a9e88838bc8fe465a198a89b6e682392e1264 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26
-# Wed Jul 30 01:55:52 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 18:44:36 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -11,17 +11,18 @@ CONFIG_GENERIC_BUG=y
 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_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_IO_TRAPPED=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -69,7 +70,9 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -77,15 +80,13 @@ CONFIG_PROFILING=y
 # CONFIG_MARKERS is not set
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -116,6 +117,7 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -183,12 +185,13 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 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=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -232,7 +235,6 @@ CONFIG_RTS7751R2D_1=y
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=60000000
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -268,6 +270,7 @@ CONFIG_HZ=250
 # CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
@@ -302,11 +305,9 @@ CONFIG_HOTPLUG_PCI=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
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -353,6 +354,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -373,11 +375,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 CONFIG_WIRELESS_EXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_MAC80211 is not set
@@ -598,6 +599,9 @@ CONFIG_MII=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
@@ -622,6 +626,7 @@ CONFIG_8139TOO=y
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_SC92031 is not set
+# CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
@@ -642,9 +647,11 @@ CONFIG_NETDEV_1000=y
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_CHELSIO_T3 is not set
+# CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
@@ -654,6 +661,7 @@ CONFIG_NETDEV_10000=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_TR is not set
 
@@ -688,7 +696,7 @@ CONFIG_NETDEV_10000=y
 # Input device support
 #
 CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
 
 #
@@ -776,11 +784,13 @@ CONFIG_SPI_SH_SCI=y
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADCXX is not set
 # CONFIG_SENSORS_I5K_AMB is not set
 # CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_F71882FG is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_MAX1111 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SIS5595 is not set
@@ -808,6 +818,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 CONFIG_MFD_SM501=y
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # Multimedia devices
@@ -835,6 +847,7 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
 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
@@ -868,6 +881,7 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 # CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
@@ -880,6 +894,7 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 CONFIG_FB_SH_MOBILE_LCDC=m
 CONFIG_FB_SM501=y
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -905,6 +920,7 @@ CONFIG_LOGO=y
 # CONFIG_LOGO_SUPERH_VGA16 is not set
 CONFIG_LOGO_SUPERH_CLUT224=y
 CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
 CONFIG_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
@@ -1005,9 +1021,36 @@ CONFIG_HID=y
 # USB Input Devices
 #
 CONFIG_USB_HID=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
+# CONFIG_HID_PID is not set
 # CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_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_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_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_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1025,6 +1068,7 @@ CONFIG_USB_DEVICE_CLASS=y
 # CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
 
 #
 # USB Host Controller Drivers
@@ -1047,6 +1091,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
 # CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -1076,7 +1121,6 @@ CONFIG_USB_LIBUSUAL=y
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_MON is not set
 
 #
 # USB port drivers
@@ -1089,7 +1133,7 @@ CONFIG_USB_LIBUSUAL=y
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_SEVSEG is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
@@ -1105,6 +1149,7 @@ CONFIG_USB_LIBUSUAL=y
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1134,16 +1179,20 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_MAX6902 is not set
 CONFIG_RTC_DRV_R9701=y
 # CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 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
 
 #
@@ -1152,6 +1201,7 @@ CONFIG_RTC_DRV_R9701=y
 # CONFIG_RTC_DRV_SH is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -1160,10 +1210,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_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_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_DNOTIFY=y
@@ -1196,6 +1247,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
@@ -1293,6 +1345,11 @@ CONFIG_DEBUG_FS=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
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 CONFIG_EARLY_SCIF_CONSOLE=y
@@ -1305,12 +1362,14 @@ CONFIG_EARLY_PRINTK=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 # CONFIG_CRYPTO_MANAGER is not set
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -1383,6 +1442,11 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
 
@@ -1390,7 +1454,6 @@ CONFIG_CRYPTO_HW=y
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC_T10DIF=y
index 7d9fa6e9ded5f65641976b9fab586b755c344c9c..f680d3eecdfb792a2c606a7d0413309b5a7feec2 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26
-# Wed Jul 30 01:59:18 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 18:47:39 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -11,17 +11,18 @@ CONFIG_GENERIC_BUG=y
 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_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_IO_TRAPPED=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -69,7 +70,9 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -77,15 +80,13 @@ CONFIG_PROFILING=y
 # CONFIG_MARKERS is not set
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -116,6 +117,7 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -183,12 +185,13 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 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=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -232,7 +235,6 @@ CONFIG_RTS7751R2D_PLUS=y
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=60000000
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -268,6 +270,7 @@ CONFIG_HZ=250
 # CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
@@ -302,11 +305,9 @@ CONFIG_HOTPLUG_PCI=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
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -353,6 +354,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -373,11 +375,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 CONFIG_WIRELESS_EXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_MAC80211 is not set
@@ -598,6 +599,9 @@ CONFIG_MII=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
@@ -622,6 +626,7 @@ CONFIG_8139TOO=y
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_SC92031 is not set
+# CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
@@ -642,9 +647,11 @@ CONFIG_NETDEV_1000=y
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_CHELSIO_T3 is not set
+# CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
@@ -654,6 +661,7 @@ CONFIG_NETDEV_10000=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_TR is not set
 
@@ -688,7 +696,7 @@ CONFIG_NETDEV_10000=y
 # Input device support
 #
 CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
 
 #
@@ -776,11 +784,13 @@ CONFIG_SPI_SH_SCI=y
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADCXX is not set
 # CONFIG_SENSORS_I5K_AMB is not set
 # CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_F71882FG is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_MAX1111 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SIS5595 is not set
@@ -808,6 +818,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 CONFIG_MFD_SM501=y
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # Multimedia devices
@@ -835,6 +847,7 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
 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
@@ -868,6 +881,7 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 # CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
@@ -880,6 +894,7 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 CONFIG_FB_SH_MOBILE_LCDC=m
 CONFIG_FB_SM501=y
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -905,6 +920,7 @@ CONFIG_LOGO=y
 # CONFIG_LOGO_SUPERH_VGA16 is not set
 CONFIG_LOGO_SUPERH_CLUT224=y
 CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
 CONFIG_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
@@ -1005,9 +1021,36 @@ CONFIG_HID=y
 # USB Input Devices
 #
 CONFIG_USB_HID=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
+# CONFIG_HID_PID is not set
 # CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_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_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_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_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1025,6 +1068,7 @@ CONFIG_USB_DEVICE_CLASS=y
 # CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
 
 #
 # USB Host Controller Drivers
@@ -1047,6 +1091,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
 # CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -1076,7 +1121,6 @@ CONFIG_USB_LIBUSUAL=y
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_MON is not set
 
 #
 # USB port drivers
@@ -1089,7 +1133,7 @@ CONFIG_USB_LIBUSUAL=y
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_SEVSEG is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
@@ -1105,6 +1149,7 @@ CONFIG_USB_LIBUSUAL=y
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1134,16 +1179,20 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_MAX6902 is not set
 CONFIG_RTC_DRV_R9701=y
 # CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 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
 
 #
@@ -1152,6 +1201,7 @@ CONFIG_RTC_DRV_R9701=y
 # CONFIG_RTC_DRV_SH is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -1160,10 +1210,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_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_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_DNOTIFY=y
@@ -1196,6 +1247,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
@@ -1293,6 +1345,11 @@ CONFIG_DEBUG_FS=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
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 CONFIG_EARLY_SCIF_CONSOLE=y
@@ -1305,12 +1362,14 @@ CONFIG_EARLY_PRINTK=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 # CONFIG_CRYPTO_MANAGER is not set
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -1383,6 +1442,11 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
 
@@ -1390,7 +1454,6 @@ CONFIG_CRYPTO_HW=y
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC_T10DIF=y
index a72796c0293c9f9431531ba1eaae3d6dae0a2af4..ae8f63000fbfb031b2a2c7f6bededccff63bd542 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc2
-# Mon Aug 18 22:17:44 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 18:51:20 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,12 +13,13 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
@@ -73,7 +74,9 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -81,15 +84,12 @@ CONFIG_PROFILING=y
 # CONFIG_MARKERS is not set
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
-CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -121,6 +121,7 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -188,12 +189,13 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 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=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -237,7 +239,6 @@ CONFIG_RTS7751R2D_PLUS=y
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=60000000
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -299,6 +300,8 @@ CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1 earlyprintk=se
 # 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_NET is not set
 
@@ -467,10 +470,12 @@ CONFIG_SPI_BITBANG=y
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADCXX is not set
 # CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_F71882FG is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_MAX1111 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -495,6 +500,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 CONFIG_MFD_SM501=y
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # Multimedia devices
@@ -519,6 +526,7 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
 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
@@ -541,6 +549,7 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 CONFIG_FB_SH_MOBILE_LCDC=m
 CONFIG_FB_SM501=y
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -566,6 +575,7 @@ CONFIG_LOGO=y
 # CONFIG_LOGO_SUPERH_VGA16 is not set
 CONFIG_LOGO_SUPERH_CLUT224=y
 CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
 CONFIG_SND=m
 # CONFIG_SND_SEQUENCER is not set
 # CONFIG_SND_MIXER_OSS is not set
@@ -588,6 +598,12 @@ 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
@@ -616,16 +632,20 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_MAX6902 is not set
 CONFIG_RTC_DRV_R9701=y
 # CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 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
 
 #
@@ -634,6 +654,7 @@ CONFIG_RTC_DRV_R9701=y
 # CONFIG_RTC_DRV_SH is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -642,10 +663,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_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_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
@@ -677,6 +699,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
@@ -790,10 +813,21 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_FRAME_POINTER is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 CONFIG_EARLY_SCIF_CONSOLE=y
@@ -811,12 +845,14 @@ CONFIG_EARLY_PRINTK=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 # CONFIG_CRYPTO_MANAGER is not set
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -889,13 +925,17 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC_T10DIF=y
index 6d834f2429058bcf80e4834e8a7508e2b81931cd..543287b97a6ad0d13862e0d025657d0c99c582a0 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26
-# Wed Jul 30 02:00:12 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 18:53:22 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -11,17 +11,18 @@ CONFIG_GENERIC_BUG=y
 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_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -56,7 +57,6 @@ CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -73,7 +73,9 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
@@ -81,15 +83,13 @@ CONFIG_SLUB=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -121,6 +121,7 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -196,12 +197,13 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# 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 is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -273,9 +275,10 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
-# CONFIG_SCHED_HRTICK is not set
+CONFIG_SCHED_HRTICK=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
@@ -328,11 +331,9 @@ CONFIG_HOTPLUG_PCI=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
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -406,6 +407,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
 # 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
@@ -424,6 +426,7 @@ CONFIG_NET_SCHED=y
 # CONFIG_NET_SCH_HTB is not set
 # CONFIG_NET_SCH_HFSC is not set
 # CONFIG_NET_SCH_PRIO is not set
+# CONFIG_NET_SCH_MULTIQ is not set
 # CONFIG_NET_SCH_RED is not set
 # CONFIG_NET_SCH_SFQ is not set
 # CONFIG_NET_SCH_TEQL is not set
@@ -456,11 +459,10 @@ CONFIG_NET_SCH_FIFO=y
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
@@ -510,21 +512,19 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_MISC_DEVICES 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_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
 # CONFIG_BLK_DEV_IDECS is not set
 # CONFIG_BLK_DEV_DELKIN is not set
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
 # CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
 CONFIG_IDE_PROC_FS=y
@@ -748,9 +748,13 @@ CONFIG_SMC91X=y
 # 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_NET_POCKET is not set
+# CONFIG_ATL2 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
@@ -790,7 +794,7 @@ CONFIG_NET_POLL_CONTROLLER=y
 # Input device support
 #
 CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
 
 #
@@ -825,6 +829,7 @@ CONFIG_MOUSE_PS2_TRACKPOINT=y
 # CONFIG_MOUSE_PS2_TOUCHKIT is not set
 # CONFIG_MOUSE_SERIAL is not set
 # CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
@@ -923,6 +928,8 @@ CONFIG_SSB_DRIVER_PCICORE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # Multimedia devices
@@ -949,6 +956,7 @@ CONFIG_SSB_DRIVER_PCICORE=y
 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=m
 CONFIG_FB_CFB_COPYAREA=m
 CONFIG_FB_CFB_IMAGEBLIT=m
@@ -982,6 +990,7 @@ CONFIG_FB_CFB_IMAGEBLIT=m
 # CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
@@ -993,6 +1002,7 @@ CONFIG_FB_CFB_IMAGEBLIT=m
 # CONFIG_FB_CARMINE is not set
 CONFIG_FB_SH_MOBILE_LCDC=m
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -1022,6 +1032,7 @@ CONFIG_LOGO_SUPERH_MONO=y
 CONFIG_LOGO_SUPERH_VGA16=y
 CONFIG_LOGO_SUPERH_CLUT224=y
 CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
 # CONFIG_SND is not set
 CONFIG_SOUND_PRIME=y
 CONFIG_HID_SUPPORT=y
@@ -1033,9 +1044,36 @@ CONFIG_HID=y
 # USB Input Devices
 #
 CONFIG_USB_HID=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
+# CONFIG_HID_PID is not set
 # CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_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_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_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_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1053,6 +1091,7 @@ CONFIG_USB_DEVICEFS=y
 # 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
 
 #
 # USB Host Controller Drivers
@@ -1074,6 +1113,7 @@ CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_ACM is not set
 CONFIG_USB_PRINTER=y
 # CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -1103,7 +1143,6 @@ CONFIG_USB_STORAGE=y
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-CONFIG_USB_MON=y
 
 #
 # USB port drivers
@@ -1117,7 +1156,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_SEVSEG is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
@@ -1135,6 +1174,7 @@ CONFIG_USB_MON=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_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1155,6 +1195,7 @@ CONFIG_LEDS_CLASS=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -1168,12 +1209,13 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 # CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4DEV_FS 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=y
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_DNOTIFY=y
@@ -1211,6 +1253,7 @@ CONFIG_NTFS_RW=y
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
@@ -1252,6 +1295,7 @@ CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1349,10 +1393,23 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_FRAME_POINTER is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -1369,12 +1426,14 @@ CONFIG_DEBUG_STACKOVERFLOW=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 # CONFIG_CRYPTO_MANAGER is not set
 # CONFIG_CRYPTO_GF128MUL is not set
@@ -1448,6 +1507,11 @@ CONFIG_CRYPTO_DES=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
 
@@ -1455,7 +1519,6 @@ CONFIG_CRYPTO_HW=y
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC_T10DIF=y
index af15cbef12baf96a5471f57a5bdbe42ec4064803..25717ff26ca9c23b98d08dbd777718e59247180a 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26
-# Wed Jul 30 02:06:07 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 18:57:39 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -11,16 +11,17 @@ CONFIG_GENERIC_BUG=y
 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_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 # CONFIG_GENERIC_TIME is not set
 # CONFIG_GENERIC_CLOCKEVENTS is not set
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -45,6 +46,7 @@ CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CGROUPS=y
 CONFIG_CGROUP_DEBUG=y
 CONFIG_CGROUP_NS=y
+# CONFIG_CGROUP_FREEZER is not set
 CONFIG_CGROUP_DEVICE=y
 # CONFIG_GROUP_SCHED is not set
 CONFIG_CGROUP_CPUACCT=y
@@ -80,7 +82,9 @@ CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 # CONFIG_SLAB is not set
 # CONFIG_SLUB is not set
 CONFIG_SLOB=y
@@ -88,14 +92,12 @@ CONFIG_PROFILING=y
 # CONFIG_MARKERS is not set
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_RT_MUTEXES=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
@@ -126,6 +128,7 @@ CONFIG_IOSCHED_NOOP=y
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
 # CONFIG_CLASSIC_RCU is not set
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -192,10 +195,10 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 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=0
 CONFIG_NR_QUICK=2
 
@@ -228,7 +231,6 @@ CONFIG_SH_CMT=y
 CONFIG_SH_TIMER_IRQ=140
 CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_SH_CLK_MD=6
-# CONFIG_TICK_ONESHOT is not set
 
 #
 # CPU Frequency scaling
@@ -275,6 +277,7 @@ CONFIG_HZ=1000
 # CONFIG_SCHED_HRTICK is not set
 CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
@@ -307,11 +310,8 @@ CONFIG_BINFMT_ELF_FDPIC=y
 CONFIG_BINFMT_FLAT=y
 CONFIG_BINFMT_ZFLAT=y
 CONFIG_BINFMT_SHARED_FLAT=y
+# CONFIG_HAVE_AOUT is not set
 CONFIG_BINFMT_MISC=y
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -361,6 +361,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -381,11 +382,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
@@ -461,7 +461,6 @@ CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_PHYSMAP_START=0x20000000
 CONFIG_MTD_PHYSMAP_LEN=0x01000000
 CONFIG_MTD_PHYSMAP_BANKWIDTH=4
-# CONFIG_MTD_UCLINUX is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -531,6 +530,9 @@ CONFIG_SMC91X=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
@@ -609,6 +611,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # Multimedia devices
@@ -666,12 +670,15 @@ CONFIG_RTC_INTF_DEV=y
 #
 # 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
 
 #
@@ -680,6 +687,7 @@ CONFIG_RTC_INTF_DEV=y
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -687,10 +695,11 @@ CONFIG_RTC_DRV_SH=y
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_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_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_DNOTIFY is not set
@@ -755,6 +764,7 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -811,10 +821,19 @@ CONFIG_DEBUG_VM=y
 CONFIG_DEBUG_LIST=y
 # CONFIG_DEBUG_SG is not set
 CONFIG_FRAME_POINTER=y
-# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -828,12 +847,14 @@ CONFIG_DEBUG_STACK_USAGE=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 # CONFIG_CRYPTO_MANAGER is not set
 # CONFIG_CRYPTO_GF128MUL is not set
@@ -907,13 +928,17 @@ CONFIG_CRYPTO_ALGAPI=y
 #
 CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 CONFIG_CRC_CCITT=y
 CONFIG_CRC16=y
 # CONFIG_CRC_T10DIF is not set
index 4e30b70377e264d4ee82ec6694c2c48fb891962e..075f42ed5b09bcb0ade08d69b08d12e73dcbeb08 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26
-# Wed Jul 30 02:08:38 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 19:00:21 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -11,16 +11,17 @@ CONFIG_GENERIC_BUG=y
 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_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -71,22 +72,22 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 # CONFIG_SHMEM is not set
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
@@ -117,6 +118,7 @@ CONFIG_DEFAULT_DEADLINE=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="deadline"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -186,12 +188,13 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 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=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -225,7 +228,6 @@ CONFIG_SH_7343_SOLUTION_ENGINE=y
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=27000000
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -261,6 +263,7 @@ CONFIG_HZ=250
 # CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
@@ -284,11 +287,9 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000
 # 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
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -334,6 +335,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -354,11 +356,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
@@ -529,6 +530,9 @@ CONFIG_SMC91X=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
@@ -632,6 +636,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # Multimedia devices
@@ -655,11 +661,11 @@ CONFIG_VIDEO_V4L2=y
 CONFIG_VIDEO_V4L1=y
 CONFIG_VIDEO_CAPTURE_DRIVERS=y
 # CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
 CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
 # CONFIG_VIDEO_VIVI is not set
 # CONFIG_VIDEO_CPIA is not set
 # CONFIG_SOC_CAMERA is not set
-# CONFIG_VIDEO_SH_MOBILE_CEU is not set
 CONFIG_RADIO_ADAPTERS=y
 # CONFIG_DAB is not set
 
@@ -671,6 +677,7 @@ CONFIG_RADIO_ADAPTERS=y
 CONFIG_FB=y
 CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
 CONFIG_FB_CFB_FILLRECT=m
 CONFIG_FB_CFB_COPYAREA=m
 CONFIG_FB_CFB_IMAGEBLIT=m
@@ -692,6 +699,7 @@ CONFIG_FB_CFB_IMAGEBLIT=m
 # CONFIG_FB_S1D13XXX is not set
 CONFIG_FB_SH_MOBILE_LCDC=m
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -706,6 +714,7 @@ CONFIG_DUMMY_CONSOLE=y
 # CONFIG_FRAMEBUFFER_CONSOLE is not set
 # CONFIG_LOGO is not set
 CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
 CONFIG_SND=y
 CONFIG_SND_TIMER=y
 CONFIG_SND_PCM=y
@@ -734,6 +743,12 @@ 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
@@ -742,6 +757,7 @@ CONFIG_HID=y
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -753,12 +769,13 @@ CONFIG_EXT3_FS=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_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_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_DNOTIFY is not set
@@ -787,6 +804,7 @@ CONFIG_FS_MBCACHE=y
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
@@ -837,6 +855,7 @@ CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -868,6 +887,11 @@ CONFIG_FRAME_WARN=1024
 # 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
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 CONFIG_EARLY_SCIF_CONSOLE=y
@@ -880,12 +904,14 @@ CONFIG_EARLY_PRINTK=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 # CONFIG_CRYPTO_MANAGER is not set
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -958,13 +984,17 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
index 80c1c72edb562593636dfc8e7c06e80c68479d15..db9cacd7c4e70eaed88ec7850b77b699e85d05e5 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26
-# Wed Jul 30 02:12:32 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 19:03:29 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -11,16 +11,17 @@ CONFIG_GENERIC_BUG=y
 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_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 # CONFIG_GENERIC_TIME is not set
 # CONFIG_GENERIC_CLOCKEVENTS is not set
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -58,21 +59,20 @@ CONFIG_ANON_INODES=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
+CONFIG_AIO=y
 # CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=1
@@ -96,6 +96,7 @@ CONFIG_IOSCHED_NOOP=y
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -161,10 +162,10 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 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=0
 CONFIG_NR_QUICK=2
 
@@ -196,7 +197,6 @@ CONFIG_SH_CMT=y
 CONFIG_SH_TIMER_IRQ=86
 CONFIG_SH_PCLK_FREQ=31250000
 CONFIG_SH_CLK_MD=5
-# CONFIG_TICK_ONESHOT is not set
 
 #
 # CPU Frequency scaling
@@ -228,6 +228,7 @@ CONFIG_HZ=100
 # CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
@@ -253,11 +254,8 @@ 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
-
-#
-# Networking
-#
 # CONFIG_NET is not set
 
 #
@@ -328,7 +326,6 @@ CONFIG_MTD_PHYSMAP_START=0xa0000000
 CONFIG_MTD_PHYSMAP_LEN=0x01000000
 CONFIG_MTD_PHYSMAP_BANKWIDTH=2
 # CONFIG_MTD_SOLUTIONENGINE is not set
-# CONFIG_MTD_UCLINUX is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -455,6 +452,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # Multimedia devices
@@ -488,6 +487,12 @@ 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=y
 CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
@@ -496,6 +501,10 @@ CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
 
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
@@ -507,16 +516,18 @@ CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_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_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
@@ -589,6 +600,11 @@ CONFIG_FRAME_WARN=1024
 # 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
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -597,6 +613,7 @@ CONFIG_FRAME_WARN=1024
 # Security options
 #
 # CONFIG_KEYS is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 # CONFIG_CRYPTO is not set
 
@@ -604,7 +621,6 @@ CONFIG_FRAME_WARN=1024
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
index 490dcbc2ce330af9262b8e8b55d94e0a3aacece8..d88190fdd7c12956bf5d2984a94779d0851d053f 100644 (file)
@@ -1,34 +1,36 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.21-rc5
-# Thu Apr 26 09:16:31 2007
+# Linux kernel version: 2.6.27
+# Wed Oct 22 19:04:52 2008
 #
 CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_BUG=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SWAP is not set
@@ -36,11 +38,13 @@ CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
-CONFIG_SYSFS_DEPRECATED=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
 # CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -53,32 +57,45 @@ CONFIG_UID16=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
-CONFIG_SLAB=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=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_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 # CONFIG_MODULE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
-
-#
-# Block layer
-#
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -92,59 +109,18 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
 #
-CONFIG_SOLUTION_ENGINE=y
-CONFIG_SH_SOLUTION_ENGINE=y
-# CONFIG_SH_7751_SOLUTION_ENGINE is not set
-# CONFIG_SH_7780_SOLUTION_ENGINE is not set
-# CONFIG_SH_7300_SOLUTION_ENGINE is not set
-# CONFIG_SH_7343_SOLUTION_ENGINE is not set
-# CONFIG_SH_73180_SOLUTION_ENGINE is not set
-# CONFIG_SH_7722_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_HP6XX is not set
-# CONFIG_SH_SATURN is not set
-# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_MPC1211 is not set
-# CONFIG_SH_SH03 is not set
-# CONFIG_SH_SECUREEDGE5410 is not set
-# CONFIG_SH_HS7751RVOIP is not set
-# CONFIG_SH_7710VOIPGW is not set
-# CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_HIGHLANDER is not set
-# CONFIG_SH_EDOSK7705 is not set
-# CONFIG_SH_SH4202_MICRODEV is not set
-# CONFIG_SH_LANDISK is not set
-# CONFIG_SH_TITAN is not set
-# CONFIG_SH_SHMIN is not set
-# CONFIG_SH_7206_SOLUTION_ENGINE is not set
-# CONFIG_SH_7619_SOLUTION_ENGINE is not set
-# CONFIG_SH_LBOX_RE2 is not set
-# CONFIG_SH_UNKNOWN is not set
-
-#
-# Processor selection
-#
 CONFIG_CPU_SH3=y
-
-#
-# SH-2 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7604 is not set
 # CONFIG_CPU_SUBTYPE_SH7619 is not set
-
-#
-# SH-2A Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
 # CONFIG_CPU_SUBTYPE_SH7206 is not set
-
-#
-# SH-3 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7300 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
 CONFIG_CPU_SUBTYPE_SH7705=y
 # CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
@@ -152,10 +128,8 @@ CONFIG_CPU_SUBTYPE_SH7705=y
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
 # CONFIG_CPU_SUBTYPE_SH7710 is not set
 # CONFIG_CPU_SUBTYPE_SH7712 is not set
-
-#
-# SH-4 Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
 # CONFIG_CPU_SUBTYPE_SH7091 is not set
 # CONFIG_CPU_SUBTYPE_SH7750R is not set
@@ -164,63 +138,62 @@ CONFIG_CPU_SUBTYPE_SH7705=y
 # CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
 # CONFIG_CPU_SUBTYPE_SH4_202 is not set
-
-#
-# ST40 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
-# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-
-#
-# SH-4A Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
-
-#
-# SH4AL-DSP Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
 
 #
 # Memory management options
 #
+CONFIG_QUICKLIST=y
 CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x02000000
+CONFIG_29BIT=y
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_STATIC=y
+CONFIG_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=0
+CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
 #
 CONFIG_SH7705_CACHE_32KB=y
 # CONFIG_SH_DIRECT_MAPPED is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
-CONFIG_CF_ENABLER=y
-# CONFIG_CF_AREA5 is not set
-CONFIG_CF_AREA6=y
-# CONFIG_CF_AREA4 is not set
-CONFIG_CF_BASE_ADDR=0xb8000000
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
 
 #
 # Processor features
@@ -228,18 +201,27 @@ CONFIG_CF_BASE_ADDR=0xb8000000
 CONFIG_CPU_LITTLE_ENDIAN=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 # CONFIG_SH_FPU_EMU is not set
-# CONFIG_SH_DSP is not set
 # CONFIG_SH_ADC is not set
 CONFIG_CPU_HAS_INTEVT=y
 CONFIG_CPU_HAS_IPR_IRQ=y
 CONFIG_CPU_HAS_SR_RB=y
 
+#
+# Board support
+#
+CONFIG_SOLUTION_ENGINE=y
+CONFIG_SH_SOLUTION_ENGINE=y
+# CONFIG_SH_EDOSK7705 is not set
+
 #
 # Timer and clock configuration
 #
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=33333333
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 
 #
 # CPU Frequency scaling
@@ -254,7 +236,6 @@ CONFIG_SH_PCLK_FREQ=33333333
 #
 # Companion Chips
 #
-# CONFIG_HD6446X_SERIES is not set
 
 #
 # Additional SuperH Device Drivers
@@ -270,55 +251,45 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
-# CONFIG_SMP is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
-CONFIG_PREEMPT_BKL=y
+# CONFIG_PREEMPT_RCU is not set
+CONFIG_GUSA=y
+# CONFIG_GUSA_RB is not set
 
 #
 # Boot options
 #
 CONFIG_ZERO_PAGE_OFFSET=0x00001000
 CONFIG_BOOT_LINK_OFFSET=0x00800000
-# CONFIG_UBC_WAKEUP is not set
 # CONFIG_CMDLINE_BOOL is not set
 
 #
 # Bus options
 #
-# CONFIG_PCI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-
-#
-# PCI Hotplug Support
-#
+CONFIG_CF_ENABLER=y
+# CONFIG_CF_AREA5 is not set
+CONFIG_CF_AREA6=y
+CONFIG_CF_BASE_ADDR=0xb8000000
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 
 #
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_FLAT is not set
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
-
-#
-# Power management options (EXPERIMENTAL)
-#
-# CONFIG_PM is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -326,6 +297,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -347,6 +319,7 @@ CONFIG_IP_PNP_RARP=y
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -354,27 +327,14 @@ CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -384,10 +344,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
 # CONFIG_NET_SCHED is not set
 
 #
@@ -395,9 +351,19 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -409,21 +375,14 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
 # CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
 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
@@ -436,6 +395,7 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
 # CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -461,7 +421,6 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -484,47 +443,29 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 # CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
 # CONFIG_MTD_ONENAND is not set
 
 #
-# Parallel port support
+# UBI - Unsorted block images
 #
+# CONFIG_MTD_UBI is not set
 # CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNPACPI is not set
-
-#
-# Block devices
-#
+CONFIG_BLK_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=8192
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-
-#
-# Misc devices
-#
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
 #
@@ -532,73 +473,41 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
 # CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
 # CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-
-#
-# PHY device support
-#
+# CONFIG_VETH is not set
 # CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
+# CONFIG_AX88796 is not set
 CONFIG_STNIC=y
 # CONFIG_SMC91X is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
+# CONFIG_SMC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+
+#
+# Wireless LAN
+#
+# 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=y
 # CONFIG_PPP_MULTILINK is not set
@@ -609,21 +518,13 @@ CONFIG_PPP_DEFLATE=y
 # CONFIG_PPP_BSDCOMP is not set
 # CONFIG_PPP_MPPE is not set
 # CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
 # CONFIG_SLIP is not set
 CONFIG_SLHC=y
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
 # CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
@@ -631,13 +532,13 @@ CONFIG_SLHC=y
 #
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
 #
 # CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
@@ -647,6 +548,7 @@ CONFIG_INPUT=y
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
@@ -664,6 +566,7 @@ CONFIG_SERIO=y
 # Character devices
 #
 # CONFIG_VT is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -681,153 +584,110 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
 CONFIG_HW_RANDOM=y
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
 # CONFIG_I2C is not set
-
-#
-# SPI support
-#
 # CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
 # CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
+# CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
 # CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 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
 
 #
-# Digital Video Broadcasting Devices
+# Multimedia drivers
 #
-# CONFIG_DVB is not set
+# CONFIG_DAB is not set
 
 #
 # Graphics support
 #
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Sound
+# Display device support
 #
+# CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_SOUND is not set
-
-#
-# HID Devices
-#
+CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
 
 #
-# USB support
+# Special HID drivers
 #
-# CONFIG_USB_ARCH_HAS_HCD is not set
+CONFIG_HID_COMPAT=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 # CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# 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
 #
 
 #
-# USB Gadget Support
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 # CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
 # CONFIG_MMC is not set
-
-#
-# LED devices
-#
+# CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
-# Auxiliary Display support
-#
-
-#
-# Virtualization
-#
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -836,18 +696,16 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_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_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
@@ -871,11 +729,11 @@ CONFIG_DNOTIFY=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 # CONFIG_SYSFS is not set
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 
 #
 # Miscellaneous filesystems
@@ -890,31 +748,33 @@ CONFIG_RAMFS=y
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
 # CONFIG_JFFS2_SUMMARY is not set
 # CONFIG_JFFS2_FS_XATTR is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_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
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -922,40 +782,34 @@ CONFIG_SUNRPC=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
 # CONFIG_NLS is not set
 
-#
-# Distributed Lock Manager
-#
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
 #
 # Kernel hacking
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_SH_KGDB is not set
@@ -964,11 +818,92 @@ CONFIG_LOG_BUF_SHIFT=14
 # Security options
 #
 # CONFIG_KEYS is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
 
 #
-# Cryptographic options
+# Random Number Generation
 #
-# CONFIG_CRYPTO is not set
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
@@ -976,10 +911,14 @@ CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=y
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index 7be79cd04eb0385936d2f7d01642988813bf7d83..869ab1737debbc7cdd3c1095e7433075f392b257 100644 (file)
@@ -1,24 +1,26 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc6
-# Wed Jun 18 16:36:08 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 19:08:12 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 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_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -51,7 +53,6 @@ CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -68,17 +69,22 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 # CONFIG_SHMEM is not set
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=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_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 CONFIG_TINY_SHMEM=y
@@ -88,12 +94,13 @@ CONFIG_MODULES=y
 # CONFIG_MODULE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-# CONFIG_KMOD 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_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -108,6 +115,7 @@ CONFIG_IOSCHED_NOOP=y
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -167,6 +175,7 @@ CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -174,12 +183,13 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 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=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -207,7 +217,6 @@ CONFIG_CPU_HAS_DSP=y
 #
 CONFIG_SOLUTION_ENGINE=y
 CONFIG_SH_SOLUTION_ENGINE=y
-# CONFIG_SH_AP325RXA is not set
 
 #
 # Timer and clock configuration
@@ -215,7 +224,6 @@ CONFIG_SH_SOLUTION_ENGINE=y
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=66666666
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -251,6 +259,7 @@ CONFIG_HZ=250
 # CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -279,11 +288,9 @@ CONFIG_CF_BASE_ADDR=0xb8000000
 # 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
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -297,6 +304,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_XFRM_MIGRATE is not set
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=y
 CONFIG_NET_KEY=y
 # CONFIG_NET_KEY_MIGRATE is not set
 CONFIG_INET=y
@@ -341,6 +349,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -359,7 +368,7 @@ CONFIG_NET_SCH_CBQ=y
 CONFIG_NET_SCH_HTB=y
 CONFIG_NET_SCH_HFSC=y
 CONFIG_NET_SCH_PRIO=y
-# CONFIG_NET_SCH_RR is not set
+# CONFIG_NET_SCH_MULTIQ is not set
 CONFIG_NET_SCH_RED=y
 CONFIG_NET_SCH_SFQ=y
 CONFIG_NET_SCH_TEQL=y
@@ -395,12 +404,11 @@ CONFIG_NET_SCH_FIFO=y
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
 CONFIG_FIB_RULES=y
-
-#
-# Wireless
-#
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
@@ -418,6 +426,8 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_DEBUG_DRIVER is not set
 # CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
@@ -504,6 +514,7 @@ CONFIG_BLK_DEV=y
 # 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_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -550,6 +561,7 @@ CONFIG_SCSI_WAIT_SCAN=m
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -558,7 +570,6 @@ CONFIG_ATA_SFF=y
 CONFIG_PATA_PLATFORM=y
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -593,9 +604,11 @@ CONFIG_SH_ETH=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 CONFIG_NETDEV_1000=y
-# CONFIG_E1000E_ENABLED is not set
 CONFIG_NETDEV_10000=y
 
 #
@@ -657,6 +670,7 @@ CONFIG_HW_RANDOM=m
 # 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
 
 #
@@ -668,8 +682,11 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # Multimedia devices
@@ -699,10 +716,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
@@ -712,6 +725,10 @@ CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
 
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
@@ -734,7 +751,9 @@ CONFIG_LEDS_TRIGGERS=y
 # CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -748,12 +767,13 @@ CONFIG_EXT3_FS=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_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=y
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_DNOTIFY is not set
@@ -782,6 +802,7 @@ CONFIG_FS_POSIX_ACL=y
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
@@ -813,6 +834,7 @@ CONFIG_JFFS2_RTIME=y
 CONFIG_CRAMFS=y
 # 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
@@ -822,12 +844,12 @@ CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 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_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -877,13 +899,26 @@ CONFIG_SCHED_DEBUG=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_LIST is not set
 # CONFIG_DEBUG_SG is not set
 CONFIG_FRAME_POINTER=y
-# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -899,16 +934,19 @@ CONFIG_FRAME_POINTER=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_AEAD=y
 CONFIG_CRYPTO_BLKCIPHER=y
 CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_RNG=y
 CONFIG_CRYPTO_MANAGER=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -947,6 +985,10 @@ CONFIG_CRYPTO_HMAC=y
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 CONFIG_CRYPTO_SHA1=y
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
@@ -977,15 +1019,20 @@ CONFIG_CRYPTO_DES=y
 #
 CONFIG_CRYPTO_DEFLATE=y
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 CONFIG_CRC_CCITT=y
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index f3d4ca0caa46e540fab1601d98a683f75b5bb3f6..b52be14074d8336f0faaea7e671889c25c9b670e 100644 (file)
@@ -1,24 +1,26 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.25-rc5
-# Fri Mar 21 12:05:31 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 19:12:06 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 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_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -71,30 +73,38 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 # CONFIG_SHMEM is not set
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=1
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 # CONFIG_MODULE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-# CONFIG_KMOD 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_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -109,6 +119,7 @@ CONFIG_IOSCHED_NOOP=y
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -136,6 +147,7 @@ CONFIG_CPU_SUBTYPE_SH7721=y
 # CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
 # CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
 # CONFIG_CPU_SUBTYPE_SH7763 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -165,7 +177,9 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -173,11 +187,13 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+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=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -211,7 +227,6 @@ CONFIG_SH_7721_SOLUTION_ENGINE=y
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=33333333
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -247,6 +262,7 @@ CONFIG_HZ=250
 # CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -275,11 +291,9 @@ CONFIG_CF_BASE_ADDR=0xb8000000
 # 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
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -293,6 +307,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_XFRM_MIGRATE is not set
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=y
 CONFIG_NET_KEY=y
 # CONFIG_NET_KEY_MIGRATE is not set
 CONFIG_INET=y
@@ -330,8 +345,6 @@ CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
@@ -339,6 +352,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -357,7 +371,7 @@ CONFIG_NET_SCH_CBQ=y
 CONFIG_NET_SCH_HTB=y
 CONFIG_NET_SCH_HFSC=y
 CONFIG_NET_SCH_PRIO=y
-# CONFIG_NET_SCH_RR is not set
+# CONFIG_NET_SCH_MULTIQ is not set
 CONFIG_NET_SCH_RED=y
 CONFIG_NET_SCH_SFQ=y
 CONFIG_NET_SCH_TEQL=y
@@ -393,12 +407,11 @@ CONFIG_NET_SCH_FIFO=y
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
 CONFIG_FIB_RULES=y
-
-#
-# Wireless
-#
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
@@ -416,6 +429,8 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_DEBUG_DRIVER is not set
 # CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
@@ -426,6 +441,7 @@ CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -502,6 +518,7 @@ CONFIG_BLK_DEV=y
 # 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_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -546,13 +563,15 @@ CONFIG_SCSI_WAIT_SCAN=m
 # 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_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
+CONFIG_SATA_PMP=y
+CONFIG_ATA_SFF=y
 # CONFIG_SATA_MV is not set
 CONFIG_PATA_PLATFORM=y
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -561,7 +580,6 @@ CONFIG_NETDEVICES=y
 # CONFIG_VETH is not set
 # CONFIG_NET_ETHERNET is not set
 CONFIG_NETDEV_1000=y
-# CONFIG_E1000E_ENABLED is not set
 CONFIG_NETDEV_10000=y
 
 #
@@ -569,6 +587,7 @@ CONFIG_NETDEV_10000=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
 
 #
 # USB Network Adapters
@@ -591,7 +610,7 @@ CONFIG_NETDEV_10000=y
 # Input device support
 #
 CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
 
 #
@@ -620,6 +639,7 @@ CONFIG_INPUT_MOUSE=y
 # CONFIG_MOUSE_PS2 is not set
 # CONFIG_MOUSE_SERIAL is not set
 # CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
@@ -636,6 +656,7 @@ CONFIG_INPUT_MOUSE=y
 # Character devices
 #
 # CONFIG_VT is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -659,12 +680,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 # CONFIG_I2C is not set
-
-#
-# SPI support
-#
 # CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
@@ -680,13 +696,26 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # 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
 
 #
@@ -701,10 +730,6 @@ CONFIG_SSB_POSSIBLE=y
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
@@ -715,9 +740,36 @@ CONFIG_HID=y
 # USB Input Devices
 #
 CONFIG_USB_HID=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
+# CONFIG_HID_PID is not set
 # CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_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_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_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_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -733,11 +785,16 @@ CONFIG_USB=y
 CONFIG_USB_DEVICE_CLASS=y
 # 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 is not set
+CONFIG_USB_MON=y
 
 #
 # USB Host Controller Drivers
 #
+# CONFIG_USB_C67X00_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
 # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
@@ -750,6 +807,8 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 #
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -771,6 +830,7 @@ CONFIG_USB_STORAGE=y
 # 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
 
 #
@@ -778,7 +838,6 @@ CONFIG_USB_STORAGE=y
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-CONFIG_USB_MON=y
 
 #
 # USB port drivers
@@ -791,7 +850,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_SEVSEG is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
@@ -806,6 +865,8 @@ CONFIG_USB_MON=y
 # CONFIG_USB_LD is not set
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -822,12 +883,12 @@ CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_TRIGGERS=y
 # CONFIG_LEDS_TRIGGER_TIMER is not set
 # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
-
-#
-# Userspace I/O
-#
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -841,14 +902,14 @@ CONFIG_EXT3_FS=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_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=y
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
@@ -879,6 +940,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
@@ -910,6 +972,7 @@ CONFIG_JFFS2_RTIME=y
 CONFIG_CRAMFS=y
 # 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
@@ -971,6 +1034,7 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
@@ -981,6 +1045,7 @@ CONFIG_DEBUG_KERNEL=y
 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_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
@@ -994,13 +1059,27 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_KOBJECT is not set
 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_LIST is not set
 # CONFIG_DEBUG_SG is not set
 CONFIG_FRAME_POINTER=y
-# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -1016,55 +1095,96 @@ CONFIG_FRAME_POINTER=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_AEAD=y
 CONFIG_CRYPTO_BLKCIPHER=y
-# CONFIG_CRYPTO_SEQIV is not set
 CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_RNG=y
 CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# 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=y
+# 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=y
 # CONFIG_CRYPTO_XCBC is not set
-# CONFIG_CRYPTO_NULL is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 CONFIG_CRYPTO_SHA1=y
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_ECB is not set
-CONFIG_CRYPTO_CBC=y
-# CONFIG_CRYPTO_PCBC is not set
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_XTS is not set
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-CONFIG_CRYPTO_DES=y
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_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_TEA is not set
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_SEED is not set
 # CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_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=y
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_TEST is not set
-CONFIG_CRYPTO_AUTHENC=y
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 
 #
@@ -1073,6 +1193,7 @@ CONFIG_CRYPTO_HW=y
 CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=y
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index 8e6a6baf5d27cc0d64dd4babde53559bf1d94996..e6df51f098f04dcbe8199809594374884b7311f8 100644 (file)
@@ -1,53 +1,56 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.22-rc4
-# Wed Jun 20 18:08:04 2007
+# Linux kernel version: 2.6.27
+# Wed Oct 22 19:15:10 2008
 #
 CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_BUG=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -61,6 +64,7 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_ANON_INODES=y
@@ -69,32 +73,41 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+# CONFIG_OPROFILE is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
 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_KMOD=y
-
-#
-# Block layer
-#
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -108,6 +121,8 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -117,8 +132,10 @@ CONFIG_CPU_SH4A=y
 CONFIG_CPU_SH4AL_DSP=y
 CONFIG_CPU_SHX2=y
 # CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
 # CONFIG_CPU_SUBTYPE_SH7206 is not set
-# CONFIG_CPU_SUBTYPE_SH7300 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
 # CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
@@ -126,6 +143,8 @@ CONFIG_CPU_SHX2=y
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
 # CONFIG_CPU_SUBTYPE_SH7710 is not set
 # CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
 # CONFIG_CPU_SUBTYPE_SH7091 is not set
 # CONFIG_CPU_SUBTYPE_SH7750R is not set
@@ -134,14 +153,17 @@ CONFIG_CPU_SHX2=y
 # CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
 # CONFIG_CPU_SUBTYPE_SH4_202 is not set
-# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
-# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 CONFIG_CPU_SUBTYPE_SH7722=y
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
 
 #
 # Memory management options
@@ -151,6 +173,7 @@ CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_29BIT=y
 # CONFIG_X2TLB is not set
 CONFIG_VSYSCALL=y
 CONFIG_NUMA=y
@@ -161,14 +184,18 @@ CONFIG_MAX_ACTIVE_REGIONS=2
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_HUGETLB_PAGE_SIZE_64K=y
 # CONFIG_HUGETLB_PAGE_SIZE_256K is not set
 # CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
 # CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
 # CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_512MB is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 # CONFIG_FLATMEM_MANUAL is not set
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -181,34 +208,38 @@ CONFIG_SPARSEMEM_STATIC=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 # CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
 #
 # CONFIG_SH_DIRECT_MAPPED is not set
-# CONFIG_SH_WRITETHROUGH is not set
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
 
 #
 # Processor features
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
 # CONFIG_CPU_BIG_ENDIAN is not set
-# CONFIG_SH_FPU is not set
 # CONFIG_SH_FPU_EMU is not set
 CONFIG_SH_DSP=y
 CONFIG_SH_STORE_QUEUES=y
 CONFIG_CPU_HAS_INTEVT=y
-CONFIG_CPU_HAS_INTC_IRQ=y
 CONFIG_CPU_HAS_SR_RB=y
 CONFIG_CPU_HAS_PTEA=y
+CONFIG_CPU_HAS_DSP=y
 
 #
 # Board support
 #
 CONFIG_SOLUTION_ENGINE=y
 CONFIG_SH_7722_SOLUTION_ENGINE=y
+# CONFIG_SH_MIGOR is not set
 
 #
 # Timer and clock configuration
@@ -219,6 +250,7 @@ CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 
 #
 # CPU Frequency scaling
@@ -248,19 +280,21 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
 CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
-CONFIG_PREEMPT_BKL=y
+# CONFIG_PREEMPT_RCU is not set
+CONFIG_GUSA=y
 
 #
 # Boot options
 #
 CONFIG_ZERO_PAGE_OFFSET=0x00001000
 CONFIG_BOOT_LINK_OFFSET=0x00800000
-# CONFIG_UBC_WAKEUP is not set
 # CONFIG_CMDLINE_BOOL is not set
 
 #
@@ -271,21 +305,15 @@ CONFIG_CF_ENABLER=y
 CONFIG_CF_AREA6=y
 CONFIG_CF_BASE_ADDR=0xb8000000
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
 # CONFIG_PCCARD is not set
 
 #
 # 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
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -298,6 +326,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -316,6 +345,7 @@ CONFIG_IP_FIB_HASH=y
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -323,8 +353,6 @@ CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
@@ -332,6 +360,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -341,10 +370,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
 # CONFIG_NET_SCHED is not set
 
 #
@@ -352,18 +377,19 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
 # CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -372,44 +398,29 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
 # CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
 # CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNPACPI is not set
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-
-#
-# Misc devices
-#
-# CONFIG_BLINK 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_HAVE_IDE=y
 # CONFIG_IDE is not set
 
 #
@@ -417,6 +428,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
 # CONFIG_SCSI_TGT is not set
 # CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
@@ -446,40 +458,41 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
 # CONFIG_SCSI_SAS_LIBSAS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
+CONFIG_SATA_PMP=y
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_MV is not set
 CONFIG_PATA_PLATFORM=y
-
-#
-# Multi-device support (RAID and LVM)
-#
 # CONFIG_MD is not set
-
-#
-# Network device support
-#
 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 is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
+# CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 CONFIG_SMC91X=y
+# CONFIG_SMC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
 
@@ -488,22 +501,14 @@ CONFIG_NETDEV_10000=y
 #
 # 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
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
 # CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
@@ -511,6 +516,7 @@ CONFIG_NETDEV_10000=y
 #
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -520,7 +526,6 @@ CONFIG_INPUT_MOUSEDEV=y
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
@@ -534,6 +539,7 @@ CONFIG_KEYBOARD_ATKBD=y
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SH_KEYSC is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
@@ -554,6 +560,7 @@ CONFIG_SERIO_LIBPS2=y
 # Character devices
 #
 # CONFIG_VT is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -572,119 +579,106 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
 CONFIG_HW_RANDOM=y
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
 # CONFIG_I2C is not set
-
-#
-# SPI support
-#
 # CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
 # CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
 # CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # Multimedia devices
 #
+
+#
+# Multimedia core support
+#
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_VIDEO_MEDIA is not set
 
 #
-# Graphics support
+# Multimedia drivers
 #
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_DAB=y
 
 #
-# Display device support
+# Graphics support
 #
-# CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Sound
+# Display device support
 #
+# CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_SOUND is not set
-
-#
-# HID Devices
-#
+CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
 
 #
-# USB support
+# Special HID drivers
 #
-# CONFIG_USB_ARCH_HAS_HCD is not set
+CONFIG_HID_COMPAT=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 # CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# 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
 #
 
 #
-# USB Gadget Support
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 # CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
-
-#
-# LED devices
-#
+# CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
+# CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_HCTOSYS=y
@@ -700,10 +694,6 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
 # CONFIG_RTC_DRV_TEST is not set
 
-#
-# I2C RTC drivers
-#
-
 #
 # SPI RTC drivers
 #
@@ -711,28 +701,24 @@ CONFIG_RTC_INTF_DEV=y
 #
 # 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_SH=y
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -744,22 +730,20 @@ CONFIG_EXT3_FS=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_EXT4_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # 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_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
@@ -783,12 +767,12 @@ CONFIG_DNOTIFY=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_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
-CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -803,14 +787,14 @@ CONFIG_RAMFS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_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
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
 # CONFIG_SMB_FS is not set
@@ -818,42 +802,39 @@ CONFIG_RAMFS=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
 # CONFIG_NLS is not set
-
-#
-# Distributed Lock Manager
-#
 # CONFIG_DLM is not set
 
-#
-# Profiling support
-#
-CONFIG_PROFILING=y
-# CONFIG_OPROFILE is not set
-
 #
 # Kernel hacking
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
 # CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
 # CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
 CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_EARLY_PRINTK is not set
@@ -864,11 +845,92 @@ CONFIG_SH_STANDARD_BIOS=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
 
 #
-# Cryptographic options
+# Random Number Generation
 #
-# CONFIG_CRYPTO is not set
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
@@ -876,8 +938,10 @@ CONFIG_SH_STANDARD_BIOS=y
 CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
index 167786f9a9bd1687fddbe50ef47e1679bcc63668..a577099c3247aaf3a9fe467a9bd05f268b474223 100644 (file)
@@ -1,48 +1,55 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20-rc2
-# Thu Dec 28 23:15:49 2006
+# Linux kernel version: 2.6.27
+# Wed Oct 22 19:17:29 2008
 #
 CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
-CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
@@ -54,33 +61,47 @@ CONFIG_KALLSYMS=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
-CONFIG_SLAB=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 # CONFIG_MODULE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
-
-#
-# Block layer
-#
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -94,68 +115,27 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
 #
-CONFIG_SOLUTION_ENGINE=y
-CONFIG_SH_SOLUTION_ENGINE=y
-# CONFIG_SH_7751_SOLUTION_ENGINE is not set
-# CONFIG_SH_7300_SOLUTION_ENGINE is not set
-# CONFIG_SH_7343_SOLUTION_ENGINE is not set
-# CONFIG_SH_73180_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_HP6XX is not set
-# CONFIG_SH_EC3104 is not set
-# CONFIG_SH_SATURN is not set
-# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_MPC1211 is not set
-# CONFIG_SH_SH03 is not set
-# CONFIG_SH_SECUREEDGE5410 is not set
-# CONFIG_SH_HS7751RVOIP is not set
-# CONFIG_SH_7710VOIPGW is not set
-# CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_R7780RP is not set
-# CONFIG_SH_EDOSK7705 is not set
-# CONFIG_SH_SH4202_MICRODEV is not set
-# CONFIG_SH_LANDISK is not set
-# CONFIG_SH_TITAN is not set
-# CONFIG_SH_SHMIN is not set
-# CONFIG_SH_7206_SOLUTION_ENGINE is not set
-# CONFIG_SH_7619_SOLUTION_ENGINE is not set
-# CONFIG_SH_UNKNOWN is not set
-
-#
-# Processor selection
-#
 CONFIG_CPU_SH4=y
-
-#
-# SH-2 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7604 is not set
 # CONFIG_CPU_SUBTYPE_SH7619 is not set
-
-#
-# SH-2A Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
 # CONFIG_CPU_SUBTYPE_SH7206 is not set
-
-#
-# SH-3 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7300 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
 # CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
 # CONFIG_CPU_SUBTYPE_SH7710 is not set
-
-#
-# SH-4 Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
 CONFIG_CPU_SUBTYPE_SH7750=y
 # CONFIG_CPU_SUBTYPE_SH7091 is not set
 # CONFIG_CPU_SUBTYPE_SH7750R is not set
@@ -164,58 +144,61 @@ CONFIG_CPU_SUBTYPE_SH7750=y
 # CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
 # CONFIG_CPU_SUBTYPE_SH4_202 is not set
-
-#
-# ST40 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
-# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-
-#
-# SH-4A Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
-
-#
-# SH4AL-DSP Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
 
 #
 # Memory management options
 #
+CONFIG_QUICKLIST=y
 CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x02000000
+CONFIG_29BIT=y
 CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_STATIC=y
+CONFIG_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=0
+CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
 #
 # CONFIG_SH_DIRECT_MAPPED is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
-CONFIG_CF_ENABLER=y
-# CONFIG_CF_AREA5 is not set
-CONFIG_CF_AREA6=y
-CONFIG_CF_BASE_ADDR=0xb8000000
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
 
 #
 # Processor features
@@ -223,19 +206,28 @@ CONFIG_CF_BASE_ADDR=0xb8000000
 CONFIG_CPU_LITTLE_ENDIAN=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_SH_FPU=y
-# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
 CONFIG_CPU_HAS_INTEVT=y
-CONFIG_CPU_HAS_INTC_IRQ=y
+CONFIG_CPU_HAS_IPR_IRQ=y
 CONFIG_CPU_HAS_SR_RB=y
 CONFIG_CPU_HAS_PTEA=y
+CONFIG_CPU_HAS_FPU=y
 
 #
-# Timer support
+# Board support
+#
+CONFIG_SOLUTION_ENGINE=y
+CONFIG_SH_SOLUTION_ENGINE=y
+
+#
+# Timer and clock configuration
 #
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=33333333
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 
 #
 # CPU Frequency scaling
@@ -250,12 +242,11 @@ CONFIG_SH_PCLK_FREQ=33333333
 #
 # Companion Chips
 #
-# CONFIG_HD6446X_SERIES is not set
-CONFIG_HEARTBEAT=y
 
 #
 # Additional SuperH Device Drivers
 #
+CONFIG_HEARTBEAT=y
 # CONFIG_PUSH_SWITCH is not set
 
 #
@@ -266,11 +257,15 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
-# CONFIG_SMP is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_GUSA=y
+# CONFIG_GUSA_RB is not set
 
 #
 # Boot options
@@ -283,43 +278,32 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000
 #
 # Bus options
 #
-# CONFIG_PCI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-
-#
-# PCI Hotplug Support
-#
+CONFIG_CF_ENABLER=y
+# CONFIG_CF_AREA5 is not set
+CONFIG_CF_AREA6=y
+CONFIG_CF_BASE_ADDR=0xb8000000
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 
 #
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_FLAT is not set
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
-
-#
-# Power management options (EXPERIMENTAL)
-#
-# CONFIG_PM is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -342,6 +326,7 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -349,27 +334,14 @@ CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -379,10 +351,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
 # CONFIG_NET_SCHED is not set
 
 #
@@ -390,9 +358,19 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -404,32 +382,27 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
 # CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
 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=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
@@ -455,7 +428,6 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 CONFIG_MTD_ROM=y
 # CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -478,75 +450,53 @@ CONFIG_MTD_ROM=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 # CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
 # CONFIG_MTD_ONENAND is not set
 
 #
-# Parallel port support
+# UBI - Unsorted block images
 #
+# CONFIG_MTD_UBI is not set
 # CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-
-#
-# Misc devices
-#
-# CONFIG_TIFM_CORE is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
 
 #
-# Please see Documentation/ide.txt for help/info on IDE drives
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
 # 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 is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
 
 #
 # IDE chipset support/bugfixes
 #
-# CONFIG_IDE_GENERIC is not set
-# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
 # CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
 # CONFIG_SCSI_TGT is not set
 # CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
@@ -568,6 +518,7 @@ CONFIG_SCSI_PROC_FS=y
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
 # CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
 
 #
 # SCSI Transports
@@ -575,96 +526,52 @@ CONFIG_SCSI_PROC_FS=y
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
 # CONFIG_SCSI_SAS_LIBSAS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_DEBUG is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
+# CONFIG_SCSI_DH is not set
 # CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-
-#
-# PHY device support
-#
+# CONFIG_VETH is not set
 # CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
+# CONFIG_AX88796 is not set
 CONFIG_STNIC=y
 # CONFIG_SMC91X is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
+# CONFIG_SMC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+
+#
+# Wireless LAN
+#
+# 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
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
 # CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
@@ -682,6 +589,7 @@ CONFIG_STNIC=y
 # Character devices
 #
 # CONFIG_VT is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -704,15 +612,30 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
+CONFIG_HW_RANDOM=y
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI 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_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -722,148 +645,92 @@ CONFIG_WATCHDOG=y
 # CONFIG_SOFT_WATCHDOG is not set
 CONFIG_SH_WDT=y
 # CONFIG_SH_WDT_MMAP is not set
-CONFIG_HW_RANDOM=y
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_RAW_DRIVER is not set
 
 #
-# TPM devices
+# Sonics Silicon Backplane
 #
-# CONFIG_TCG_TPM is not set
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
-# I2C support
+# Multifunction device drivers
 #
-# CONFIG_I2C is not set
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
-# SPI support
-#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
+# Multimedia devices
 #
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_HWMON_DEBUG_CHIP 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
 
 #
-# Digital Video Broadcasting Devices
+# Multimedia drivers
 #
-# CONFIG_DVB is not set
+# CONFIG_DAB is not set
 
 #
 # Graphics support
 #
-CONFIG_FIRMWARE_EDID=y
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Sound
+# Display device support
 #
+# CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 # CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# 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
 #
 
 #
-# USB Gadget Support
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 # CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
 # CONFIG_MMC is not set
-
-#
-# LED devices
-#
+# CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
-# Virtualization
-#
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_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_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
@@ -887,12 +754,12 @@ CONFIG_DNOTIFY=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_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -908,31 +775,33 @@ CONFIG_RAMFS=y
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
 # CONFIG_JFFS2_SUMMARY is not set
 # CONFIG_JFFS2_FS_XATTR is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_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
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -940,7 +809,6 @@ CONFIG_SUNRPC=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -958,49 +826,126 @@ CONFIG_PARTITION_ADVANCED=y
 # CONFIG_SUN_PARTITION is not set
 # CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
-
-#
-# Native Language Support
-#
+# CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
-
-#
-# Distributed Lock Manager
-#
 # CONFIG_DLM is not set
 
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
 #
 # Kernel hacking
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
 # CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
-# CONFIG_KGDB is not set
+# CONFIG_SH_KGDB is not set
 
 #
 # Security options
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
 
 #
-# Cryptographic options
+# Random Number Generation
 #
-# CONFIG_CRYPTO is not set
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
@@ -1008,9 +953,14 @@ CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
-CONFIG_IOMAP_COPY=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index a9095593f8f362d3c2be237c84014f3aafd6f3f9..d99a6bdf410fafaa641ccd9d013230e5fbe1afe9 100644 (file)
@@ -1,40 +1,54 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18
-# Tue Oct  3 12:10:12 2006
+# Linux kernel version: 2.6.27
+# Wed Oct 22 19:21:12 2008
 #
 CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED 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
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
@@ -47,33 +61,47 @@ CONFIG_KALLSYMS=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
-CONFIG_SLAB=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 # CONFIG_MODULE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-# CONFIG_KMOD is not set
-
-#
-# Block layer
-#
+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_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -87,60 +115,27 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
 #
-CONFIG_SOLUTION_ENGINE=y
-# CONFIG_SH_SOLUTION_ENGINE is not set
-CONFIG_SH_7751_SOLUTION_ENGINE=y
-# CONFIG_SH_7300_SOLUTION_ENGINE is not set
-# CONFIG_SH_7343_SOLUTION_ENGINE is not set
-# CONFIG_SH_73180_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_HP6XX is not set
-# CONFIG_SH_EC3104 is not set
-# CONFIG_SH_SATURN is not set
-# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_MPC1211 is not set
-# CONFIG_SH_SH03 is not set
-# CONFIG_SH_SECUREEDGE5410 is not set
-# CONFIG_SH_HS7751RVOIP is not set
-# CONFIG_SH_7710VOIPGW is not set
-# CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_R7780RP is not set
-# CONFIG_SH_EDOSK7705 is not set
-# CONFIG_SH_SH4202_MICRODEV is not set
-# CONFIG_SH_LANDISK is not set
-# CONFIG_SH_TITAN is not set
-# CONFIG_SH_SHMIN is not set
-# CONFIG_SH_UNKNOWN is not set
-
-#
-# Processor selection
-#
 CONFIG_CPU_SH4=y
-
-#
-# SH-2 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7604 is not set
-
-#
-# SH-3 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7300 is not set
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
 # CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
 # CONFIG_CPU_SUBTYPE_SH7710 is not set
-
-#
-# SH-4 Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
 # CONFIG_CPU_SUBTYPE_SH7091 is not set
 # CONFIG_CPU_SUBTYPE_SH7750R is not set
@@ -149,65 +144,91 @@ CONFIG_CPU_SUBTYPE_SH7751=y
 # CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
 # CONFIG_CPU_SUBTYPE_SH4_202 is not set
-
-#
-# ST40 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
-# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-
-#
-# SH-4A Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
-
-#
-# SH4AL-DSP Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
 
 #
 # Memory management options
 #
+CONFIG_QUICKLIST=y
 CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_29BIT=y
 CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_STATIC=y
+CONFIG_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=0
+CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
 #
 # CONFIG_SH_DIRECT_MAPPED is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
 
 #
 # Processor features
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_SH_FPU=y
-# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
 CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_IPR_IRQ=y
 CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEA=y
+CONFIG_CPU_HAS_FPU=y
 
 #
-# Timer support
+# Board support
+#
+CONFIG_SOLUTION_ENGINE=y
+CONFIG_SH_7751_SOLUTION_ENGINE=y
+# CONFIG_SH_SH03 is not set
+
+#
+# Timer and clock configuration
 #
 CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=60000000
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 
 #
 # CPU Frequency scaling
@@ -222,21 +243,30 @@ CONFIG_SH_PCLK_FREQ=60000000
 #
 # Companion Chips
 #
-# CONFIG_HD6446X_SERIES is not set
+
+#
+# Additional SuperH Device Drivers
+#
 CONFIG_HEARTBEAT=y
+# CONFIG_PUSH_SWITCH is not set
 
 #
 # Kernel features
 #
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
-# CONFIG_SMP is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_GUSA=y
+# CONFIG_GUSA_RB is not set
 
 #
 # Boot options
@@ -250,43 +280,29 @@ CONFIG_CMDLINE="console=ttySC1,38400"
 #
 # Bus options
 #
-# CONFIG_PCI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-
-#
-# PCI Hotplug Support
-#
+# CONFIG_CF_ENABLER is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 
 #
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_FLAT is not set
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
-
-#
-# Power management options (EXPERIMENTAL)
-#
-# CONFIG_PM is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -308,52 +324,42 @@ CONFIG_IP_PNP_RARP=y
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
+# CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 CONFIG_NETFILTER_DEBUG=y
+CONFIG_NETFILTER_ADVANCED=y
 
 #
 # Core Netfilter Configuration
 #
-# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
 # CONFIG_NF_CONNTRACK is not set
 # CONFIG_NETFILTER_XTABLES is not set
+# CONFIG_IP_VS is not set
 
 #
 # IP: Netfilter Configuration
 #
-# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_NF_DEFRAG_IPV4 is not set
 CONFIG_IP_NF_QUEUE=y
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -363,10 +369,6 @@ CONFIG_IP_NF_QUEUE=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
 # CONFIG_NET_SCHED is not set
 
 #
@@ -374,9 +376,19 @@ CONFIG_IP_NF_QUEUE=y
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -388,32 +400,27 @@ CONFIG_IP_NF_QUEUE=y
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
 # CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
 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 is not set
+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
@@ -439,7 +446,6 @@ CONFIG_MTD_CFI_UTIL=y
 CONFIG_MTD_RAM=y
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -462,43 +468,29 @@ CONFIG_MTD_RAM=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 # CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
 # CONFIG_MTD_ONENAND is not set
 
 #
-# Parallel port support
+# UBI - Unsorted block images
 #
+# CONFIG_MTD_UBI is not set
 # CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
 #
@@ -506,89 +498,48 @@ CONFIG_BLK_DEV_INITRD=y
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
 # CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
 # CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-
-#
-# PHY device support
-#
+# CONFIG_VETH is not set
 # CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
+# CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 # CONFIG_SMC91X is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
+# CONFIG_SMC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+
+#
+# Wireless LAN
+#
+# 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
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
 # CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
@@ -606,6 +557,7 @@ CONFIG_MII=y
 # Character devices
 #
 # CONFIG_VT is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -620,150 +572,107 @@ CONFIG_MII=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-
-#
-# Watchdog Device Drivers
-#
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_SH_WDT is not set
 CONFIG_HW_RANDOM=y
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
 # CONFIG_I2C is not set
+# CONFIG_SPI 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_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
 
 #
-# SPI support
+# Watchdog Device Drivers
 #
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_SH_WDT is not set
 
 #
-# Dallas's 1-wire bus
+# Sonics Silicon Backplane
 #
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
-# Hardware Monitoring support
+# Multifunction device drivers
 #
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
-# Misc devices
+# Multimedia devices
 #
 
 #
-# Multimedia devices
+# Multimedia core support
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
 
 #
-# Digital Video Broadcasting Devices
+# Multimedia drivers
 #
-# CONFIG_DVB is not set
+# CONFIG_DAB is not set
 
 #
 # Graphics support
 #
-CONFIG_FIRMWARE_EDID=y
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Sound
+# Display device support
 #
+# CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 # CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# 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
 #
 
 #
-# USB Gadget Support
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 # CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
 # CONFIG_MMC is not set
-
-#
-# LED devices
-#
+# CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -772,17 +681,17 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_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_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
@@ -806,12 +715,12 @@ CONFIG_DNOTIFY=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_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -824,26 +733,27 @@ CONFIG_RAMFS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
 # CONFIG_JFFS2_SUMMARY is not set
 # CONFIG_JFFS2_FS_XATTR is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_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
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
 # CONFIG_SMB_FS is not set
@@ -851,57 +761,146 @@ CONFIG_JFFS2_RTIME=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
 # CONFIG_NLS is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
+# CONFIG_DLM is not set
 
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
-# CONFIG_KGDB is not set
+# CONFIG_SH_KGDB is not set
 
 #
 # Security options
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
 
 #
-# Cryptographic options
+# Random Number Generation
 #
-# CONFIG_CRYPTO is not set
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index 30f5ee40c312fc43105d4660d9eb4e23c6796d05..ad95b80bb1988fb15552ba1b2fd51b759112575b 100644 (file)
@@ -1,26 +1,28 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.25-rc3
-# Thu Feb 28 10:18:04 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 19:27:30 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_BUG=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -41,11 +43,8 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CGROUPS is not set
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
@@ -68,20 +67,27 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_KPROBES is not set
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+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
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
@@ -90,6 +96,7 @@ CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -104,7 +111,7 @@ CONFIG_DEFAULT_DEADLINE=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="deadline"
 CONFIG_CLASSIC_RCU=y
-# CONFIG_PREEMPT_RCU is not set
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -115,6 +122,7 @@ CONFIG_CPU_SH4A=y
 # CONFIG_CPU_SUBTYPE_SH7203 is not set
 # CONFIG_CPU_SUBTYPE_SH7206 is not set
 # CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
 # CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
@@ -132,6 +140,7 @@ CONFIG_CPU_SH4A=y
 # CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
 # CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
 # CONFIG_CPU_SUBTYPE_SH7763 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 CONFIG_CPU_SUBTYPE_SH7780=y
@@ -152,7 +161,6 @@ CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
 CONFIG_29BIT=y
-# CONFIG_PMB is not set
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -161,9 +169,12 @@ CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_SELECT_MEMORY_MODEL=y
 # CONFIG_FLATMEM_MANUAL is not set
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -171,11 +182,14 @@ CONFIG_SPARSEMEM_MANUAL=y
 CONFIG_SPARSEMEM=y
 CONFIG_HAVE_MEMORY_PRESENT=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
 # CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -210,7 +224,6 @@ CONFIG_SH_7780_SOLUTION_ENGINE=y
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=28
 CONFIG_SH_PCLK_FREQ=33333333
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -244,10 +257,10 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
 # CONFIG_SCHED_HRTICK is not set
+# CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
-CONFIG_RCU_TRACE=y
 CONFIG_GUSA=y
 
 #
@@ -273,11 +286,9 @@ CONFIG_PCI_LEGACY=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
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -347,11 +358,10 @@ CONFIG_IPV6=y
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
@@ -374,6 +384,7 @@ CONFIG_MTD=y
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -461,11 +472,13 @@ CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -537,9 +550,13 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_DH is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
+CONFIG_SATA_PMP=y
 # CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SIL24 is not set
+CONFIG_ATA_SFF=y
 # CONFIG_SATA_SVW is not set
 # CONFIG_ATA_PIIX is not set
 # CONFIG_SATA_NV is not set
@@ -547,11 +564,11 @@ CONFIG_ATA=y
 # CONFIG_SATA_QSTOR is not set
 # CONFIG_SATA_PROMISE is not set
 CONFIG_SATA_SIL=y
-# CONFIG_SATA_SIL24 is not set
 # CONFIG_SATA_SIS is not set
 # CONFIG_SATA_ULI is not set
 # CONFIG_SATA_VIA is not set
 # CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
 # CONFIG_PATA_AMD is not set
 # CONFIG_PATA_ARTOP is not set
 # CONFIG_PATA_ATIIXP is not set
@@ -575,6 +592,7 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
+# CONFIG_PATA_SCH is not set
 # CONFIG_MD is not set
 # CONFIG_FUSION is not set
 
@@ -583,12 +601,11 @@ CONFIG_SATA_SIL=y
 #
 
 #
-# An alternative FireWire stack is available with EXPERIMENTAL=y
+# A new alternative FireWire stack is available with EXPERIMENTAL=y
 #
 # 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_EQUALIZER is not set
@@ -621,12 +638,16 @@ CONFIG_MII=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 CONFIG_SMC91X=y
+# CONFIG_SMC911X is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
@@ -645,6 +666,7 @@ CONFIG_NET_PCI=y
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
+# CONFIG_ATL2 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
@@ -654,6 +676,7 @@ CONFIG_NET_PCI=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
 
 #
 # USB Network Adapters
@@ -675,7 +698,7 @@ CONFIG_NET_PCI=y
 # Input device support
 #
 CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
 
 #
@@ -709,9 +732,11 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 # CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -737,12 +762,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_RAW_DRIVER is not set
 CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
-
-#
-# SPI support
-#
 # CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
@@ -757,6 +777,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 CONFIG_THERMAL=y
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -768,13 +789,26 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # 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
 
 #
@@ -786,15 +820,16 @@ CONFIG_SSB_POSSIBLE=y
 CONFIG_FB=y
 CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB_DDC is not set
-# CONFIG_FB_CFB_FILLRECT is not set
-# CONFIG_FB_CFB_COPYAREA is not set
-# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=m
+CONFIG_FB_CFB_COPYAREA=m
+CONFIG_FB_CFB_IMAGEBLIT=m
 # 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_DEFERRED_IO=y
 # CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
@@ -818,6 +853,7 @@ CONFIG_FB_DEFERRED_IO=y
 # CONFIG_FB_ATY is not set
 # CONFIG_FB_S3 is not set
 # CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
@@ -825,7 +861,10 @@ CONFIG_FB_DEFERRED_IO=y
 # CONFIG_FB_VT8623 is not set
 # CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_ARK is not set
+# CONFIG_FB_CARMINE is not set
+CONFIG_FB_SH_MOBILE_LCDC=m
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -850,24 +889,10 @@ CONFIG_LOGO_LINUX_CLUT224=y
 # CONFIG_LOGO_SUPERH_MONO is not set
 # CONFIG_LOGO_SUPERH_VGA16 is not set
 CONFIG_LOGO_SUPERH_CLUT224=y
-
-#
-# Sound
-#
 CONFIG_SOUND=y
-
-#
-# Advanced Linux Sound Architecture
-#
+CONFIG_SOUND_OSS_CORE=y
 # CONFIG_SND is not set
-
-#
-# Open Sound System
-#
 CONFIG_SOUND_PRIME=y
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
@@ -877,8 +902,36 @@ CONFIG_HID=y
 # USB Input Devices
 #
 CONFIG_USB_HID=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_PID is not set
 # CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_BRIGHT=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DELL=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_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_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -892,11 +945,17 @@ CONFIG_USB=y
 #
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
 
 #
 # USB Host Controller Drivers
 #
+# CONFIG_USB_C67X00_HCD is not set
 CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
@@ -911,6 +970,8 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 #
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -921,17 +982,25 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 #
 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
+# 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
-CONFIG_USB_MON=y
 
 #
 # USB port drivers
@@ -943,6 +1012,10 @@ CONFIG_USB_MON=y
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_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
@@ -956,17 +1029,19 @@ CONFIG_USB_MON=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
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
 # CONFIG_RTC_CLASS is not set
-
-#
-# Userspace I/O
-#
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -975,9 +1050,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_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_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_DNOTIFY is not set
@@ -1010,6 +1087,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
@@ -1025,6 +1103,7 @@ CONFIG_TMPFS=y
 CONFIG_CRAMFS=y
 # 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
@@ -1034,9 +1113,8 @@ CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
-# CONFIG_NFS_DIRECTIO 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
@@ -1099,12 +1177,20 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -1115,45 +1201,86 @@ CONFIG_DEBUG_FS=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
-# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
 # CONFIG_CRYPTO_MANAGER is not set
-# CONFIG_CRYPTO_HMAC 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_PCBC is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 # CONFIG_CRYPTO_SHA1 is not set
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_ECB is not set
-# CONFIG_CRYPTO_CBC is not set
-# CONFIG_CRYPTO_PCBC is not set
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_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_TEA is not set
-# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS 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_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_TEST is not set
-# CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
 
@@ -1163,6 +1290,7 @@ CONFIG_CRYPTO_HW=y
 CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index 9fd5ea7304e5aef2fc99ed4216cd8fd77dcea730..95f0f5d5b63129f131c1a672999bb00b734505e6 100644 (file)
@@ -1,41 +1,56 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18
-# Tue Oct  3 12:13:26 2006
+# Linux kernel version: 2.6.27
+# Wed Oct 22 19:31:54 2008
 #
 CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_SYS_SUPPORTS_PCI=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED 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
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
@@ -48,34 +63,49 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
-CONFIG_SLAB=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=m
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
-
-#
-# Block layer
-#
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -89,59 +119,27 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
 #
-# CONFIG_SH_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SOLUTION_ENGINE is not set
-# CONFIG_SH_7300_SOLUTION_ENGINE is not set
-# CONFIG_SH_7343_SOLUTION_ENGINE is not set
-# CONFIG_SH_73180_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_HP6XX is not set
-# CONFIG_SH_EC3104 is not set
-# CONFIG_SH_SATURN is not set
-# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_MPC1211 is not set
-CONFIG_SH_SH03=y
-# CONFIG_SH_SECUREEDGE5410 is not set
-# CONFIG_SH_HS7751RVOIP is not set
-# CONFIG_SH_7710VOIPGW is not set
-# CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_R7780RP is not set
-# CONFIG_SH_EDOSK7705 is not set
-# CONFIG_SH_SH4202_MICRODEV is not set
-# CONFIG_SH_LANDISK is not set
-# CONFIG_SH_TITAN is not set
-# CONFIG_SH_SHMIN is not set
-# CONFIG_SH_UNKNOWN is not set
-
-#
-# Processor selection
-#
 CONFIG_CPU_SH4=y
-
-#
-# SH-2 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7604 is not set
-
-#
-# SH-3 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7300 is not set
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
 # CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
 # CONFIG_CPU_SUBTYPE_SH7710 is not set
-
-#
-# SH-4 Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
 # CONFIG_CPU_SUBTYPE_SH7091 is not set
 # CONFIG_CPU_SUBTYPE_SH7750R is not set
@@ -150,69 +148,90 @@ CONFIG_CPU_SUBTYPE_SH7751=y
 # CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
 # CONFIG_CPU_SUBTYPE_SH4_202 is not set
-
-#
-# ST40 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
-# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-
-#
-# SH-4A Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
-
-#
-# SH4AL-DSP Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
 
 #
 # Memory management options
 #
+CONFIG_QUICKLIST=y
 CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
+CONFIG_29BIT=y
 CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_STATIC=y
+CONFIG_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=0
+CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
 #
 # CONFIG_SH_DIRECT_MAPPED is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
-CONFIG_CF_ENABLER=y
-CONFIG_CF_AREA5=y
-# CONFIG_CF_AREA6 is not set
-CONFIG_CF_BASE_ADDR=0xb4000000
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
 
 #
 # Processor features
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_SH_FPU=y
-# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
 CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_IPR_IRQ=y
 CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEA=y
+CONFIG_CPU_HAS_FPU=y
 
 #
-# Timer support
+# Board support
+#
+# CONFIG_SH_7751_SOLUTION_ENGINE is not set
+CONFIG_SH_SH03=y
+
+#
+# Timer and clock configuration
 #
 CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=60000000
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 
 #
 # CPU Frequency scaling
@@ -227,22 +246,31 @@ CONFIG_SH_PCLK_FREQ=60000000
 #
 # Companion Chips
 #
-# CONFIG_HD6446X_SERIES is not set
+
+#
+# Additional SuperH Device Drivers
+#
 CONFIG_HEARTBEAT=y
+# CONFIG_PUSH_SWITCH is not set
 
 #
 # Kernel features
 #
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
-# CONFIG_SMP is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
-CONFIG_PREEMPT_BKL=y
+# CONFIG_PREEMPT_RCU is not set
+CONFIG_GUSA=y
+# CONFIG_GUSA_RB is not set
 
 #
 # Boot options
@@ -256,20 +284,17 @@ CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs"
 #
 # Bus options
 #
+CONFIG_CF_ENABLER=y
+CONFIG_CF_AREA5=y
+# CONFIG_CF_AREA6 is not set
+CONFIG_CF_BASE_ADDR=0xb4000000
 CONFIG_PCI=y
 CONFIG_SH_PCIDMA_NONCOHERENT=y
 CONFIG_PCI_AUTO=y
 CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-# CONFIG_PCI_MULTITHREAD_PROBE is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
 # CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
 CONFIG_HOTPLUG_PCI=m
 # CONFIG_HOTPLUG_PCI_FAKE is not set
 # CONFIG_HOTPLUG_PCI_CPCI is not set
@@ -279,30 +304,24 @@ CONFIG_HOTPLUG_PCI=m
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_FLAT is not set
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 CONFIG_BINFMT_MISC=y
-
-#
-# Power management options (EXPERIMENTAL)
-#
-# CONFIG_PM is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
 CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -323,33 +342,23 @@ CONFIG_IP_PNP_RARP=y
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -359,10 +368,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
 # CONFIG_NET_SCHED is not set
 
 #
@@ -370,9 +375,19 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -381,34 +396,15 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
 # CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
 # CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
 # CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
 # CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_CPQ_DA is not set
+CONFIG_BLK_DEV=y
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
@@ -420,45 +416,76 @@ CONFIG_BLK_DEV_NBD=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
 
 #
-# Please see Documentation/ide.txt for help/info on IDE drives
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
 CONFIG_BLK_DEV_IDECD=m
+CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
 CONFIG_BLK_DEV_IDETAPE=m
-CONFIG_BLK_DEV_IDEFLOPPY=m
 # CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
 
 #
 # IDE chipset support/bugfixes
 #
-CONFIG_IDE_GENERIC=y
-# CONFIG_BLK_DEV_IDEPCI is not set
-# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
+
+#
+# PCI IDE chipsets support
+#
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8213 is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
 # CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
 # CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
@@ -479,6 +506,8 @@ CONFIG_CHR_DEV_SG=m
 # 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
@@ -486,12 +515,9 @@ CONFIG_CHR_DEV_SG=m
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
 # CONFIG_SCSI_SAS_LIBSAS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
@@ -501,7 +527,6 @@ CONFIG_CHR_DEV_SG=m
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_AIC94XX is not set
-# CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
@@ -512,88 +537,67 @@ CONFIG_CHR_DEV_SG=m
 # 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
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_DH is not set
 # CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
 # CONFIG_FUSION is not set
-# CONFIG_FUSION_SPI is not set
-# CONFIG_FUSION_FC is not set
-# CONFIG_FUSION_SAS is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
-# CONFIG_IEEE1394 is not set
 
 #
-# I2O device support
+# Enable only one of the two stacks, unless you know what you are doing
 #
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
-
-#
-# Network device support
-#
 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
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
 # CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
 # CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
+# CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
-
-#
-# Tulip family network device support
-#
+# CONFIG_SMC911X is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 # CONFIG_E100 is not set
 # CONFIG_FEALNX is not set
@@ -601,18 +605,21 @@ CONFIG_NET_PCI=y
 # CONFIG_NE2K_PCI is not set
 CONFIG_8139CP=y
 # CONFIG_8139TOO is not set
+# CONFIG_R6040 is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-
-#
-# Ethernet (1000 Mbit)
-#
+# CONFIG_SC92031 is not set
+# CONFIG_ATL2 is not set
+CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 # CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -620,52 +627,46 @@ CONFIG_8139CP=y
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
 # CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 # CONFIG_QLA3XXX is not set
-
-#
-# Ethernet (10000 Mbit)
-#
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_JME is not set
+CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_ENIC is not set
+# CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
-
-#
-# Token Ring devices
-#
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
+# CONFIG_QLGE is not set
+# CONFIG_SFC is not set
 # CONFIG_TR is not set
 
 #
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
+# Wireless LAN
 #
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
 # CONFIG_NET_FC is not set
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
 # CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
@@ -673,6 +674,7 @@ CONFIG_8139CP=y
 #
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -682,7 +684,6 @@ CONFIG_INPUT_MOUSEDEV=y
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
@@ -692,6 +693,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
@@ -705,10 +707,13 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 # CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
 
 #
 # Serial drivers
@@ -731,15 +736,36 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
+CONFIG_HW_RANDOM=y
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_I2C is not set
+# CONFIG_SPI 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_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -747,6 +773,7 @@ CONFIG_WATCHDOG=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ALIM7101_WDT is not set
 CONFIG_SH_WDT=m
 # CONFIG_SH_WDT_MMAP is not set
 
@@ -755,142 +782,92 @@ CONFIG_SH_WDT=m
 #
 # CONFIG_PCIPCWATCHDOG is not set
 # CONFIG_WDTPCI is not set
-CONFIG_HW_RANDOM=y
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
 
 #
-# TPM devices
+# Sonics Silicon Backplane
 #
-# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
-# I2C support
-#
-# CONFIG_I2C is not set
-
+# Multifunction device drivers
 #
-# SPI support
-#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
-
-#
-# Hardware Monitoring support
-#
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
-# Misc devices
+# Multimedia devices
 #
 
 #
-# Multimedia devices
+# Multimedia core support
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
 
 #
-# Digital Video Broadcasting Devices
+# Multimedia drivers
 #
-# CONFIG_DVB is not set
+# CONFIG_DAB is not set
 
 #
 # Graphics support
 #
-CONFIG_FIRMWARE_EDID=y
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Console display driver support
+# Display device support
 #
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_DISPLAY_SUPPORT is not set
 
 #
-# Sound
+# Console display driver support
 #
+CONFIG_DUMMY_CONSOLE=y
 # CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
 
 #
-# USB support
+# Special HID drivers
 #
+CONFIG_HID_COMPAT=y
+CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# 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
 #
 
 #
-# USB Gadget Support
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 # CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
 # CONFIG_MMC is not set
-
-#
-# LED devices
-#
+# CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
 # CONFIG_RTC_CLASS is not set
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -904,20 +881,19 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
 CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=y
 CONFIG_AUTOFS4_FS=y
 # CONFIG_FUSE_FS is not set
@@ -928,7 +904,6 @@ CONFIG_AUTOFS4_FS=y
 CONFIG_ISO9660_FS=m
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
-CONFIG_ZISOFS_FS=m
 CONFIG_UDF_FS=m
 CONFIG_UDF_NLS=y
 
@@ -948,12 +923,12 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -968,31 +943,30 @@ CONFIG_RAMFS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_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
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
-# CONFIG_NFS_DIRECTIO is not set
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_NFSD_TCP=y
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1000,7 +974,6 @@ CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -1022,10 +995,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SUN_PARTITION is not set
 # CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
-
-#
-# Native Language Support
-#
+# CONFIG_SYSV68_PARTITION is not set
 CONFIG_NLS=m
 CONFIG_NLS_DEFAULT="iso8859-1"
 CONFIG_NLS_CODEPAGE_437=m
@@ -1066,81 +1036,146 @@ CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
 CONFIG_NLS_UTF8=m
-
-#
-# Profiling support
-#
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
+# CONFIG_DLM is not set
 
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
 CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_EARLY_PRINTK is not set
-# CONFIG_KGDB is not set
+# CONFIG_SH_KGDB is not set
 
 #
 # Security options
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
 
 #
-# Cryptographic options
+# Crypto core or helper
 #
-CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_BLKCIPHER=y
 CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=m
-CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 CONFIG_CRYPTO_SHA1=y
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_DES=y
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT 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_TEA is not set
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS 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=y
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_LZO is not set
 
 #
-# Hardware crypto devices
+# Random Number Generation
 #
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=y
 # 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=y
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index 37e49a58920792af09be018214e24011074e9bde..9a768b28adcbaca72fda7bc9c727c076720669f1 100644 (file)
@@ -1,25 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.25-rc4
-# Thu Mar  6 16:02:29 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 19:35:18 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_BUG=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -70,30 +72,38 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 # CONFIG_SHMEM is not set
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-# CONFIG_KMOD 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_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -108,7 +118,7 @@ CONFIG_DEFAULT_DEADLINE=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="deadline"
 CONFIG_CLASSIC_RCU=y
-# CONFIG_PREEMPT_RCU is not set
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -118,6 +128,7 @@ CONFIG_CPU_SH3=y
 # CONFIG_CPU_SUBTYPE_SH7203 is not set
 # CONFIG_CPU_SUBTYPE_SH7206 is not set
 # CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
 # CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
@@ -135,6 +146,7 @@ CONFIG_CPU_SUBTYPE_SH7710=y
 # CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
 # CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
 # CONFIG_CPU_SUBTYPE_SH7763 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
@@ -164,7 +176,9 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -172,11 +186,13 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+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=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -209,7 +225,6 @@ CONFIG_CPU_HAS_DSP=y
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=32768000
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -245,10 +260,10 @@ CONFIG_HZ=250
 # CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
-CONFIG_RCU_TRACE=y
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
 
@@ -269,11 +284,9 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000
 # 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
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -311,10 +324,7 @@ CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
-# CONFIG_IP_VS is not set
 # CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
@@ -327,10 +337,12 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_NETFILTER_NETLINK_LOG is not set
 # CONFIG_NF_CONNTRACK is not set
 # CONFIG_NETFILTER_XTABLES is not set
+# CONFIG_IP_VS is not set
 
 #
 # IP: Netfilter Configuration
 #
+# CONFIG_NF_DEFRAG_IPV4 is not set
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
@@ -339,6 +351,7 @@ CONFIG_NETFILTER_ADVANCED=y
 # 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
@@ -357,7 +370,7 @@ CONFIG_NET_SCH_CBQ=y
 # CONFIG_NET_SCH_HTB is not set
 # CONFIG_NET_SCH_HFSC is not set
 # CONFIG_NET_SCH_PRIO is not set
-# CONFIG_NET_SCH_RR is not set
+# CONFIG_NET_SCH_MULTIQ is not set
 # CONFIG_NET_SCH_RED is not set
 # CONFIG_NET_SCH_SFQ is not set
 # CONFIG_NET_SCH_TEQL is not set
@@ -395,11 +408,10 @@ CONFIG_NET_SCH_FIFO=y
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
@@ -417,6 +429,8 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
@@ -425,6 +439,7 @@ CONFIG_MTD=y
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -500,6 +515,7 @@ CONFIG_BLK_DEV=y
 # 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_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -516,7 +532,6 @@ CONFIG_HAVE_IDE=y
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -528,14 +543,18 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
+# CONFIG_SH_ETH is not set
 # CONFIG_SMC91X is not set
+# CONFIG_SMC911X is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 CONFIG_NETDEV_1000=y
-# CONFIG_E1000E_ENABLED is not set
 CONFIG_NETDEV_10000=y
 
 #
@@ -543,6 +562,7 @@ CONFIG_NETDEV_10000=y
 #
 # 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
@@ -587,6 +607,7 @@ CONFIG_INPUT=y
 # Character devices
 #
 # CONFIG_VT is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -611,12 +632,7 @@ CONFIG_HW_RANDOM=y
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 # CONFIG_I2C is not set
-
-#
-# SPI support
-#
 # CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
@@ -632,13 +648,26 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # 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
 
 #
@@ -653,20 +682,28 @@ CONFIG_SSB_POSSIBLE=y
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 # CONFIG_USB_ARCH_HAS_EHCI is not set
 # CONFIG_USB is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+
+#
+# Enable Host or Gadget support to see Inventra options
+#
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -675,24 +712,23 @@ CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
-
-#
-# Userspace I/O
-#
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_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_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
@@ -720,6 +756,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
@@ -751,6 +788,7 @@ CONFIG_JFFS2_RTIME=y
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -780,12 +818,19 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -796,51 +841,91 @@ CONFIG_DEBUG_FS=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
-# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
 # CONFIG_CRYPTO_MANAGER 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_NULL is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 # CONFIG_CRYPTO_SHA1 is not set
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_ECB is not set
-# CONFIG_CRYPTO_CBC is not set
-# CONFIG_CRYPTO_PCBC is not set
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_XTS is not set
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_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_TEA is not set
-# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_SEED is not set
 # CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_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_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_TEST is not set
-# CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 
 #
@@ -849,6 +934,7 @@ CONFIG_CRYPTO_HW=y
 CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index baf830c4a7e40189616755c9602f17fd78cf71c0..6a77f691fb87d512d3258a2f2436ebcd1ccc260a 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc2
-# Fri Aug  8 13:44:20 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 19:37:12 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,11 +13,12 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
@@ -76,7 +77,9 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -84,15 +87,12 @@ CONFIG_PROFILING=y
 # CONFIG_MARKERS is not set
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
-CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -124,6 +124,7 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -181,6 +182,7 @@ CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -193,13 +195,15 @@ CONFIG_SPARSEMEM_MANUAL=y
 CONFIG_SPARSEMEM=y
 CONFIG_HAVE_MEMORY_PRESENT=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 # CONFIG_MEMORY_HOTPLUG is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
 # CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -231,7 +235,6 @@ CONFIG_SH_SH7763RDP=y
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=28
 CONFIG_SH_PCLK_FREQ=66666666
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -291,6 +294,8 @@ CONFIG_CMDLINE="console=ttySC2,115200 root=/dev/sda1 rootdelay=10"
 # 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_NET=y
 
@@ -341,6 +346,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -361,11 +367,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 CONFIG_WIRELESS_EXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_MAC80211 is not set
@@ -563,6 +568,9 @@ CONFIG_SH_ETH=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
@@ -675,6 +683,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # Multimedia devices
@@ -700,6 +710,7 @@ CONFIG_SSB_POSSIBLE=y
 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
@@ -725,6 +736,7 @@ CONFIG_FB_BOTH_ENDIAN=y
 # CONFIG_FB_SH_MOBILE_LCDC is not set
 CONFIG_FB_SH7760=y
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -768,6 +780,7 @@ CONFIG_USB_DEVICE_CLASS=y
 # 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
 
 #
 # USB Host Controller Drivers
@@ -788,6 +801,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
 # CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -817,7 +831,6 @@ CONFIG_USB_STORAGE=y
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-CONFIG_USB_MON=y
 
 #
 # USB port drivers
@@ -830,7 +843,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_SEVSEG is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
@@ -846,13 +859,14 @@ CONFIG_USB_MON=y
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
 
 #
-# MMC/SD Card Drivers
+# MMC/SD/SDIO Card Drivers
 #
 CONFIG_MMC_BLOCK=y
 CONFIG_MMC_BLOCK_BOUNCE=y
@@ -860,7 +874,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # CONFIG_MMC_TEST is not set
 
 #
-# MMC/SD Host Controller Drivers
+# MMC/SD/SDIO Host Controller Drivers
 #
 # CONFIG_MMC_SDHCI is not set
 # CONFIG_MEMSTICK is not set
@@ -869,6 +883,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -880,12 +895,13 @@ CONFIG_EXT3_FS=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_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=y
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_DNOTIFY=y
@@ -919,6 +935,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
@@ -955,6 +972,7 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1025,6 +1043,11 @@ CONFIG_FRAME_WARN=1024
 # 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
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -1035,12 +1058,14 @@ CONFIG_FRAME_WARN=1024
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 # CONFIG_CRYPTO_MANAGER is not set
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -1113,13 +1138,17 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC_T10DIF=y
index ff72697365d18d8f1a1416263bd0706ae72cf9dc..07e33c285b930df97ec2293ae344b18476d8c87f 100644 (file)
@@ -1,27 +1,29 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc8
-# Tue Jul 15 21:37:59 2008
+# Linux kernel version: 2.6.27
+# Wed Oct 22 19:49:23 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_BUG=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_IO_TRAPPED=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -61,7 +63,6 @@ CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -78,7 +79,9 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -86,10 +89,13 @@ CONFIG_PROFILING=y
 # CONFIG_MARKERS is not set
 # CONFIG_OPROFILE 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_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -106,6 +112,7 @@ CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -120,6 +127,7 @@ CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
@@ -181,10 +189,12 @@ CONFIG_MAX_ACTIVE_REGIONS=2
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_SELECT_MEMORY_MODEL=y
 # CONFIG_FLATMEM_MANUAL is not set
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -192,13 +202,15 @@ CONFIG_SPARSEMEM_MANUAL=y
 CONFIG_SPARSEMEM=y
 CONFIG_HAVE_MEMORY_PRESENT=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 # CONFIG_MEMORY_HOTPLUG is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
 # CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
@@ -266,9 +278,10 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
-# CONFIG_SCHED_HRTICK is not set
+CONFIG_SCHED_HRTICK=y
 CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
@@ -299,11 +312,9 @@ CONFIG_PCI_LEGACY=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
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -358,6 +369,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -378,12 +390,12 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
 # CONFIG_RFKILL is not set
@@ -499,6 +511,7 @@ 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 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
@@ -541,6 +554,7 @@ CONFIG_SCSI_WAIT_SCAN=m
 # 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_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -615,7 +629,6 @@ CONFIG_SATA_SIL=y
 # 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
@@ -624,19 +637,18 @@ CONFIG_NETDEVICES=y
 # CONFIG_VETH is not set
 # CONFIG_ARCNET is not set
 # CONFIG_NET_ETHERNET is not set
+CONFIG_MII=y
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 # CONFIG_E1000 is not set
 # CONFIG_E1000E is not set
-# CONFIG_E1000E_ENABLED is not set
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 CONFIG_R8169=y
-# CONFIG_R8169_NAPI is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
 # CONFIG_SKY2 is not set
@@ -645,6 +657,8 @@ CONFIG_R8169=y
 # CONFIG_BNX2 is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_JME is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 
@@ -679,7 +693,7 @@ CONFIG_R8169=y
 # Input device support
 #
 CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
 
 #
@@ -720,6 +734,7 @@ CONFIG_INPUT_KEYBOARD=y
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -754,44 +769,65 @@ CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
 # CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_ALGOPCA=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_SIMTEC is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_TINY_USB is not set
 # CONFIG_I2C_VIA is not set
 # CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SH_MOBILE is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
 # CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
 CONFIG_I2C_PCA_PLATFORM=y
-# CONFIG_I2C_SH_MOBILE is not set
+# CONFIG_I2C_STUB is not set
 
 #
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
@@ -816,8 +852,12 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 CONFIG_MFD_SM501=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
 
 #
 # Multimedia devices
@@ -844,6 +884,7 @@ CONFIG_MFD_SM501=y
 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
@@ -877,6 +918,7 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 # CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
@@ -885,8 +927,11 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 # CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_ARK is not set
 # CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+CONFIG_FB_SH_MOBILE_LCDC=m
 CONFIG_FB_SM501=y
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -911,10 +956,6 @@ CONFIG_LOGO_LINUX_CLUT224=y
 # CONFIG_LOGO_SUPERH_MONO is not set
 # CONFIG_LOGO_SUPERH_VGA16 is not set
 # CONFIG_LOGO_SUPERH_CLUT224 is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
@@ -925,9 +966,36 @@ CONFIG_HID=y
 # USB Input Devices
 #
 CONFIG_USB_HID=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
+# CONFIG_HID_PID is not set
 # CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_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_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_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_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -945,6 +1013,7 @@ CONFIG_USB_DEVICE_CLASS=y
 # 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
 
 #
 # USB Host Controller Drivers
@@ -969,6 +1038,7 @@ CONFIG_USB_R8A66597_HCD=y
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
 # CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -998,7 +1068,6 @@ CONFIG_USB_STORAGE=y
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-CONFIG_USB_MON=y
 
 #
 # USB port drivers
@@ -1011,7 +1080,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_SEVSEG is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
@@ -1029,6 +1098,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_IOWARRIOR is not set
 CONFIG_USB_TEST=m
 # CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1073,19 +1143,24 @@ CONFIG_RTC_DRV_RS5C372=y
 #
 # 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_SH is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -1097,12 +1172,13 @@ CONFIG_EXT3_FS=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_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=y
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_DNOTIFY=y
@@ -1137,6 +1213,7 @@ 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
@@ -1158,6 +1235,7 @@ CONFIG_TMPFS=y
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1168,18 +1246,18 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 CONFIG_NFSD_V4=y
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1250,6 +1328,8 @@ CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -1270,13 +1350,27 @@ CONFIG_DEBUG_PREEMPT=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_FRAME_POINTER is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -1292,15 +1386,19 @@ CONFIG_DEBUG_PREEMPT=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
 CONFIG_CRYPTO_BLKCIPHER=y
 CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_RNG=y
 CONFIG_CRYPTO_MANAGER=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -1339,6 +1437,10 @@ CONFIG_CRYPTO_HMAC=y
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 # CONFIG_CRYPTO_SHA1 is not set
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
@@ -1369,15 +1471,20 @@ CONFIG_CRYPTO_DES=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index 8800fefcbaf028075a913dc82559f9864285a24a..e2b38a334976a4795f2e69ed70e9216ac9738e02 100644 (file)
@@ -1,27 +1,34 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18
-# Tue Oct  3 12:52:49 2006
+# Linux kernel version: 2.6.27
+# Wed Oct 22 19:52:59 2008
 #
 CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 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_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SWAP is not set
@@ -29,11 +36,14 @@ CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
 # CONFIG_RELAY is not set
-CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
@@ -44,27 +54,38 @@ CONFIG_EMBEDDED=y
 CONFIG_PRINTK=y
 # CONFIG_BUG is not set
 # CONFIG_ELF_CORE is not set
+CONFIG_COMPAT_BRK=y
 # CONFIG_BASE_FULL is not set
 # CONFIG_FUTEX is not set
+CONFIG_ANON_INODES=y
 # CONFIG_EPOLL is not set
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 # CONFIG_SHMEM is not set
-# CONFIG_SLAB is not set
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+# CONFIG_SLAB is not set
+# CONFIG_SLUB is not set
+CONFIG_SLOB=y
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=1
-CONFIG_SLOB=y
-
-#
-# Loadable module support
-#
 # CONFIG_MODULES is not set
-
-#
-# Block layer
-#
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -78,59 +99,27 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
 #
-# CONFIG_SH_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SOLUTION_ENGINE is not set
-# CONFIG_SH_7300_SOLUTION_ENGINE is not set
-# CONFIG_SH_7343_SOLUTION_ENGINE is not set
-# CONFIG_SH_73180_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_HP6XX is not set
-# CONFIG_SH_EC3104 is not set
-# CONFIG_SH_SATURN is not set
-# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_MPC1211 is not set
-# CONFIG_SH_SH03 is not set
-# CONFIG_SH_SECUREEDGE5410 is not set
-# CONFIG_SH_HS7751RVOIP is not set
-# CONFIG_SH_7710VOIPGW is not set
-# CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_R7780RP is not set
-# CONFIG_SH_EDOSK7705 is not set
-# CONFIG_SH_SH4202_MICRODEV is not set
-# CONFIG_SH_LANDISK is not set
-# CONFIG_SH_TITAN is not set
-CONFIG_SH_SHMIN=y
-# CONFIG_SH_UNKNOWN is not set
-
-#
-# Processor selection
-#
 CONFIG_CPU_SH3=y
-
-#
-# SH-2 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7604 is not set
-
-#
-# SH-3 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7300 is not set
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
 CONFIG_CPU_SUBTYPE_SH7706=y
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
 # CONFIG_CPU_SUBTYPE_SH7710 is not set
-
-#
-# SH-4 Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
 # CONFIG_CPU_SUBTYPE_SH7091 is not set
 # CONFIG_CPU_SUBTYPE_SH7750R is not set
@@ -139,65 +128,87 @@ CONFIG_CPU_SUBTYPE_SH7706=y
 # CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
 # CONFIG_CPU_SUBTYPE_SH4_202 is not set
-
-#
-# ST40 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
-# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-
-#
-# SH-4A Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
-
-#
-# SH4AL-DSP Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
 
 #
 # Memory management options
 #
+CONFIG_QUICKLIST=y
 CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x00800000
+CONFIG_29BIT=y
 CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_STATIC=y
+CONFIG_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=0
+CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
 #
 # CONFIG_SH_DIRECT_MAPPED is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
 
 #
 # Processor features
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
 # CONFIG_SH_FPU_EMU is not set
-# CONFIG_SH_DSP is not set
 # CONFIG_SH_ADC is not set
 CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_IPR_IRQ=y
 CONFIG_CPU_HAS_SR_RB=y
 
 #
-# Timer support
+# Board support
+#
+CONFIG_SH_SHMIN=y
+
+#
+# Timer and clock configuration
 #
 CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=32000000
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 
 #
 # CPU Frequency scaling
@@ -212,69 +223,63 @@ CONFIG_SH_PCLK_FREQ=32000000
 #
 # Companion Chips
 #
-# CONFIG_HD6446X_SERIES is not set
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_HEARTBEAT is not set
+# CONFIG_PUSH_SWITCH is not set
 
 #
 # Kernel features
 #
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
-# CONFIG_SMP is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_GUSA=y
+# CONFIG_GUSA_RB is not set
 
 #
 # Boot options
 #
 CONFIG_ZERO_PAGE_OFFSET=0x00001000
 CONFIG_BOOT_LINK_OFFSET=0x00210000
-# CONFIG_UBC_WAKEUP is not set
 CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="console=ttySC1,115200 root=1f01 mtdparts=phys_mapped_flash:64k(firm)ro,-(sys) netdev=34,0x300,eth0 "
 
 #
 # Bus options
 #
-# CONFIG_PCI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-
-#
-# PCI Hotplug Support
-#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 
 #
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_FLAT is not set
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
-
-#
-# Power management options (EXPERIMENTAL)
-#
-# CONFIG_PM is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 # CONFIG_PACKET 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
@@ -295,33 +300,23 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -331,10 +326,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
 # CONFIG_NET_SCHED is not set
 
 #
@@ -342,9 +333,19 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -356,32 +357,27 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
 # CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
 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 is not set
+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
@@ -407,7 +403,6 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -433,41 +428,27 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 # CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
 # CONFIG_MTD_ONENAND is not set
 
 #
-# Parallel port support
+# UBI - Unsorted block images
 #
+# CONFIG_MTD_UBI is not set
 # CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
 #
@@ -475,89 +456,48 @@ CONFIG_BLK_DEV_LOOP=y
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
 # CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
 # CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-
-#
-# PHY device support
-#
+# CONFIG_VETH is not set
 # CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
+# CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 # CONFIG_SMC91X is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
+# CONFIG_SMC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+
+#
+# Wireless LAN
+#
+# 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
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
 # CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
@@ -575,6 +515,7 @@ CONFIG_NET_ETHERNET=y
 # Character devices
 #
 # CONFIG_VT is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -593,153 +534,103 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
 CONFIG_HW_RANDOM=y
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
 # CONFIG_I2C is not set
-
-#
-# SPI support
-#
 # CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
 
 #
-# Dallas's 1-wire bus
+# Sonics Silicon Backplane
 #
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
-# Hardware Monitoring support
+# Multifunction device drivers
 #
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
-# Misc devices
+# Multimedia devices
 #
 
 #
-# Multimedia devices
+# Multimedia core support
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
 
 #
-# Digital Video Broadcasting Devices
+# Multimedia drivers
 #
-# CONFIG_DVB is not set
+# CONFIG_DAB is not set
 
 #
 # Graphics support
 #
-CONFIG_FIRMWARE_EDID=y
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Sound
+# Display device support
 #
+# CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 # CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# 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
 #
 
 #
-# USB Gadget Support
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 # CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
 # CONFIG_MMC is not set
-
-#
-# LED devices
-#
+# CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
 # CONFIG_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_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
 # CONFIG_QUOTA is not set
-# CONFIG_DNOTIFY is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
@@ -763,12 +654,12 @@ CONFIG_FIRMWARE_EDID=y
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 # CONFIG_SYSFS is not set
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 
 #
 # Miscellaneous filesystems
@@ -780,29 +671,28 @@ CONFIG_RAMFS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 CONFIG_CRAMFS=y
 # 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
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -810,53 +700,140 @@ CONFIG_SUNRPC=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
 # CONFIG_NLS is not set
 
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_UNWIND_INFO is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
 CONFIG_SH_STANDARD_BIOS=y
+# CONFIG_EARLY_SCIF_CONSOLE is not set
 CONFIG_EARLY_PRINTK=y
-# CONFIG_KGDB is not set
+# CONFIG_SH_KGDB is not set
 
 #
 # Security options
 #
 # CONFIG_KEYS is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+# CONFIG_CRYPTO_MANAGER 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
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
 
 #
-# Cryptographic options
+# Random Number Generation
 #
-# CONFIG_CRYPTO is not set
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index a794c082709bf5a4e532bc5e87fd771fdf8b7a6b..ae5cbe237fff81353a998f65a8695b8551f7dc98 100644 (file)
@@ -1,18 +1,23 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.23-rc7
-# Fri Sep 21 19:07:30 2007
+# Linux kernel version: 2.6.27
+# Tue Oct 21 12:16:25 2008
 #
 CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_BUG=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_LOCKBREAK=y
 CONFIG_SYS_SUPPORTS_SMP=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -26,7 +31,6 @@ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 # General setup
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
@@ -34,20 +38,41 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_POSIX_MQUEUE is not set
+CONFIG_POSIX_MQUEUE=y
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_AUDIT is not set
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+CONFIG_AUDIT_TREE=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_SYSFS_DEPRECATED is not set
-# CONFIG_RELAY is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+CONFIG_CGROUP_NS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+# CONFIG_CPUSETS is not set
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_MM_OWNER=y
+CONFIG_CGROUP_MEM_RES_CTLR=y
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
@@ -59,44 +84,66 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 # CONFIG_SLAB is not set
 # CONFIG_SLUB is not set
 CONFIG_SLOB=y
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_KRETPROBES=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=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
 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_STOP_MACHINE=y
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
+# 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_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
-CONFIG_DEFAULT_NOOP=y
-CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+# CONFIG_CLASSIC_RCU is not set
+CONFIG_FREEZER=y
 
 #
 # System type
@@ -105,7 +152,10 @@ CONFIG_CPU_SH4=y
 CONFIG_CPU_SH4A=y
 CONFIG_CPU_SHX3=y
 # CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
 # CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
 # CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
@@ -114,6 +164,7 @@ CONFIG_CPU_SHX3=y
 # CONFIG_CPU_SUBTYPE_SH7710 is not set
 # CONFIG_CPU_SUBTYPE_SH7712 is not set
 # CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
 # CONFIG_CPU_SUBTYPE_SH7091 is not set
 # CONFIG_CPU_SUBTYPE_SH7750R is not set
@@ -122,14 +173,17 @@ CONFIG_CPU_SHX3=y
 # CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
 # CONFIG_CPU_SUBTYPE_SH4_202 is not set
-# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
-# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
 CONFIG_CPU_SUBTYPE_SHX3=y
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
 
 #
 # Memory management options
@@ -139,45 +193,56 @@ CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_29BIT=y
+# CONFIG_X2TLB is not set
 CONFIG_VSYSCALL=y
-# CONFIG_NUMA is not set
-CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_NUMA=y
+CONFIG_NODES_SHIFT=3
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=6
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 CONFIG_ARCH_MEMORY_PROBE=y
-CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_4KB is not set
 # CONFIG_PAGE_SIZE_8KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_HUGETLB_PAGE_SIZE_64K=y
+# CONFIG_PAGE_SIZE_16KB is not set
+CONFIG_PAGE_SIZE_64KB=y
+CONFIG_ENTRY_OFFSET=0x00010000
+# CONFIG_HUGETLB_PAGE_SIZE_64K is not set
 # CONFIG_HUGETLB_PAGE_SIZE_256K is not set
-# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
+CONFIG_HUGETLB_PAGE_SIZE_1MB=y
 # CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
 # CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_512MB is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 # CONFIG_FLATMEM_MANUAL is not set
 # CONFIG_DISCONTIGMEM_MANUAL is not set
 CONFIG_SPARSEMEM_MANUAL=y
 CONFIG_SPARSEMEM=y
+CONFIG_NEED_MULTIPLE_NODES=y
 CONFIG_HAVE_MEMORY_PRESENT=y
 CONFIG_SPARSEMEM_STATIC=y
 CONFIG_MEMORY_HOTPLUG=y
 CONFIG_MEMORY_HOTPLUG_SPARSE=y
+CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
 # CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
 #
 # CONFIG_SH_DIRECT_MAPPED is not set
-# CONFIG_CACHE_WRITEBACK is not set
+CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
-CONFIG_CACHE_OFF=y
+# CONFIG_CACHE_OFF is not set
 
 #
 # Processor features
@@ -202,8 +267,9 @@ CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=50000000
 CONFIG_TICK_ONESHOT=y
-# CONFIG_NO_HZ is not set
+CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 
 #
 # CPU Frequency scaling
@@ -214,7 +280,10 @@ CONFIG_CPU_FREQ_TABLE=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
@@ -245,20 +314,23 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
 CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
-# CONFIG_SMP is not set
+CONFIG_SECCOMP=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
-CONFIG_PREEMPT_BKL=y
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_TRACE=y
 
 #
 # Boot options
 #
 CONFIG_ZERO_PAGE_OFFSET=0x00001000
 CONFIG_BOOT_LINK_OFFSET=0x00800000
-# CONFIG_UBC_WAKEUP is not set
 CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="console=ttySC0,115200 earlyprintk=bios ignore_loglevel"
 
@@ -266,21 +338,15 @@ CONFIG_CMDLINE="console=ttySC0,115200 earlyprintk=bios ignore_loglevel"
 # Bus options
 #
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
 # CONFIG_PCCARD is not set
 
 #
 # 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=y
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -292,6 +358,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -313,6 +380,7 @@ CONFIG_INET_TUNNEL=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -334,8 +402,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_BEET=m
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
@@ -343,6 +413,7 @@ CONFIG_IPV6_SIT=m
 # 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
@@ -352,28 +423,28 @@ CONFIG_IPV6_SIT=m
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
 # CONFIG_NET_SCHED is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
 # CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_AF_RXRPC is not set
+CONFIG_CAN=m
+CONFIG_CAN_RAW=m
+CONFIG_CAN_BCM=m
 
 #
-# Wireless
+# CAN Device Drivers
 #
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+CONFIG_CAN_VCAN=m
+# CONFIG_CAN_DEBUG_DEVICES is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -384,6 +455,7 @@ CONFIG_IPV6_SIT=m
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
@@ -397,14 +469,18 @@ 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_RAM_BLOCKSIZE=1024
+# 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_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
 #
@@ -443,25 +519,41 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
 # CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
+CONFIG_SATA_PMP=y
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_MV is not set
 CONFIG_PATA_PLATFORM=y
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_VETH is not set
 # CONFIG_PHYLIB is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
+# CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 CONFIG_SMC91X=y
+# CONFIG_ENC28J60 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 
@@ -470,10 +562,19 @@ CONFIG_SMC91X=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# 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_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
@@ -495,6 +596,7 @@ CONFIG_SMC91X=y
 # Character devices
 #
 # CONFIG_VT is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -514,6 +616,76 @@ CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=m
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SH_MOBILE 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_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_SH_SCI is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -522,78 +694,158 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_SOFT_WATCHDOG is not set
 # CONFIG_SH_WDT 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 is not set
 
 #
-# SPI support
+# USB-based Watchdog Cards
 #
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
+# CONFIG_USBPCWATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
 
 #
 # Multimedia devices
 #
+
+#
+# Multimedia core support
+#
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
-# CONFIG_DAB is not set
+# CONFIG_VIDEO_MEDIA is not set
 
 #
-# Graphics support
+# Multimedia drivers
 #
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_DAB is not set
 
 #
-# Display device support
+# Graphics support
 #
-# CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Sound
+# Display device support
 #
+# CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_SOUND is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 # CONFIG_USB_ARCH_HAS_EHCI is not set
-# CONFIG_USB is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# 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 is not set
+CONFIG_USB_MON=y
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+CONFIG_USB_R8A66597_HCD=m
+# CONFIG_USB_GADGET_MUSB_HDRC 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 enables SCSI, and 'SCSI disk support'
 #
 
 #
-# USB Gadget Support
+# may also be needed; see USB_STORAGE Help for more information
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
 #
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
 CONFIG_USB_GADGET=y
 # CONFIG_USB_GADGET_DEBUG is not set
 # 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_AMD5536UDC is not set
+# 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_NET2280 is not set
-# CONFIG_USB_GADGET_PXA2XX is not set
-CONFIG_USB_GADGET_M66592=y
-CONFIG_USB_M66592=y
-# CONFIG_USB_GADGET_GOKU 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_PXA27X is not set
 # CONFIG_USB_GADGET_S3C2410 is not set
-# CONFIG_USB_GADGET_AT91 is not set
+CONFIG_USB_GADGET_M66592=y
+CONFIG_USB_M66592=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
 # CONFIG_USB_GADGET_DUMMY_HCD is not set
 CONFIG_USB_GADGET_DUALSPEED=y
 # CONFIG_USB_ZERO is not set
@@ -602,27 +854,78 @@ CONFIG_USB_GADGET_DUALSPEED=y
 # CONFIG_USB_FILE_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_MMC is not set
+# CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
-# CONFIG_RTC_CLASS 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
 
 #
-# DMA Engine support
+# RTC interfaces
 #
-# CONFIG_DMA_ENGINE is not set
+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
 
 #
-# DMA Clients
-#
+# 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
 
 #
-# DMA Devices
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 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
+
 #
+# 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
 
 #
-# Userspace I/O
+# on-CPU RTC drivers
 #
+CONFIG_RTC_DRV_SH=y
+# CONFIG_DMADEVICES is not set
 CONFIG_UIO=m
+# 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
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -634,22 +937,20 @@ CONFIG_EXT3_FS=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_EXT4_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # 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_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
@@ -673,12 +974,12 @@ CONFIG_DNOTIFY=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_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
-CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -693,14 +994,14 @@ CONFIG_RAMFS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_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
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
 # CONFIG_SMB_FS is not set
@@ -714,29 +1015,17 @@ CONFIG_RAMFS=y
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
 # CONFIG_NLS is not set
-
-#
-# Distributed Lock Manager
-#
 # CONFIG_DLM is not set
 
-#
-# Profiling support
-#
-CONFIG_PROFILING=y
-# CONFIG_OPROFILE is not set
-
 #
 # Kernel hacking
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
 # CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
@@ -744,9 +1033,12 @@ CONFIG_DEBUG_FS=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_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
 CONFIG_DEBUG_PREEMPT=y
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
@@ -761,18 +1053,36 @@ CONFIG_DEBUG_PREEMPT=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_VM=y
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
 CONFIG_FRAME_POINTER=y
-CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_KPROBES_SANITY_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
 CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 CONFIG_EARLY_PRINTK=y
 # CONFIG_DEBUG_BOOTMEM is not set
 CONFIG_DEBUG_STACKOVERFLOW=y
 CONFIG_DEBUG_STACK_USAGE=y
-# CONFIG_4KSTACKS is not set
+# CONFIG_IRQSTACKS is not set
 # CONFIG_SH_KGDB is not set
 
 #
@@ -780,7 +1090,92 @@ CONFIG_DEBUG_STACK_USAGE=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
-# CONFIG_CRYPTO is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
@@ -788,10 +1183,12 @@ CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
+CONFIG_AUDIT_GENERIC=y
 CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
index e4e5d21781313fc5bb05a07c9af095f44ab00011..b4ca5110958f07312fdff7be5fd7cf8344b98869 100644 (file)
@@ -1,36 +1,36 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.23-rc1
-# Thu Jul 26 11:49:11 2007
+# Linux kernel version: 2.6.27
+# Wed Oct 22 19:55:03 2008
 #
 CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_BUG=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SWAP is not set
@@ -38,12 +38,15 @@ CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_USER_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -57,6 +60,7 @@ CONFIG_KALLSYMS=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_ANON_INODES=y
@@ -65,10 +69,22 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_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_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
@@ -78,6 +94,7 @@ CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -91,13 +108,18 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
 #
 CONFIG_CPU_SH4=y
 # CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
 # CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
 # CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
@@ -105,6 +127,8 @@ CONFIG_CPU_SH4=y
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
 # CONFIG_CPU_SUBTYPE_SH7710 is not set
 # CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
 # CONFIG_CPU_SUBTYPE_SH7091 is not set
 # CONFIG_CPU_SUBTYPE_SH7750R is not set
@@ -113,14 +137,17 @@ CONFIG_CPU_SH4=y
 CONFIG_CPU_SUBTYPE_SH7751R=y
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
 # CONFIG_CPU_SUBTYPE_SH4_202 is not set
-# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
-# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
 
 #
 # Memory management options
@@ -130,6 +157,7 @@ CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x01000000
+CONFIG_29BIT=y
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -139,7 +167,9 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -147,16 +177,21 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=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=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
 #
 # CONFIG_SH_DIRECT_MAPPED is not set
-# CONFIG_SH_WRITETHROUGH is not set
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
 
 #
 # Processor features
@@ -164,20 +199,18 @@ CONFIG_NR_QUICK=2
 CONFIG_CPU_LITTLE_ENDIAN=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_SH_FPU=y
-# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
 CONFIG_CPU_HAS_INTEVT=y
-CONFIG_CPU_HAS_INTC_IRQ=y
 CONFIG_CPU_HAS_IPR_IRQ=y
 CONFIG_CPU_HAS_SR_RB=y
 CONFIG_CPU_HAS_PTEA=y
+CONFIG_CPU_HAS_FPU=y
 
 #
 # Board support
 #
 # CONFIG_SH_7751_SYSTEMH is not set
 CONFIG_SH_SECUREEDGE5410=y
-# CONFIG_SH_HS7751RVOIP is not set
 # CONFIG_SH_RTS7751R2D is not set
 # CONFIG_SH_LANDISK is not set
 # CONFIG_SH_TITAN is not set
@@ -189,9 +222,9 @@ CONFIG_SH_SECUREEDGE5410=y
 CONFIG_SH_TMU=y
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=60000000
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 
 #
 # CPU Frequency scaling
@@ -224,11 +257,15 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_GUSA=y
+# CONFIG_GUSA_RB is not set
 
 #
 # Boot options
@@ -241,26 +278,20 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000
 #
 # Bus options
 #
-CONFIG_SH_CONCAT_FS=y
 CONFIG_PCI=y
 CONFIG_SH_PCIDMA_NONCOHERENT=y
 CONFIG_PCI_AUTO=y
 CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
+CONFIG_PCI_LEGACY=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
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -286,14 +317,13 @@ CONFIG_IP_FIB_HASH=y
 # CONFIG_INET_XFRM_MODE_TRANSPORT is not set
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
@@ -301,6 +331,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -310,10 +341,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
 # CONFIG_NET_SCHED is not set
 
 #
@@ -321,14 +348,14 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
@@ -352,6 +379,7 @@ CONFIG_MTD=y
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -365,6 +393,7 @@ CONFIG_MTD_BLOCK_RO=y
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
 # CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -401,6 +430,7 @@ CONFIG_MTD_RAM=y
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 # CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
 CONFIG_MTD_PLATRAM=y
 
 #
@@ -437,10 +467,12 @@ CONFIG_BLK_DEV=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
 # CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
 #
@@ -452,44 +484,52 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_SCSI_NETLINK is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
+# CONFIG_FUSION is not set
 
 #
-# Fusion MPT device support
+# IEEE 1394 (FireWire) support
 #
-# CONFIG_FUSION is not set
 
 #
-# IEEE 1394 (FireWire) support
+# Enable only one of the two stacks, unless you know what you are doing
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_VETH is not set
 # CONFIG_ARCNET is not set
 # CONFIG_PHYLIB is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
+# CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_SMC911X is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 # CONFIG_E100 is not set
 # CONFIG_FEALNX is not set
@@ -501,12 +541,14 @@ CONFIG_8139TOO_PIO=y
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
 # CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_R6040 is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_SC92031 is not set
+# CONFIG_ATL2 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
@@ -516,12 +558,12 @@ CONFIG_8139TOO_PIO=y
 #
 # 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
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
@@ -540,7 +582,6 @@ CONFIG_INPUT=y
 #
 # CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
@@ -564,7 +605,9 @@ CONFIG_INPUT=y
 # Character devices
 #
 # CONFIG_VT is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
 
 #
 # Serial drivers
@@ -584,82 +627,77 @@ CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
-
-#
-# SPI support
-#
 # CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # Multimedia devices
 #
+
+#
+# Multimedia core support
+#
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
-# CONFIG_DAB is not set
+# CONFIG_VIDEO_MEDIA is not set
 
 #
-# Graphics support
+# Multimedia drivers
 #
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_DAB is not set
 
 #
-# Display device support
+# Graphics support
 #
-# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Sound
+# Display device support
 #
+# CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_SOUND is not set
 # CONFIG_HID_SUPPORT is not set
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
-
-#
-# Real Time Clock
-#
 # CONFIG_RTC_CLASS is not set
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
-# Userspace I/O
-#
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -668,18 +706,16 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_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_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_ROMFS_FS=y
+# CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
 # CONFIG_QUOTA is not set
-# CONFIG_DNOTIFY is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
@@ -703,12 +739,12 @@ CONFIG_ROMFS_FS=y
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -724,14 +760,14 @@ CONFIG_RAMFS=y
 # CONFIG_JFFS2_FS is not set
 CONFIG_CRAMFS=y
 # CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
 # CONFIG_SMB_FS is not set
@@ -745,34 +781,30 @@ CONFIG_CRAMFS=y
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
 # CONFIG_NLS is not set
-
-#
-# Distributed Lock Manager
-#
 # CONFIG_DLM is not set
 
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
 #
 # Kernel hacking
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_SH_KGDB is not set
@@ -782,6 +814,8 @@ CONFIG_ENABLE_MUST_CHECK=y
 #
 # 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
 
 #
@@ -790,6 +824,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index af921b5a9d4638e368a9a0cc54d0e38ecd5bd21f..1711f0f70d7227584cef2828070df5f8fe7c38a6 100644 (file)
@@ -1,36 +1,50 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18
-# Tue Oct  3 12:57:29 2006
+# Linux kernel version: 2.6.27
+# Wed Oct 22 19:56:48 2008
 #
 CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_UTS_NS is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
@@ -43,34 +57,48 @@ CONFIG_KALLSYMS=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
-CONFIG_SLAB=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
+# CONFIG_MODULE_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_KMOD is not set
-
-#
-# Block layer
-#
+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_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -84,59 +112,27 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
 #
-# CONFIG_SH_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SOLUTION_ENGINE is not set
-# CONFIG_SH_7300_SOLUTION_ENGINE is not set
-# CONFIG_SH_7343_SOLUTION_ENGINE is not set
-# CONFIG_SH_73180_SOLUTION_ENGINE is not set
-CONFIG_SH_7751_SYSTEMH=y
-# CONFIG_SH_HP6XX is not set
-# CONFIG_SH_EC3104 is not set
-# CONFIG_SH_SATURN is not set
-# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_MPC1211 is not set
-# CONFIG_SH_SH03 is not set
-# CONFIG_SH_SECUREEDGE5410 is not set
-# CONFIG_SH_HS7751RVOIP is not set
-# CONFIG_SH_7710VOIPGW is not set
-# CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_R7780RP is not set
-# CONFIG_SH_EDOSK7705 is not set
-# CONFIG_SH_SH4202_MICRODEV is not set
-# CONFIG_SH_LANDISK is not set
-# CONFIG_SH_TITAN is not set
-# CONFIG_SH_SHMIN is not set
-# CONFIG_SH_UNKNOWN is not set
-
-#
-# Processor selection
-#
 CONFIG_CPU_SH4=y
-
-#
-# SH-2 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7604 is not set
-
-#
-# SH-3 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7300 is not set
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
 # CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
 # CONFIG_CPU_SUBTYPE_SH7710 is not set
-
-#
-# SH-4 Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
 # CONFIG_CPU_SUBTYPE_SH7091 is not set
 # CONFIG_CPU_SUBTYPE_SH7750R is not set
@@ -145,65 +141,93 @@ CONFIG_CPU_SH4=y
 CONFIG_CPU_SUBTYPE_SH7751R=y
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
 # CONFIG_CPU_SUBTYPE_SH4_202 is not set
-
-#
-# ST40 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
-# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-
-#
-# SH-4A Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
-
-#
-# SH4AL-DSP Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
 
 #
 # Memory management options
 #
+CONFIG_QUICKLIST=y
 CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x00400000
+CONFIG_29BIT=y
 CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_STATIC=y
+CONFIG_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=0
+CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
 #
 # CONFIG_SH_DIRECT_MAPPED is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
 
 #
 # Processor features
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_SH_FPU=y
-# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
 CONFIG_CPU_HAS_INTEVT=y
 CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEA=y
+CONFIG_CPU_HAS_FPU=y
 
 #
-# Timer support
+# Board support
+#
+CONFIG_SH_7751_SYSTEMH=y
+# CONFIG_SH_SECUREEDGE5410 is not set
+# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_LBOX_RE2 is not set
+
+#
+# Timer and clock configuration
 #
 CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=60000000
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 
 #
 # CPU Frequency scaling
@@ -218,21 +242,31 @@ CONFIG_SH_PCLK_FREQ=60000000
 #
 # Companion Chips
 #
-# CONFIG_HD6446X_SERIES is not set
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_HEARTBEAT is not set
+# CONFIG_PUSH_SWITCH is not set
 
 #
 # Kernel features
 #
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
-# CONFIG_SMP is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
-CONFIG_PREEMPT_BKL=y
+# CONFIG_PREEMPT_RCU is not set
+CONFIG_GUSA=y
+# CONFIG_GUSA_RB is not set
 
 #
 # Boot options
@@ -245,31 +279,15 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000
 #
 # Bus options
 #
-# CONFIG_PCI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-
-#
-# PCI Hotplug Support
-#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 
 #
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_FLAT is not set
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
-
-#
-# Power management options (EXPERIMENTAL)
-#
-# CONFIG_PM is not set
-
-#
-# Networking
-#
 # CONFIG_NET is not set
 
 #
@@ -282,40 +300,21 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_STANDALONE is not set
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-
-#
-# Memory Technology Devices (MTD)
-#
 # CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
 # CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=1024
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
 #
@@ -323,38 +322,10 @@ CONFIG_BLK_DEV_INITRD=y
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
 # CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
 # CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# ISDN subsystem
-#
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
@@ -376,6 +347,7 @@ CONFIG_SERIO=y
 # Character devices
 #
 # CONFIG_VT is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -390,158 +362,115 @@ CONFIG_SERIO=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
 CONFIG_HW_RANDOM=y
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
 # CONFIG_I2C is not set
-
-#
-# SPI support
-#
 # CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
-
-#
-# Hardware Monitoring support
-#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
 # CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
 
 #
-# Misc devices
+# Sonics Silicon Backplane
 #
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
 # Multimedia devices
 #
+
+#
+# Multimedia core support
+#
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
+# CONFIG_VIDEO_MEDIA is not set
 
 #
-# Digital Video Broadcasting Devices
+# Multimedia drivers
 #
+# CONFIG_DAB is not set
 
 #
 # Graphics support
 #
-CONFIG_FIRMWARE_EDID=y
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Sound
+# Display device support
 #
+# CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 # CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# 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
 #
 
 #
-# USB Gadget Support
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 # CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
 # CONFIG_MMC is not set
-
-#
-# LED devices
-#
+# CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
 # CONFIG_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_MINIX_FS is not set
-CONFIG_ROMFS_FS=y
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
@@ -565,12 +494,12 @@ CONFIG_DNOTIFY=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_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -585,8 +514,11 @@ CONFIG_RAMFS=y
 # CONFIG_EFS_FS is not set
 CONFIG_CRAMFS=y
 # 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=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
 
@@ -595,49 +527,55 @@ CONFIG_CRAMFS=y
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
 # CONFIG_NLS is not set
 
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
-# CONFIG_KGDB is not set
+# CONFIG_SH_KGDB is not set
 
 #
 # Security options
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 # CONFIG_CRYPTO is not set
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index 0686ed6fe17a8a5abf5038989711d781565ba08b..ea3c5e838fc3be82aa2eac947d563e828a096907 100644 (file)
@@ -1,41 +1,55 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-rc3
-# Mon Oct 30 18:04:49 2006
+# Linux kernel version: 2.6.27
+# Wed Oct 22 19:58:12 2008
 #
 CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_SYS_SUPPORTS_PCI=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
@@ -49,34 +63,48 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
-CONFIG_SLAB=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
-
-#
-# Block layer
-#
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -90,59 +118,27 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # System type
 #
-# CONFIG_SH_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SOLUTION_ENGINE is not set
-# CONFIG_SH_7300_SOLUTION_ENGINE is not set
-# CONFIG_SH_7343_SOLUTION_ENGINE is not set
-# CONFIG_SH_73180_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_HP6XX is not set
-# CONFIG_SH_EC3104 is not set
-# CONFIG_SH_SATURN is not set
-# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_MPC1211 is not set
-# CONFIG_SH_SH03 is not set
-# CONFIG_SH_SECUREEDGE5410 is not set
-# CONFIG_SH_HS7751RVOIP is not set
-# CONFIG_SH_7710VOIPGW is not set
-# CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_R7780RP is not set
-# CONFIG_SH_EDOSK7705 is not set
-# CONFIG_SH_SH4202_MICRODEV is not set
-# CONFIG_SH_LANDISK is not set
-CONFIG_SH_TITAN=y
-# CONFIG_SH_SHMIN is not set
-# CONFIG_SH_UNKNOWN is not set
-
-#
-# Processor selection
-#
 CONFIG_CPU_SH4=y
-
-#
-# SH-2 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7604 is not set
-
-#
-# SH-3 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7300 is not set
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
 # CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
 # CONFIG_CPU_SUBTYPE_SH7710 is not set
-
-#
-# SH-4 Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
 # CONFIG_CPU_SUBTYPE_SH7091 is not set
 # CONFIG_CPU_SUBTYPE_SH7750R is not set
@@ -151,65 +147,94 @@ CONFIG_CPU_SH4=y
 CONFIG_CPU_SUBTYPE_SH7751R=y
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
 # CONFIG_CPU_SUBTYPE_SH4_202 is not set
-
-#
-# ST40 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
-# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-
-#
-# SH-4A Processor Support
-#
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
-
-#
-# SH4AL-DSP Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
 
 #
 # Memory management options
 #
+CONFIG_QUICKLIST=y
 CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x08030000
 CONFIG_MEMORY_SIZE=0x7fd0000
+CONFIG_29BIT=y
 CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_STATIC=y
+CONFIG_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=0
+CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
 #
 # CONFIG_SH_DIRECT_MAPPED is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
 
 #
 # Processor features
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_SH_FPU=y
-# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
 CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_IPR_IRQ=y
 CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEA=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+# CONFIG_SH_7751_SYSTEMH is not set
+# CONFIG_SH_SECUREEDGE5410 is not set
+# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_LANDISK is not set
+CONFIG_SH_TITAN=y
+# CONFIG_SH_LBOX_RE2 is not set
 
 #
-# Timer support
+# Timer and clock configuration
 #
 CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=30000000
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 
 #
 # CPU Frequency scaling
@@ -219,6 +244,7 @@ CONFIG_SH_PCLK_FREQ=30000000
 #
 # DMA support
 #
+CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
 CONFIG_NR_ONCHIP_DMA_CHANNELS=8
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
@@ -226,20 +252,30 @@ CONFIG_NR_ONCHIP_DMA_CHANNELS=8
 #
 # Companion Chips
 #
-# CONFIG_HD6446X_SERIES is not set
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_HEARTBEAT is not set
+# CONFIG_PUSH_SWITCH is not set
 
 #
 # Kernel features
 #
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
-# CONFIG_SMP is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
+CONFIG_GUSA=y
+# CONFIG_GUSA_RB is not set
 
 #
 # Boot options
@@ -257,17 +293,10 @@ CONFIG_PCI=y
 CONFIG_SH_PCIDMA_NONCOHERENT=y
 CONFIG_PCI_AUTO=y
 CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-# CONFIG_PCI_MULTITHREAD_PROBE is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
 # CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
 CONFIG_HOTPLUG_PCI=y
 # CONFIG_HOTPLUG_PCI_FAKE is not set
 # CONFIG_HOTPLUG_PCI_CPCI is not set
@@ -277,30 +306,25 @@ CONFIG_HOTPLUG_PCI=y
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_FLAT is not set
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
-
-#
-# Power management options (EXPERIMENTAL)
-#
-# CONFIG_PM is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=y
 CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_IP_ADVANCED_ROUTER=y
@@ -308,13 +332,7 @@ CONFIG_ASK_IP_FIB_HASH=y
 # CONFIG_IP_FIB_TRIE is not set
 CONFIG_IP_FIB_HASH=y
 CONFIG_IP_MULTIPLE_TABLES=y
-# CONFIG_IP_ROUTE_FWMARK is not set
 CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_MULTIPATH_CACHED=y
-CONFIG_IP_ROUTE_MULTIPATH_RR=m
-CONFIG_IP_ROUTE_MULTIPATH_RANDOM=m
-CONFIG_IP_ROUTE_MULTIPATH_WRANDOM=m
-CONFIG_IP_ROUTE_MULTIPATH_DRR=m
 # CONFIG_IP_ROUTE_VERBOSE is not set
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
@@ -336,19 +354,17 @@ CONFIG_INET_TUNNEL=y
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
 CONFIG_INET_TCP_DIAG=m
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
+# CONFIG_TCP_MD5SIG is not set
 CONFIG_IPV6=y
 CONFIG_IPV6_PRIVACY=y
 # CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
 CONFIG_INET6_AH=y
 CONFIG_INET6_ESP=y
 CONFIG_INET6_IPCOMP=y
@@ -360,11 +376,14 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y
 CONFIG_INET6_XFRM_MODE_BEET=y
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
 CONFIG_IPV6_TUNNEL=y
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
 # CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
 CONFIG_BRIDGE_NETFILTER=y
 
 #
@@ -373,134 +392,95 @@ CONFIG_BRIDGE_NETFILTER=y
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
+# CONFIG_NF_CONNTRACK is not set
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 # CONFIG_NETFILTER_XT_TARGET_DSCP is not set
 CONFIG_NETFILTER_XT_TARGET_MARK=m
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
-CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
 # CONFIG_NETFILTER_XT_MATCH_DSCP is not set
 CONFIG_NETFILTER_XT_MATCH_ESP=m
-CONFIG_NETFILTER_XT_MATCH_HELPER=m
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
 CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
-CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
 # CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
 CONFIG_NETFILTER_XT_MATCH_REALM=m
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
 CONFIG_NETFILTER_XT_MATCH_SCTP=m
-CONFIG_NETFILTER_XT_MATCH_STATE=m
 # CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
 CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_IP_VS is not set
 
 #
 # IP: Netfilter Configuration
 #
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_CT_ACCT=y
-CONFIG_IP_NF_CONNTRACK_MARK=y
-CONFIG_IP_NF_CONNTRACK_EVENTS=y
-CONFIG_IP_NF_CONNTRACK_NETLINK=m
-# CONFIG_IP_NF_CT_PROTO_SCTP is not set
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-CONFIG_IP_NF_NETBIOS_NS=m
-CONFIG_IP_NF_TFTP=m
-# CONFIG_IP_NF_AMANDA is not set
-CONFIG_IP_NF_PPTP=m
-CONFIG_IP_NF_H323=m
-# CONFIG_IP_NF_SIP is not set
+# CONFIG_NF_DEFRAG_IPV4 is not set
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_RECENT=m
-CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
 CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
 CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_TARGET_NETMAP=m
-CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_PPTP=m
-CONFIG_IP_NF_NAT_H323=m
 CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_ECN=m
 CONFIG_IP_NF_TARGET_TTL=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_RAW=m
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 
 #
-# IPv6: Netfilter Configuration (EXPERIMENTAL)
+# IPv6: Netfilter Configuration
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_RT=m
-CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
 CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_HL=m
-CONFIG_IP6_NF_MATCH_OWNER=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_AH=m
-CONFIG_IP6_NF_MATCH_EUI64=m
-CONFIG_IP6_NF_FILTER=m
+# CONFIG_IP6_NF_MATCH_MH is not set
+CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
-
-#
-# Bridge: Netfilter Configuration
-#
 # CONFIG_BRIDGE_NF_EBTABLES is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
+CONFIG_STP=y
 CONFIG_BRIDGE=y
+# CONFIG_NET_DSA is not set
 CONFIG_VLAN_8021Q=y
+# CONFIG_VLAN_8021Q_GVRP is not set
 # CONFIG_DECNET is not set
 CONFIG_LLC=y
 # CONFIG_LLC2 is not set
@@ -510,14 +490,7 @@ CONFIG_LLC=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
 CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_CLK_JIFFIES=y
-# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
-# CONFIG_NET_SCH_CLK_CPU is not set
 
 #
 # Queueing/Scheduling
@@ -526,6 +499,7 @@ CONFIG_NET_SCH_CBQ=m
 CONFIG_NET_SCH_HTB=m
 CONFIG_NET_SCH_HFSC=m
 CONFIG_NET_SCH_PRIO=m
+# CONFIG_NET_SCH_MULTIQ is not set
 CONFIG_NET_SCH_RED=m
 CONFIG_NET_SCH_SFQ=m
 CONFIG_NET_SCH_TEQL=m
@@ -549,6 +523,7 @@ CONFIG_CLS_U32_PERF=y
 CONFIG_CLS_U32_MARK=y
 CONFIG_NET_CLS_RSVP=m
 CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_CLS_FLOW is not set
 CONFIG_NET_EMATCH=y
 CONFIG_NET_EMATCH_STACK=32
 CONFIG_NET_EMATCH_CMP=m
@@ -562,27 +537,37 @@ CONFIG_NET_ACT_GACT=m
 CONFIG_GACT_PROB=y
 CONFIG_NET_ACT_MIRRED=m
 CONFIG_NET_ACT_IPT=m
+# CONFIG_NET_ACT_NAT is not set
 CONFIG_NET_ACT_PEDIT=m
 # CONFIG_NET_ACT_SIMP is not set
+# CONFIG_NET_ACT_SKBEDIT is not set
 CONFIG_NET_CLS_IND=y
-CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_SCH_FIFO=y
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_FIB_RULES=y
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=y
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=y
 CONFIG_IEEE80211_CRYPT_CCMP=y
 CONFIG_IEEE80211_CRYPT_TKIP=y
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-CONFIG_WIRELESS_EXT=y
-CONFIG_FIB_RULES=y
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -591,20 +576,16 @@ CONFIG_FIB_RULES=y
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 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
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
 CONFIG_CONNECTOR=m
-
-#
-# Memory Technology Devices (MTD)
-#
 CONFIG_MTD=m
 CONFIG_MTD_DEBUG=y
 CONFIG_MTD_DEBUG_VERBOSE=0
@@ -615,6 +596,7 @@ CONFIG_MTD_DEBUG_VERBOSE=0
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLKDEVS=m
 CONFIG_MTD_BLOCK=m
 # CONFIG_MTD_BLOCK_RO is not set
 CONFIG_FTL=m
@@ -623,6 +605,7 @@ CONFIG_NFTL=m
 CONFIG_INFTL=m
 CONFIG_RFD_FTL=m
 # CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -644,16 +627,17 @@ CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_CFI_INTELEXT is not set
 # CONFIG_MTD_CFI_AMDSTD is not set
 # CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=m
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 # CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -671,34 +655,23 @@ CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 CONFIG_MTD_NAND=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_DISKONCHIP is not set
-
-#
-# OneNAND Flash Device Drivers
-#
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
 # CONFIG_MTD_ONENAND is not set
 
 #
-# Parallel port support
+# UBI - Unsorted block images
 #
+# CONFIG_MTD_UBI is not set
 # CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_CPQ_DA is not set
+CONFIG_BLK_DEV=y
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
@@ -711,20 +684,18 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 CONFIG_ATA_OVER_ETH=m
-
-#
-# Misc devices
-#
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
 #
@@ -732,6 +703,8 @@ CONFIG_ATA_OVER_ETH=m
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
 # CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
@@ -752,6 +725,8 @@ CONFIG_CHR_DEV_SG=m
 # 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
@@ -759,12 +734,9 @@ CONFIG_CHR_DEV_SG=m
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
 # CONFIG_SCSI_SAS_LIBSAS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
@@ -774,7 +746,6 @@ CONFIG_CHR_DEV_SG=m
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_AIC94XX is not set
-# CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
@@ -785,6 +756,7 @@ CONFIG_CHR_DEV_SG=m
 # 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_QLOGIC_1280 is not set
@@ -795,53 +767,31 @@ CONFIG_CHR_DEV_SG=m
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_DH is not set
 # CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
 # CONFIG_FUSION is not set
-# CONFIG_FUSION_SPI is not set
-# CONFIG_FUSION_FC is not set
-# CONFIG_FUSION_SAS is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
-# CONFIG_IEEE1394 is not set
 
 #
-# I2O device support
+# Enable only one of the two stacks, unless you know what you are doing
 #
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
 # CONFIG_IFB is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 CONFIG_TUN=m
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
 # CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
 CONFIG_PHYLIB=m
 
 #
@@ -854,32 +804,35 @@ CONFIG_LXT_PHY=m
 CONFIG_CICADA_PHY=m
 # CONFIG_VITESSE_PHY is not set
 # CONFIG_SMSC_PHY is not set
-# CONFIG_FIXED_PHY is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
+# CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
-
-#
-# Tulip family network device support
-#
+# CONFIG_SMC911X is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 # CONFIG_E100 is not set
 # CONFIG_FEALNX is not set
@@ -891,18 +844,21 @@ CONFIG_8139TOO=y
 CONFIG_8139TOO_TUNE_TWISTER=y
 # CONFIG_8139TOO_8129 is not set
 CONFIG_8139_OLD_RX_RESET=y
+# CONFIG_R6040 is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-
-#
-# Ethernet (1000 Mbit)
-#
+# CONFIG_SC92031 is not set
+# CONFIG_ATL2 is not set
+CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 # CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -910,63 +866,56 @@ CONFIG_8139_OLD_RX_RESET=y
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
 # CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 # CONFIG_QLA3XXX is not set
-
-#
-# Ethernet (10000 Mbit)
-#
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_JME is not set
+CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_ENIC is not set
+# CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
-
-#
-# Token Ring devices
-#
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
+# CONFIG_QLGE is not set
+# CONFIG_SFC is not set
 # CONFIG_TR is not set
 
 #
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-CONFIG_NET_WIRELESS_RTNETLINK=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-# CONFIG_IPW2100 is not set
-# CONFIG_IPW2200 is not set
-# CONFIG_HERMES is not set
-# CONFIG_ATMEL is not set
-
-#
-# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+# Wireless LAN
 #
-CONFIG_PRISM54=m
-# CONFIG_USB_ZD1201 is not set
-# CONFIG_HOSTAP is not set
-CONFIG_BCM43XX=m
-CONFIG_BCM43XX_DEBUG=y
-CONFIG_BCM43XX_DMA=y
-CONFIG_BCM43XX_PIO=y
-CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
-# CONFIG_BCM43XX_DMA_MODE is not set
-# CONFIG_BCM43XX_PIO_MODE is not set
-# CONFIG_ZD1211RW is not set
-CONFIG_NET_WIRELESS=y
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
 
 #
-# Wan interfaces
+# USB Network Adapters
 #
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+# CONFIG_USB_NET_DM9601 is not set
+# CONFIG_USB_NET_SMSC95XX is not set
+# CONFIG_USB_NET_GL620A is not set
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+# CONFIG_USB_NET_MCS7830 is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+CONFIG_USB_NET_ZAURUS=m
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -979,25 +928,17 @@ CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
 CONFIG_SLIP=m
 CONFIG_SLIP_COMPRESSED=y
 CONFIG_SLHC=m
 CONFIG_SLIP_SMART=y
 # CONFIG_SLIP_MODE_SLIP6 is not set
 # CONFIG_NET_FC is not set
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
 # CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
@@ -1005,6 +946,7 @@ CONFIG_SLIP_SMART=y
 #
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -1014,7 +956,6 @@ CONFIG_INPUT_MOUSEDEV=y
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
@@ -1024,6 +965,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
@@ -1037,10 +979,13 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 # CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
 
 #
 # Serial drivers
@@ -1059,15 +1004,36 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
+CONFIG_HW_RANDOM=y
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_I2C is not set
+# CONFIG_SPI 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_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -1075,6 +1041,7 @@ CONFIG_WATCHDOG=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ALIM7101_WDT is not set
 CONFIG_SH_WDT=m
 # CONFIG_SH_WDT_MMAP is not set
 
@@ -1088,113 +1055,121 @@ CONFIG_SH_WDT=m
 # USB-based Watchdog Cards
 #
 # CONFIG_USBPCWATCHDOG is not set
-CONFIG_HW_RANDOM=y
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
 
 #
-# Ftape, the floppy tape device driver
+# Sonics Silicon Backplane
 #
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
-# I2C support
+# Multifunction device drivers
 #
-# CONFIG_I2C is not set
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
 
 #
-# SPI support
+# Multimedia devices
 #
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
 
 #
-# Dallas's 1-wire bus
+# Multimedia core support
 #
-# CONFIG_W1 is not set
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
 
 #
-# Hardware Monitoring support
+# Multimedia drivers
 #
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_DAB is not set
 
 #
-# Multimedia devices
+# Graphics support
 #
-# CONFIG_VIDEO_DEV is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Digital Video Broadcasting Devices
+# Display device support
 #
-# CONFIG_DVB is not set
-# CONFIG_USB_DABUSB is not set
+# CONFIG_DISPLAY_SUPPORT is not set
 
 #
-# Graphics support
+# Console display driver support
 #
-CONFIG_FIRMWARE_EDID=y
-# CONFIG_FB is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
 
 #
-# Console display driver support
+# USB Input Devices
 #
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_USB_HID is not set
+# CONFIG_HID_PID is not set
 
 #
-# Sound
+# USB HID Boot Protocol drivers
 #
-# CONFIG_SOUND is not set
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
 
 #
-# USB support
+# Special HID drivers
 #
+CONFIG_HID_COMPAT=y
+CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
 
 #
 # Miscellaneous USB options
 #
 CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
+CONFIG_USB_DEVICE_CLASS=y
 # 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 is not set
+CONFIG_USB_MON=y
 
 #
 # USB Host Controller Drivers
 #
+# CONFIG_USB_C67X00_HCD is not set
 CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_SPLIT_ISO=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 CONFIG_USB_EHCI_TT_NEWSCHED=y
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=y
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
 
 #
 # USB Device Class drivers
 #
 CONFIG_USB_ACM=m
 CONFIG_USB_PRINTER=m
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -1207,76 +1182,34 @@ 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
 # 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 Input Devices
-#
-# CONFIG_USB_HID is not set
-
-#
-# USB HID Boot Protocol drivers
-#
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_ACECAD is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_TOUCHSCREEN is not set
-# CONFIG_USB_YEALINK is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-# CONFIG_USB_ATI_REMOTE2 is not set
-# CONFIG_USB_KEYSPAN_REMOTE is not set
-# CONFIG_USB_APPLETOUCH is not set
-
 #
 # USB Imaging devices
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
 
-#
-# USB Network Adapters
-#
-CONFIG_USB_CATC=m
-CONFIG_USB_KAWETH=m
-CONFIG_USB_PEGASUS=m
-CONFIG_USB_RTL8150=m
-CONFIG_USB_USBNET=m
-CONFIG_USB_NET_AX8817X=m
-CONFIG_USB_NET_CDCETHER=m
-# CONFIG_USB_NET_GL620A is not set
-CONFIG_USB_NET_NET1080=m
-CONFIG_USB_NET_PLUSB=m
-# CONFIG_USB_NET_MCS7830 is not set
-# CONFIG_USB_NET_RNDIS_HOST is not set
-# CONFIG_USB_NET_CDC_SUBSET is not set
-CONFIG_USB_NET_ZAURUS=m
-CONFIG_USB_MON=y
-
 #
 # USB port drivers
 #
-
-#
-# USB Serial Converter support
-#
 CONFIG_USB_SERIAL=m
+# CONFIG_USB_EZUSB is not set
 CONFIG_USB_SERIAL_GENERIC=y
 # CONFIG_USB_SERIAL_AIRCABLE is not set
-# CONFIG_USB_SERIAL_AIRPRIME is not set
 CONFIG_USB_SERIAL_ARK3116=m
 # CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
 # CONFIG_USB_SERIAL_WHITEHEAT is not set
 # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
 # CONFIG_USB_SERIAL_CP2101 is not set
@@ -1291,6 +1224,7 @@ CONFIG_USB_SERIAL_ARK3116=m
 # CONFIG_USB_SERIAL_EDGEPORT_TI is not set
 # CONFIG_USB_SERIAL_GARMIN is not set
 # CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
 # CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
 # CONFIG_USB_SERIAL_KEYSPAN is not set
 # CONFIG_USB_SERIAL_KLSI is not set
@@ -1298,8 +1232,11 @@ CONFIG_USB_SERIAL_ARK3116=m
 # CONFIG_USB_SERIAL_MCT_U232 is not set
 # CONFIG_USB_SERIAL_MOS7720 is not set
 # CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
 # CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
 # CONFIG_USB_SERIAL_HP4X is not set
 # CONFIG_USB_SERIAL_SAFE is not set
 # CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
@@ -1308,6 +1245,7 @@ CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_SERIAL_XIRCOM is not set
 # CONFIG_USB_SERIAL_OPTION is not set
 # CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
 
 #
 # USB Miscellaneous drivers
@@ -1315,10 +1253,11 @@ CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_SEVSEG is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# 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
@@ -1329,80 +1268,53 @@ CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
 # CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
-#
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
 # CONFIG_MMC is not set
-
-#
-# LED devices
-#
+# CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
 CONFIG_RTC_LIB=m
 CONFIG_RTC_CLASS=m
 
 #
 # RTC interfaces
 #
-CONFIG_RTC_INTF_SYSFS=m
-CONFIG_RTC_INTF_PROC=m
-CONFIG_RTC_INTF_DEV=m
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
-
-#
-# RTC drivers
-#
-# CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_DS1742 is not set
-# CONFIG_RTC_DRV_M48T86 is not set
-CONFIG_RTC_DRV_SH=m
 # CONFIG_RTC_DRV_TEST is not set
-# CONFIG_RTC_DRV_V3020 is not set
 
 #
-# DMA Engine support
+# SPI RTC drivers
 #
-# CONFIG_DMA_ENGINE is not set
 
 #
-# DMA Clients
+# 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
 
 #
-# DMA Devices
+# on-CPU RTC drivers
 #
+CONFIG_RTC_DRV_SH=m
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -1412,31 +1324,25 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
-CONFIG_EXT4DEV_FS=m
-# CONFIG_EXT4DEV_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
 CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_JBD2=m
-# CONFIG_JBD2_DEBUG is not set
 CONFIG_REISERFS_FS=m
 # CONFIG_REISERFS_CHECK is not set
 # CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_REISERFS_FS_XATTR is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
 CONFIG_XFS_FS=m
 # CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_SECURITY is not set
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
-# CONFIG_GFS2_FS is not set
+# CONFIG_XFS_DEBUG is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_ROMFS_FS=y
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_FUSE_FS=m
@@ -1447,7 +1353,6 @@ CONFIG_FUSE_FS=m
 CONFIG_ISO9660_FS=m
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
-CONFIG_ZISOFS_FS=m
 CONFIG_UDF_FS=m
 CONFIG_UDF_NLS=y
 
@@ -1467,12 +1372,12 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 CONFIG_CONFIGFS_FS=m
 
 #
@@ -1485,34 +1390,32 @@ CONFIG_CONFIGFS_FS=m
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_NFSD_TCP=y
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
+# 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
@@ -1526,7 +1429,6 @@ CONFIG_CIFS_WEAK_PW_HASH=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-CONFIG_9P_FS=m
 
 #
 # Partition Types
@@ -1548,10 +1450,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SUN_PARTITION is not set
 # CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
-
-#
-# Native Language Support
-#
+# CONFIG_SYSV68_PARTITION is not set
 CONFIG_NLS=m
 CONFIG_NLS_DEFAULT="iso8859-1"
 CONFIG_NLS_CODEPAGE_437=m
@@ -1592,101 +1491,180 @@ CONFIG_NLS_ISO8859_1=m
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=m
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
+# CONFIG_DLM is not set
 
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_DEBUG_SHIRQ is not set
 # CONFIG_DETECT_SOFTLOCKUP is not set
+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_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
-# CONFIG_DEBUG_RWSEMS 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 is not set
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
 # CONFIG_FRAME_POINTER is not set
-# CONFIG_FORCED_INLINING is not set
-# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
-# CONFIG_EARLY_PRINTK is not set
+# CONFIG_DEBUG_BOOTMEM is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_4KSTACKS is not set
-# CONFIG_KGDB is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_SH_KGDB is not set
 
 #
 # Security options
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
 
 #
-# Cryptographic options
+# Crypto core or helper
 #
-CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
 CONFIG_CRYPTO_BLKCIPHER=y
 CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_RNG=y
 CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_GF128MUL is not set
 CONFIG_CRYPTO_NULL=m
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# 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=y
+# 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=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 CONFIG_CRYPTO_SHA1=y
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_TWOFISH_COMMON=m
-CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
 CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=m
+# CONFIG_CRYPTO_CAMELLIA is not set
 CONFIG_CRYPTO_CAST5=m
 CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
 CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
 CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
-CONFIG_CRYPTO_CRC32C=m
-# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_LZO is not set
 
 #
-# Hardware crypto devices
+# Random Number Generation
 #
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
@@ -1695,3 +1673,6 @@ CONFIG_TEXTSEARCH_KMP=m
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
 CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index 9650e7c9c39e989c5763cca1182a4c5c69f8ae9a..90673658eb14c19e5506ebcda7c3024084fbd036 100644 (file)
@@ -12,6 +12,9 @@
 #ifndef __ASM_SH_GPIO_H
 #define __ASM_SH_GPIO_H
 
+#include <linux/kernel.h>
+#include <linux/errno.h>
+
 #if defined(CONFIG_CPU_SH3)
 #include <cpu/gpio.h>
 #endif
@@ -62,6 +65,7 @@ struct pinmux_data_reg {
 struct pinmux_range {
        pinmux_enum_t begin;
        pinmux_enum_t end;
+       pinmux_enum_t force;
 };
 
 struct pinmux_info {
@@ -99,9 +103,20 @@ int gpio_direction_input(unsigned gpio);
 int gpio_direction_output(unsigned gpio, int value);
 int gpio_get_value(unsigned gpio);
 void gpio_set_value(unsigned gpio, int value);
-static inline int gpio_export(unsigned gpio, bool direction_may_change)
+
+/* IRQ modes are unspported */
+static inline int gpio_to_irq(unsigned gpio)
+{
+       WARN_ON(1);
+       return -EINVAL;
+}
+
+static inline int irq_to_gpio(unsigned irq)
 {
-       return 0;
+       WARN_ON(1);
+       return -EINVAL;
 }
 
+#include <asm-generic/gpio.h>
+
 #endif /* __ASM_SH_GPIO_H */
index 49cd69051a8896392fa1c9335c1770c802d1aa15..0b9f896f203c20ff35972de69c20dd9d7463c928 100644 (file)
@@ -4,6 +4,7 @@
 /* Grossly misnamed. */
 enum die_val {
        DIE_TRAP,
+       DIE_OOPS,
 };
 
 #endif /* __ASM_SH_KDEBUG_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7785.h b/arch/sh/include/cpu-sh4/cpu/sh7785.h
new file mode 100644 (file)
index 0000000..e4006af
--- /dev/null
@@ -0,0 +1,234 @@
+#ifndef __ASM_SH7785_H__
+#define __ASM_SH7785_H__
+
+enum {
+       /* PA */
+       GPIO_PA7, GPIO_PA6, GPIO_PA5, GPIO_PA4,
+       GPIO_PA3, GPIO_PA2, GPIO_PA1, GPIO_PA0,
+
+       /* PB */
+       GPIO_PB7, GPIO_PB6, GPIO_PB5, GPIO_PB4,
+       GPIO_PB3, GPIO_PB2, GPIO_PB1, GPIO_PB0,
+
+       /* PC */
+       GPIO_PC7, GPIO_PC6, GPIO_PC5, GPIO_PC4,
+       GPIO_PC3, GPIO_PC2, GPIO_PC1, GPIO_PC0,
+
+       /* PD */
+       GPIO_PD7, GPIO_PD6, GPIO_PD5, GPIO_PD4,
+       GPIO_PD3, GPIO_PD2, GPIO_PD1, GPIO_PD0,
+
+       /* PE */
+       GPIO_PE5, GPIO_PE4, GPIO_PE3, GPIO_PE2,
+       GPIO_PE1, GPIO_PE0,
+
+       /* PF */
+       GPIO_PF7, GPIO_PF6, GPIO_PF5, GPIO_PF4,
+       GPIO_PF3, GPIO_PF2, GPIO_PF1, GPIO_PF0,
+
+       /* PG */
+       GPIO_PG7, GPIO_PG6, GPIO_PG5, GPIO_PG4,
+       GPIO_PG3, GPIO_PG2, GPIO_PG1, GPIO_PG0,
+
+       /* PH */
+       GPIO_PH7, GPIO_PH6, GPIO_PH5, GPIO_PH4,
+       GPIO_PH3, GPIO_PH2, GPIO_PH1, GPIO_PH0,
+
+       /* PJ */
+       GPIO_PJ7, GPIO_PJ6, GPIO_PJ5, GPIO_PJ4,
+       GPIO_PJ3, GPIO_PJ2, GPIO_PJ1, GPIO_PJ0,
+
+       /* PK */
+       GPIO_PK7, GPIO_PK6, GPIO_PK5, GPIO_PK4,
+       GPIO_PK3, GPIO_PK2, GPIO_PK1, GPIO_PK0,
+
+       /* PL */
+       GPIO_PL7, GPIO_PL6, GPIO_PL5, GPIO_PL4,
+       GPIO_PL3, GPIO_PL2, GPIO_PL1, GPIO_PL0,
+
+       /* PM */
+       GPIO_PM1, GPIO_PM0,
+
+       /* PN */
+       GPIO_PN7, GPIO_PN6, GPIO_PN5, GPIO_PN4,
+       GPIO_PN3, GPIO_PN2, GPIO_PN1, GPIO_PN0,
+
+       /* PP */
+       GPIO_PP5, GPIO_PP4,
+       GPIO_PP3, GPIO_PP2, GPIO_PP1, GPIO_PP0,
+
+       /* PQ */
+       GPIO_PQ4,
+       GPIO_PQ3, GPIO_PQ2, GPIO_PQ1, GPIO_PQ0,
+
+       /* PR */
+       GPIO_PR3, GPIO_PR2, GPIO_PR1, GPIO_PR0,
+
+       GPIO_FN_D63_AD31,
+       GPIO_FN_D62_AD30,
+       GPIO_FN_D61_AD29,
+       GPIO_FN_D60_AD28,
+       GPIO_FN_D59_AD27,
+       GPIO_FN_D58_AD26,
+       GPIO_FN_D57_AD25,
+       GPIO_FN_D56_AD24,
+       GPIO_FN_D55_AD23,
+       GPIO_FN_D54_AD22,
+       GPIO_FN_D53_AD21,
+       GPIO_FN_D52_AD20,
+       GPIO_FN_D51_AD19,
+       GPIO_FN_D50_AD18,
+       GPIO_FN_D49_AD17_DB5,
+       GPIO_FN_D48_AD16_DB4,
+       GPIO_FN_D47_AD15_DB3,
+       GPIO_FN_D46_AD14_DB2,
+       GPIO_FN_D45_AD13_DB1,
+       GPIO_FN_D44_AD12_DB0,
+       GPIO_FN_D43_AD11_DG5,
+       GPIO_FN_D42_AD10_DG4,
+       GPIO_FN_D41_AD9_DG3,
+       GPIO_FN_D40_AD8_DG2,
+       GPIO_FN_D39_AD7_DG1,
+       GPIO_FN_D38_AD6_DG0,
+       GPIO_FN_D37_AD5_DR5,
+       GPIO_FN_D36_AD4_DR4,
+       GPIO_FN_D35_AD3_DR3,
+       GPIO_FN_D34_AD2_DR2,
+       GPIO_FN_D33_AD1_DR1,
+       GPIO_FN_D32_AD0_DR0,
+       GPIO_FN_REQ1,
+       GPIO_FN_REQ2,
+       GPIO_FN_REQ3,
+       GPIO_FN_GNT1,
+       GPIO_FN_GNT2,
+       GPIO_FN_GNT3,
+       GPIO_FN_MMCCLK,
+       GPIO_FN_D31,
+       GPIO_FN_D30,
+       GPIO_FN_D29,
+       GPIO_FN_D28,
+       GPIO_FN_D27,
+       GPIO_FN_D26,
+       GPIO_FN_D25,
+       GPIO_FN_D24,
+       GPIO_FN_D23,
+       GPIO_FN_D22,
+       GPIO_FN_D21,
+       GPIO_FN_D20,
+       GPIO_FN_D19,
+       GPIO_FN_D18,
+       GPIO_FN_D17,
+       GPIO_FN_D16,
+       GPIO_FN_SCIF1_SCK,
+       GPIO_FN_SCIF1_RXD,
+       GPIO_FN_SCIF1_TXD,
+       GPIO_FN_SCIF0_CTS,
+       GPIO_FN_INTD,
+       GPIO_FN_FCE,
+       GPIO_FN_SCIF0_RTS,
+       GPIO_FN_HSPI_CS,
+       GPIO_FN_FSE,
+       GPIO_FN_SCIF0_SCK,
+       GPIO_FN_HSPI_CLK,
+       GPIO_FN_FRE,
+       GPIO_FN_SCIF0_RXD,
+       GPIO_FN_HSPI_RX,
+       GPIO_FN_FRB,
+       GPIO_FN_SCIF0_TXD,
+       GPIO_FN_HSPI_TX,
+       GPIO_FN_FWE,
+       GPIO_FN_SCIF5_TXD,
+       GPIO_FN_HAC1_SYNC,
+       GPIO_FN_SSI1_WS,
+       GPIO_FN_SIOF_TXD_PJ,
+       GPIO_FN_HAC0_SDOUT,
+       GPIO_FN_SSI0_SDATA,
+       GPIO_FN_SIOF_RXD_PJ,
+       GPIO_FN_HAC0_SDIN,
+       GPIO_FN_SSI0_SCK,
+       GPIO_FN_SIOF_SYNC_PJ,
+       GPIO_FN_HAC0_SYNC,
+       GPIO_FN_SSI0_WS,
+       GPIO_FN_SIOF_MCLK_PJ,
+       GPIO_FN_HAC_RES,
+       GPIO_FN_SIOF_SCK_PJ,
+       GPIO_FN_HAC0_BITCLK,
+       GPIO_FN_SSI0_CLK,
+       GPIO_FN_HAC1_BITCLK,
+       GPIO_FN_SSI1_CLK,
+       GPIO_FN_TCLK,
+       GPIO_FN_IOIS16,
+       GPIO_FN_STATUS0,
+       GPIO_FN_DRAK0_PK3,
+       GPIO_FN_STATUS1,
+       GPIO_FN_DRAK1_PK2,
+       GPIO_FN_DACK2,
+       GPIO_FN_SCIF2_TXD,
+       GPIO_FN_MMCCMD,
+       GPIO_FN_SIOF_TXD_PK,
+       GPIO_FN_DACK3,
+       GPIO_FN_SCIF2_SCK,
+       GPIO_FN_MMCDAT,
+       GPIO_FN_SIOF_SCK_PK,
+       GPIO_FN_DREQ0,
+       GPIO_FN_DREQ1,
+       GPIO_FN_DRAK0_PK1,
+       GPIO_FN_DRAK1_PK0,
+       GPIO_FN_DREQ2,
+       GPIO_FN_INTB,
+       GPIO_FN_DREQ3,
+       GPIO_FN_INTC,
+       GPIO_FN_DRAK2,
+       GPIO_FN_CE2A,
+       GPIO_FN_IRL4,
+       GPIO_FN_FD4,
+       GPIO_FN_IRL5,
+       GPIO_FN_FD5,
+       GPIO_FN_IRL6,
+       GPIO_FN_FD6,
+       GPIO_FN_IRL7,
+       GPIO_FN_FD7,
+       GPIO_FN_DRAK3,
+       GPIO_FN_CE2B,
+       GPIO_FN_BREQ_BSACK,
+       GPIO_FN_BACK_BSREQ,
+       GPIO_FN_SCIF5_RXD,
+       GPIO_FN_HAC1_SDIN,
+       GPIO_FN_SSI1_SCK,
+       GPIO_FN_SCIF5_SCK,
+       GPIO_FN_HAC1_SDOUT,
+       GPIO_FN_SSI1_SDATA,
+       GPIO_FN_SCIF3_TXD,
+       GPIO_FN_FCLE,
+       GPIO_FN_SCIF3_RXD,
+       GPIO_FN_FALE,
+       GPIO_FN_SCIF3_SCK,
+       GPIO_FN_FD0,
+       GPIO_FN_SCIF4_TXD,
+       GPIO_FN_FD1,
+       GPIO_FN_SCIF4_RXD,
+       GPIO_FN_FD2,
+       GPIO_FN_SCIF4_SCK,
+       GPIO_FN_FD3,
+       GPIO_FN_DEVSEL_DCLKOUT,
+       GPIO_FN_STOP_CDE,
+       GPIO_FN_LOCK_ODDF,
+       GPIO_FN_TRDY_DISPL,
+       GPIO_FN_IRDY_HSYNC,
+       GPIO_FN_PCIFRAME_VSYNC,
+       GPIO_FN_INTA,
+       GPIO_FN_GNT0_GNTIN,
+       GPIO_FN_REQ0_REQOUT,
+       GPIO_FN_PERR,
+       GPIO_FN_SERR,
+       GPIO_FN_WE7_CBE3,
+       GPIO_FN_WE6_CBE2,
+       GPIO_FN_WE5_CBE1,
+       GPIO_FN_WE4_CBE0,
+       GPIO_FN_SCIF2_RXD,
+       GPIO_FN_SIOF_RXD,
+       GPIO_FN_MRESETOUT,
+       GPIO_FN_IRQOUT,
+};
+
+#endif /* __ASM_SH7785_H__ */
index 306f7359f7d4c345a9cb8b19b7556d79720a3969..bd26a848cb0b3a2a991d31460089baa71800b792 100644 (file)
 
 unsigned char *highlander_plat_irq_setup(void);
 
+#ifdef CONFIG_SH_R7785RP
+void highlander_plat_pinmux_setup(void);
+#else
+#define highlander_plat_pinmux_setup() do { } while (0)
+#endif
+
 #endif  /* __ASM_SH_RENESAS_R7780RP */
index 39a5b880418fa88d8469669d0a5937a36c5cd240..c465af7283fc89793ad1da0f76cb756e1c5b5237 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/gpio.h>
-#include <asm/sh7203.h>
+#include <cpu/sh7203.h>
 
 enum {
        PINMUX_RESERVED = 0,
@@ -46,11 +46,10 @@ enum {
        PINMUX_DATA_END,
 
        PINMUX_INPUT_BEGIN,
+       FORCE_IN,
        PA7_IN, PA6_IN, PA5_IN, PA4_IN,
        PA3_IN, PA2_IN, PA1_IN, PA0_IN,
        PB11_IN, PB10_IN, PB9_IN, PB8_IN,
-       PB7_IN, PB6_IN, PB5_IN, PB4_IN,
-       PB3_IN, PB2_IN, PB1_IN, PB0_IN,
        PC14_IN, PC13_IN, PC12_IN,
        PC11_IN, PC10_IN, PC9_IN, PC8_IN,
        PC7_IN, PC6_IN, PC5_IN, PC4_IN,
@@ -74,7 +73,7 @@ enum {
        PINMUX_INPUT_END,
 
        PINMUX_OUTPUT_BEGIN,
-       PB12_OUT,
+       FORCE_OUT,
        PB11_OUT, PB10_OUT, PB9_OUT, PB8_OUT,
        PC14_OUT, PC13_OUT, PC12_OUT,
        PC11_OUT, PC10_OUT, PC9_OUT, PC8_OUT,
@@ -285,7 +284,7 @@ static pinmux_enum_t pinmux_data[] = {
        PINMUX_DATA(PA0_DATA, PA0_IN),
 
        /* PB */
-       PINMUX_DATA(PB12_DATA, PB12MD_00, PB12_OUT),
+       PINMUX_DATA(PB12_DATA, PB12MD_00, FORCE_OUT),
        PINMUX_DATA(WDTOVF_MARK, PB12MD_01),
        PINMUX_DATA(IRQOUT_MARK, PB12MD_10, PB12IRQ_00),
        PINMUX_DATA(REFOUT_MARK, PB12MD_10, PB12IRQ_01),
@@ -306,42 +305,42 @@ static pinmux_enum_t pinmux_data[] = {
        PINMUX_DATA(CRX0_MARK, PB8MD_01),
        PINMUX_DATA(CRX0_CRX1_MARK, PB8MD_10),
 
-       PINMUX_DATA(PB7_DATA, PB7MD_00, PB7_IN),
+       PINMUX_DATA(PB7_DATA, PB7MD_00, FORCE_IN),
        PINMUX_DATA(SDA3_MARK, PB7MD_01),
        PINMUX_DATA(PINT7_PB_MARK, PB7MD_10),
        PINMUX_DATA(IRQ7_PB_MARK, PB7MD_11),
 
-       PINMUX_DATA(PB6_DATA, PB6MD_00, PB6_IN),
+       PINMUX_DATA(PB6_DATA, PB6MD_00, FORCE_IN),
        PINMUX_DATA(SCL3_MARK, PB6MD_01),
        PINMUX_DATA(PINT6_PB_MARK, PB6MD_10),
        PINMUX_DATA(IRQ6_PB_MARK, PB6MD_11),
 
-       PINMUX_DATA(PB5_DATA, PB5MD_00, PB5_IN),
+       PINMUX_DATA(PB5_DATA, PB5MD_00, FORCE_IN),
        PINMUX_DATA(SDA2_MARK, PB6MD_01),
        PINMUX_DATA(PINT5_PB_MARK, PB6MD_10),
        PINMUX_DATA(IRQ5_PB_MARK, PB6MD_11),
 
-       PINMUX_DATA(PB4_DATA, PB4MD_00, PB4_IN),
+       PINMUX_DATA(PB4_DATA, PB4MD_00, FORCE_IN),
        PINMUX_DATA(SCL2_MARK, PB4MD_01),
        PINMUX_DATA(PINT4_PB_MARK, PB4MD_10),
        PINMUX_DATA(IRQ4_PB_MARK, PB4MD_11),
 
-       PINMUX_DATA(PB3_DATA, PB3MD_00, PB3_IN),
+       PINMUX_DATA(PB3_DATA, PB3MD_00, FORCE_IN),
        PINMUX_DATA(SDA1_MARK, PB3MD_01),
        PINMUX_DATA(PINT3_PB_MARK, PB3MD_10),
        PINMUX_DATA(IRQ3_PB_MARK, PB3MD_11),
 
-       PINMUX_DATA(PB2_DATA, PB2MD_00, PB2_IN),
+       PINMUX_DATA(PB2_DATA, PB2MD_00, FORCE_IN),
        PINMUX_DATA(SCL1_MARK, PB2MD_01),
        PINMUX_DATA(PINT2_PB_MARK, PB2MD_10),
        PINMUX_DATA(IRQ2_PB_MARK, PB2MD_11),
 
-       PINMUX_DATA(PB1_DATA, PB1MD_00, PB1_IN),
+       PINMUX_DATA(PB1_DATA, PB1MD_00, FORCE_IN),
        PINMUX_DATA(SDA0_MARK, PB1MD_01),
        PINMUX_DATA(PINT1_PB_MARK, PB1MD_10),
        PINMUX_DATA(IRQ1_PB_MARK, PB1MD_11),
 
-       PINMUX_DATA(PB0_DATA, PB0MD_00, PB0_IN),
+       PINMUX_DATA(PB0_DATA, PB0MD_00, FORCE_IN),
        PINMUX_DATA(SCL0_MARK, PB0MD_01),
        PINMUX_DATA(PINT0_PB_MARK, PB0MD_10),
        PINMUX_DATA(IRQ0_PB_MARK, PB0MD_11),
@@ -1575,8 +1574,8 @@ static struct pinmux_info sh7203_pinmux_info = {
        .name = "sh7203_pfc",
        .reserved_id = PINMUX_RESERVED,
        .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
-       .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
-       .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+       .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END, FORCE_IN },
+       .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END, FORCE_OUT },
        .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
        .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
 
@@ -1595,5 +1594,4 @@ static int __init plat_pinmux_setup(void)
 {
        return register_pinmux(&sh7203_pinmux_info);
 }
-
 arch_initcall(plat_pinmux_setup);
index be9a0c185958375585c3f4ac9de363cce18e375c..8e344ec5847e4e21d1d60de374dcd8871c9caae9 100644 (file)
@@ -30,6 +30,7 @@ clock-$(CONFIG_CPU_SUBTYPE_SHX3)      := clock-shx3.o
 # Pinmux setup
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7722)    := pinmux-sh7722.o
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7723)    := pinmux-sh7723.o
+pinmux-$(CONFIG_CPU_SUBTYPE_SH7785)    := pinmux-sh7785.o
 
 obj-y                  += $(clock-y)
 obj-$(CONFIG_SMP)      += $(smp-y)
index 45889d412c800e66f0b4aa3b2ccc449c82dd735d..3177d0d1e06da240cac4fccf5e56a90c7c2b19f9 100644 (file)
@@ -18,7 +18,6 @@
 
 static int bfc_divisors[] = { 1, 1, 1, 8, 1, 1, 1, 1 };
 static int p0fc_divisors[] = { 1, 1, 1, 8, 1, 1, 1, 1 };
-static int p1fc_divisors[] = { 1, 1, 1, 16, 1, 1, 1, 1 };
 static int cfc_divisors[] = { 1, 1, 4, 1, 1, 1, 1, 1 };
 
 static void master_clk_init(struct clk *clk)
diff --git a/arch/sh/kernel/cpu/sh4a/pinmux-sh7785.c b/arch/sh/kernel/cpu/sh4a/pinmux-sh7785.c
new file mode 100644 (file)
index 0000000..5ebc25f
--- /dev/null
@@ -0,0 +1,1310 @@
+/*
+ * SH7785 Pinmux
+ *
+ *  Copyright (C) 2008  Magnus Damm
+ *
+ * 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/kernel.h>
+#include <linux/gpio.h>
+#include <cpu/sh7785.h>
+
+enum {
+       PINMUX_RESERVED = 0,
+
+       PINMUX_DATA_BEGIN,
+       PA7_DATA, PA6_DATA, PA5_DATA, PA4_DATA,
+       PA3_DATA, PA2_DATA, PA1_DATA, PA0_DATA,
+       PB7_DATA, PB6_DATA, PB5_DATA, PB4_DATA,
+       PB3_DATA, PB2_DATA, PB1_DATA, PB0_DATA,
+       PC7_DATA, PC6_DATA, PC5_DATA, PC4_DATA,
+       PC3_DATA, PC2_DATA, PC1_DATA, PC0_DATA,
+       PD7_DATA, PD6_DATA, PD5_DATA, PD4_DATA,
+       PD3_DATA, PD2_DATA, PD1_DATA, PD0_DATA,
+       PE5_DATA, PE4_DATA, PE3_DATA, PE2_DATA, PE1_DATA, PE0_DATA,
+       PF7_DATA, PF6_DATA, PF5_DATA, PF4_DATA,
+       PF3_DATA, PF2_DATA, PF1_DATA, PF0_DATA,
+       PG7_DATA, PG6_DATA, PG5_DATA, PG4_DATA,
+       PG3_DATA, PG2_DATA, PG1_DATA, PG0_DATA,
+       PH7_DATA, PH6_DATA, PH5_DATA, PH4_DATA,
+       PH3_DATA, PH2_DATA, PH1_DATA, PH0_DATA,
+       PJ7_DATA, PJ6_DATA, PJ5_DATA, PJ4_DATA,
+       PJ3_DATA, PJ2_DATA, PJ1_DATA, PJ0_DATA,
+       PK7_DATA, PK6_DATA, PK5_DATA, PK4_DATA,
+       PK3_DATA, PK2_DATA, PK1_DATA, PK0_DATA,
+       PL7_DATA, PL6_DATA, PL5_DATA, PL4_DATA,
+       PL3_DATA, PL2_DATA, PL1_DATA, PL0_DATA,
+       PM1_DATA, PM0_DATA,
+       PN7_DATA, PN6_DATA, PN5_DATA, PN4_DATA,
+       PN3_DATA, PN2_DATA, PN1_DATA, PN0_DATA,
+       PP5_DATA, PP4_DATA, PP3_DATA, PP2_DATA, PP1_DATA, PP0_DATA,
+       PQ4_DATA, PQ3_DATA, PQ2_DATA, PQ1_DATA, PQ0_DATA,
+       PR3_DATA, PR2_DATA, PR1_DATA, PR0_DATA,
+       PINMUX_DATA_END,
+
+       PINMUX_INPUT_BEGIN,
+       PA7_IN, PA6_IN, PA5_IN, PA4_IN,
+       PA3_IN, PA2_IN, PA1_IN, PA0_IN,
+       PB7_IN, PB6_IN, PB5_IN, PB4_IN,
+       PB3_IN, PB2_IN, PB1_IN, PB0_IN,
+       PC7_IN, PC6_IN, PC5_IN, PC4_IN,
+       PC3_IN, PC2_IN, PC1_IN, PC0_IN,
+       PD7_IN, PD6_IN, PD5_IN, PD4_IN,
+       PD3_IN, PD2_IN, PD1_IN, PD0_IN,
+       PE5_IN, PE4_IN, PE3_IN, PE2_IN, PE1_IN, PE0_IN,
+       PF7_IN, PF6_IN, PF5_IN, PF4_IN,
+       PF3_IN, PF2_IN, PF1_IN, PF0_IN,
+       PG7_IN, PG6_IN, PG5_IN, PG4_IN,
+       PG3_IN, PG2_IN, PG1_IN, PG0_IN,
+       PH7_IN, PH6_IN, PH5_IN, PH4_IN,
+       PH3_IN, PH2_IN, PH1_IN, PH0_IN,
+       PJ7_IN, PJ6_IN, PJ5_IN, PJ4_IN,
+       PJ3_IN, PJ2_IN, PJ1_IN, PJ0_IN,
+       PK7_IN, PK6_IN, PK5_IN, PK4_IN,
+       PK3_IN, PK2_IN, PK1_IN, PK0_IN,
+       PL7_IN, PL6_IN, PL5_IN, PL4_IN,
+       PL3_IN, PL2_IN, PL1_IN, PL0_IN,
+       PM1_IN, PM0_IN,
+       PN7_IN, PN6_IN, PN5_IN, PN4_IN,
+       PN3_IN, PN2_IN, PN1_IN, PN0_IN,
+       PP5_IN, PP4_IN, PP3_IN, PP2_IN, PP1_IN, PP0_IN,
+       PQ4_IN, PQ3_IN, PQ2_IN, PQ1_IN, PQ0_IN,
+       PR3_IN, PR2_IN, PR1_IN, PR0_IN,
+       PINMUX_INPUT_END,
+
+       PINMUX_INPUT_PULLUP_BEGIN,
+       PA7_IN_PU, PA6_IN_PU, PA5_IN_PU, PA4_IN_PU,
+       PA3_IN_PU, PA2_IN_PU, PA1_IN_PU, PA0_IN_PU,
+       PB7_IN_PU, PB6_IN_PU, PB5_IN_PU, PB4_IN_PU,
+       PB3_IN_PU, PB2_IN_PU, PB1_IN_PU, PB0_IN_PU,
+       PC7_IN_PU, PC6_IN_PU, PC5_IN_PU, PC4_IN_PU,
+       PC3_IN_PU, PC2_IN_PU, PC1_IN_PU, PC0_IN_PU,
+       PD7_IN_PU, PD6_IN_PU, PD5_IN_PU, PD4_IN_PU,
+       PD3_IN_PU, PD2_IN_PU, PD1_IN_PU, PD0_IN_PU,
+       PE5_IN_PU, PE4_IN_PU, PE3_IN_PU, PE2_IN_PU, PE1_IN_PU, PE0_IN_PU,
+       PF7_IN_PU, PF6_IN_PU, PF5_IN_PU, PF4_IN_PU,
+       PF3_IN_PU, PF2_IN_PU, PF1_IN_PU, PF0_IN_PU,
+       PG7_IN_PU, PG6_IN_PU, PG5_IN_PU, PG4_IN_PU,
+       PG3_IN_PU, PG2_IN_PU, PG1_IN_PU, PG0_IN_PU,
+       PH7_IN_PU, PH6_IN_PU, PH5_IN_PU, PH4_IN_PU,
+       PH3_IN_PU, PH2_IN_PU, PH1_IN_PU, PH0_IN_PU,
+       PJ7_IN_PU, PJ6_IN_PU, PJ5_IN_PU, PJ4_IN_PU,
+       PJ3_IN_PU, PJ2_IN_PU, PJ1_IN_PU, PJ0_IN_PU,
+       PK7_IN_PU, PK6_IN_PU, PK5_IN_PU, PK4_IN_PU,
+       PK3_IN_PU, PK2_IN_PU, PK1_IN_PU, PK0_IN_PU,
+       PL7_IN_PU, PL6_IN_PU, PL5_IN_PU, PL4_IN_PU,
+       PL3_IN_PU, PL2_IN_PU, PL1_IN_PU, PL0_IN_PU,
+       PM1_IN_PU, PM0_IN_PU,
+       PN7_IN_PU, PN6_IN_PU, PN5_IN_PU, PN4_IN_PU,
+       PN3_IN_PU, PN2_IN_PU, PN1_IN_PU, PN0_IN_PU,
+       PP5_IN_PU, PP4_IN_PU, PP3_IN_PU, PP2_IN_PU, PP1_IN_PU, PP0_IN_PU,
+       PQ4_IN_PU, PQ3_IN_PU, PQ2_IN_PU, PQ1_IN_PU, PQ0_IN_PU,
+       PR3_IN_PU, PR2_IN_PU, PR1_IN_PU, PR0_IN_PU,
+       PINMUX_INPUT_PULLUP_END,
+
+       PINMUX_OUTPUT_BEGIN,
+       PA7_OUT, PA6_OUT, PA5_OUT, PA4_OUT,
+       PA3_OUT, PA2_OUT, PA1_OUT, PA0_OUT,
+       PB7_OUT, PB6_OUT, PB5_OUT, PB4_OUT,
+       PB3_OUT, PB2_OUT, PB1_OUT, PB0_OUT,
+       PC7_OUT, PC6_OUT, PC5_OUT, PC4_OUT,
+       PC3_OUT, PC2_OUT, PC1_OUT, PC0_OUT,
+       PD7_OUT, PD6_OUT, PD5_OUT, PD4_OUT,
+       PD3_OUT, PD2_OUT, PD1_OUT, PD0_OUT,
+       PE5_OUT, PE4_OUT, PE3_OUT, PE2_OUT, PE1_OUT, PE0_OUT,
+       PF7_OUT, PF6_OUT, PF5_OUT, PF4_OUT,
+       PF3_OUT, PF2_OUT, PF1_OUT, PF0_OUT,
+       PG7_OUT, PG6_OUT, PG5_OUT, PG4_OUT,
+       PG3_OUT, PG2_OUT, PG1_OUT, PG0_OUT,
+       PH7_OUT, PH6_OUT, PH5_OUT, PH4_OUT,
+       PH3_OUT, PH2_OUT, PH1_OUT, PH0_OUT,
+       PJ7_OUT, PJ6_OUT, PJ5_OUT, PJ4_OUT,
+       PJ3_OUT, PJ2_OUT, PJ1_OUT, PJ0_OUT,
+       PK7_OUT, PK6_OUT, PK5_OUT, PK4_OUT,
+       PK3_OUT, PK2_OUT, PK1_OUT, PK0_OUT,
+       PL7_OUT, PL6_OUT, PL5_OUT, PL4_OUT,
+       PL3_OUT, PL2_OUT, PL1_OUT, PL0_OUT,
+       PM1_OUT, PM0_OUT,
+       PN7_OUT, PN6_OUT, PN5_OUT, PN4_OUT,
+       PN3_OUT, PN2_OUT, PN1_OUT, PN0_OUT,
+       PP5_OUT, PP4_OUT, PP3_OUT, PP2_OUT, PP1_OUT, PP0_OUT,
+       PQ4_OUT, PQ3_OUT, PQ2_OUT, PQ1_OUT, PQ0_OUT,
+       PR3_OUT, PR2_OUT, PR1_OUT, PR0_OUT,
+       PINMUX_OUTPUT_END,
+
+       PINMUX_FUNCTION_BEGIN,
+       PA7_FN, PA6_FN, PA5_FN, PA4_FN,
+       PA3_FN, PA2_FN, PA1_FN, PA0_FN,
+       PB7_FN, PB6_FN, PB5_FN, PB4_FN,
+       PB3_FN, PB2_FN, PB1_FN, PB0_FN,
+       PC7_FN, PC6_FN, PC5_FN, PC4_FN,
+       PC3_FN, PC2_FN, PC1_FN, PC0_FN,
+       PD7_FN, PD6_FN, PD5_FN, PD4_FN,
+       PD3_FN, PD2_FN, PD1_FN, PD0_FN,
+       PE5_FN, PE4_FN, PE3_FN, PE2_FN, PE1_FN, PE0_FN,
+       PF7_FN, PF6_FN, PF5_FN, PF4_FN,
+       PF3_FN, PF2_FN, PF1_FN, PF0_FN,
+       PG7_FN, PG6_FN, PG5_FN, PG4_FN,
+       PG3_FN, PG2_FN, PG1_FN, PG0_FN,
+       PH7_FN, PH6_FN, PH5_FN, PH4_FN,
+       PH3_FN, PH2_FN, PH1_FN, PH0_FN,
+       PJ7_FN, PJ6_FN, PJ5_FN, PJ4_FN,
+       PJ3_FN, PJ2_FN, PJ1_FN, PJ0_FN,
+       PK7_FN, PK6_FN, PK5_FN, PK4_FN,
+       PK3_FN, PK2_FN, PK1_FN, PK0_FN,
+       PL7_FN, PL6_FN, PL5_FN, PL4_FN,
+       PL3_FN, PL2_FN, PL1_FN, PL0_FN,
+       PM1_FN, PM0_FN,
+       PN7_FN, PN6_FN, PN5_FN, PN4_FN,
+       PN3_FN, PN2_FN, PN1_FN, PN0_FN,
+       PP5_FN, PP4_FN, PP3_FN, PP2_FN, PP1_FN, PP0_FN,
+       PQ4_FN, PQ3_FN, PQ2_FN, PQ1_FN, PQ0_FN,
+       PR3_FN, PR2_FN, PR1_FN, PR0_FN,
+       P1MSEL15_0, P1MSEL15_1,
+       P1MSEL14_0, P1MSEL14_1,
+       P1MSEL13_0, P1MSEL13_1,
+       P1MSEL12_0, P1MSEL12_1,
+       P1MSEL11_0, P1MSEL11_1,
+       P1MSEL10_0, P1MSEL10_1,
+       P1MSEL9_0, P1MSEL9_1,
+       P1MSEL8_0, P1MSEL8_1,
+       P1MSEL7_0, P1MSEL7_1,
+       P1MSEL6_0, P1MSEL6_1,
+       P1MSEL5_0,
+       P1MSEL4_0, P1MSEL4_1,
+       P1MSEL3_0, P1MSEL3_1,
+       P1MSEL2_0, P1MSEL2_1,
+       P1MSEL1_0, P1MSEL1_1,
+       P1MSEL0_0, P1MSEL0_1,
+       P2MSEL2_0, P2MSEL2_1,
+       P2MSEL1_0, P2MSEL1_1,
+       P2MSEL0_0, P2MSEL0_1,
+       PINMUX_FUNCTION_END,
+
+       PINMUX_MARK_BEGIN,
+       D63_AD31_MARK,
+       D62_AD30_MARK,
+       D61_AD29_MARK,
+       D60_AD28_MARK,
+       D59_AD27_MARK,
+       D58_AD26_MARK,
+       D57_AD25_MARK,
+       D56_AD24_MARK,
+       D55_AD23_MARK,
+       D54_AD22_MARK,
+       D53_AD21_MARK,
+       D52_AD20_MARK,
+       D51_AD19_MARK,
+       D50_AD18_MARK,
+       D49_AD17_DB5_MARK,
+       D48_AD16_DB4_MARK,
+       D47_AD15_DB3_MARK,
+       D46_AD14_DB2_MARK,
+       D45_AD13_DB1_MARK,
+       D44_AD12_DB0_MARK,
+       D43_AD11_DG5_MARK,
+       D42_AD10_DG4_MARK,
+       D41_AD9_DG3_MARK,
+       D40_AD8_DG2_MARK,
+       D39_AD7_DG1_MARK,
+       D38_AD6_DG0_MARK,
+       D37_AD5_DR5_MARK,
+       D36_AD4_DR4_MARK,
+       D35_AD3_DR3_MARK,
+       D34_AD2_DR2_MARK,
+       D33_AD1_DR1_MARK,
+       D32_AD0_DR0_MARK,
+       REQ1_MARK,
+       REQ2_MARK,
+       REQ3_MARK,
+       GNT1_MARK,
+       GNT2_MARK,
+       GNT3_MARK,
+       MMCCLK_MARK,
+       D31_MARK,
+       D30_MARK,
+       D29_MARK,
+       D28_MARK,
+       D27_MARK,
+       D26_MARK,
+       D25_MARK,
+       D24_MARK,
+       D23_MARK,
+       D22_MARK,
+       D21_MARK,
+       D20_MARK,
+       D19_MARK,
+       D18_MARK,
+       D17_MARK,
+       D16_MARK,
+       SCIF1_SCK_MARK,
+       SCIF1_RXD_MARK,
+       SCIF1_TXD_MARK,
+       SCIF0_CTS_MARK,
+       INTD_MARK,
+       FCE_MARK,
+       SCIF0_RTS_MARK,
+       HSPI_CS_MARK,
+       FSE_MARK,
+       SCIF0_SCK_MARK,
+       HSPI_CLK_MARK,
+       FRE_MARK,
+       SCIF0_RXD_MARK,
+       HSPI_RX_MARK,
+       FRB_MARK,
+       SCIF0_TXD_MARK,
+       HSPI_TX_MARK,
+       FWE_MARK,
+       SCIF5_TXD_MARK,
+       HAC1_SYNC_MARK,
+       SSI1_WS_MARK,
+       SIOF_TXD_PJ_MARK,
+       HAC0_SDOUT_MARK,
+       SSI0_SDATA_MARK,
+       SIOF_RXD_PJ_MARK,
+       HAC0_SDIN_MARK,
+       SSI0_SCK_MARK,
+       SIOF_SYNC_PJ_MARK,
+       HAC0_SYNC_MARK,
+       SSI0_WS_MARK,
+       SIOF_MCLK_PJ_MARK,
+       HAC_RES_MARK,
+       SIOF_SCK_PJ_MARK,
+       HAC0_BITCLK_MARK,
+       SSI0_CLK_MARK,
+       HAC1_BITCLK_MARK,
+       SSI1_CLK_MARK,
+       TCLK_MARK,
+       IOIS16_MARK,
+       STATUS0_MARK,
+       DRAK0_PK3_MARK,
+       STATUS1_MARK,
+       DRAK1_PK2_MARK,
+       DACK2_MARK,
+       SCIF2_TXD_MARK,
+       MMCCMD_MARK,
+       SIOF_TXD_PK_MARK,
+       DACK3_MARK,
+       SCIF2_SCK_MARK,
+       MMCDAT_MARK,
+       SIOF_SCK_PK_MARK,
+       DREQ0_MARK,
+       DREQ1_MARK,
+       DRAK0_PK1_MARK,
+       DRAK1_PK0_MARK,
+       DREQ2_MARK,
+       INTB_MARK,
+       DREQ3_MARK,
+       INTC_MARK,
+       DRAK2_MARK,
+       CE2A_MARK,
+       IRL4_MARK,
+       FD4_MARK,
+       IRL5_MARK,
+       FD5_MARK,
+       IRL6_MARK,
+       FD6_MARK,
+       IRL7_MARK,
+       FD7_MARK,
+       DRAK3_MARK,
+       CE2B_MARK,
+       BREQ_BSACK_MARK,
+       BACK_BSREQ_MARK,
+       SCIF5_RXD_MARK,
+       HAC1_SDIN_MARK,
+       SSI1_SCK_MARK,
+       SCIF5_SCK_MARK,
+       HAC1_SDOUT_MARK,
+       SSI1_SDATA_MARK,
+       SCIF3_TXD_MARK,
+       FCLE_MARK,
+       SCIF3_RXD_MARK,
+       FALE_MARK,
+       SCIF3_SCK_MARK,
+       FD0_MARK,
+       SCIF4_TXD_MARK,
+       FD1_MARK,
+       SCIF4_RXD_MARK,
+       FD2_MARK,
+       SCIF4_SCK_MARK,
+       FD3_MARK,
+       DEVSEL_DCLKOUT_MARK,
+       STOP_CDE_MARK,
+       LOCK_ODDF_MARK,
+       TRDY_DISPL_MARK,
+       IRDY_HSYNC_MARK,
+       PCIFRAME_VSYNC_MARK,
+       INTA_MARK,
+       GNT0_GNTIN_MARK,
+       REQ0_REQOUT_MARK,
+       PERR_MARK,
+       SERR_MARK,
+       WE7_CBE3_MARK,
+       WE6_CBE2_MARK,
+       WE5_CBE1_MARK,
+       WE4_CBE0_MARK,
+       SCIF2_RXD_MARK,
+       SIOF_RXD_MARK,
+       MRESETOUT_MARK,
+       IRQOUT_MARK,
+       PINMUX_MARK_END,
+};
+
+static pinmux_enum_t pinmux_data[] = {
+
+       /* PA GPIO */
+       PINMUX_DATA(PA7_DATA, PA7_IN, PA7_OUT, PA7_IN_PU),
+       PINMUX_DATA(PA6_DATA, PA6_IN, PA6_OUT, PA6_IN_PU),
+       PINMUX_DATA(PA5_DATA, PA5_IN, PA5_OUT, PA5_IN_PU),
+       PINMUX_DATA(PA4_DATA, PA4_IN, PA4_OUT, PA4_IN_PU),
+       PINMUX_DATA(PA3_DATA, PA3_IN, PA3_OUT, PA3_IN_PU),
+       PINMUX_DATA(PA2_DATA, PA2_IN, PA2_OUT, PA2_IN_PU),
+       PINMUX_DATA(PA1_DATA, PA1_IN, PA1_OUT, PA1_IN_PU),
+       PINMUX_DATA(PA0_DATA, PA0_IN, PA0_OUT, PA0_IN_PU),
+
+       /* PB GPIO */
+       PINMUX_DATA(PB7_DATA, PB7_IN, PB7_OUT, PB7_IN_PU),
+       PINMUX_DATA(PB6_DATA, PB6_IN, PB6_OUT, PB6_IN_PU),
+       PINMUX_DATA(PB5_DATA, PB5_IN, PB5_OUT, PB5_IN_PU),
+       PINMUX_DATA(PB4_DATA, PB4_IN, PB4_OUT, PB4_IN_PU),
+       PINMUX_DATA(PB3_DATA, PB3_IN, PB3_OUT, PB3_IN_PU),
+       PINMUX_DATA(PB2_DATA, PB2_IN, PB2_OUT, PB2_IN_PU),
+       PINMUX_DATA(PB1_DATA, PB1_IN, PB1_OUT, PB1_IN_PU),
+       PINMUX_DATA(PB0_DATA, PB0_IN, PB0_OUT, PB0_IN_PU),
+
+       /* PC GPIO */
+       PINMUX_DATA(PC7_DATA, PC7_IN, PC7_OUT, PC7_IN_PU),
+       PINMUX_DATA(PC6_DATA, PC6_IN, PC6_OUT, PC6_IN_PU),
+       PINMUX_DATA(PC5_DATA, PC5_IN, PC5_OUT, PC5_IN_PU),
+       PINMUX_DATA(PC4_DATA, PC4_IN, PC4_OUT, PC4_IN_PU),
+       PINMUX_DATA(PC3_DATA, PC3_IN, PC3_OUT, PC3_IN_PU),
+       PINMUX_DATA(PC2_DATA, PC2_IN, PC2_OUT, PC2_IN_PU),
+       PINMUX_DATA(PC1_DATA, PC1_IN, PC1_OUT, PC1_IN_PU),
+       PINMUX_DATA(PC0_DATA, PC0_IN, PC0_OUT, PC0_IN_PU),
+
+       /* PD GPIO */
+       PINMUX_DATA(PD7_DATA, PD7_IN, PD7_OUT, PD7_IN_PU),
+       PINMUX_DATA(PD6_DATA, PD6_IN, PD6_OUT, PD6_IN_PU),
+       PINMUX_DATA(PD5_DATA, PD5_IN, PD5_OUT, PD5_IN_PU),
+       PINMUX_DATA(PD4_DATA, PD4_IN, PD4_OUT, PD4_IN_PU),
+       PINMUX_DATA(PD3_DATA, PD3_IN, PD3_OUT, PD3_IN_PU),
+       PINMUX_DATA(PD2_DATA, PD2_IN, PD2_OUT, PD2_IN_PU),
+       PINMUX_DATA(PD1_DATA, PD1_IN, PD1_OUT, PD1_IN_PU),
+       PINMUX_DATA(PD0_DATA, PD0_IN, PD0_OUT, PD0_IN_PU),
+
+       /* PE GPIO */
+       PINMUX_DATA(PE5_DATA, PE5_IN, PE5_OUT, PE5_IN_PU),
+       PINMUX_DATA(PE4_DATA, PE4_IN, PE4_OUT, PE4_IN_PU),
+       PINMUX_DATA(PE3_DATA, PE3_IN, PE3_OUT, PE3_IN_PU),
+       PINMUX_DATA(PE2_DATA, PE2_IN, PE2_OUT, PE2_IN_PU),
+       PINMUX_DATA(PE1_DATA, PE1_IN, PE1_OUT, PE1_IN_PU),
+       PINMUX_DATA(PE0_DATA, PE0_IN, PE0_OUT, PE0_IN_PU),
+
+       /* PF GPIO */
+       PINMUX_DATA(PF7_DATA, PF7_IN, PF7_OUT, PF7_IN_PU),
+       PINMUX_DATA(PF6_DATA, PF6_IN, PF6_OUT, PF6_IN_PU),
+       PINMUX_DATA(PF5_DATA, PF5_IN, PF5_OUT, PF5_IN_PU),
+       PINMUX_DATA(PF4_DATA, PF4_IN, PF4_OUT, PF4_IN_PU),
+       PINMUX_DATA(PF3_DATA, PF3_IN, PF3_OUT, PF3_IN_PU),
+       PINMUX_DATA(PF2_DATA, PF2_IN, PF2_OUT, PF2_IN_PU),
+       PINMUX_DATA(PF1_DATA, PF1_IN, PF1_OUT, PF1_IN_PU),
+       PINMUX_DATA(PF0_DATA, PF0_IN, PF0_OUT, PF0_IN_PU),
+
+       /* PG GPIO */
+       PINMUX_DATA(PG7_DATA, PG7_IN, PG7_OUT, PG7_IN_PU),
+       PINMUX_DATA(PG6_DATA, PG6_IN, PG6_OUT, PG6_IN_PU),
+       PINMUX_DATA(PG5_DATA, PG5_IN, PG5_OUT, PG5_IN_PU),
+       PINMUX_DATA(PG4_DATA, PG4_IN, PG4_OUT, PG4_IN_PU),
+       PINMUX_DATA(PG3_DATA, PG3_IN, PG3_OUT, PG3_IN_PU),
+       PINMUX_DATA(PG2_DATA, PG2_IN, PG2_OUT, PG2_IN_PU),
+       PINMUX_DATA(PG1_DATA, PG1_IN, PG1_OUT, PG1_IN_PU),
+       PINMUX_DATA(PG0_DATA, PG0_IN, PG0_OUT, PG0_IN_PU),
+
+       /* PH GPIO */
+       PINMUX_DATA(PH7_DATA, PH7_IN, PH7_OUT, PH7_IN_PU),
+       PINMUX_DATA(PH6_DATA, PH6_IN, PH6_OUT, PH6_IN_PU),
+       PINMUX_DATA(PH5_DATA, PH5_IN, PH5_OUT, PH5_IN_PU),
+       PINMUX_DATA(PH4_DATA, PH4_IN, PH4_OUT, PH4_IN_PU),
+       PINMUX_DATA(PH3_DATA, PH3_IN, PH3_OUT, PH3_IN_PU),
+       PINMUX_DATA(PH2_DATA, PH2_IN, PH2_OUT, PH2_IN_PU),
+       PINMUX_DATA(PH1_DATA, PH1_IN, PH1_OUT, PH1_IN_PU),
+       PINMUX_DATA(PH0_DATA, PH0_IN, PH0_OUT, PH0_IN_PU),
+
+       /* PJ GPIO */
+       PINMUX_DATA(PJ7_DATA, PJ7_IN, PJ7_OUT, PJ7_IN_PU),
+       PINMUX_DATA(PJ6_DATA, PJ6_IN, PJ6_OUT, PJ6_IN_PU),
+       PINMUX_DATA(PJ5_DATA, PJ5_IN, PJ5_OUT, PJ5_IN_PU),
+       PINMUX_DATA(PJ4_DATA, PJ4_IN, PJ4_OUT, PJ4_IN_PU),
+       PINMUX_DATA(PJ3_DATA, PJ3_IN, PJ3_OUT, PJ3_IN_PU),
+       PINMUX_DATA(PJ2_DATA, PJ2_IN, PJ2_OUT, PJ2_IN_PU),
+       PINMUX_DATA(PJ1_DATA, PJ1_IN, PJ1_OUT, PJ1_IN_PU),
+       PINMUX_DATA(PJ0_DATA, PJ0_IN, PJ0_OUT, PJ0_IN_PU),
+
+       /* PK GPIO */
+       PINMUX_DATA(PK7_DATA, PK7_IN, PK7_OUT, PK7_IN_PU),
+       PINMUX_DATA(PK6_DATA, PK6_IN, PK6_OUT, PK6_IN_PU),
+       PINMUX_DATA(PK5_DATA, PK5_IN, PK5_OUT, PK5_IN_PU),
+       PINMUX_DATA(PK4_DATA, PK4_IN, PK4_OUT, PK4_IN_PU),
+       PINMUX_DATA(PK3_DATA, PK3_IN, PK3_OUT, PK3_IN_PU),
+       PINMUX_DATA(PK2_DATA, PK2_IN, PK2_OUT, PK2_IN_PU),
+       PINMUX_DATA(PK1_DATA, PK1_IN, PK1_OUT, PK1_IN_PU),
+       PINMUX_DATA(PK0_DATA, PK0_IN, PK0_OUT, PK0_IN_PU),
+
+       /* PL GPIO */
+       PINMUX_DATA(PL7_DATA, PL7_IN, PL7_OUT, PL7_IN_PU),
+       PINMUX_DATA(PL6_DATA, PL6_IN, PL6_OUT, PL6_IN_PU),
+       PINMUX_DATA(PL5_DATA, PL5_IN, PL5_OUT, PL5_IN_PU),
+       PINMUX_DATA(PL4_DATA, PL4_IN, PL4_OUT, PL4_IN_PU),
+       PINMUX_DATA(PL3_DATA, PL3_IN, PL3_OUT, PL3_IN_PU),
+       PINMUX_DATA(PL2_DATA, PL2_IN, PL2_OUT, PL2_IN_PU),
+       PINMUX_DATA(PL1_DATA, PL1_IN, PL1_OUT, PL1_IN_PU),
+       PINMUX_DATA(PL0_DATA, PL0_IN, PL0_OUT, PL0_IN_PU),
+
+       /* PM GPIO */
+       PINMUX_DATA(PM1_DATA, PM1_IN, PM1_OUT, PM1_IN_PU),
+       PINMUX_DATA(PM0_DATA, PM0_IN, PM0_OUT, PM0_IN_PU),
+
+       /* PN GPIO */
+       PINMUX_DATA(PN7_DATA, PN7_IN, PN7_OUT, PN7_IN_PU),
+       PINMUX_DATA(PN6_DATA, PN6_IN, PN6_OUT, PN6_IN_PU),
+       PINMUX_DATA(PN5_DATA, PN5_IN, PN5_OUT, PN5_IN_PU),
+       PINMUX_DATA(PN4_DATA, PN4_IN, PN4_OUT, PN4_IN_PU),
+       PINMUX_DATA(PN3_DATA, PN3_IN, PN3_OUT, PN3_IN_PU),
+       PINMUX_DATA(PN2_DATA, PN2_IN, PN2_OUT, PN2_IN_PU),
+       PINMUX_DATA(PN1_DATA, PN1_IN, PN1_OUT, PN1_IN_PU),
+       PINMUX_DATA(PN0_DATA, PN0_IN, PN0_OUT, PN0_IN_PU),
+
+       /* PP GPIO */
+       PINMUX_DATA(PP5_DATA, PP5_IN, PP5_OUT, PP5_IN_PU),
+       PINMUX_DATA(PP4_DATA, PP4_IN, PP4_OUT, PP4_IN_PU),
+       PINMUX_DATA(PP3_DATA, PP3_IN, PP3_OUT, PP3_IN_PU),
+       PINMUX_DATA(PP2_DATA, PP2_IN, PP2_OUT, PP2_IN_PU),
+       PINMUX_DATA(PP1_DATA, PP1_IN, PP1_OUT, PP1_IN_PU),
+       PINMUX_DATA(PP0_DATA, PP0_IN, PP0_OUT, PP0_IN_PU),
+
+       /* PQ GPIO */
+       PINMUX_DATA(PQ4_DATA, PQ4_IN, PQ4_OUT, PQ4_IN_PU),
+       PINMUX_DATA(PQ3_DATA, PQ3_IN, PQ3_OUT, PQ3_IN_PU),
+       PINMUX_DATA(PQ2_DATA, PQ2_IN, PQ2_OUT, PQ2_IN_PU),
+       PINMUX_DATA(PQ1_DATA, PQ1_IN, PQ1_OUT, PQ1_IN_PU),
+       PINMUX_DATA(PQ0_DATA, PQ0_IN, PQ0_OUT, PQ0_IN_PU),
+
+       /* PR GPIO */
+       PINMUX_DATA(PR3_DATA, PR3_IN, PR3_OUT, PR3_IN_PU),
+       PINMUX_DATA(PR2_DATA, PR2_IN, PR2_OUT, PR2_IN_PU),
+       PINMUX_DATA(PR1_DATA, PR1_IN, PR1_OUT, PR1_IN_PU),
+       PINMUX_DATA(PR0_DATA, PR0_IN, PR0_OUT, PR0_IN_PU),
+
+       /* PA FN */
+       PINMUX_DATA(D63_AD31_MARK, PA7_FN),
+       PINMUX_DATA(D62_AD30_MARK, PA6_FN),
+       PINMUX_DATA(D61_AD29_MARK, PA5_FN),
+       PINMUX_DATA(D60_AD28_MARK, PA4_FN),
+       PINMUX_DATA(D59_AD27_MARK, PA3_FN),
+       PINMUX_DATA(D58_AD26_MARK, PA2_FN),
+       PINMUX_DATA(D57_AD25_MARK, PA1_FN),
+       PINMUX_DATA(D56_AD24_MARK, PA0_FN),
+
+       /* PB FN */
+       PINMUX_DATA(D55_AD23_MARK, PB7_FN),
+       PINMUX_DATA(D54_AD22_MARK, PB6_FN),
+       PINMUX_DATA(D53_AD21_MARK, PB5_FN),
+       PINMUX_DATA(D52_AD20_MARK, PB4_FN),
+       PINMUX_DATA(D51_AD19_MARK, PB3_FN),
+       PINMUX_DATA(D50_AD18_MARK, PB2_FN),
+       PINMUX_DATA(D49_AD17_DB5_MARK, PB1_FN),
+       PINMUX_DATA(D48_AD16_DB4_MARK, PB0_FN),
+
+       /* PC FN */
+       PINMUX_DATA(D47_AD15_DB3_MARK, PC7_FN),
+       PINMUX_DATA(D46_AD14_DB2_MARK, PC6_FN),
+       PINMUX_DATA(D45_AD13_DB1_MARK, PC5_FN),
+       PINMUX_DATA(D44_AD12_DB0_MARK, PC4_FN),
+       PINMUX_DATA(D43_AD11_DG5_MARK, PC3_FN),
+       PINMUX_DATA(D42_AD10_DG4_MARK, PC2_FN),
+       PINMUX_DATA(D41_AD9_DG3_MARK, PC1_FN),
+       PINMUX_DATA(D40_AD8_DG2_MARK, PC0_FN),
+
+       /* PD FN */
+       PINMUX_DATA(D39_AD7_DG1_MARK, PD7_FN),
+       PINMUX_DATA(D38_AD6_DG0_MARK, PD6_FN),
+       PINMUX_DATA(D37_AD5_DR5_MARK, PD5_FN),
+       PINMUX_DATA(D36_AD4_DR4_MARK, PD4_FN),
+       PINMUX_DATA(D35_AD3_DR3_MARK, PD3_FN),
+       PINMUX_DATA(D34_AD2_DR2_MARK, PD2_FN),
+       PINMUX_DATA(D33_AD1_DR1_MARK, PD1_FN),
+       PINMUX_DATA(D32_AD0_DR0_MARK, PD0_FN),
+
+       /* PE FN */
+       PINMUX_DATA(REQ1_MARK, PE5_FN),
+       PINMUX_DATA(REQ2_MARK, PE4_FN),
+       PINMUX_DATA(REQ3_MARK, P2MSEL0_0, PE3_FN),
+       PINMUX_DATA(GNT1_MARK, PE2_FN),
+       PINMUX_DATA(GNT2_MARK, PE1_FN),
+       PINMUX_DATA(GNT3_MARK, P2MSEL0_0, PE0_FN),
+       PINMUX_DATA(MMCCLK_MARK, P2MSEL0_1, PE0_FN),
+
+       /* PF FN */
+       PINMUX_DATA(D31_MARK, PF7_FN),
+       PINMUX_DATA(D30_MARK, PF6_FN),
+       PINMUX_DATA(D29_MARK, PF5_FN),
+       PINMUX_DATA(D28_MARK, PF4_FN),
+       PINMUX_DATA(D27_MARK, PF3_FN),
+       PINMUX_DATA(D26_MARK, PF2_FN),
+       PINMUX_DATA(D25_MARK, PF1_FN),
+       PINMUX_DATA(D24_MARK, PF0_FN),
+
+       /* PF FN */
+       PINMUX_DATA(D23_MARK, PG7_FN),
+       PINMUX_DATA(D22_MARK, PG6_FN),
+       PINMUX_DATA(D21_MARK, PG5_FN),
+       PINMUX_DATA(D20_MARK, PG4_FN),
+       PINMUX_DATA(D19_MARK, PG3_FN),
+       PINMUX_DATA(D18_MARK, PG2_FN),
+       PINMUX_DATA(D17_MARK, PG1_FN),
+       PINMUX_DATA(D16_MARK, PG0_FN),
+
+       /* PH FN */
+       PINMUX_DATA(SCIF1_SCK_MARK, PH7_FN),
+       PINMUX_DATA(SCIF1_RXD_MARK, PH6_FN),
+       PINMUX_DATA(SCIF1_TXD_MARK, PH5_FN),
+       PINMUX_DATA(SCIF0_CTS_MARK, PH4_FN),
+       PINMUX_DATA(INTD_MARK, P1MSEL7_1, PH4_FN),
+       PINMUX_DATA(FCE_MARK, P1MSEL8_1, P1MSEL7_0, PH4_FN),
+       PINMUX_DATA(SCIF0_RTS_MARK, P1MSEL8_0, P1MSEL7_0, PH3_FN),
+       PINMUX_DATA(HSPI_CS_MARK, P1MSEL8_0, P1MSEL7_1, PH3_FN),
+       PINMUX_DATA(FSE_MARK, P1MSEL8_1, P1MSEL7_0, PH3_FN),
+       PINMUX_DATA(SCIF0_SCK_MARK, P1MSEL8_0, P1MSEL7_0, PH2_FN),
+       PINMUX_DATA(HSPI_CLK_MARK, P1MSEL8_0, P1MSEL7_1, PH2_FN),
+       PINMUX_DATA(FRE_MARK, P1MSEL8_1, P1MSEL7_0, PH2_FN),
+       PINMUX_DATA(SCIF0_RXD_MARK, P1MSEL8_0, P1MSEL7_0, PH1_FN),
+       PINMUX_DATA(HSPI_RX_MARK, P1MSEL8_0, P1MSEL7_1, PH1_FN),
+       PINMUX_DATA(FRB_MARK, P1MSEL8_1, P1MSEL7_0, PH1_FN),
+       PINMUX_DATA(SCIF0_TXD_MARK, P1MSEL8_0, P1MSEL7_0, PH0_FN),
+       PINMUX_DATA(HSPI_TX_MARK, P1MSEL8_0, P1MSEL7_1, PH0_FN),
+       PINMUX_DATA(FWE_MARK, P1MSEL8_1, P1MSEL7_0, PH0_FN),
+
+       /* PJ FN */
+       PINMUX_DATA(SCIF5_TXD_MARK, P1MSEL2_0, P1MSEL1_0, PJ7_FN),
+       PINMUX_DATA(HAC1_SYNC_MARK, P1MSEL2_0, P1MSEL1_1, PJ7_FN),
+       PINMUX_DATA(SSI1_WS_MARK, P1MSEL2_1, P1MSEL1_0, PJ7_FN),
+       PINMUX_DATA(SIOF_TXD_PJ_MARK, P2MSEL1_0, P1MSEL4_0, P1MSEL3_0, PJ6_FN),
+       PINMUX_DATA(HAC0_SDOUT_MARK, P1MSEL4_0, P1MSEL3_1, PJ6_FN),
+       PINMUX_DATA(SSI0_SDATA_MARK, P1MSEL4_1, P1MSEL3_0, PJ6_FN),
+       PINMUX_DATA(SIOF_RXD_PJ_MARK, P2MSEL1_0, P1MSEL4_0, P1MSEL3_0, PJ5_FN),
+       PINMUX_DATA(HAC0_SDIN_MARK, P1MSEL4_0, P1MSEL3_1, PJ5_FN),
+       PINMUX_DATA(SSI0_SCK_MARK, P1MSEL4_1, P1MSEL3_0, PJ5_FN),
+       PINMUX_DATA(SIOF_SYNC_PJ_MARK, P2MSEL1_0, P1MSEL4_0, P1MSEL3_0, PJ4_FN),
+       PINMUX_DATA(HAC0_SYNC_MARK, P1MSEL4_0, P1MSEL3_1, PJ4_FN),
+       PINMUX_DATA(SSI0_WS_MARK, P1MSEL4_1, P1MSEL3_0, PJ4_FN),
+       PINMUX_DATA(SIOF_MCLK_PJ_MARK, P2MSEL1_0, P1MSEL4_0, P1MSEL3_0, PJ3_FN),
+       PINMUX_DATA(HAC_RES_MARK, P1MSEL4_0, P1MSEL3_1, PJ3_FN),
+       PINMUX_DATA(SIOF_SCK_PJ_MARK, P2MSEL1_0, P1MSEL4_0, P1MSEL3_0, PJ2_FN),
+       PINMUX_DATA(HAC0_BITCLK_MARK, P1MSEL4_0, P1MSEL3_1, PJ2_FN),
+       PINMUX_DATA(SSI0_CLK_MARK, P1MSEL4_1, P1MSEL3_0, PJ2_FN),
+       PINMUX_DATA(HAC1_BITCLK_MARK, P1MSEL2_0, PJ1_FN),
+       PINMUX_DATA(SSI1_CLK_MARK, P1MSEL2_1, P1MSEL1_0, PJ1_FN),
+       PINMUX_DATA(TCLK_MARK, P1MSEL9_0, PJ0_FN),
+       PINMUX_DATA(IOIS16_MARK, P1MSEL9_1, PJ0_FN),
+
+       /* PK FN */
+       PINMUX_DATA(STATUS0_MARK, P1MSEL15_0, PK7_FN),
+       PINMUX_DATA(DRAK0_PK3_MARK, P1MSEL15_1, PK7_FN),
+       PINMUX_DATA(STATUS1_MARK, P1MSEL15_0, PK6_FN),
+       PINMUX_DATA(DRAK1_PK2_MARK, P1MSEL15_1, PK6_FN),
+       PINMUX_DATA(DACK2_MARK, P1MSEL12_0, P1MSEL11_0, PK5_FN),
+       PINMUX_DATA(SCIF2_TXD_MARK, P1MSEL12_1, P1MSEL11_0, PK5_FN),
+       PINMUX_DATA(MMCCMD_MARK, P1MSEL12_1, P1MSEL11_1, PK5_FN),
+       PINMUX_DATA(SIOF_TXD_PK_MARK, P2MSEL1_1,
+                   P1MSEL12_0, P1MSEL11_1, PK5_FN),
+       PINMUX_DATA(DACK3_MARK, P1MSEL12_0, P1MSEL11_0, PK4_FN),
+       PINMUX_DATA(SCIF2_SCK_MARK, P1MSEL12_1, P1MSEL11_0, PK4_FN),
+       PINMUX_DATA(MMCDAT_MARK, P1MSEL12_1, P1MSEL11_1, PK4_FN),
+       PINMUX_DATA(SIOF_SCK_PK_MARK, P2MSEL1_1,
+                   P1MSEL12_0, P1MSEL11_1, PK4_FN),
+       PINMUX_DATA(DREQ0_MARK, PK3_FN),
+       PINMUX_DATA(DREQ1_MARK, PK2_FN),
+       PINMUX_DATA(DRAK0_PK1_MARK, PK1_FN),
+       PINMUX_DATA(DRAK1_PK0_MARK, PK0_FN),
+
+       /* PL FN */
+       PINMUX_DATA(DREQ2_MARK, P1MSEL13_0, PL7_FN),
+       PINMUX_DATA(INTB_MARK, P1MSEL13_1, PL7_FN),
+       PINMUX_DATA(DREQ3_MARK, P1MSEL13_0, PL6_FN),
+       PINMUX_DATA(INTC_MARK, P1MSEL13_1, PL6_FN),
+       PINMUX_DATA(DRAK2_MARK, P1MSEL10_0, PL5_FN),
+       PINMUX_DATA(CE2A_MARK, P1MSEL10_1, PL5_FN),
+       PINMUX_DATA(IRL4_MARK, P1MSEL14_0, PL4_FN),
+       PINMUX_DATA(FD4_MARK, P1MSEL14_1, PL4_FN),
+       PINMUX_DATA(IRL5_MARK, P1MSEL14_0, PL3_FN),
+       PINMUX_DATA(FD5_MARK, P1MSEL14_1, PL3_FN),
+       PINMUX_DATA(IRL6_MARK, P1MSEL14_0, PL2_FN),
+       PINMUX_DATA(FD6_MARK, P1MSEL14_1, PL2_FN),
+       PINMUX_DATA(IRL7_MARK, P1MSEL14_0, PL1_FN),
+       PINMUX_DATA(FD7_MARK, P1MSEL14_1, PL1_FN),
+       PINMUX_DATA(DRAK3_MARK, P1MSEL10_0, PL0_FN),
+       PINMUX_DATA(CE2B_MARK, P1MSEL10_1, PL0_FN),
+
+       /* PM FN */
+       PINMUX_DATA(BREQ_BSACK_MARK, PM1_FN),
+       PINMUX_DATA(BACK_BSREQ_MARK, PM0_FN),
+
+       /* PN FN */
+       PINMUX_DATA(SCIF5_RXD_MARK, P1MSEL2_0, P1MSEL1_0, PN7_FN),
+       PINMUX_DATA(HAC1_SDIN_MARK, P1MSEL2_0, P1MSEL1_1, PN7_FN),
+       PINMUX_DATA(SSI1_SCK_MARK, P1MSEL2_1, P1MSEL1_0, PN7_FN),
+       PINMUX_DATA(SCIF5_SCK_MARK, P1MSEL2_0, P1MSEL1_0, PN6_FN),
+       PINMUX_DATA(HAC1_SDOUT_MARK, P1MSEL2_0, P1MSEL1_1, PN6_FN),
+       PINMUX_DATA(SSI1_SDATA_MARK, P1MSEL2_1, P1MSEL1_0, PN6_FN),
+       PINMUX_DATA(SCIF3_TXD_MARK, P1MSEL0_0, PN5_FN),
+       PINMUX_DATA(FCLE_MARK, P1MSEL0_1, PN5_FN),
+       PINMUX_DATA(SCIF3_RXD_MARK, P1MSEL0_0, PN4_FN),
+       PINMUX_DATA(FALE_MARK, P1MSEL0_1, PN4_FN),
+       PINMUX_DATA(SCIF3_SCK_MARK, P1MSEL0_0, PN3_FN),
+       PINMUX_DATA(FD0_MARK, P1MSEL0_1, PN3_FN),
+       PINMUX_DATA(SCIF4_TXD_MARK, P1MSEL0_0, PN2_FN),
+       PINMUX_DATA(FD1_MARK, P1MSEL0_1, PN2_FN),
+       PINMUX_DATA(SCIF4_RXD_MARK, P1MSEL0_0, PN1_FN),
+       PINMUX_DATA(FD2_MARK, P1MSEL0_1, PN1_FN),
+       PINMUX_DATA(SCIF4_SCK_MARK, P1MSEL0_0, PN0_FN),
+       PINMUX_DATA(FD3_MARK, P1MSEL0_1, PN0_FN),
+
+       /* PP FN */
+       PINMUX_DATA(DEVSEL_DCLKOUT_MARK, PP5_FN),
+       PINMUX_DATA(STOP_CDE_MARK, PP4_FN),
+       PINMUX_DATA(LOCK_ODDF_MARK, PP3_FN),
+       PINMUX_DATA(TRDY_DISPL_MARK, PP2_FN),
+       PINMUX_DATA(IRDY_HSYNC_MARK, PP1_FN),
+       PINMUX_DATA(PCIFRAME_VSYNC_MARK, PP0_FN),
+
+       /* PQ FN */
+       PINMUX_DATA(INTA_MARK, PQ4_FN),
+       PINMUX_DATA(GNT0_GNTIN_MARK, PQ3_FN),
+       PINMUX_DATA(REQ0_REQOUT_MARK, PQ2_FN),
+       PINMUX_DATA(PERR_MARK, PQ1_FN),
+       PINMUX_DATA(SERR_MARK, PQ0_FN),
+
+       /* PR FN */
+       PINMUX_DATA(WE7_CBE3_MARK, PR3_FN),
+       PINMUX_DATA(WE6_CBE2_MARK, PR2_FN),
+       PINMUX_DATA(WE5_CBE1_MARK, PR1_FN),
+       PINMUX_DATA(WE4_CBE0_MARK, PR0_FN),
+
+       /* MISC FN */
+       PINMUX_DATA(SCIF2_RXD_MARK, P1MSEL6_0, P1MSEL5_0),
+       PINMUX_DATA(SIOF_RXD_MARK, P2MSEL1_1, P1MSEL6_1, P1MSEL5_0),
+       PINMUX_DATA(MRESETOUT_MARK, P2MSEL2_0),
+       PINMUX_DATA(IRQOUT_MARK, P2MSEL2_1),
+};
+
+static struct pinmux_gpio pinmux_gpios[] = {
+       /* PA */
+       PINMUX_GPIO(GPIO_PA7, PA7_DATA),
+       PINMUX_GPIO(GPIO_PA6, PA6_DATA),
+       PINMUX_GPIO(GPIO_PA5, PA5_DATA),
+       PINMUX_GPIO(GPIO_PA4, PA4_DATA),
+       PINMUX_GPIO(GPIO_PA3, PA3_DATA),
+       PINMUX_GPIO(GPIO_PA2, PA2_DATA),
+       PINMUX_GPIO(GPIO_PA1, PA1_DATA),
+       PINMUX_GPIO(GPIO_PA0, PA0_DATA),
+
+       /* PB */
+       PINMUX_GPIO(GPIO_PB7, PB7_DATA),
+       PINMUX_GPIO(GPIO_PB6, PB6_DATA),
+       PINMUX_GPIO(GPIO_PB5, PB5_DATA),
+       PINMUX_GPIO(GPIO_PB4, PB4_DATA),
+       PINMUX_GPIO(GPIO_PB3, PB3_DATA),
+       PINMUX_GPIO(GPIO_PB2, PB2_DATA),
+       PINMUX_GPIO(GPIO_PB1, PB1_DATA),
+       PINMUX_GPIO(GPIO_PB0, PB0_DATA),
+
+       /* PC */
+       PINMUX_GPIO(GPIO_PC7, PC7_DATA),
+       PINMUX_GPIO(GPIO_PC6, PC6_DATA),
+       PINMUX_GPIO(GPIO_PC5, PC5_DATA),
+       PINMUX_GPIO(GPIO_PC4, PC4_DATA),
+       PINMUX_GPIO(GPIO_PC3, PC3_DATA),
+       PINMUX_GPIO(GPIO_PC2, PC2_DATA),
+       PINMUX_GPIO(GPIO_PC1, PC1_DATA),
+       PINMUX_GPIO(GPIO_PC0, PC0_DATA),
+
+       /* PD */
+       PINMUX_GPIO(GPIO_PD7, PD7_DATA),
+       PINMUX_GPIO(GPIO_PD6, PD6_DATA),
+       PINMUX_GPIO(GPIO_PD5, PD5_DATA),
+       PINMUX_GPIO(GPIO_PD4, PD4_DATA),
+       PINMUX_GPIO(GPIO_PD3, PD3_DATA),
+       PINMUX_GPIO(GPIO_PD2, PD2_DATA),
+       PINMUX_GPIO(GPIO_PD1, PD1_DATA),
+       PINMUX_GPIO(GPIO_PD0, PD0_DATA),
+
+       /* PE */
+       PINMUX_GPIO(GPIO_PE5, PE5_DATA),
+       PINMUX_GPIO(GPIO_PE4, PE4_DATA),
+       PINMUX_GPIO(GPIO_PE3, PE3_DATA),
+       PINMUX_GPIO(GPIO_PE2, PE2_DATA),
+       PINMUX_GPIO(GPIO_PE1, PE1_DATA),
+       PINMUX_GPIO(GPIO_PE0, PE0_DATA),
+
+       /* PF */
+       PINMUX_GPIO(GPIO_PF7, PF7_DATA),
+       PINMUX_GPIO(GPIO_PF6, PF6_DATA),
+       PINMUX_GPIO(GPIO_PF5, PF5_DATA),
+       PINMUX_GPIO(GPIO_PF4, PF4_DATA),
+       PINMUX_GPIO(GPIO_PF3, PF3_DATA),
+       PINMUX_GPIO(GPIO_PF2, PF2_DATA),
+       PINMUX_GPIO(GPIO_PF1, PF1_DATA),
+       PINMUX_GPIO(GPIO_PF0, PF0_DATA),
+
+       /* PG */
+       PINMUX_GPIO(GPIO_PG7, PG7_DATA),
+       PINMUX_GPIO(GPIO_PG6, PG6_DATA),
+       PINMUX_GPIO(GPIO_PG5, PG5_DATA),
+       PINMUX_GPIO(GPIO_PG4, PG4_DATA),
+       PINMUX_GPIO(GPIO_PG3, PG3_DATA),
+       PINMUX_GPIO(GPIO_PG2, PG2_DATA),
+       PINMUX_GPIO(GPIO_PG1, PG1_DATA),
+       PINMUX_GPIO(GPIO_PG0, PG0_DATA),
+
+       /* PH */
+       PINMUX_GPIO(GPIO_PH7, PH7_DATA),
+       PINMUX_GPIO(GPIO_PH6, PH6_DATA),
+       PINMUX_GPIO(GPIO_PH5, PH5_DATA),
+       PINMUX_GPIO(GPIO_PH4, PH4_DATA),
+       PINMUX_GPIO(GPIO_PH3, PH3_DATA),
+       PINMUX_GPIO(GPIO_PH2, PH2_DATA),
+       PINMUX_GPIO(GPIO_PH1, PH1_DATA),
+       PINMUX_GPIO(GPIO_PH0, PH0_DATA),
+
+       /* PJ */
+       PINMUX_GPIO(GPIO_PJ7, PJ7_DATA),
+       PINMUX_GPIO(GPIO_PJ6, PJ6_DATA),
+       PINMUX_GPIO(GPIO_PJ5, PJ5_DATA),
+       PINMUX_GPIO(GPIO_PJ4, PJ4_DATA),
+       PINMUX_GPIO(GPIO_PJ3, PJ3_DATA),
+       PINMUX_GPIO(GPIO_PJ2, PJ2_DATA),
+       PINMUX_GPIO(GPIO_PJ1, PJ1_DATA),
+       PINMUX_GPIO(GPIO_PJ0, PJ0_DATA),
+
+       /* PK */
+       PINMUX_GPIO(GPIO_PK7, PK7_DATA),
+       PINMUX_GPIO(GPIO_PK6, PK6_DATA),
+       PINMUX_GPIO(GPIO_PK5, PK5_DATA),
+       PINMUX_GPIO(GPIO_PK4, PK4_DATA),
+       PINMUX_GPIO(GPIO_PK3, PK3_DATA),
+       PINMUX_GPIO(GPIO_PK2, PK2_DATA),
+       PINMUX_GPIO(GPIO_PK1, PK1_DATA),
+       PINMUX_GPIO(GPIO_PK0, PK0_DATA),
+
+       /* PL */
+       PINMUX_GPIO(GPIO_PL7, PL7_DATA),
+       PINMUX_GPIO(GPIO_PL6, PL6_DATA),
+       PINMUX_GPIO(GPIO_PL5, PL5_DATA),
+       PINMUX_GPIO(GPIO_PL4, PL4_DATA),
+       PINMUX_GPIO(GPIO_PL3, PL3_DATA),
+       PINMUX_GPIO(GPIO_PL2, PL2_DATA),
+       PINMUX_GPIO(GPIO_PL1, PL1_DATA),
+       PINMUX_GPIO(GPIO_PL0, PL0_DATA),
+
+       /* PM */
+       PINMUX_GPIO(GPIO_PM1, PM1_DATA),
+       PINMUX_GPIO(GPIO_PM0, PM0_DATA),
+
+       /* PN */
+       PINMUX_GPIO(GPIO_PN7, PN7_DATA),
+       PINMUX_GPIO(GPIO_PN6, PN6_DATA),
+       PINMUX_GPIO(GPIO_PN5, PN5_DATA),
+       PINMUX_GPIO(GPIO_PN4, PN4_DATA),
+       PINMUX_GPIO(GPIO_PN3, PN3_DATA),
+       PINMUX_GPIO(GPIO_PN2, PN2_DATA),
+       PINMUX_GPIO(GPIO_PN1, PN1_DATA),
+       PINMUX_GPIO(GPIO_PN0, PN0_DATA),
+
+       /* PP */
+       PINMUX_GPIO(GPIO_PP5, PP5_DATA),
+       PINMUX_GPIO(GPIO_PP4, PP4_DATA),
+       PINMUX_GPIO(GPIO_PP3, PP3_DATA),
+       PINMUX_GPIO(GPIO_PP2, PP2_DATA),
+       PINMUX_GPIO(GPIO_PP1, PP1_DATA),
+       PINMUX_GPIO(GPIO_PP0, PP0_DATA),
+
+       /* PQ */
+       PINMUX_GPIO(GPIO_PQ4, PQ4_DATA),
+       PINMUX_GPIO(GPIO_PQ3, PQ3_DATA),
+       PINMUX_GPIO(GPIO_PQ2, PQ2_DATA),
+       PINMUX_GPIO(GPIO_PQ1, PQ1_DATA),
+       PINMUX_GPIO(GPIO_PQ0, PQ0_DATA),
+
+       /* PR */
+       PINMUX_GPIO(GPIO_PR3, PR3_DATA),
+       PINMUX_GPIO(GPIO_PR2, PR2_DATA),
+       PINMUX_GPIO(GPIO_PR1, PR1_DATA),
+       PINMUX_GPIO(GPIO_PR0, PR0_DATA),
+
+       /* FN */
+       PINMUX_GPIO(GPIO_FN_D63_AD31, D63_AD31_MARK),
+       PINMUX_GPIO(GPIO_FN_D62_AD30, D62_AD30_MARK),
+       PINMUX_GPIO(GPIO_FN_D61_AD29, D61_AD29_MARK),
+       PINMUX_GPIO(GPIO_FN_D60_AD28, D60_AD28_MARK),
+       PINMUX_GPIO(GPIO_FN_D59_AD27, D59_AD27_MARK),
+       PINMUX_GPIO(GPIO_FN_D58_AD26, D58_AD26_MARK),
+       PINMUX_GPIO(GPIO_FN_D57_AD25, D57_AD25_MARK),
+       PINMUX_GPIO(GPIO_FN_D56_AD24, D56_AD24_MARK),
+       PINMUX_GPIO(GPIO_FN_D55_AD23, D55_AD23_MARK),
+       PINMUX_GPIO(GPIO_FN_D54_AD22, D54_AD22_MARK),
+       PINMUX_GPIO(GPIO_FN_D53_AD21, D53_AD21_MARK),
+       PINMUX_GPIO(GPIO_FN_D52_AD20, D52_AD20_MARK),
+       PINMUX_GPIO(GPIO_FN_D51_AD19, D51_AD19_MARK),
+       PINMUX_GPIO(GPIO_FN_D50_AD18, D50_AD18_MARK),
+       PINMUX_GPIO(GPIO_FN_D49_AD17_DB5, D49_AD17_DB5_MARK),
+       PINMUX_GPIO(GPIO_FN_D48_AD16_DB4, D48_AD16_DB4_MARK),
+       PINMUX_GPIO(GPIO_FN_D47_AD15_DB3, D47_AD15_DB3_MARK),
+       PINMUX_GPIO(GPIO_FN_D46_AD14_DB2, D46_AD14_DB2_MARK),
+       PINMUX_GPIO(GPIO_FN_D45_AD13_DB1, D45_AD13_DB1_MARK),
+       PINMUX_GPIO(GPIO_FN_D44_AD12_DB0, D44_AD12_DB0_MARK),
+       PINMUX_GPIO(GPIO_FN_D43_AD11_DG5, D43_AD11_DG5_MARK),
+       PINMUX_GPIO(GPIO_FN_D42_AD10_DG4, D42_AD10_DG4_MARK),
+       PINMUX_GPIO(GPIO_FN_D41_AD9_DG3, D41_AD9_DG3_MARK),
+       PINMUX_GPIO(GPIO_FN_D40_AD8_DG2, D40_AD8_DG2_MARK),
+       PINMUX_GPIO(GPIO_FN_D39_AD7_DG1, D39_AD7_DG1_MARK),
+       PINMUX_GPIO(GPIO_FN_D38_AD6_DG0, D38_AD6_DG0_MARK),
+       PINMUX_GPIO(GPIO_FN_D37_AD5_DR5, D37_AD5_DR5_MARK),
+       PINMUX_GPIO(GPIO_FN_D36_AD4_DR4, D36_AD4_DR4_MARK),
+       PINMUX_GPIO(GPIO_FN_D35_AD3_DR3, D35_AD3_DR3_MARK),
+       PINMUX_GPIO(GPIO_FN_D34_AD2_DR2, D34_AD2_DR2_MARK),
+       PINMUX_GPIO(GPIO_FN_D33_AD1_DR1, D33_AD1_DR1_MARK),
+       PINMUX_GPIO(GPIO_FN_D32_AD0_DR0, D32_AD0_DR0_MARK),
+       PINMUX_GPIO(GPIO_FN_REQ1, REQ1_MARK),
+       PINMUX_GPIO(GPIO_FN_REQ2, REQ2_MARK),
+       PINMUX_GPIO(GPIO_FN_REQ3, REQ3_MARK),
+       PINMUX_GPIO(GPIO_FN_GNT1, GNT1_MARK),
+       PINMUX_GPIO(GPIO_FN_GNT2, GNT2_MARK),
+       PINMUX_GPIO(GPIO_FN_GNT3, GNT3_MARK),
+       PINMUX_GPIO(GPIO_FN_MMCCLK, MMCCLK_MARK),
+       PINMUX_GPIO(GPIO_FN_D31, D31_MARK),
+       PINMUX_GPIO(GPIO_FN_D30, D30_MARK),
+       PINMUX_GPIO(GPIO_FN_D29, D29_MARK),
+       PINMUX_GPIO(GPIO_FN_D28, D28_MARK),
+       PINMUX_GPIO(GPIO_FN_D27, D27_MARK),
+       PINMUX_GPIO(GPIO_FN_D26, D26_MARK),
+       PINMUX_GPIO(GPIO_FN_D25, D25_MARK),
+       PINMUX_GPIO(GPIO_FN_D24, D24_MARK),
+       PINMUX_GPIO(GPIO_FN_D23, D23_MARK),
+       PINMUX_GPIO(GPIO_FN_D22, D22_MARK),
+       PINMUX_GPIO(GPIO_FN_D21, D21_MARK),
+       PINMUX_GPIO(GPIO_FN_D20, D20_MARK),
+       PINMUX_GPIO(GPIO_FN_D19, D19_MARK),
+       PINMUX_GPIO(GPIO_FN_D18, D18_MARK),
+       PINMUX_GPIO(GPIO_FN_D17, D17_MARK),
+       PINMUX_GPIO(GPIO_FN_D16, D16_MARK),
+       PINMUX_GPIO(GPIO_FN_SCIF1_SCK, SCIF1_SCK_MARK),
+       PINMUX_GPIO(GPIO_FN_SCIF1_RXD, SCIF1_RXD_MARK),
+       PINMUX_GPIO(GPIO_FN_SCIF1_TXD, SCIF1_TXD_MARK),
+       PINMUX_GPIO(GPIO_FN_SCIF0_CTS, SCIF0_CTS_MARK),
+       PINMUX_GPIO(GPIO_FN_INTD, INTD_MARK),
+       PINMUX_GPIO(GPIO_FN_FCE, FCE_MARK),
+       PINMUX_GPIO(GPIO_FN_SCIF0_RTS, SCIF0_RTS_MARK),
+       PINMUX_GPIO(GPIO_FN_HSPI_CS, HSPI_CS_MARK),
+       PINMUX_GPIO(GPIO_FN_FSE, FSE_MARK),
+       PINMUX_GPIO(GPIO_FN_SCIF0_SCK, SCIF0_SCK_MARK),
+       PINMUX_GPIO(GPIO_FN_HSPI_CLK, HSPI_CLK_MARK),
+       PINMUX_GPIO(GPIO_FN_FRE, FRE_MARK),
+       PINMUX_GPIO(GPIO_FN_SCIF0_RXD, SCIF0_RXD_MARK),
+       PINMUX_GPIO(GPIO_FN_HSPI_RX, HSPI_RX_MARK),
+       PINMUX_GPIO(GPIO_FN_FRB, FRB_MARK),
+       PINMUX_GPIO(GPIO_FN_SCIF0_TXD, SCIF0_TXD_MARK),
+       PINMUX_GPIO(GPIO_FN_HSPI_TX, HSPI_TX_MARK),
+       PINMUX_GPIO(GPIO_FN_FWE, FWE_MARK),
+       PINMUX_GPIO(GPIO_FN_SCIF5_TXD, SCIF5_TXD_MARK),
+       PINMUX_GPIO(GPIO_FN_HAC1_SYNC, HAC1_SYNC_MARK),
+       PINMUX_GPIO(GPIO_FN_SSI1_WS, SSI1_WS_MARK),
+       PINMUX_GPIO(GPIO_FN_SIOF_TXD_PJ, SIOF_TXD_PJ_MARK),
+       PINMUX_GPIO(GPIO_FN_HAC0_SDOUT, HAC0_SDOUT_MARK),
+       PINMUX_GPIO(GPIO_FN_SSI0_SDATA, SSI0_SDATA_MARK),
+       PINMUX_GPIO(GPIO_FN_SIOF_RXD_PJ, SIOF_RXD_PJ_MARK),
+       PINMUX_GPIO(GPIO_FN_HAC0_SDIN, HAC0_SDIN_MARK),
+       PINMUX_GPIO(GPIO_FN_SSI0_SCK, SSI0_SCK_MARK),
+       PINMUX_GPIO(GPIO_FN_SIOF_SYNC_PJ, SIOF_SYNC_PJ_MARK),
+       PINMUX_GPIO(GPIO_FN_HAC0_SYNC, HAC0_SYNC_MARK),
+       PINMUX_GPIO(GPIO_FN_SSI0_WS, SSI0_WS_MARK),
+       PINMUX_GPIO(GPIO_FN_SIOF_MCLK_PJ, SIOF_MCLK_PJ_MARK),
+       PINMUX_GPIO(GPIO_FN_HAC_RES, HAC_RES_MARK),
+       PINMUX_GPIO(GPIO_FN_SIOF_SCK_PJ, SIOF_SCK_PJ_MARK),
+       PINMUX_GPIO(GPIO_FN_HAC0_BITCLK, HAC0_BITCLK_MARK),
+       PINMUX_GPIO(GPIO_FN_SSI0_CLK, SSI0_CLK_MARK),
+       PINMUX_GPIO(GPIO_FN_HAC1_BITCLK, HAC1_BITCLK_MARK),
+       PINMUX_GPIO(GPIO_FN_SSI1_CLK, SSI1_CLK_MARK),
+       PINMUX_GPIO(GPIO_FN_TCLK, TCLK_MARK),
+       PINMUX_GPIO(GPIO_FN_IOIS16, IOIS16_MARK),
+       PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_MARK),
+       PINMUX_GPIO(GPIO_FN_DRAK0_PK3, DRAK0_PK3_MARK),
+       PINMUX_GPIO(GPIO_FN_STATUS1, STATUS1_MARK),
+       PINMUX_GPIO(GPIO_FN_DRAK1_PK2, DRAK1_PK2_MARK),
+       PINMUX_GPIO(GPIO_FN_DACK2, DACK2_MARK),
+       PINMUX_GPIO(GPIO_FN_SCIF2_TXD, SCIF2_TXD_MARK),
+       PINMUX_GPIO(GPIO_FN_MMCCMD, MMCCMD_MARK),
+       PINMUX_GPIO(GPIO_FN_SIOF_TXD_PK, SIOF_TXD_PK_MARK),
+       PINMUX_GPIO(GPIO_FN_DACK3, DACK3_MARK),
+       PINMUX_GPIO(GPIO_FN_SCIF2_SCK, SCIF2_SCK_MARK),
+       PINMUX_GPIO(GPIO_FN_MMCDAT, MMCDAT_MARK),
+       PINMUX_GPIO(GPIO_FN_SIOF_SCK_PK, SIOF_SCK_PK_MARK),
+       PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK),
+       PINMUX_GPIO(GPIO_FN_DREQ1, DREQ1_MARK),
+       PINMUX_GPIO(GPIO_FN_DRAK0_PK1, DRAK0_PK1_MARK),
+       PINMUX_GPIO(GPIO_FN_DRAK1_PK0, DRAK1_PK0_MARK),
+       PINMUX_GPIO(GPIO_FN_DREQ2, DREQ2_MARK),
+       PINMUX_GPIO(GPIO_FN_INTB, INTB_MARK),
+       PINMUX_GPIO(GPIO_FN_DREQ3, DREQ3_MARK),
+       PINMUX_GPIO(GPIO_FN_INTC, INTC_MARK),
+       PINMUX_GPIO(GPIO_FN_DRAK2, DRAK2_MARK),
+       PINMUX_GPIO(GPIO_FN_CE2A, CE2A_MARK),
+       PINMUX_GPIO(GPIO_FN_IRL4, IRL4_MARK),
+       PINMUX_GPIO(GPIO_FN_FD4, FD4_MARK),
+       PINMUX_GPIO(GPIO_FN_IRL5, IRL5_MARK),
+       PINMUX_GPIO(GPIO_FN_FD5, FD5_MARK),
+       PINMUX_GPIO(GPIO_FN_IRL6, IRL6_MARK),
+       PINMUX_GPIO(GPIO_FN_FD6, FD6_MARK),
+       PINMUX_GPIO(GPIO_FN_IRL7, IRL7_MARK),
+       PINMUX_GPIO(GPIO_FN_FD7, FD7_MARK),
+       PINMUX_GPIO(GPIO_FN_DRAK3, DRAK3_MARK),
+       PINMUX_GPIO(GPIO_FN_CE2B, CE2B_MARK),
+       PINMUX_GPIO(GPIO_FN_BREQ_BSACK, BREQ_BSACK_MARK),
+       PINMUX_GPIO(GPIO_FN_BACK_BSREQ, BACK_BSREQ_MARK),
+       PINMUX_GPIO(GPIO_FN_SCIF5_RXD, SCIF5_RXD_MARK),
+       PINMUX_GPIO(GPIO_FN_HAC1_SDIN, HAC1_SDIN_MARK),
+       PINMUX_GPIO(GPIO_FN_SSI1_SCK, SSI1_SCK_MARK),
+       PINMUX_GPIO(GPIO_FN_SCIF5_SCK, SCIF5_SCK_MARK),
+       PINMUX_GPIO(GPIO_FN_HAC1_SDOUT, HAC1_SDOUT_MARK),
+       PINMUX_GPIO(GPIO_FN_SSI1_SDATA, SSI1_SDATA_MARK),
+       PINMUX_GPIO(GPIO_FN_SCIF3_TXD, SCIF3_TXD_MARK),
+       PINMUX_GPIO(GPIO_FN_FCLE, FCLE_MARK),
+       PINMUX_GPIO(GPIO_FN_SCIF3_RXD, SCIF3_RXD_MARK),
+       PINMUX_GPIO(GPIO_FN_FALE, FALE_MARK),
+       PINMUX_GPIO(GPIO_FN_SCIF3_SCK, SCIF3_SCK_MARK),
+       PINMUX_GPIO(GPIO_FN_FD0, FD0_MARK),
+       PINMUX_GPIO(GPIO_FN_SCIF4_TXD, SCIF4_TXD_MARK),
+       PINMUX_GPIO(GPIO_FN_FD1, FD1_MARK),
+       PINMUX_GPIO(GPIO_FN_SCIF4_RXD, SCIF4_RXD_MARK),
+       PINMUX_GPIO(GPIO_FN_FD2, FD2_MARK),
+       PINMUX_GPIO(GPIO_FN_SCIF4_SCK, SCIF4_SCK_MARK),
+       PINMUX_GPIO(GPIO_FN_FD3, FD3_MARK),
+       PINMUX_GPIO(GPIO_FN_DEVSEL_DCLKOUT, DEVSEL_DCLKOUT_MARK),
+       PINMUX_GPIO(GPIO_FN_STOP_CDE, STOP_CDE_MARK),
+       PINMUX_GPIO(GPIO_FN_LOCK_ODDF, LOCK_ODDF_MARK),
+       PINMUX_GPIO(GPIO_FN_TRDY_DISPL, TRDY_DISPL_MARK),
+       PINMUX_GPIO(GPIO_FN_IRDY_HSYNC, IRDY_HSYNC_MARK),
+       PINMUX_GPIO(GPIO_FN_PCIFRAME_VSYNC, PCIFRAME_VSYNC_MARK),
+       PINMUX_GPIO(GPIO_FN_INTA, INTA_MARK),
+       PINMUX_GPIO(GPIO_FN_GNT0_GNTIN, GNT0_GNTIN_MARK),
+       PINMUX_GPIO(GPIO_FN_REQ0_REQOUT, REQ0_REQOUT_MARK),
+       PINMUX_GPIO(GPIO_FN_PERR, PERR_MARK),
+       PINMUX_GPIO(GPIO_FN_SERR, SERR_MARK),
+       PINMUX_GPIO(GPIO_FN_WE7_CBE3, WE7_CBE3_MARK),
+       PINMUX_GPIO(GPIO_FN_WE6_CBE2, WE6_CBE2_MARK),
+       PINMUX_GPIO(GPIO_FN_WE5_CBE1, WE5_CBE1_MARK),
+       PINMUX_GPIO(GPIO_FN_WE4_CBE0, WE4_CBE0_MARK),
+       PINMUX_GPIO(GPIO_FN_SCIF2_RXD, SCIF2_RXD_MARK),
+       PINMUX_GPIO(GPIO_FN_SIOF_RXD, SIOF_RXD_MARK),
+       PINMUX_GPIO(GPIO_FN_MRESETOUT, MRESETOUT_MARK),
+       PINMUX_GPIO(GPIO_FN_IRQOUT, IRQOUT_MARK),
+};
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+       { PINMUX_CFG_REG("PACR", 0xffe70000, 16, 2) {
+               PA7_FN, PA7_OUT, PA7_IN, PA7_IN_PU,
+               PA6_FN, PA6_OUT, PA6_IN, PA6_IN_PU,
+               PA5_FN, PA5_OUT, PA5_IN, PA5_IN_PU,
+               PA4_FN, PA4_OUT, PA4_IN, PA4_IN_PU,
+               PA3_FN, PA3_OUT, PA3_IN, PA3_IN_PU,
+               PA2_FN, PA2_OUT, PA2_IN, PA2_IN_PU,
+               PA1_FN, PA1_OUT, PA1_IN, PA1_IN_PU,
+               PA0_FN, PA0_OUT, PA0_IN, PA0_IN_PU }
+       },
+       { PINMUX_CFG_REG("PBCR", 0xffe70002, 16, 2) {
+               PB7_FN, PB7_OUT, PB7_IN, PB7_IN_PU,
+               PB6_FN, PB6_OUT, PB6_IN, PB6_IN_PU,
+               PB5_FN, PB5_OUT, PB5_IN, PB5_IN_PU,
+               PB4_FN, PB4_OUT, PB4_IN, PB4_IN_PU,
+               PB3_FN, PB3_OUT, PB3_IN, PB3_IN_PU,
+               PB2_FN, PB2_OUT, PB2_IN, PB2_IN_PU,
+               PB1_FN, PB1_OUT, PB1_IN, PB1_IN_PU,
+               PB0_FN, PB0_OUT, PB0_IN, PB0_IN_PU }
+       },
+       { PINMUX_CFG_REG("PCCR", 0xffe70004, 16, 2) {
+               PC7_FN, PC7_OUT, PC7_IN, PC7_IN_PU,
+               PC6_FN, PC6_OUT, PC6_IN, PC6_IN_PU,
+               PC5_FN, PC5_OUT, PC5_IN, PC5_IN_PU,
+               PC4_FN, PC4_OUT, PC4_IN, PC4_IN_PU,
+               PC3_FN, PC3_OUT, PC3_IN, PC3_IN_PU,
+               PC2_FN, PC2_OUT, PC2_IN, PC2_IN_PU,
+               PC1_FN, PC1_OUT, PC1_IN, PC1_IN_PU,
+               PC0_FN, PC0_OUT, PC0_IN, PC0_IN_PU }
+       },
+       { PINMUX_CFG_REG("PDCR", 0xffe70006, 16, 2) {
+               PD7_FN, PD7_OUT, PD7_IN, PD7_IN_PU,
+               PD6_FN, PD6_OUT, PD6_IN, PD6_IN_PU,
+               PD5_FN, PD5_OUT, PD5_IN, PD5_IN_PU,
+               PD4_FN, PD4_OUT, PD4_IN, PD4_IN_PU,
+               PD3_FN, PD3_OUT, PD3_IN, PD3_IN_PU,
+               PD2_FN, PD2_OUT, PD2_IN, PD2_IN_PU,
+               PD1_FN, PD1_OUT, PD1_IN, PD1_IN_PU,
+               PD0_FN, PD0_OUT, PD0_IN, PD0_IN_PU }
+       },
+       { PINMUX_CFG_REG("PECR", 0xffe70008, 16, 2) {
+               0, 0, 0, 0,
+               0, 0, 0, 0,
+               PE5_FN, PE5_OUT, PE5_IN, PE5_IN_PU,
+               PE4_FN, PE4_OUT, PE4_IN, PE4_IN_PU,
+               PE3_FN, PE3_OUT, PE3_IN, PE3_IN_PU,
+               PE2_FN, PE2_OUT, PE2_IN, PE2_IN_PU,
+               PE1_FN, PE1_OUT, PE1_IN, PE1_IN_PU,
+               PE0_FN, PE0_OUT, PE0_IN, PE0_IN_PU }
+       },
+       { PINMUX_CFG_REG("PFCR", 0xffe7000a, 16, 2) {
+               PF7_FN, PF7_OUT, PF7_IN, PF7_IN_PU,
+               PF6_FN, PF6_OUT, PF6_IN, PF6_IN_PU,
+               PF5_FN, PF5_OUT, PF5_IN, PF5_IN_PU,
+               PF4_FN, PF4_OUT, PF4_IN, PF4_IN_PU,
+               PF3_FN, PF3_OUT, PF3_IN, PF3_IN_PU,
+               PF2_FN, PF2_OUT, PF2_IN, PF2_IN_PU,
+               PF1_FN, PF1_OUT, PF1_IN, PF1_IN_PU,
+               PF0_FN, PF0_OUT, PF0_IN, PF0_IN_PU }
+       },
+       { PINMUX_CFG_REG("PGCR", 0xffe7000c, 16, 2) {
+               PG7_FN, PG7_OUT, PG7_IN, PG7_IN_PU,
+               PG6_FN, PG6_OUT, PG6_IN, PG6_IN_PU,
+               PG5_FN, PG5_OUT, PG5_IN, PG5_IN_PU,
+               PG4_FN, PG4_OUT, PG4_IN, PG4_IN_PU,
+               PG3_FN, PG3_OUT, PG3_IN, PG3_IN_PU,
+               PG2_FN, PG2_OUT, PG2_IN, PG2_IN_PU,
+               PG1_FN, PG1_OUT, PG1_IN, PG1_IN_PU,
+               PG0_FN, PG0_OUT, PG0_IN, PG0_IN_PU }
+       },
+       { PINMUX_CFG_REG("PHCR", 0xffe7000e, 16, 2) {
+               PH7_FN, PH7_OUT, PH7_IN, PH7_IN_PU,
+               PH6_FN, PH6_OUT, PH6_IN, PH6_IN_PU,
+               PH5_FN, PH5_OUT, PH5_IN, PH5_IN_PU,
+               PH4_FN, PH4_OUT, PH4_IN, PH4_IN_PU,
+               PH3_FN, PH3_OUT, PH3_IN, PH3_IN_PU,
+               PH2_FN, PH2_OUT, PH2_IN, PH2_IN_PU,
+               PH1_FN, PH1_OUT, PH1_IN, PH1_IN_PU,
+               PH0_FN, PH0_OUT, PH0_IN, PH0_IN_PU }
+       },
+       { PINMUX_CFG_REG("PJCR", 0xffe70010, 16, 2) {
+               PJ7_FN, PJ7_OUT, PJ7_IN, PJ7_IN_PU,
+               PJ6_FN, PJ6_OUT, PJ6_IN, PJ6_IN_PU,
+               PJ5_FN, PJ5_OUT, PJ5_IN, PJ5_IN_PU,
+               PJ4_FN, PJ4_OUT, PJ4_IN, PJ4_IN_PU,
+               PJ3_FN, PJ3_OUT, PJ3_IN, PJ3_IN_PU,
+               PJ2_FN, PJ2_OUT, PJ2_IN, PJ2_IN_PU,
+               PJ1_FN, PJ1_OUT, PJ1_IN, PJ1_IN_PU,
+               PJ0_FN, PJ0_OUT, PJ0_IN, PJ0_IN_PU }
+       },
+       { PINMUX_CFG_REG("PKCR", 0xffe70012, 16, 2) {
+               PK7_FN, PK7_OUT, PK7_IN, PK7_IN_PU,
+               PK6_FN, PK6_OUT, PK6_IN, PK6_IN_PU,
+               PK5_FN, PK5_OUT, PK5_IN, PK5_IN_PU,
+               PK4_FN, PK4_OUT, PK4_IN, PK4_IN_PU,
+               PK3_FN, PK3_OUT, PK3_IN, PK3_IN_PU,
+               PK2_FN, PK2_OUT, PK2_IN, PK2_IN_PU,
+               PK1_FN, PK1_OUT, PK1_IN, PK1_IN_PU,
+               PK0_FN, PK0_OUT, PK0_IN, PK0_IN_PU }
+       },
+       { PINMUX_CFG_REG("PLCR", 0xffe70014, 16, 2) {
+               PL7_FN, PL7_OUT, PL7_IN, PL7_IN_PU,
+               PL6_FN, PL6_OUT, PL6_IN, PL6_IN_PU,
+               PL5_FN, PL5_OUT, PL5_IN, PL5_IN_PU,
+               PL4_FN, PL4_OUT, PL4_IN, PL4_IN_PU,
+               PL3_FN, PL3_OUT, PL3_IN, PL3_IN_PU,
+               PL2_FN, PL2_OUT, PL2_IN, PL2_IN_PU,
+               PL1_FN, PL1_OUT, PL1_IN, PL1_IN_PU,
+               PL0_FN, PL0_OUT, PL0_IN, PL0_IN_PU }
+       },
+       { PINMUX_CFG_REG("PMCR", 0xffe70016, 16, 2) {
+               0, 0, 0, 0,
+               0, 0, 0, 0,
+               0, 0, 0, 0,
+               0, 0, 0, 0,
+               0, 0, 0, 0,
+               0, 0, 0, 0,
+               PM1_FN, PM1_OUT, PM1_IN, PM1_IN_PU,
+               PM0_FN, PM0_OUT, PM0_IN, PM0_IN_PU }
+       },
+       { PINMUX_CFG_REG("PNCR", 0xffe70018, 16, 2) {
+               PN7_FN, PN7_OUT, PN7_IN, PN7_IN_PU,
+               PN6_FN, PN6_OUT, PN6_IN, PN6_IN_PU,
+               PN5_FN, PN5_OUT, PN5_IN, PN5_IN_PU,
+               PN4_FN, PN4_OUT, PN4_IN, PN4_IN_PU,
+               PN3_FN, PN3_OUT, PN3_IN, PN3_IN_PU,
+               PN2_FN, PN2_OUT, PN2_IN, PN2_IN_PU,
+               PN1_FN, PN1_OUT, PN1_IN, PN1_IN_PU,
+               PN0_FN, PN0_OUT, PN0_IN, PN0_IN_PU }
+       },
+       { PINMUX_CFG_REG("PPCR", 0xffe7001a, 16, 2) {
+               0, 0, 0, 0,
+               0, 0, 0, 0,
+               PP5_FN, PP5_OUT, PP5_IN, PP5_IN_PU,
+               PP4_FN, PP4_OUT, PP4_IN, PP4_IN_PU,
+               PP3_FN, PP3_OUT, PP3_IN, PP3_IN_PU,
+               PP2_FN, PP2_OUT, PP2_IN, PP2_IN_PU,
+               PP1_FN, PP1_OUT, PP1_IN, PP1_IN_PU,
+               PP0_FN, PP0_OUT, PP0_IN, PP0_IN_PU }
+       },
+       { PINMUX_CFG_REG("PQCR", 0xffe7001c, 16, 2) {
+               0, 0, 0, 0,
+               0, 0, 0, 0,
+               0, 0, 0, 0,
+               PQ4_FN, PQ4_OUT, PQ4_IN, PQ4_IN_PU,
+               PQ3_FN, PQ3_OUT, PQ3_IN, PQ3_IN_PU,
+               PQ2_FN, PQ2_OUT, PQ2_IN, PQ2_IN_PU,
+               PQ1_FN, PQ1_OUT, PQ1_IN, PQ1_IN_PU,
+               PQ0_FN, PQ0_OUT, PQ0_IN, PQ0_IN_PU }
+       },
+       { PINMUX_CFG_REG("PRCR", 0xffe7001e, 16, 2) {
+               0, 0, 0, 0,
+               0, 0, 0, 0,
+               0, 0, 0, 0,
+               0, 0, 0, 0,
+               PR3_FN, PR3_OUT, PR3_IN, PR3_IN_PU,
+               PR2_FN, PR2_OUT, PR2_IN, PR2_IN_PU,
+               PR1_FN, PR1_OUT, PR1_IN, PR1_IN_PU,
+               PR0_FN, PR0_OUT, PR0_IN, PR0_IN_PU }
+       },
+       { PINMUX_CFG_REG("P1MSELR", 0xffe70080, 16, 1) {
+               P1MSEL15_0, P1MSEL15_1,
+               P1MSEL14_0, P1MSEL14_1,
+               P1MSEL13_0, P1MSEL13_1,
+               P1MSEL12_0, P1MSEL12_1,
+               P1MSEL11_0, P1MSEL11_1,
+               P1MSEL10_0, P1MSEL10_1,
+               P1MSEL9_0, P1MSEL9_1,
+               P1MSEL8_0, P1MSEL8_1,
+               P1MSEL7_0, P1MSEL7_1,
+               P1MSEL6_0, P1MSEL6_1,
+               P1MSEL5_0, 0,
+               P1MSEL4_0, P1MSEL4_1,
+               P1MSEL3_0, P1MSEL3_1,
+               P1MSEL2_0, P1MSEL2_1,
+               P1MSEL1_0, P1MSEL1_1,
+               P1MSEL0_0, P1MSEL0_1 }
+       },
+       { PINMUX_CFG_REG("P2MSELR", 0xffe70082, 16, 1) {
+               0, 0,
+               0, 0,
+               0, 0,
+               0, 0,
+               0, 0,
+               0, 0,
+               0, 0,
+               0, 0,
+               0, 0,
+               0, 0,
+               0, 0,
+               0, 0,
+               0, 0,
+               P2MSEL2_0, P2MSEL2_1,
+               P2MSEL1_0, P2MSEL1_1,
+               P2MSEL0_0, P2MSEL0_1 }
+       },
+       {}
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+       { PINMUX_DATA_REG("PADR", 0xffe70020, 8) {
+               PA7_DATA, PA6_DATA, PA5_DATA, PA4_DATA,
+               PA3_DATA, PA2_DATA, PA1_DATA, PA0_DATA }
+       },
+       { PINMUX_DATA_REG("PBDR", 0xffe70022, 8) {
+               PB7_DATA, PB6_DATA, PB5_DATA, PB4_DATA,
+               PB3_DATA, PB2_DATA, PB1_DATA, PB0_DATA }
+       },
+       { PINMUX_DATA_REG("PCDR", 0xffe70024, 8) {
+               PC7_DATA, PC6_DATA, PC5_DATA, PC4_DATA,
+               PC3_DATA, PC2_DATA, PC1_DATA, PC0_DATA }
+       },
+       { PINMUX_DATA_REG("PDDR", 0xffe70026, 8) {
+               PD7_DATA, PD6_DATA, PD5_DATA, PD4_DATA,
+               PD3_DATA, PD2_DATA, PD1_DATA, PD0_DATA }
+       },
+       { PINMUX_DATA_REG("PEDR", 0xffe70028, 8) {
+               0, 0, PE5_DATA, PE4_DATA,
+               PE3_DATA, PE2_DATA, PE1_DATA, PE0_DATA }
+       },
+       { PINMUX_DATA_REG("PFDR", 0xffe7002a, 8) {
+               PF7_DATA, PF6_DATA, PF5_DATA, PF4_DATA,
+               PF3_DATA, PF2_DATA, PF1_DATA, PF0_DATA }
+       },
+       { PINMUX_DATA_REG("PGDR", 0xffe7002c, 8) {
+               PG7_DATA, PG6_DATA, PG5_DATA, PG4_DATA,
+               PG3_DATA, PG2_DATA, PG1_DATA, PG0_DATA }
+       },
+       { PINMUX_DATA_REG("PHDR", 0xffe7002e, 8) {
+               PH7_DATA, PH6_DATA, PH5_DATA, PH4_DATA,
+               PH3_DATA, PH2_DATA, PH1_DATA, PH0_DATA }
+       },
+       { PINMUX_DATA_REG("PJDR", 0xffe70030, 8) {
+               PJ7_DATA, PJ6_DATA, PJ5_DATA, PJ4_DATA,
+               PJ3_DATA, PJ2_DATA, PJ1_DATA, PJ0_DATA }
+       },
+       { PINMUX_DATA_REG("PKDR", 0xffe70032, 8) {
+               PK7_DATA, PK6_DATA, PK5_DATA, PK4_DATA,
+               PK3_DATA, PK2_DATA, PK1_DATA, PK0_DATA }
+       },
+       { PINMUX_DATA_REG("PLDR", 0xffe70034, 8) {
+               PL7_DATA, PL6_DATA, PL5_DATA, PL4_DATA,
+               PL3_DATA, PL2_DATA, PL1_DATA, PL0_DATA }
+       },
+       { PINMUX_DATA_REG("PMDR", 0xffe70036, 8) {
+               0, 0, 0, 0,
+               0, 0, PM1_DATA, PM0_DATA }
+       },
+       { PINMUX_DATA_REG("PNDR", 0xffe70038, 8) {
+               PN7_DATA, PN6_DATA, PN5_DATA, PN4_DATA,
+               PN3_DATA, PN2_DATA, PN1_DATA, PN0_DATA }
+       },
+       { PINMUX_DATA_REG("PPDR", 0xffe7003a, 8) {
+               0, 0, PP5_DATA, PP4_DATA,
+               PP3_DATA, PP2_DATA, PP1_DATA, PP0_DATA }
+       },
+       { PINMUX_DATA_REG("PQDR", 0xffe7003c, 8) {
+               0, 0, 0, PQ4_DATA,
+               PQ3_DATA, PQ2_DATA, PQ1_DATA, PQ0_DATA }
+       },
+       { PINMUX_DATA_REG("PRDR", 0xffe7003e, 8) {
+               0, 0, 0, 0,
+               PR3_DATA, PR2_DATA, PR1_DATA, PR0_DATA }
+       },
+       { },
+};
+
+static struct pinmux_info sh7785_pinmux_info = {
+       .name = "sh7785_pfc",
+       .reserved_id = PINMUX_RESERVED,
+       .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+       .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+       .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END },
+       .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+       .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
+       .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+       .first_gpio = GPIO_PA7,
+       .last_gpio = GPIO_FN_IRQOUT,
+
+       .gpios = pinmux_gpios,
+       .cfg_regs = pinmux_config_regs,
+       .data_regs = pinmux_data_regs,
+
+       .gpio_data = pinmux_data,
+       .gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+static int __init plat_pinmux_setup(void)
+{
+       return register_pinmux(&sh7785_pinmux_info);
+}
+
+arch_initcall(plat_pinmux_setup);
index bb8b812c6895c1f1d46299a9f4bb09d608ec3cdc..d371653610348313dc4b6481764b9b0ea4a08988 100644 (file)
@@ -267,9 +267,13 @@ int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
                        break;
 
                in_range = enum_in_range(enum_id, &gpioc->function);
-               if (!in_range && range)
+               if (!in_range && range) {
                        in_range = enum_in_range(enum_id, range);
 
+                       if (in_range && enum_id == range->force)
+                               continue;
+               }
+
                if (!in_range)
                        continue;
 
@@ -432,7 +436,7 @@ static int __gpio_get_set_value(struct pinmux_info *gpioc,
                BUG();
        else
                value = read_write_reg(dr->reg, dr->reg_width,
-                                      1, bit, value, do_write);
+                                      1, bit, !!value, do_write);
 
        return value;
 }
index d917b7b4042bcb81ce8c2a1219e099b95a3feea1..d366a7443720875e7489721dc5765f598f6b2ffe 100644 (file)
@@ -126,7 +126,6 @@ DECLARE_EXPORT(__movstrSI12_i4);
 EXPORT_SYMBOL(flush_cache_all);
 EXPORT_SYMBOL(flush_cache_range);
 EXPORT_SYMBOL(flush_dcache_page);
-EXPORT_SYMBOL(__flush_purge_region);
 #endif
 
 #if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) && \
@@ -147,3 +146,9 @@ EXPORT_SYMBOL(copy_page);
 EXPORT_SYMBOL(__clear_user);
 EXPORT_SYMBOL(_ebss);
 EXPORT_SYMBOL(empty_zero_page);
+
+#ifndef CONFIG_CACHE_OFF
+EXPORT_SYMBOL(__flush_purge_region);
+EXPORT_SYMBOL(__flush_wback_region);
+EXPORT_SYMBOL(__flush_invalidate_region);
+#endif
index 508dfb023628d980233110f462802dd27f8c93d2..3c5ad1660bbcdd6b0366934167b3dc879cdb026d 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/spinlock.h>
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/cpu.h>
 #include <linux/interrupt.h>
 #include <asm/atomic.h>
 #include <asm/processor.h>
index b359b08a8e33a9cb827145abe0c02c6ad66dc9d9..1e5c74efbacc35d4f729b17cb08b342bbca2045f 100644 (file)
@@ -105,6 +105,8 @@ void die(const char * str, struct pt_regs * regs, long err)
                dump_mem("Stack: ", regs->regs[15], THREAD_SIZE +
                         (unsigned long)task_stack_page(current));
 
+       notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV);
+
        bust_spinlocks(0);
        add_taint(TAINT_DIE);
        spin_unlock_irq(&die_lock);
index 2a53943924b2c99479e3c748a31acf9db45494d1..4abf00031daef8521e39d09a1d032f1d937b26af 100644 (file)
@@ -321,21 +321,4 @@ int memory_add_physaddr_to_nid(u64 addr)
 }
 EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
 #endif
-
-#ifdef CONFIG_MEMORY_HOTREMOVE
-int remove_memory(u64 start, u64 size)
-{
-       unsigned long start_pfn = start >> PAGE_SHIFT;
-       unsigned long end_pfn = start_pfn + (size >> PAGE_SHIFT);
-       int ret;
-
-       ret = offline_pages(start_pfn, end_pfn, 120 * HZ);
-       if (unlikely(ret))
-               printk("%s: Failed, offline_pages() == %d\n", __func__, ret);
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(remove_memory);
-#endif
-
 #endif /* CONFIG_MEMORY_HOTPLUG */
index 9ab815b95b5a773de179dfaec9ddf71ad1c6c6ef..17bb6035069b7158286ebd50462aac61d07507f4 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
  
-int __init oprofile_arch_init(struct oprofile_operations * ops)
+int __init oprofile_arch_init(struct oprofile_operations *ops)
 {
        return -ENODEV;
 }
index 9ab815b95b5a773de179dfaec9ddf71ad1c6c6ef..17bb6035069b7158286ebd50462aac61d07507f4 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
  
-int __init oprofile_arch_init(struct oprofile_operations * ops)
+int __init oprofile_arch_init(struct oprofile_operations *ops)
 {
        return -ENODEV;
 }
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common
new file mode 100644 (file)
index 0000000..0d207e7
--- /dev/null
@@ -0,0 +1,77 @@
+config DEFCONFIG_LIST
+       string
+       option defconfig_list
+       default "arch/$ARCH/defconfig"
+
+# UML uses the generic IRQ subsystem
+config GENERIC_HARDIRQS
+       bool
+       default y
+
+config UML
+       bool
+       default y
+
+config MMU
+       bool
+       default y
+
+config NO_IOMEM
+       def_bool y
+
+mainmenu "Linux/Usermode Kernel Configuration"
+
+config ISA
+       bool
+
+config SBUS
+       bool
+
+config PCI
+       bool
+
+config PCMCIA
+       bool
+
+# Yet to do!
+config TRACE_IRQFLAGS_SUPPORT
+       bool
+       default n
+
+config LOCKDEP_SUPPORT
+       bool
+       default y
+
+config STACKTRACE_SUPPORT
+       bool
+       default n
+
+config GENERIC_CALIBRATE_DELAY
+       bool
+       default y
+
+config GENERIC_BUG
+       bool
+       default y
+       depends on BUG
+
+config GENERIC_TIME
+       bool
+       default y
+
+config GENERIC_CLOCKEVENTS
+       bool
+       default y
+
+# Used in kernel/irq/manage.c and include/linux/irq.h
+config IRQ_RELEASE_METHOD
+       bool
+       default y
+
+config HZ
+       int
+       default 100
+
+config SUBARCH
+       string
+       option env="SUBARCH"
diff --git a/arch/um/Kconfig.rest b/arch/um/Kconfig.rest
new file mode 100644 (file)
index 0000000..7b5cea7
--- /dev/null
@@ -0,0 +1,42 @@
+source "init/Kconfig"
+
+source "kernel/Kconfig.freezer"
+
+source "drivers/block/Kconfig"
+
+source "arch/um/Kconfig.char"
+
+source "drivers/base/Kconfig"
+
+source "net/Kconfig"
+
+source "arch/um/Kconfig.net"
+
+source "drivers/net/Kconfig"
+
+source "drivers/connector/Kconfig"
+
+source "fs/Kconfig"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
+
+source "drivers/scsi/Kconfig"
+
+source "drivers/md/Kconfig"
+
+if BROKEN
+       source "drivers/mtd/Kconfig"
+endif
+
+source "drivers/leds/Kconfig"
+
+#This is just to shut up some Kconfig warnings, so no prompt.
+config INPUT
+       bool
+       default n
+
+source "arch/um/Kconfig.debug"
similarity index 77%
rename from arch/um/Kconfig
rename to arch/um/Kconfig.um
index 393bccfe1785108579dc6c18bab682f2e7984110..ec2b8da1aba483acb7e80b20c2c14041c81f4e7c 100644 (file)
@@ -1,79 +1,3 @@
-config DEFCONFIG_LIST
-       string
-       option defconfig_list
-       default "arch/$ARCH/defconfig"
-
-# UML uses the generic IRQ subsystem
-config GENERIC_HARDIRQS
-       bool
-       default y
-
-config UML
-       bool
-       default y
-
-config MMU
-       bool
-       default y
-
-config NO_IOMEM
-       def_bool y
-
-mainmenu "Linux/Usermode Kernel Configuration"
-
-config ISA
-       bool
-
-config SBUS
-       bool
-
-config PCI
-       bool
-
-config PCMCIA
-       bool
-
-# Yet to do!
-config TRACE_IRQFLAGS_SUPPORT
-       bool
-       default n
-
-config LOCKDEP_SUPPORT
-       bool
-       default y
-
-config STACKTRACE_SUPPORT
-       bool
-       default n
-
-config GENERIC_CALIBRATE_DELAY
-       bool
-       default y
-
-config GENERIC_BUG
-       bool
-       default y
-       depends on BUG
-
-config GENERIC_TIME
-       bool
-       default y
-
-config GENERIC_CLOCKEVENTS
-       bool
-       default y
-
-# Used in kernel/irq/manage.c and include/linux/irq.h
-config IRQ_RELEASE_METHOD
-       bool
-       default y
-
-config HZ
-       int
-       default 100
-
-menu "UML-specific options"
-
 config STATIC_LINK
        bool "Force a static link"
        default n
@@ -85,7 +9,6 @@ config STATIC_LINK
          Additionally, this option enables using higher memory spaces (up to
          2.75G) for UML.
 
-source "arch/um/Kconfig.arch"
 source "mm/Kconfig"
 source "kernel/time/Kconfig"
 
@@ -224,48 +147,3 @@ config KERNEL_STACK_ORDER
          This option determines the size of UML kernel stacks.  They will
          be 1 << order pages.  The default is OK unless you're running Valgrind
          on UML, in which case, set this to 3.
-
-endmenu
-
-source "init/Kconfig"
-
-source "kernel/Kconfig.freezer"
-
-source "drivers/block/Kconfig"
-
-source "arch/um/Kconfig.char"
-
-source "drivers/base/Kconfig"
-
-source "net/Kconfig"
-
-source "arch/um/Kconfig.net"
-
-source "drivers/net/Kconfig"
-
-source "drivers/connector/Kconfig"
-
-source "fs/Kconfig"
-
-source "security/Kconfig"
-
-source "crypto/Kconfig"
-
-source "lib/Kconfig"
-
-source "drivers/scsi/Kconfig"
-
-source "drivers/md/Kconfig"
-
-if BROKEN
-       source "drivers/mtd/Kconfig"
-endif
-
-source "drivers/leds/Kconfig"
-
-#This is just to shut up some Kconfig warnings, so no prompt.
-config INPUT
-       bool
-       default n
-
-source "arch/um/Kconfig.debug"
similarity index 59%
rename from arch/um/Kconfig.i386
rename to arch/um/Kconfig.x86
index 1f57c113df6dab5d6816b829d994958c1ad657e4..5ee328099c6359ae721f919ba554ba53e7052551 100644 (file)
@@ -1,3 +1,7 @@
+source "arch/um/Kconfig.common"
+
+menu "UML-specific options"
+
 menu "Host processor type and features"
 
 source "arch/x86/Kconfig.cpu"
@@ -5,24 +9,25 @@ source "arch/x86/Kconfig.cpu"
 endmenu
 
 config UML_X86
+       def_bool y
+
+config 64BIT
        bool
-       default y
+       default SUBARCH = "x86_64"
 
 config X86_32
-       bool
-       default y
-       select HAVE_AOUT
+       def_bool !64BIT
+       select HAVE_AOUT
 
 config RWSEM_XCHGADD_ALGORITHM
-       def_bool y
+       def_bool X86_XADD
 
-config 64BIT
-       bool
-       default n
+config RWSEM_GENERIC_SPINLOCK
+       def_bool !X86_XADD
 
 config 3_LEVEL_PGTABLES
-       bool "Three-level pagetables (EXPERIMENTAL)"
-       default n
+       bool "Three-level pagetables (EXPERIMENTAL)" if !64BIT
+       default 64BIT
        depends on EXPERIMENTAL
        help
        Three-level pagetables will let UML have more than 4G of physical
@@ -33,13 +38,19 @@ config 3_LEVEL_PGTABLES
        N (on x86-64 it's automatically enabled, instead, as it's safe there).
 
 config ARCH_HAS_SC_SIGNALS
-       bool
-       default y
+       def_bool !64BIT
 
 config ARCH_REUSE_HOST_VSYSCALL_AREA
-       bool
-       default y
+       def_bool !64BIT
+
+config SMP_BROKEN
+       def_bool 64BIT
 
 config GENERIC_HWEIGHT
-       bool
-       default y
+       def_bool y
+
+source "arch/um/Kconfig.um"
+
+endmenu
+
+source "arch/um/Kconfig.rest"
diff --git a/arch/um/Kconfig.x86_64 b/arch/um/Kconfig.x86_64
deleted file mode 100644 (file)
index 40b3407..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-
-menu "Host processor type and features"
-
-source "arch/x86/Kconfig.cpu"
-
-endmenu
-
-config UML_X86
-       bool
-       default y
-
-config 64BIT
-       bool
-       default y
-
-#XXX: this is so in the underlying arch, but it's wrong!!!
-config RWSEM_GENERIC_SPINLOCK
-       bool
-       default y
-
-config 3_LEVEL_PGTABLES
-       bool
-       default y
-
-config ARCH_HAS_SC_SIGNALS
-       bool
-       default n
-
-config ARCH_REUSE_HOST_VSYSCALL_AREA
-       bool
-       default n
-
-config SMP_BROKEN
-       bool
-       default y
-
-config GENERIC_HWEIGHT
-       bool
-       default y
index ca40397017b98007a1504fb5761624bda030aeab..d944c343acdb26ab68a9d3243fa58c95ee090868 100644 (file)
@@ -18,28 +18,16 @@ core-y                      += $(ARCH_DIR)/kernel/          \
                           $(ARCH_DIR)/drivers/         \
                           $(ARCH_DIR)/os-$(OS)/
 
-# Have to precede the include because the included Makefiles reference them.
-SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \
-       module.h vm-flags.h elf.h host_ldt.h
-SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
-
-# XXX: The "os" symlink is only used by arch/um/include/os.h, which includes
-# ../os/include/file.h
-#
-# These are cleaned up during mrproper. Please DO NOT fix it again, this is
-# the Correct Thing(tm) to do!
-ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
-       $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
-
-MODE_INCLUDE   += -I$(srctree)/$(ARCH_DIR)/include/skas
+MODE_INCLUDE   += -I$(srctree)/$(ARCH_DIR)/include/shared/skas
 
 include $(srctree)/$(ARCH_DIR)/Makefile-skas
 
-ARCH_INCLUDE   := -I$(ARCH_DIR)/include
+ARCH_INCLUDE   := -I$(srctree)/$(ARCH_DIR)/include/shared
+ARCH_INCLUDE   += -I$(srctree)/$(ARCH_DIR)/sys-$(SUBARCH)/shared
 ifneq ($(KBUILD_SRC),)
-ARCH_INCLUDE   += -I$(srctree)/$(ARCH_DIR)/include
+ARCH_INCLUDE   += -I$(ARCH_DIR)/include/shared # for two generated files
 endif
-SYS_DIR                := $(ARCH_DIR)/include/sysdep-$(SUBARCH)
+KBUILD_CPPFLAGS += -I$(srctree)/$(ARCH_DIR)/sys-$(SUBARCH)
 
 # -Dvmap=kernel_vmap prevents anything from referencing the libpcap.o symbol so
 # named - it's a common symbol in libpcap, so we get a binary which crashes.
@@ -65,6 +53,8 @@ include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
 #This will adjust *FLAGS accordingly to the platform.
 include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
 
+KBUILD_CPPFLAGS += -I$(srctree)/arch/$(HEADER_ARCH)/include
+
 # -Derrno=kernel_errno - This turns all kernel references to errno into
 # kernel_errno to separate them from the libc errno.  This allows -fno-common
 # in KBUILD_CFLAGS.  Otherwise, it would cause ld to complain about the two different
@@ -93,14 +83,10 @@ define archhelp
   echo '                  find in the kernel root.'
 endef
 
-ifneq ($(KBUILD_SRC),)
-$(shell mkdir -p $(ARCH_DIR) && ln -fsn $(srctree)/$(ARCH_DIR)/Kconfig.$(SUBARCH) $(ARCH_DIR)/Kconfig.arch)
-else
-$(shell cd $(ARCH_DIR) && ln -sf Kconfig.$(SUBARCH) Kconfig.arch)
-endif
+KBUILD_KCONFIG := arch/um/Kconfig.$(HEADER_ARCH)
 
-archprepare: $(ARCH_SYMLINKS) $(ARCH_DIR)/include/user_constants.h
-prepare: $(ARCH_DIR)/include/kern_constants.h
+archprepare: $(ARCH_DIR)/include/shared/user_constants.h
+prepare: $(ARCH_DIR)/include/shared/kern_constants.h
 
 LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static
 LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib
@@ -132,62 +118,19 @@ endef
 
 # When cleaning we don't include .config, so we don't include
 # TT or skas makefiles and don't clean skas_ptregs.h.
-CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/include/uml-config.h \
-       $(ARCH_DIR)/include/user_constants.h \
-       $(ARCH_DIR)/include/kern_constants.h $(ARCH_DIR)/Kconfig.arch
-
-MRPROPER_FILES += $(ARCH_SYMLINKS)
+CLEAN_FILES += linux x.i gmon.out \
+       $(ARCH_DIR)/include/shared/user_constants.h \
+       $(ARCH_DIR)/include/shared/kern_constants.h
 
 archclean:
        @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
                -o -name '*.gcov' \) -type f -print | xargs rm -f
 
-$(SYMLINK_HEADERS):
-       @echo '  SYMLINK $@'
-ifneq ($(KBUILD_SRC),)
-       $(Q)mkdir -p $(objtree)/include/asm-um
-       $(Q)ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@
-else
-       $(Q)cd $(srctree)/$(dir $@) ; \
-       ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@)
-endif
-
-include/asm-um/arch:
-       @echo '  SYMLINK $@'
-ifneq ($(KBUILD_SRC),)
-       $(Q)mkdir -p $(objtree)/include/asm-um
-       $(Q)ln -fsn $(srctree)/include/asm-$(HEADER_ARCH) include/asm-um/arch
-else
-       $(Q)cd $(srctree)/include/asm-um && ln -fsn ../asm-$(HEADER_ARCH) arch
-endif
-
-$(objtree)/$(ARCH_DIR)/include:
+$(objtree)/$(ARCH_DIR)/include/shared:
        @echo '  MKDIR $@'
        $(Q)mkdir -p $@
 
-$(ARCH_DIR)/include/sysdep: $(objtree)/$(ARCH_DIR)/include
-       @echo '  SYMLINK $@'
-ifneq ($(KBUILD_SRC),)
-       $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/include/sysdep-$(SUBARCH) $(ARCH_DIR)/include/sysdep
-else
-       $(Q)cd $(ARCH_DIR)/include && ln -fsn sysdep-$(SUBARCH) sysdep
-endif
-
-$(ARCH_DIR)/os:
-       @echo '  SYMLINK $@'
-ifneq ($(KBUILD_SRC),)
-       $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/os-$(OS) $(ARCH_DIR)/os
-else
-       $(Q)cd $(ARCH_DIR) && ln -fsn os-$(OS) os
-endif
-
 # Generated files
-define filechk_umlconfig
-       sed 's/ CONFIG/ UML_CONFIG/'
-endef
-
-$(ARCH_DIR)/include/uml-config.h : include/linux/autoconf.h
-       $(call filechk,umlconfig)
 
 $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s: FORCE
        $(Q)$(MAKE) $(build)=$(ARCH_DIR)/sys-$(SUBARCH) $@
@@ -205,11 +148,11 @@ define filechk_gen-asm-offsets
          echo ""; )
 endef
 
-$(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s
+$(ARCH_DIR)/include/shared/user_constants.h: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s
        $(call filechk,gen-asm-offsets)
 
-$(ARCH_DIR)/include/kern_constants.h: $(objtree)/$(ARCH_DIR)/include
+$(ARCH_DIR)/include/shared/kern_constants.h: $(objtree)/$(ARCH_DIR)/include/shared
        @echo '  SYMLINK $@'
-       $(Q)ln -sf ../../../include/asm-um/asm-offsets.h $@
+       $(Q)ln -sf ../../../../include/asm/asm-offsets.h $@
 
-export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS HEADER_ARCH
+export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS HEADER_ARCH DEV_NULL_PATH
index 52859487c95d7d4a2aa9b958144a568b10c99a0f..2c8a598ec14b56221761e7890db42e290e551afe 100644 (file)
@@ -6,3 +6,4 @@
 # To get a definition of F_SETSIG
 USER_CFLAGS += -D_GNU_SOURCE -D_LARGEFILE64_SOURCE
 KBUILD_CFLAGS += -D_LARGEFILE64_SOURCE
+DEV_NULL_PATH = \"/dev/null\"
index d283e7b022a0d8229e3869ad57595178129e0f66..1d9b6ae967b089c780afd713932af0bf42900468 100644 (file)
@@ -62,5 +62,6 @@ obj-$(CONFIG_UML_RANDOM) += random.o
 
 # pcap_user.o must be added explicitly.
 USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o pcap_user.o vde_user.o
+CFLAGS_null.o = -DDEV_NULL=$(DEV_NULL_PATH)
 
 include arch/um/scripts/Makefile.rules
index b58fb8941d8d7eb4cb27447084332f686dca031a..0a868118cf06b2bb2aece4afbbd89d18228d43dc 100644 (file)
@@ -98,9 +98,9 @@ static inline void ubd_set_bit(__u64 bit, unsigned char *data)
 
 static DEFINE_MUTEX(ubd_lock);
 
-static int ubd_open(struct inode * inode, struct file * filp);
-static int ubd_release(struct inode * inode, struct file * file);
-static int ubd_ioctl(struct inode * inode, struct file * file,
+static int ubd_open(struct block_device *bdev, fmode_t mode);
+static int ubd_release(struct gendisk *disk, fmode_t mode);
+static int ubd_ioctl(struct block_device *bdev, fmode_t mode,
                     unsigned int cmd, unsigned long arg);
 static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
 
@@ -1112,9 +1112,9 @@ static int __init ubd_driver_init(void){
 
 device_initcall(ubd_driver_init);
 
-static int ubd_open(struct inode *inode, struct file *filp)
+static int ubd_open(struct block_device *bdev, fmode_t mode)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
+       struct gendisk *disk = bdev->bd_disk;
        struct ubd *ubd_dev = disk->private_data;
        int err = 0;
 
@@ -1131,7 +1131,7 @@ static int ubd_open(struct inode *inode, struct file *filp)
 
        /* This should no more be needed. And it didn't work anyway to exclude
         * read-write remounting of filesystems.*/
-       /*if((filp->f_mode & FMODE_WRITE) && !ubd_dev->openflags.w){
+       /*if((mode & FMODE_WRITE) && !ubd_dev->openflags.w){
                if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev);
                err = -EROFS;
        }*/
@@ -1139,9 +1139,8 @@ static int ubd_open(struct inode *inode, struct file *filp)
        return err;
 }
 
-static int ubd_release(struct inode * inode, struct file * file)
+static int ubd_release(struct gendisk *disk, fmode_t mode)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
        struct ubd *ubd_dev = disk->private_data;
 
        if(--ubd_dev->count == 0)
@@ -1306,10 +1305,10 @@ static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
        return 0;
 }
 
-static int ubd_ioctl(struct inode * inode, struct file * file,
+static int ubd_ioctl(struct block_device *bdev, fmode_t mode,
                     unsigned int cmd, unsigned long arg)
 {
-       struct ubd *ubd_dev = inode->i_bdev->bd_disk->private_data;
+       struct ubd *ubd_dev = bdev->bd_disk->private_data;
        struct hd_driveid ubd_id = {
                .cyls           = 0,
                .heads          = 128,
similarity index 99%
rename from include/asm-um/fixmap.h
rename to arch/um/include/asm/fixmap.h
index 9d2be52b865526586c93a79f1a14d4d7515b820c..69c0252345f10e0ad3061df4d45c325475776c18 100644 (file)
@@ -6,6 +6,7 @@
 #include <asm/kmap_types.h>
 #include <asm/archparam.h>
 #include <asm/page.h>
+#include <linux/threads.h>
 
 /*
  * Here we define all the compile-time 'special' virtual
similarity index 100%
rename from include/asm-um/io.h
rename to arch/um/include/asm/io.h
similarity index 99%
rename from include/asm-um/page.h
rename to arch/um/include/asm/page.h
index a6df1f13d732ddaf7d487fdcb5eabf20a14f6c93..55f28a0bae6d3dd99ee7e23eb01ccb546ba446ef 100644 (file)
@@ -19,7 +19,7 @@
 struct page;
 
 #include <linux/types.h>
-#include <asm/vm-flags.h>
+#include <sysdep/vm-flags.h>
 
 /*
  * These are used to make use of C type-checking..
similarity index 97%
rename from include/asm-um/pgtable.h
rename to arch/um/include/asm/pgtable.h
index 02db81b7b86ea48ffc43ed9405bbe1491959036e..58da2480a7f4229fb164ae81947bfc901de8b27d 100644 (file)
@@ -47,6 +47,7 @@ extern unsigned long end_iomem;
 
 #define VMALLOC_OFFSET (__va_space)
 #define VMALLOC_START ((end_iomem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define PKMAP_BASE ((FIXADDR_START - LAST_PKMAP * PAGE_SIZE) & PMD_MASK)
 #ifdef CONFIG_HIGHMEM
 # define VMALLOC_END   (PKMAP_BASE-2*PAGE_SIZE)
 #else
@@ -355,4 +356,11 @@ extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr);
 
 #include <asm-generic/pgtable.h>
 
+/* Clear a kernel PTE and flush it from the TLB */
+#define kpte_clear_flush(ptep, vaddr)          \
+do {                                           \
+       pte_clear(&init_mm, (vaddr), (ptep));   \
+       __flush_tlb_one((vaddr));               \
+} while (0)
+
 #endif
similarity index 97%
rename from include/asm-um/ptrace-generic.h
rename to arch/um/include/asm/ptrace-generic.h
index 315749705ea1b91fccf261ba1161eb785cff9701..6c8899013c92cbf45eaa1039142179374e8136ba 100644 (file)
@@ -8,7 +8,7 @@
 
 #ifndef __ASSEMBLY__
 
-#include "asm/arch/ptrace-abi.h"
+#include <asm/ptrace-abi.h>
 #include <asm/user.h>
 #include "sysdep/ptrace.h"
 
similarity index 79%
rename from include/asm-um/system-generic.h
rename to arch/um/include/asm/system.h
index 5bcfa35e7a22c79eed604df3697ba7c89baeb43d..753346e2cdfd64d5d472f3388014952f5d0ca4ff 100644 (file)
@@ -1,19 +1,7 @@
 #ifndef __UM_SYSTEM_GENERIC_H
 #define __UM_SYSTEM_GENERIC_H
 
-#include "asm/arch/system.h"
-
-#undef switch_to
-#undef local_irq_save
-#undef local_irq_restore
-#undef local_irq_disable
-#undef local_irq_enable
-#undef local_save_flags
-#undef local_irq_restore
-#undef local_irq_enable
-#undef local_irq_disable
-#undef local_irq_save
-#undef irqs_disabled
+#include "sysdep/system.h"
 
 extern void *switch_to(void *prev, void *next, void *last);
 
similarity index 98%
rename from arch/um/include/as-layout.h
rename to arch/um/include/shared/as-layout.h
index 58e852dfb0ce95ff1e6877eaa549c2200b50e620..a92b678503cf78b0d760a436ca9b54440f3aac5c 100644 (file)
@@ -6,7 +6,6 @@
 #ifndef __START_H__
 #define __START_H__
 
-#include "uml-config.h"
 #include "kern_constants.h"
 
 /*
similarity index 80%
rename from arch/um/include/common-offsets.h
rename to arch/um/include/shared/common-offsets.h
index b54bd35585c2d7c306dd6e6def01c2d958dc9d2b..72009c7e3210a036cbbef0b688bd08718eacbb59 100644 (file)
@@ -39,3 +39,16 @@ DEFINE(UM_HZ, HZ);
 DEFINE(UM_USEC_PER_SEC, USEC_PER_SEC);
 DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
 DEFINE(UM_NSEC_PER_USEC, NSEC_PER_USEC);
+
+#ifdef CONFIG_PRINTK
+DEFINE(UML_CONFIG_PRINTK, CONFIG_PRINTK);
+#endif
+#ifdef CONFIG_NO_HZ
+DEFINE(UML_CONFIG_NO_HZ, CONFIG_NO_HZ);
+#endif
+#ifdef CONFIG_UML_X86
+DEFINE(UML_CONFIG_UML_X86, CONFIG_UML_X86);
+#endif
+#ifdef CONFIG_64BIT
+DEFINE(UML_CONFIG_64BIT, CONFIG_64BIT);
+#endif
similarity index 95%
rename from include/asm-um/ldt.h
rename to arch/um/include/shared/ldt.h
index 52af512f5e7dcf272a73de968b709f900218e98d..a7f999a58774d636f5003f08910f10a5f4dcd40f 100644 (file)
@@ -9,7 +9,7 @@
 #define __ASM_LDT_H
 
 #include <linux/mutex.h>
-#include "asm/host_ldt.h"
+#include <sysdep/host_ldt.h>
 
 extern void ldt_host_info(void);
 
similarity index 99%
rename from arch/um/include/os.h
rename to arch/um/include/shared/os.h
index db5be46e3e186677c8f16c93f585e82413d7740f..cd40fddcf99df8fcf4a583d5c8fe05314d27077c 100644 (file)
@@ -11,7 +11,6 @@
 #include "longjmp.h"
 #include "mm_id.h"
 #include "sysdep/tls.h"
-#include "../os/include/file.h"
 
 #define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR))
 
similarity index 91%
rename from arch/um/include/um_mmu.h
rename to arch/um/include/shared/um_mmu.h
index f575ff91f2a01796951c90090542b18344e6998b..b1a7e47d10277689535add4b4027fe092655f2d0 100644 (file)
@@ -6,9 +6,8 @@
 #ifndef __ARCH_UM_MMU_H
 #define __ARCH_UM_MMU_H
 
-#include "uml-config.h"
 #include "mm_id.h"
-#include "asm/ldt.h"
+#include "ldt.h"
 
 typedef struct mm_context {
        struct mm_id id;
similarity index 97%
rename from arch/um/include/user.h
rename to arch/um/include/shared/user.h
index 1723fac6f40d1eb45329133e4d9146666769076a..293f7c794faa46a38c4767125d5d37201c72c675 100644 (file)
@@ -6,7 +6,7 @@
 #ifndef __USER_H__
 #define __USER_H__
 
-#include "uml-config.h"
+#include "kern_constants.h"
 
 /*
  * The usual definition - copied here because the kernel provides its own,
diff --git a/arch/um/include/sigcontext.h b/arch/um/include/sigcontext.h
deleted file mode 100644 (file)
index 59816ca..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/* 
- * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __UML_SIGCONTEXT_H__
-#define __UML_SIGCONTEXT_H__
-
-#include "sysdep/sigcontext.h"
-
-extern int sc_size(void *data);
-extern void sc_to_sc(void *to_ptr, void *from_ptr);
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index 598711c62c82cbb59ce79193eaa67e70d45b48e3..fda30d21fb90628cec430c151f9e3993df74fc5c 100644 (file)
@@ -15,6 +15,7 @@
 #include "mem_user.h"
 #include "skas.h"
 #include "os.h"
+#include "internal.h"
 
 void flush_thread(void)
 {
diff --git a/arch/um/kernel/internal.h b/arch/um/kernel/internal.h
new file mode 100644 (file)
index 0000000..3bda43c
--- /dev/null
@@ -0,0 +1 @@
+extern long um_execve(char *file, char __user *__user *argv, char __user *__user *env);
index b0fce720c4d08378afba4f642ec97b712ca482c3..b5c094c4ade4020f379856fe9117dce8124be57b 100644 (file)
@@ -11,7 +11,7 @@
 #include <asm/unistd.h>
 #include "frame_kern.h"
 #include "kern_util.h"
-#include "sigcontext.h"
+#include <sysdep/sigcontext.h>
 
 EXPORT_SYMBOL(block_signals);
 EXPORT_SYMBOL(unblock_signals);
index 128ee85bc8d96b78522fb7f1043a913ec0e9d269..c4df705b835937f9256cafe43fcd92c9830eba59 100644 (file)
@@ -12,6 +12,7 @@
 #include "asm/mman.h"
 #include "asm/uaccess.h"
 #include "asm/unistd.h"
+#include "internal.h"
 
 long sys_fork(void)
 {
diff --git a/arch/um/os-Linux/include/file.h b/arch/um/os-Linux/include/file.h
deleted file mode 100644 (file)
index fe71be2..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/* 
- * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- * Licensed under the GPL
- */
-
-#ifndef __OS_FILE_H__
-#define __OS_FILE_H__
-
-#define DEV_NULL "/dev/null"
-
-#endif
index 484e68f9f7ae7362a0e36b87505ed9048f7302f2..d261f170d120862010cbea1facfe6d4bcc8ab69d 100644 (file)
@@ -20,7 +20,6 @@
 #include "user.h"
 #include "sysdep/ptrace.h"
 #include "sysdep/stub.h"
-#include "uml-config.h"
 
 extern unsigned long batch_syscall_stub, __syscall_stub_start;
 
similarity index 77%
rename from include/asm-um/archparam-i386.h
rename to arch/um/sys-i386/asm/archparam.h
index 49e89b8d7e588354d47a896a824f4e25c3970e7c..93fd723344e54fef2cc64c12b10023cc3538d61f 100644 (file)
@@ -6,11 +6,11 @@
 #ifndef __UM_ARCHPARAM_I386_H
 #define __UM_ARCHPARAM_I386_H
 
-/********* Nothing for asm-um/hardirq.h **********/
-
-/********* Nothing for asm-um/hw_irq.h **********/
-
-/********* Nothing for asm-um/string.h **********/
+#ifdef CONFIG_X86_PAE
+#define LAST_PKMAP 512
+#else
+#define LAST_PKMAP 1024
+#endif
 
 #endif
 
similarity index 97%
rename from include/asm-um/processor-i386.h
rename to arch/um/sys-i386/asm/processor.h
index a2b7fe13fe1e48179b1fd5f0eeff8315dcb15b0d..82a9061ab5be641fb72763e89efe96c1f346f08e 100644 (file)
@@ -7,7 +7,7 @@
 #define __UM_PROCESSOR_I386_H
 
 #include "linux/string.h"
-#include "asm/host_ldt.h"
+#include <sysdep/host_ldt.h>
 #include "asm/segment.h"
 
 extern int host_has_cmov;
@@ -48,7 +48,7 @@ static inline void arch_copy_thread(struct arch_thread *from,
         memcpy(&to->tls_array, &from->tls_array, sizeof(from->tls_array));
 }
 
-#include "asm/arch/user.h"
+#include <asm/user.h>
 
 /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
 static inline void rep_nop(void)
similarity index 93%
rename from include/asm-um/ptrace-i386.h
rename to arch/um/sys-i386/asm/ptrace.h
index b2d24c5ea2c3237ed1a573666ced4f7205004d0d..0273e4d09af7b65e47c5dab30936f5d1acd69643 100644 (file)
@@ -10,8 +10,6 @@
 
 #include "linux/compiler.h"
 #include "asm/ptrace-generic.h"
-#include <asm/user.h>
-#include "sysdep/ptrace.h"
 
 #define PT_REGS_EAX(r) UPT_EAX(&(r)->regs)
 #define PT_REGS_EBX(r) UPT_EBX(&(r)->regs)
@@ -34,8 +32,6 @@
 #define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r)
 #define PT_FIX_EXEC_STACK(sp) do ; while(0)
 
-/* Cope with a conditional i386 definition. */
-#undef profile_pc
 #define profile_pc(regs) PT_REGS_IP(regs)
 
 #define user_mode(r) UPT_IS_USER(&(r)->regs)
similarity index 97%
rename from include/asm-um/host_ldt-i386.h
rename to arch/um/sys-i386/shared/sysdep/host_ldt.h
index b27cb0a9dd30a016f2f3dee36111454530262991..0953cc4df65284bc61745abb2fdb487935aef03b 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __ASM_HOST_LDT_I386_H
 #define __ASM_HOST_LDT_I386_H
 
-#include "asm/arch/ldt.h"
+#include <asm/ldt.h>
 
 /*
  * macros stolen from include/asm-i386/desc.h
similarity index 99%
rename from arch/um/include/sysdep-i386/ptrace.h
rename to arch/um/sys-i386/shared/sysdep/ptrace.h
index 11c08969d1342b8fce90a27233b87b979f57218a..d50e62e070707ce6ca88b9e8f450ac5eec61d98e 100644 (file)
@@ -6,7 +6,6 @@
 #ifndef __SYSDEP_I386_PTRACE_H
 #define __SYSDEP_I386_PTRACE_H
 
-#include "uml-config.h"
 #include "user_constants.h"
 #include "sysdep/faultinfo.h"
 
similarity index 98%
rename from arch/um/include/sysdep-i386/stub.h
rename to arch/um/sys-i386/shared/sysdep/stub.h
index 8c097b87fca7be4b3ea209feff41aa4fa2adc3d6..977dedd9221bf44cd97a0611febb727486f823a3 100644 (file)
@@ -12,7 +12,6 @@
 #include "as-layout.h"
 #include "stub-data.h"
 #include "kern_constants.h"
-#include "uml-config.h"
 
 extern void stub_segv_handler(int sig);
 extern void stub_clone_handler(void);
diff --git a/arch/um/sys-i386/shared/sysdep/system.h b/arch/um/sys-i386/shared/sysdep/system.h
new file mode 100644 (file)
index 0000000..d1b93c4
--- /dev/null
@@ -0,0 +1,132 @@
+#ifndef _ASM_X86_SYSTEM_H_
+#define _ASM_X86_SYSTEM_H_
+
+#include <asm/asm.h>
+#include <asm/segment.h>
+#include <asm/cpufeature.h>
+#include <asm/cmpxchg.h>
+#include <asm/nops.h>
+
+#include <linux/kernel.h>
+#include <linux/irqflags.h>
+
+/* entries in ARCH_DLINFO: */
+#ifdef CONFIG_IA32_EMULATION
+# define AT_VECTOR_SIZE_ARCH 2
+#else
+# define AT_VECTOR_SIZE_ARCH 1
+#endif
+
+extern unsigned long arch_align_stack(unsigned long sp);
+
+void default_idle(void);
+
+/*
+ * Force strict CPU ordering.
+ * And yes, this is required on UP too when we're talking
+ * to devices.
+ */
+#ifdef CONFIG_X86_32
+/*
+ * Some non-Intel clones support out of order store. wmb() ceases to be a
+ * nop for these.
+ */
+#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
+#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)
+#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)
+#else
+#define mb()   asm volatile("mfence":::"memory")
+#define rmb()  asm volatile("lfence":::"memory")
+#define wmb()  asm volatile("sfence" ::: "memory")
+#endif
+
+/**
+ * read_barrier_depends - Flush all pending reads that subsequents reads
+ * depend on.
+ *
+ * No data-dependent reads from memory-like regions are ever reordered
+ * over this barrier.  All reads preceding this primitive are guaranteed
+ * to access memory (but not necessarily other CPUs' caches) before any
+ * reads following this primitive that depend on the data return by
+ * any of the preceding reads.  This primitive is much lighter weight than
+ * rmb() on most CPUs, and is never heavier weight than is
+ * rmb().
+ *
+ * These ordering constraints are respected by both the local CPU
+ * and the compiler.
+ *
+ * Ordering is not guaranteed by anything other than these primitives,
+ * not even by data dependencies.  See the documentation for
+ * memory_barrier() for examples and URLs to more information.
+ *
+ * For example, the following code would force ordering (the initial
+ * value of "a" is zero, "b" is one, and "p" is "&a"):
+ *
+ * <programlisting>
+ *     CPU 0                           CPU 1
+ *
+ *     b = 2;
+ *     memory_barrier();
+ *     p = &b;                         q = p;
+ *                                     read_barrier_depends();
+ *                                     d = *q;
+ * </programlisting>
+ *
+ * because the read of "*q" depends on the read of "p" and these
+ * two reads are separated by a read_barrier_depends().  However,
+ * the following code, with the same initial values for "a" and "b":
+ *
+ * <programlisting>
+ *     CPU 0                           CPU 1
+ *
+ *     a = 2;
+ *     memory_barrier();
+ *     b = 3;                          y = b;
+ *                                     read_barrier_depends();
+ *                                     x = a;
+ * </programlisting>
+ *
+ * does not enforce ordering, since there is no data dependency between
+ * the read of "a" and the read of "b".  Therefore, on some CPUs, such
+ * as Alpha, "y" could be set to 3 and "x" to 0.  Use rmb()
+ * in cases like this where there are no data dependencies.
+ **/
+
+#define read_barrier_depends() do { } while (0)
+
+#ifdef CONFIG_SMP
+#define smp_mb()       mb()
+#ifdef CONFIG_X86_PPRO_FENCE
+# define smp_rmb()     rmb()
+#else
+# define smp_rmb()     barrier()
+#endif
+#ifdef CONFIG_X86_OOSTORE
+# define smp_wmb()     wmb()
+#else
+# define smp_wmb()     barrier()
+#endif
+#define smp_read_barrier_depends()     read_barrier_depends()
+#define set_mb(var, value) do { (void)xchg(&var, value); } while (0)
+#else
+#define smp_mb()       barrier()
+#define smp_rmb()      barrier()
+#define smp_wmb()      barrier()
+#define smp_read_barrier_depends()     do { } while (0)
+#define set_mb(var, value) do { var = value; barrier(); } while (0)
+#endif
+
+/*
+ * Stop RDTSC speculation. This is needed when you need to use RDTSC
+ * (or get_cycles or vread that possibly accesses the TSC) in a defined
+ * code region.
+ *
+ * (Could use an alternative three way for this if there was one.)
+ */
+static inline void rdtsc_barrier(void)
+{
+       alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC);
+       alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC);
+}
+
+#endif
similarity index 97%
rename from arch/um/include/sysdep-i386/tls.h
rename to arch/um/sys-i386/shared/sysdep/tls.h
index 918fd3c5ff9cad3ff4854fb47010386bf20f3bc3..34550755b2a1621939f597f2b86c4bfa77de0551 100644 (file)
@@ -21,7 +21,7 @@ typedef struct um_dup_user_desc {
 
 # else /* __KERNEL__ */
 
-#  include <asm/ldt.h>
+#  include <ldt.h>
 typedef struct user_desc user_desc_t;
 
 # endif /* __KERNEL__ */
index 7699e89f660fd42701736ce1bfe79e4d6b2d0ddc..c41b04bf5fa005399183176935a683dbfe92d3ce 100644 (file)
@@ -1,4 +1,3 @@
-#include "uml-config.h"
 #include "as-layout.h"
 
        .globl syscall_stub
index e2d14268441201d87f09c1adfb27f9a14233f24e..857ca0b3bdef136a78b7eb59a00b2de4a14b6aed 100644 (file)
@@ -6,6 +6,7 @@
 #include "linux/sched.h"
 #include "linux/shm.h"
 #include "linux/ipc.h"
+#include "linux/syscalls.h"
 #include "asm/mman.h"
 #include "asm/uaccess.h"
 #include "asm/unistd.h"
similarity index 97%
rename from include/asm-um/processor-x86_64.h
rename to arch/um/sys-x86_64/asm/processor.h
index e50933175e9105206e207afcdc61ec46d0d49463..875a26a62614a9ae7f1788cc6549ebafc99aca07 100644 (file)
@@ -40,7 +40,7 @@ static inline void arch_copy_thread(struct arch_thread *from,
        to->fs = from->fs;
 }
 
-#include "asm/arch/user.h"
+#include <asm/user.h>
 
 #define current_text_addr() \
        ({ void *pc; __asm__("movq $1f,%0\n1:":"=g" (pc)); pc; })
similarity index 85%
rename from include/asm-um/ptrace-x86_64.h
rename to arch/um/sys-x86_64/asm/ptrace.h
index 4c475350dcf02a545102042493508d9aa70686ba..83d8c473b905886b62585cf43839473a12fb791f 100644 (file)
@@ -9,23 +9,12 @@
 
 #include "linux/compiler.h"
 #include "asm/errno.h"
-#include "asm/host_ldt.h"
 
 #define __FRAME_OFFSETS /* Needed to get the R* macros */
 #include "asm/ptrace-generic.h"
 
 #define HOST_AUDIT_ARCH AUDIT_ARCH_X86_64
 
-/* Also defined in sysdep/ptrace.h, so may already be defined. */
-#ifndef FS_BASE
-#define FS_BASE (21 * sizeof(unsigned long))
-#define GS_BASE (22 * sizeof(unsigned long))
-#define DS (23 * sizeof(unsigned long))
-#define ES (24 * sizeof(unsigned long))
-#define FS (25 * sizeof(unsigned long))
-#define GS (26 * sizeof(unsigned long))
-#endif
-
 #define PT_REGS_RBX(r) UPT_RBX(&(r)->regs)
 #define PT_REGS_RCX(r) UPT_RCX(&(r)->regs)
 #define PT_REGS_RDX(r) UPT_RDX(&(r)->regs)
@@ -64,6 +53,8 @@
 
 #define profile_pc(regs) PT_REGS_IP(regs)
 
+struct user_desc;
+
 static inline int ptrace_get_thread_area(struct task_struct *child, int idx,
                                          struct user_desc __user *user_desc)
 {
similarity index 97%
rename from include/asm-um/host_ldt-x86_64.h
rename to arch/um/sys-x86_64/shared/sysdep/host_ldt.h
index 74a63f7d9a90b10a8c0571ac8c18abff717e4337..e8b1be1e154f44a6437b5b78d1c7fe120784e7e2 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __ASM_HOST_LDT_X86_64_H
 #define __ASM_HOST_LDT_X86_64_H
 
-#include "asm/arch/ldt.h"
+#include <asm/ldt.h>
 
 /*
  * macros stolen from include/asm-x86_64/desc.h
similarity index 99%
rename from arch/um/include/sysdep-x86_64/ptrace.h
rename to arch/um/sys-x86_64/shared/sysdep/ptrace.h
index 9ea44d111f335c5184fdd8924cd72a5fc0b52ac2..fdba5457947a0cc7f16cfd34d30a63bb05120e0d 100644 (file)
@@ -8,7 +8,6 @@
 #ifndef __SYSDEP_X86_64_PTRACE_H
 #define __SYSDEP_X86_64_PTRACE_H
 
-#include "uml-config.h"
 #include "user_constants.h"
 #include "sysdep/faultinfo.h"
 
similarity index 98%
rename from arch/um/include/sysdep-x86_64/stub.h
rename to arch/um/sys-x86_64/shared/sysdep/stub.h
index 655f9c2de3ac0b127a6e57729b5d5ab3de7b9540..3432aa249970c54880fbae342d5c9b1c28cc619e 100644 (file)
@@ -12,7 +12,6 @@
 #include "as-layout.h"
 #include "stub-data.h"
 #include "kern_constants.h"
-#include "uml-config.h"
 
 extern void stub_segv_handler(int sig);
 extern void stub_clone_handler(void);
diff --git a/arch/um/sys-x86_64/shared/sysdep/system.h b/arch/um/sys-x86_64/shared/sysdep/system.h
new file mode 100644 (file)
index 0000000..d1b93c4
--- /dev/null
@@ -0,0 +1,132 @@
+#ifndef _ASM_X86_SYSTEM_H_
+#define _ASM_X86_SYSTEM_H_
+
+#include <asm/asm.h>
+#include <asm/segment.h>
+#include <asm/cpufeature.h>
+#include <asm/cmpxchg.h>
+#include <asm/nops.h>
+
+#include <linux/kernel.h>
+#include <linux/irqflags.h>
+
+/* entries in ARCH_DLINFO: */
+#ifdef CONFIG_IA32_EMULATION
+# define AT_VECTOR_SIZE_ARCH 2
+#else
+# define AT_VECTOR_SIZE_ARCH 1
+#endif
+
+extern unsigned long arch_align_stack(unsigned long sp);
+
+void default_idle(void);
+
+/*
+ * Force strict CPU ordering.
+ * And yes, this is required on UP too when we're talking
+ * to devices.
+ */
+#ifdef CONFIG_X86_32
+/*
+ * Some non-Intel clones support out of order store. wmb() ceases to be a
+ * nop for these.
+ */
+#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
+#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)
+#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)
+#else
+#define mb()   asm volatile("mfence":::"memory")
+#define rmb()  asm volatile("lfence":::"memory")
+#define wmb()  asm volatile("sfence" ::: "memory")
+#endif
+
+/**
+ * read_barrier_depends - Flush all pending reads that subsequents reads
+ * depend on.
+ *
+ * No data-dependent reads from memory-like regions are ever reordered
+ * over this barrier.  All reads preceding this primitive are guaranteed
+ * to access memory (but not necessarily other CPUs' caches) before any
+ * reads following this primitive that depend on the data return by
+ * any of the preceding reads.  This primitive is much lighter weight than
+ * rmb() on most CPUs, and is never heavier weight than is
+ * rmb().
+ *
+ * These ordering constraints are respected by both the local CPU
+ * and the compiler.
+ *
+ * Ordering is not guaranteed by anything other than these primitives,
+ * not even by data dependencies.  See the documentation for
+ * memory_barrier() for examples and URLs to more information.
+ *
+ * For example, the following code would force ordering (the initial
+ * value of "a" is zero, "b" is one, and "p" is "&a"):
+ *
+ * <programlisting>
+ *     CPU 0                           CPU 1
+ *
+ *     b = 2;
+ *     memory_barrier();
+ *     p = &b;                         q = p;
+ *                                     read_barrier_depends();
+ *                                     d = *q;
+ * </programlisting>
+ *
+ * because the read of "*q" depends on the read of "p" and these
+ * two reads are separated by a read_barrier_depends().  However,
+ * the following code, with the same initial values for "a" and "b":
+ *
+ * <programlisting>
+ *     CPU 0                           CPU 1
+ *
+ *     a = 2;
+ *     memory_barrier();
+ *     b = 3;                          y = b;
+ *                                     read_barrier_depends();
+ *                                     x = a;
+ * </programlisting>
+ *
+ * does not enforce ordering, since there is no data dependency between
+ * the read of "a" and the read of "b".  Therefore, on some CPUs, such
+ * as Alpha, "y" could be set to 3 and "x" to 0.  Use rmb()
+ * in cases like this where there are no data dependencies.
+ **/
+
+#define read_barrier_depends() do { } while (0)
+
+#ifdef CONFIG_SMP
+#define smp_mb()       mb()
+#ifdef CONFIG_X86_PPRO_FENCE
+# define smp_rmb()     rmb()
+#else
+# define smp_rmb()     barrier()
+#endif
+#ifdef CONFIG_X86_OOSTORE
+# define smp_wmb()     wmb()
+#else
+# define smp_wmb()     barrier()
+#endif
+#define smp_read_barrier_depends()     read_barrier_depends()
+#define set_mb(var, value) do { (void)xchg(&var, value); } while (0)
+#else
+#define smp_mb()       barrier()
+#define smp_rmb()      barrier()
+#define smp_wmb()      barrier()
+#define smp_read_barrier_depends()     do { } while (0)
+#define set_mb(var, value) do { var = value; barrier(); } while (0)
+#endif
+
+/*
+ * Stop RDTSC speculation. This is needed when you need to use RDTSC
+ * (or get_cycles or vread that possibly accesses the TSC) in a defined
+ * code region.
+ *
+ * (Could use an alternative three way for this if there was one.)
+ */
+static inline void rdtsc_barrier(void)
+{
+       alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC);
+       alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC);
+}
+
+#endif
similarity index 96%
rename from arch/um/include/sysdep-x86_64/tls.h
rename to arch/um/sys-x86_64/shared/sysdep/tls.h
index 35f19f25bd3b749240ba5a7591fb55023cc666a1..18c000d0357a3fb465605cdd881988fff9d28c74 100644 (file)
@@ -22,7 +22,7 @@ typedef struct um_dup_user_desc {
 
 # else /* __KERNEL__ */
 
-#  include <asm/ldt.h>
+#  include <ldt.h>
 typedef struct user_desc user_desc_t;
 
 # endif /* __KERNEL__ */
index 5687687631554dabc7e61719a4a900d8d5f691c1..6d9edf9fabce15d4dac536ae8ce18e70b301822e 100644 (file)
@@ -1,4 +1,3 @@
-#include "uml-config.h"
 #include "as-layout.h"
 
        .globl syscall_stub
index 32f5fbe2d0d2fe2aca4a7f3b5eeec80b3eb6d87d..dd21d69715e62abc7bacc3fde820466f9320cf44 100644 (file)
 #define stub_rt_sigreturn sys_rt_sigreturn
 
 #define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ;
-#undef ASM_X86__UNISTD_64_H
-#include <asm-x86/unistd_64.h>
+#undef _ASM_X86_UNISTD_64_H
+#include "../../x86/include/asm/unistd_64.h"
 
 #undef __SYSCALL
 #define __SYSCALL(nr, sym) [ nr ] = sym,
-#undef ASM_X86__UNISTD_64_H
+#undef _ASM_X86_UNISTD_64_H
 
 typedef void (*sys_call_ptr_t)(void);
 
@@ -64,7 +64,7 @@ extern void sys_ni_syscall(void);
  */
 
 sys_call_ptr_t sys_call_table[] __cacheline_aligned = {
-#include <asm-x86/unistd_64.h>
+#include "../../x86/include/asm/unistd_64.h"
 };
 
 int syscall_table_size = sizeof(sys_call_table);
index 49349ba77d80b81141deb6065510e54fc74eb077..350bee1d54dc2ae41851f503d9ef7705a0e93e31 100644 (file)
@@ -26,6 +26,7 @@ config X86
        select HAVE_KPROBES
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select HAVE_KRETPROBES
+       select HAVE_FTRACE_MCOUNT_RECORD
        select HAVE_DYNAMIC_FTRACE
        select HAVE_FTRACE
        select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64)
@@ -115,6 +116,9 @@ config GENERIC_TIME_VSYSCALL
 config ARCH_HAS_CPU_RELAX
        def_bool y
 
+config ARCH_HAS_DEFAULT_IDLE
+       def_bool y
+
 config ARCH_HAS_CACHE_LINE_SIZE
        def_bool y
 
@@ -1242,14 +1246,6 @@ config EFI
        resultant kernel should continue to boot on existing non-EFI
        platforms.
 
-config IRQBALANCE
-       def_bool y
-       prompt "Enable kernel irq balancing"
-       depends on X86_32 && SMP && X86_IO_APIC
-       help
-         The default yes will allow the kernel to do irq load balancing.
-         Saying no will keep the kernel from doing irq load balancing.
-
 config SECCOMP
        def_bool y
        prompt "Enable seccomp to safely compute untrusted bytecode"
@@ -1642,6 +1638,8 @@ source "arch/x86/kernel/cpu/cpufreq/Kconfig"
 
 source "drivers/cpuidle/Kconfig"
 
+source "drivers/idle/Kconfig"
+
 endmenu
 
 
index f5631da585b69ac1722891bc0bee1e63a1ec652c..d1a47adb5aec0b14cfd6b52297be80f87fbf0682 100644 (file)
@@ -110,16 +110,16 @@ KBUILD_CFLAGS += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
 mcore-y  := arch/x86/mach-default/
 
 # Voyager subarch support
-mflags-$(CONFIG_X86_VOYAGER)   := -Iinclude/asm-x86/mach-voyager
+mflags-$(CONFIG_X86_VOYAGER)   := -Iarch/x86/include/asm/mach-voyager
 mcore-$(CONFIG_X86_VOYAGER)    := arch/x86/mach-voyager/
 
 # generic subarchitecture
-mflags-$(CONFIG_X86_GENERICARCH):= -Iinclude/asm-x86/mach-generic
+mflags-$(CONFIG_X86_GENERICARCH):= -Iarch/x86/include/asm/mach-generic
 fcore-$(CONFIG_X86_GENERICARCH)        += arch/x86/mach-generic/
 mcore-$(CONFIG_X86_GENERICARCH)        := arch/x86/mach-default/
 
 # default subarch .h files
-mflags-y += -Iinclude/asm-x86/mach-default
+mflags-y += -Iarch/x86/include/asm/mach-default
 
 # 64 bit does not support subarch support - clear sub arch variables
 fcore-$(CONFIG_X86_64)  :=
index 5780d361105bf4863328243386ed69ecdbc89889..da062216948a6951990f354fa11ee9125b865fe7 100644 (file)
@@ -16,7 +16,7 @@
  */
 #undef CONFIG_PARAVIRT
 #ifdef CONFIG_X86_32
-#define ASM_X86__DESC_H 1
+#define _ASM_X86_DESC_H 1
 #endif
 
 #ifdef CONFIG_X86_64
index 49f26aaaebc8f2d58064cc1be981103742ab8524..3fa979c9c363a5dbe6f9ce6d754636ed301d01b1 100644 (file)
@@ -17,7 +17,7 @@
 #include "boot.h"
 #include "video.h"
 
-__videocard video_bios;
+static __videocard video_bios;
 
 /* Set a conventional BIOS mode */
 static int set_bios_mode(u8 mode);
@@ -119,7 +119,7 @@ static int bios_probe(void)
        return nmodes;
 }
 
-__videocard video_bios =
+static __videocard video_bios =
 {
        .card_name      = "BIOS",
        .probe          = bios_probe,
index 99b3079dc6ab1fb25c4f083639b13547fa663354..75115849af330e057c71eecd845e4b799107a077 100644 (file)
@@ -20,7 +20,7 @@
 static struct vesa_general_info vginfo;
 static struct vesa_mode_info vminfo;
 
-__videocard video_vesa;
+static __videocard video_vesa;
 
 #ifndef _WAKEUP
 static void vesa_store_mode_params_graphics(void);
@@ -293,7 +293,7 @@ void vesa_store_edid(void)
 
 #endif /* not _WAKEUP */
 
-__videocard video_vesa =
+static __videocard video_vesa =
 {
        .card_name      = "VESA",
        .probe          = vesa_probe,
index 52d0359719d7dda3c15ec870be577e653d829896..13b8c86ae98570f67375b505e9d106374e24b574 100644 (file)
@@ -287,7 +287,6 @@ CONFIG_MTRR=y
 # CONFIG_MTRR_SANITIZER is not set
 CONFIG_X86_PAT=y
 CONFIG_EFI=y
-# CONFIG_IRQBALANCE is not set
 CONFIG_SECCOMP=y
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_250 is not set
similarity index 95%
rename from include/asm-x86/a.out-core.h
rename to arch/x86/include/asm/a.out-core.h
index f5705761a37b14509c5603e79c69292fdb4adb66..37822206083e2684026984d69ee8732a9b74118a 100644 (file)
@@ -9,8 +9,8 @@
  * 2 of the Licence, or (at your option) any later version.
  */
 
-#ifndef ASM_X86__A_OUT_CORE_H
-#define ASM_X86__A_OUT_CORE_H
+#ifndef _ASM_X86_A_OUT_CORE_H
+#define _ASM_X86_A_OUT_CORE_H
 
 #ifdef __KERNEL__
 #ifdef CONFIG_X86_32
@@ -70,4 +70,4 @@ static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump)
 
 #endif /* CONFIG_X86_32 */
 #endif /* __KERNEL__ */
-#endif /* ASM_X86__A_OUT_CORE_H */
+#endif /* _ASM_X86_A_OUT_CORE_H */
similarity index 88%
rename from include/asm-x86/a.out.h
rename to arch/x86/include/asm/a.out.h
index 0948748bc69c1dd8f694c34878551868e01a3da7..4684f97a5bbd1b1edce881a88e75393b580a2cd1 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__A_OUT_H
-#define ASM_X86__A_OUT_H
+#ifndef _ASM_X86_A_OUT_H
+#define _ASM_X86_A_OUT_H
 
 struct exec
 {
@@ -17,4 +17,4 @@ struct exec
 #define N_DRSIZE(a)    ((a).a_drsize)
 #define N_SYMSIZE(a)   ((a).a_syms)
 
-#endif /* ASM_X86__A_OUT_H */
+#endif /* _ASM_X86_A_OUT_H */
similarity index 98%
rename from include/asm-x86/acpi.h
rename to arch/x86/include/asm/acpi.h
index 392e17336be1dede3964b6e61ca4cdf568b258fd..8d676d8ecde93d2bd0f76f5891ea5982970aae8a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__ACPI_H
-#define ASM_X86__ACPI_H
+#ifndef _ASM_X86_ACPI_H
+#define _ASM_X86_ACPI_H
 
 /*
  *  Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
@@ -175,4 +175,4 @@ static inline void acpi_fake_nodes(const struct bootnode *fake_nodes,
 
 #define acpi_unlazy_tlb(x)     leave_mm(x)
 
-#endif /* ASM_X86__ACPI_H */
+#endif /* _ASM_X86_ACPI_H */
similarity index 93%
rename from include/asm-x86/agp.h
rename to arch/x86/include/asm/agp.h
index 3617fd4fcdf9faa1f110055cd33f607e98662c76..9825cd64c9b6e7126432e14c0ee6aebd804a799c 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__AGP_H
-#define ASM_X86__AGP_H
+#ifndef _ASM_X86_AGP_H
+#define _ASM_X86_AGP_H
 
 #include <asm/pgtable.h>
 #include <asm/cacheflush.h>
@@ -32,4 +32,4 @@
 #define free_gatt_pages(table, order)  \
        free_pages((unsigned long)(table), (order))
 
-#endif /* ASM_X86__AGP_H */
+#endif /* _ASM_X86_AGP_H */
similarity index 98%
rename from include/asm-x86/alternative.h
rename to arch/x86/include/asm/alternative.h
index 22d3c9862bf3b3a0967df0c9c2f2b7038d6e1ba3..f6aa18eadf71717d9e86c53ac3719776fa035969 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__ALTERNATIVE_H
-#define ASM_X86__ALTERNATIVE_H
+#ifndef _ASM_X86_ALTERNATIVE_H
+#define _ASM_X86_ALTERNATIVE_H
 
 #include <linux/types.h>
 #include <linux/stddef.h>
@@ -180,4 +180,4 @@ extern void add_nops(void *insns, unsigned int len);
 extern void *text_poke(void *addr, const void *opcode, size_t len);
 extern void *text_poke_early(void *addr, const void *opcode, size_t len);
 
-#endif /* ASM_X86__ALTERNATIVE_H */
+#endif /* _ASM_X86_ALTERNATIVE_H */
similarity index 92%
rename from include/asm-x86/amd_iommu.h
rename to arch/x86/include/asm/amd_iommu.h
index 041d0db7da272d42abe5d5659f38da6fe2b0e590..f712344329bc7a6929a38f8e0e968bd1166e4c9e 100644 (file)
@@ -17,8 +17,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-#ifndef ASM_X86__AMD_IOMMU_H
-#define ASM_X86__AMD_IOMMU_H
+#ifndef _ASM_X86_AMD_IOMMU_H
+#define _ASM_X86_AMD_IOMMU_H
 
 #include <linux/irqreturn.h>
 
@@ -32,4 +32,4 @@ static inline int amd_iommu_init(void) { return -ENODEV; }
 static inline void amd_iommu_detect(void) { }
 #endif
 
-#endif /* ASM_X86__AMD_IOMMU_H */
+#endif /* _ASM_X86_AMD_IOMMU_H */
similarity index 99%
rename from include/asm-x86/amd_iommu_types.h
rename to arch/x86/include/asm/amd_iommu_types.h
index b3085869a17b04aaa686e7360c2c424d0d875969..1a30c0440c6bb4c907b400313c7bbd1865bb9298 100644 (file)
@@ -17,8 +17,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-#ifndef ASM_X86__AMD_IOMMU_TYPES_H
-#define ASM_X86__AMD_IOMMU_TYPES_H
+#ifndef _ASM_X86_AMD_IOMMU_TYPES_H
+#define _ASM_X86_AMD_IOMMU_TYPES_H
 
 #include <linux/types.h>
 #include <linux/list.h>
@@ -401,4 +401,4 @@ static inline u16 calc_devid(u8 bus, u8 devfn)
        return (((u16)bus) << 8) | devfn;
 }
 
-#endif /* ASM_X86__AMD_IOMMU_TYPES_H */
+#endif /* _ASM_X86_AMD_IOMMU_TYPES_H */
similarity index 93%
rename from include/asm-x86/apic.h
rename to arch/x86/include/asm/apic.h
index d76a0839abe932c789738f0b0ec5b81c79f96b6c..3b1510b4fc5741290d5660bb4c30f34bc70f6371 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__APIC_H
-#define ASM_X86__APIC_H
+#ifndef _ASM_X86_APIC_H
+#define _ASM_X86_APIC_H
 
 #include <linux/pm.h>
 #include <linux/delay.h>
@@ -40,8 +40,6 @@ extern void generic_apic_probe(void);
 extern unsigned int apic_verbosity;
 extern int local_apic_timer_c2_ok;
 
-extern int ioapic_force;
-
 extern int disable_apic;
 /*
  * Basic functions accessing APICs.
@@ -100,6 +98,20 @@ extern void check_x2apic(void);
 extern void enable_x2apic(void);
 extern void enable_IR_x2apic(void);
 extern void x2apic_icr_write(u32 low, u32 id);
+static inline int x2apic_enabled(void)
+{
+       int msr, msr2;
+
+       if (!cpu_has_x2apic)
+               return 0;
+
+       rdmsr(MSR_IA32_APICBASE, msr, msr2);
+       if (msr & X2APIC_ENABLE)
+               return 1;
+       return 0;
+}
+#else
+#define x2apic_enabled()       0
 #endif
 
 struct apic_ops {
@@ -184,4 +196,4 @@ static inline void init_apic_mappings(void) { }
 
 #endif /* !CONFIG_X86_LOCAL_APIC */
 
-#endif /* ASM_X86__APIC_H */
+#endif /* _ASM_X86_APIC_H */
similarity index 99%
rename from include/asm-x86/apicdef.h
rename to arch/x86/include/asm/apicdef.h
index b922c85ac91d8ab0e3f8fbd6c993f22ffe047879..63134e31e8b933acb973ee2e66f62a2f815bb326 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__APICDEF_H
-#define ASM_X86__APICDEF_H
+#ifndef _ASM_X86_APICDEF_H
+#define _ASM_X86_APICDEF_H
 
 /*
  * Constants for various Intel APICs. (local APIC, IOAPIC, etc.)
@@ -414,4 +414,4 @@ struct local_apic {
 #else
  #define BAD_APICID 0xFFFFu
 #endif
-#endif /* ASM_X86__APICDEF_H */
+#endif /* _ASM_X86_APICDEF_H */
similarity index 86%
rename from include/asm-x86/arch_hooks.h
rename to arch/x86/include/asm/arch_hooks.h
index de4596b24c23a8e4a0e14135125d051f25a3fcdf..cbd4957838a60d83ad767e5b8a1935aa44d30f5a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__ARCH_HOOKS_H
-#define ASM_X86__ARCH_HOOKS_H
+#ifndef _ASM_X86_ARCH_HOOKS_H
+#define _ASM_X86_ARCH_HOOKS_H
 
 #include <linux/interrupt.h>
 
@@ -23,4 +23,4 @@ extern void pre_time_init_hook(void);
 extern void time_init_hook(void);
 extern void mca_nmi_hook(void);
 
-#endif /* ASM_X86__ARCH_HOOKS_H */
+#endif /* _ASM_X86_ARCH_HOOKS_H */
similarity index 93%
rename from include/asm-x86/asm.h
rename to arch/x86/include/asm/asm.h
index e1355f44d7c3395753317faaf2b2fb61f100bfea..56be78f582f0eabff9f9a64545a15bc28b518710 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__ASM_H
-#define ASM_X86__ASM_H
+#ifndef _ASM_X86_ASM_H
+#define _ASM_X86_ASM_H
 
 #ifdef __ASSEMBLY__
 # define __ASM_FORM(x) x
@@ -44,4 +44,4 @@
        _ASM_PTR #from "," #to "\n" \
        " .previous\n"
 
-#endif /* ASM_X86__ASM_H */
+#endif /* _ASM_X86_ASM_H */
similarity index 98%
rename from include/asm-x86/atomic_32.h
rename to arch/x86/include/asm/atomic_32.h
index 14d3f0beb889917c3d6af356bdd84d114a7cae06..ad5b9f6ecddf317e32f1abad071246b61471999a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__ATOMIC_32_H
-#define ASM_X86__ATOMIC_32_H
+#ifndef _ASM_X86_ATOMIC_32_H
+#define _ASM_X86_ATOMIC_32_H
 
 #include <linux/compiler.h>
 #include <asm/processor.h>
@@ -256,4 +256,4 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
 #define smp_mb__after_atomic_inc()     barrier()
 
 #include <asm-generic/atomic.h>
-#endif /* ASM_X86__ATOMIC_32_H */
+#endif /* _ASM_X86_ATOMIC_32_H */
similarity index 99%
rename from include/asm-x86/atomic_64.h
rename to arch/x86/include/asm/atomic_64.h
index 2cb218c4a356ce332b2e887b88e8d146e602fe84..279d2a731f3fb57e9cdb061d1917df4ed7bb053e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__ATOMIC_64_H
-#define ASM_X86__ATOMIC_64_H
+#ifndef _ASM_X86_ATOMIC_64_H
+#define _ASM_X86_ATOMIC_64_H
 
 #include <asm/alternative.h>
 #include <asm/cmpxchg.h>
@@ -470,4 +470,4 @@ static inline void atomic_or_long(unsigned long *v1, unsigned long v2)
 #define smp_mb__after_atomic_inc()     barrier()
 
 #include <asm-generic/atomic.h>
-#endif /* ASM_X86__ATOMIC_64_H */
+#endif /* _ASM_X86_ATOMIC_64_H */
similarity index 70%
rename from include/asm-x86/auxvec.h
rename to arch/x86/include/asm/auxvec.h
index 12c7cac7420202c7a4a11997187b966bc4d392c4..1316b4c3542594cf42024fa98b7cee52afb8b882 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__AUXVEC_H
-#define ASM_X86__AUXVEC_H
+#ifndef _ASM_X86_AUXVEC_H
+#define _ASM_X86_AUXVEC_H
 /*
  * Architecture-neutral AT_ values in 0-17, leave some room
  * for more of them, start the x86-specific ones at 32.
@@ -9,4 +9,4 @@
 #endif
 #define AT_SYSINFO_EHDR                33
 
-#endif /* ASM_X86__AUXVEC_H */
+#endif /* _ASM_X86_AUXVEC_H */
similarity index 90%
rename from include/asm-x86/bigsmp/apic.h
rename to arch/x86/include/asm/bigsmp/apic.h
index 0a9cd7c5ca0c8813ddb6899f1ad2a776cb9a85e1..1d9543b9d35824c259a1110005866be3d1f54a4e 100644 (file)
@@ -9,22 +9,17 @@ static inline int apic_id_registered(void)
        return (1);
 }
 
-/* Round robin the irqs amoung the online cpus */
 static inline cpumask_t target_cpus(void)
 {
-       static unsigned long cpu = NR_CPUS;
-       do {
-               if (cpu >= NR_CPUS)
-                       cpu = first_cpu(cpu_online_map);
-               else
-                       cpu = next_cpu(cpu, cpu_online_map);
-       } while (cpu >= NR_CPUS);
-       return cpumask_of_cpu(cpu);
+#ifdef CONFIG_SMP
+        return cpu_online_map;
+#else
+        return cpumask_of_cpu(0);
+#endif
 }
 
 #undef APIC_DEST_LOGICAL
 #define APIC_DEST_LOGICAL      0
-#define TARGET_CPUS            (target_cpus())
 #define APIC_DFR_VALUE         (APIC_DFR_FLAT)
 #define INT_DELIVERY_MODE      (dest_Fixed)
 #define INT_DEST_MODE          (0)    /* phys delivery to target proc */
similarity index 88%
rename from include/asm-x86/bios_ebda.h
rename to arch/x86/include/asm/bios_ebda.h
index 79b4b88505d743eed1e0e5ad7c6e55df8dc63c3f..3c7521063d3fd3f70ea346cf855e4d02c4fdb9f0 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__BIOS_EBDA_H
-#define ASM_X86__BIOS_EBDA_H
+#ifndef _ASM_X86_BIOS_EBDA_H
+#define _ASM_X86_BIOS_EBDA_H
 
 #include <asm/io.h>
 
@@ -33,4 +33,4 @@ static inline void start_periodic_check_for_corruption(void)
 }
 #endif
 
-#endif /* ASM_X86__BIOS_EBDA_H */
+#endif /* _ASM_X86_BIOS_EBDA_H */
similarity index 99%
rename from include/asm-x86/bitops.h
rename to arch/x86/include/asm/bitops.h
index 451a74762bd4e95aa3fd1ba20c2c6230ced14c84..360010322711037f80040829acceed8de6a15f42 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__BITOPS_H
-#define ASM_X86__BITOPS_H
+#ifndef _ASM_X86_BITOPS_H
+#define _ASM_X86_BITOPS_H
 
 /*
  * Copyright 1992, Linus Torvalds.
@@ -448,4 +448,4 @@ static inline int fls(int x)
 #include <asm-generic/bitops/minix.h>
 
 #endif /* __KERNEL__ */
-#endif /* ASM_X86__BITOPS_H */
+#endif /* _ASM_X86_BITOPS_H */
similarity index 89%
rename from include/asm-x86/boot.h
rename to arch/x86/include/asm/boot.h
index 1d63bd5d59462833cd5a458956c20a2d05618d9e..dd61616cb73d1d3aab1bb7d5c2dfd8923ec6e672 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__BOOT_H
-#define ASM_X86__BOOT_H
+#ifndef _ASM_X86_BOOT_H
+#define _ASM_X86_BOOT_H
 
 /* Don't touch these, unless you really know what you're doing. */
 #define DEF_SYSSEG     0x1000
@@ -23,4 +23,4 @@
 #define BOOT_STACK_SIZE        0x1000
 #endif
 
-#endif /* ASM_X86__BOOT_H */
+#endif /* _ASM_X86_BOOT_H */
similarity index 96%
rename from include/asm-x86/bootparam.h
rename to arch/x86/include/asm/bootparam.h
index ccf027e2d97da02eabaab3d54eea8bd4fe727d87..433adaebf9b631f108399a3d27f660ff61a0369b 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__BOOTPARAM_H
-#define ASM_X86__BOOTPARAM_H
+#ifndef _ASM_X86_BOOTPARAM_H
+#define _ASM_X86_BOOTPARAM_H
 
 #include <linux/types.h>
 #include <linux/screen_info.h>
@@ -108,4 +108,4 @@ struct boot_params {
        __u8  _pad9[276];                               /* 0xeec */
 } __attribute__((packed));
 
-#endif /* ASM_X86__BOOTPARAM_H */
+#endif /* _ASM_X86_BOOTPARAM_H */
similarity index 90%
rename from include/asm-x86/bug.h
rename to arch/x86/include/asm/bug.h
index 91ad43a54c47c6f9b9cb28bfc3cb7003a7b666a1..3def2065fcea73ba085fcb31ee5063e2cfc57adb 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__BUG_H
-#define ASM_X86__BUG_H
+#ifndef _ASM_X86_BUG_H
+#define _ASM_X86_BUG_H
 
 #ifdef CONFIG_BUG
 #define HAVE_ARCH_BUG
@@ -36,4 +36,4 @@ do {                                                          \
 #endif /* !CONFIG_BUG */
 
 #include <asm-generic/bug.h>
-#endif /* ASM_X86__BUG_H */
+#endif /* _ASM_X86_BUG_H */
similarity index 71%
rename from include/asm-x86/bugs.h
rename to arch/x86/include/asm/bugs.h
index dc604985f2ad71a92be6de6a7f9d48d70816bc2d..08abf639075f92b795d014cfde240d2769a224d5 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__BUGS_H
-#define ASM_X86__BUGS_H
+#ifndef _ASM_X86_BUGS_H
+#define _ASM_X86_BUGS_H
 
 extern void check_bugs(void);
 
@@ -9,4 +9,4 @@ int ppro_with_ram_bug(void);
 static inline int ppro_with_ram_bug(void) { return 0; }
 #endif
 
-#endif /* ASM_X86__BUGS_H */
+#endif /* _ASM_X86_BUGS_H */
similarity index 94%
rename from include/asm-x86/byteorder.h
rename to arch/x86/include/asm/byteorder.h
index 722f27d68105f8e454ccaf01d1b7de4baa8dd0ce..e02ae2d89acf13936aad26502e485aa6ddae0b65 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__BYTEORDER_H
-#define ASM_X86__BYTEORDER_H
+#ifndef _ASM_X86_BYTEORDER_H
+#define _ASM_X86_BYTEORDER_H
 
 #include <asm/types.h>
 #include <linux/compiler.h>
@@ -78,4 +78,4 @@ static inline __attribute_const__ __u32 ___arch__swab32(__u32 x)
 
 #include <linux/byteorder/little_endian.h>
 
-#endif /* ASM_X86__BYTEORDER_H */
+#endif /* _ASM_X86_BYTEORDER_H */
similarity index 85%
rename from include/asm-x86/cache.h
rename to arch/x86/include/asm/cache.h
index ea3f1cc06a974e8d3255bb07e74777f390976afa..5d367caa0e36c437e17cb29f76dc285d9b6d4a49 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__CACHE_H
-#define ASM_X86__CACHE_H
+#ifndef _ASM_X86_CACHE_H
+#define _ASM_X86_CACHE_H
 
 /* L1 cache line size */
 #define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
@@ -17,4 +17,4 @@
 #endif
 #endif
 
-#endif /* ASM_X86__CACHE_H */
+#endif /* _ASM_X86_CACHE_H */
similarity index 97%
rename from include/asm-x86/cacheflush.h
rename to arch/x86/include/asm/cacheflush.h
index 68840ef1b35a01c01fa7e23e45f3b5c0415d39e8..2f8466540fb52237c71373513304ddbf5627b873 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__CACHEFLUSH_H
-#define ASM_X86__CACHEFLUSH_H
+#ifndef _ASM_X86_CACHEFLUSH_H
+#define _ASM_X86_CACHEFLUSH_H
 
 /* Keep includes the same across arches.  */
 #include <linux/mm.h>
@@ -115,4 +115,4 @@ static inline int rodata_test(void)
 }
 #endif
 
-#endif /* ASM_X86__CACHEFLUSH_H */
+#endif /* _ASM_X86_CACHEFLUSH_H */
similarity index 96%
rename from include/asm-x86/calgary.h
rename to arch/x86/include/asm/calgary.h
index 933fd272f82663c6ed0c2224df4e668a0870681c..b03bedb62aa7f43ab8bc8f75168206dfbb5dd721 100644 (file)
@@ -21,8 +21,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-#ifndef ASM_X86__CALGARY_H
-#define ASM_X86__CALGARY_H
+#ifndef _ASM_X86_CALGARY_H
+#define _ASM_X86_CALGARY_H
 
 #include <linux/spinlock.h>
 #include <linux/device.h>
@@ -69,4 +69,4 @@ static inline int calgary_iommu_init(void) { return 1; }
 static inline void detect_calgary(void) { return; }
 #endif
 
-#endif /* ASM_X86__CALGARY_H */
+#endif /* _ASM_X86_CALGARY_H */
similarity index 97%
rename from include/asm-x86/checksum_32.h
rename to arch/x86/include/asm/checksum_32.h
index d041e8cda227a6b191f70052599b00383af83ea7..7c5ef8b14d925624e85fd3f2d589cbbbb98a4292 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__CHECKSUM_32_H
-#define ASM_X86__CHECKSUM_32_H
+#ifndef _ASM_X86_CHECKSUM_32_H
+#define _ASM_X86_CHECKSUM_32_H
 
 #include <linux/in6.h>
 
@@ -186,4 +186,4 @@ static inline __wsum csum_and_copy_to_user(const void *src,
        return (__force __wsum)-1; /* invalid checksum */
 }
 
-#endif /* ASM_X86__CHECKSUM_32_H */
+#endif /* _ASM_X86_CHECKSUM_32_H */
similarity index 98%
rename from include/asm-x86/checksum_64.h
rename to arch/x86/include/asm/checksum_64.h
index 110f403beb8953d60218bc5b8c940b9f92dc80bd..9bfdc41629ecb8478135754cd89659f358fcc2c0 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__CHECKSUM_64_H
-#define ASM_X86__CHECKSUM_64_H
+#ifndef _ASM_X86_CHECKSUM_64_H
+#define _ASM_X86_CHECKSUM_64_H
 
 /*
  * Checksums for x86-64
@@ -188,4 +188,4 @@ static inline unsigned add32_with_carry(unsigned a, unsigned b)
        return a;
 }
 
-#endif /* ASM_X86__CHECKSUM_64_H */
+#endif /* _ASM_X86_CHECKSUM_64_H */
similarity index 98%
rename from include/asm-x86/cmpxchg_32.h
rename to arch/x86/include/asm/cmpxchg_32.h
index 0622e45cdf7cf2b26413e506ef98a0352d6fb400..82ceb788a981e7c73a7cb06e3d0bec311e205be7 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__CMPXCHG_32_H
-#define ASM_X86__CMPXCHG_32_H
+#ifndef _ASM_X86_CMPXCHG_32_H
+#define _ASM_X86_CMPXCHG_32_H
 
 #include <linux/bitops.h> /* for LOCK_PREFIX */
 
@@ -341,4 +341,4 @@ extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64);
 
 #endif
 
-#endif /* ASM_X86__CMPXCHG_32_H */
+#endif /* _ASM_X86_CMPXCHG_32_H */
similarity index 97%
rename from include/asm-x86/cmpxchg_64.h
rename to arch/x86/include/asm/cmpxchg_64.h
index 63c1a5e61b994a781ef3ff8e9c1f858e9afac264..52de72e0de8c882c3673fcff25c315f270db977f 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__CMPXCHG_64_H
-#define ASM_X86__CMPXCHG_64_H
+#ifndef _ASM_X86_CMPXCHG_64_H
+#define _ASM_X86_CMPXCHG_64_H
 
 #include <asm/alternative.h> /* Provides LOCK_PREFIX */
 
@@ -182,4 +182,4 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr,
        cmpxchg_local((ptr), (o), (n));                                 \
 })
 
-#endif /* ASM_X86__CMPXCHG_64_H */
+#endif /* _ASM_X86_CMPXCHG_64_H */
similarity index 98%
rename from include/asm-x86/compat.h
rename to arch/x86/include/asm/compat.h
index 6732b150949e8c8ef0b333673c5b92438c3a9a9e..9a9c7bdc923dee66a411bdae3f30065e9e4ee09f 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__COMPAT_H
-#define ASM_X86__COMPAT_H
+#ifndef _ASM_X86_COMPAT_H
+#define _ASM_X86_COMPAT_H
 
 /*
  * Architecture specific compatibility types
@@ -215,4 +215,4 @@ static inline int is_compat_task(void)
        return current_thread_info()->status & TS_COMPAT;
 }
 
-#endif /* ASM_X86__COMPAT_H */
+#endif /* _ASM_X86_COMPAT_H */
similarity index 80%
rename from include/asm-x86/cpu.h
rename to arch/x86/include/asm/cpu.h
index 83a115083f0d74ad3eb0f82eae64e19aea5a7cc1..bae482df6039a5122617bbc781db52fbf8ae56e2 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__CPU_H
-#define ASM_X86__CPU_H
+#ifndef _ASM_X86_CPU_H
+#define _ASM_X86_CPU_H
 
 #include <linux/device.h>
 #include <linux/cpu.h>
@@ -17,4 +17,4 @@ extern void arch_unregister_cpu(int);
 #endif
 
 DECLARE_PER_CPU(int, cpu_state);
-#endif /* ASM_X86__CPU_H */
+#endif /* _ASM_X86_CPU_H */
similarity index 99%
rename from include/asm-x86/cpufeature.h
rename to arch/x86/include/asm/cpufeature.h
index adfeae6586e175f9972012a94c823ede9527d0d1..f73e95d75b45b48b360aaadf8a4c3d26b31b5b14 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Defines x86 CPU feature bits
  */
-#ifndef ASM_X86__CPUFEATURE_H
-#define ASM_X86__CPUFEATURE_H
+#ifndef _ASM_X86_CPUFEATURE_H
+#define _ASM_X86_CPUFEATURE_H
 
 #include <asm/required-features.h>
 
@@ -268,4 +268,4 @@ extern const char * const x86_power_flags[32];
 
 #endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */
 
-#endif /* ASM_X86__CPUFEATURE_H */
+#endif /* _ASM_X86_CPUFEATURE_H */
similarity index 87%
rename from include/asm-x86/current.h
rename to arch/x86/include/asm/current.h
index a863ead856f3d37de49d023a156f98b1d4f540c5..0930b4f8d672249145ea249cbc0d272471e822de 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__CURRENT_H
-#define ASM_X86__CURRENT_H
+#ifndef _ASM_X86_CURRENT_H
+#define _ASM_X86_CURRENT_H
 
 #ifdef CONFIG_X86_32
 #include <linux/compiler.h>
@@ -36,4 +36,4 @@ static __always_inline struct task_struct *get_current(void)
 
 #define current get_current()
 
-#endif /* ASM_X86__CURRENT_H */
+#endif /* _ASM_X86_CURRENT_H */
similarity index 96%
rename from include/asm-x86/debugreg.h
rename to arch/x86/include/asm/debugreg.h
index ecb6907c3ea4ff97ef7aacb4b9c47809ef2701c4..3ea6f37be9e2d29a69f6982bb3ddcc80554f1652 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__DEBUGREG_H
-#define ASM_X86__DEBUGREG_H
+#ifndef _ASM_X86_DEBUGREG_H
+#define _ASM_X86_DEBUGREG_H
 
 
 /* Indicate the register numbers for a number of the specific
@@ -67,4 +67,4 @@
 #define DR_LOCAL_SLOWDOWN (0x100)   /* Local slow the pipeline */
 #define DR_GLOBAL_SLOWDOWN (0x200)  /* Global slow the pipeline */
 
-#endif /* ASM_X86__DEBUGREG_H */
+#endif /* _ASM_X86_DEBUGREG_H */
similarity index 90%
rename from include/asm-x86/delay.h
rename to arch/x86/include/asm/delay.h
index 8a0da95b4fc50e290187fd3bf3eb05b161fdf955..409a649204aa7308c8936d6cc08d4479222d6885 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__DELAY_H
-#define ASM_X86__DELAY_H
+#ifndef _ASM_X86_DELAY_H
+#define _ASM_X86_DELAY_H
 
 /*
  * Copyright (C) 1993 Linus Torvalds
@@ -28,4 +28,4 @@ extern void __delay(unsigned long loops);
 
 void use_tsc_delay(void);
 
-#endif /* ASM_X86__DELAY_H */
+#endif /* _ASM_X86_DELAY_H */
similarity index 99%
rename from include/asm-x86/desc.h
rename to arch/x86/include/asm/desc.h
index f06adac7938c746f87b02939205b3d3370c100a0..e6b82b17b0721095cb79fced0888d320eb64230a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__DESC_H
-#define ASM_X86__DESC_H
+#ifndef _ASM_X86_DESC_H
+#define _ASM_X86_DESC_H
 
 #ifndef __ASSEMBLY__
 #include <asm/desc_defs.h>
@@ -406,4 +406,4 @@ static inline void set_system_intr_gate_ist(int n, void *addr, unsigned ist)
 
 #endif /* __ASSEMBLY__ */
 
-#endif /* ASM_X86__DESC_H */
+#endif /* _ASM_X86_DESC_H */
similarity index 96%
rename from include/asm-x86/desc_defs.h
rename to arch/x86/include/asm/desc_defs.h
index b881db664b46a27927d9febc4f16e39e24227d49..a6adefa28b946f4bc8d996bd2a6c5953668fb716 100644 (file)
@@ -1,6 +1,6 @@
 /* Written 2000 by Andi Kleen */
-#ifndef ASM_X86__DESC_DEFS_H
-#define ASM_X86__DESC_DEFS_H
+#ifndef _ASM_X86_DESC_DEFS_H
+#define _ASM_X86_DESC_DEFS_H
 
 /*
  * Segment descriptor structure definitions, usable from both x86_64 and i386
@@ -92,4 +92,4 @@ struct desc_ptr {
 
 #endif /* !__ASSEMBLY__ */
 
-#endif /* ASM_X86__DESC_DEFS_H */
+#endif /* _ASM_X86_DESC_DEFS_H */
similarity index 72%
rename from include/asm-x86/device.h
rename to arch/x86/include/asm/device.h
index 1bece04c7d9d9b829d6d51abe191ce1b8abf0da9..3c034f48fdb0a12f5a3fefe1499d014b68e6f4a2 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__DEVICE_H
-#define ASM_X86__DEVICE_H
+#ifndef _ASM_X86_DEVICE_H
+#define _ASM_X86_DEVICE_H
 
 struct dev_archdata {
 #ifdef CONFIG_ACPI
@@ -13,4 +13,4 @@ struct dma_mapping_ops *dma_ops;
 #endif
 };
 
-#endif /* ASM_X86__DEVICE_H */
+#endif /* _ASM_X86_DEVICE_H */
similarity index 94%
rename from include/asm-x86/div64.h
rename to arch/x86/include/asm/div64.h
index f9530f23f1d6ac2e4577ec036748cbbbc4752a93..9a2d644c08efc0981dbc13b1700e81917fef7c63 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__DIV64_H
-#define ASM_X86__DIV64_H
+#ifndef _ASM_X86_DIV64_H
+#define _ASM_X86_DIV64_H
 
 #ifdef CONFIG_X86_32
 
@@ -57,4 +57,4 @@ static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
 # include <asm-generic/div64.h>
 #endif /* CONFIG_X86_32 */
 
-#endif /* ASM_X86__DIV64_H */
+#endif /* _ASM_X86_DIV64_H */
similarity index 98%
rename from include/asm-x86/dma-mapping.h
rename to arch/x86/include/asm/dma-mapping.h
index 219c33d6361cdfa640878431cd6e6523dc2a475a..4a5397bfce276dc11caa1956ac9eebeab4e0c128 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__DMA_MAPPING_H
-#define ASM_X86__DMA_MAPPING_H
+#ifndef _ASM_X86_DMA_MAPPING_H
+#define _ASM_X86_DMA_MAPPING_H
 
 /*
  * IOMMU interface. See Documentation/DMA-mapping.txt and DMA-API.txt for
@@ -65,7 +65,7 @@ static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
                return dma_ops;
        else
                return dev->archdata.dma_ops;
-#endif /* ASM_X86__DMA_MAPPING_H */
+#endif /* _ASM_X86_DMA_MAPPING_H */
 }
 
 /* Make sure we keep the same behaviour */
similarity index 99%
rename from include/asm-x86/dma.h
rename to arch/x86/include/asm/dma.h
index c9f7a4eec5557c7ce8ee02b67af6daa6dd234062..ca1098a7e58057eebe268c059a682990c6ebb7e6 100644 (file)
@@ -5,8 +5,8 @@
  * and John Boyd, Nov. 1992.
  */
 
-#ifndef ASM_X86__DMA_H
-#define ASM_X86__DMA_H
+#ifndef _ASM_X86_DMA_H
+#define _ASM_X86_DMA_H
 
 #include <linux/spinlock.h>    /* And spinlocks */
 #include <asm/io.h>            /* need byte IO */
@@ -315,4 +315,4 @@ extern int isa_dma_bridge_buggy;
 #define isa_dma_bridge_buggy   (0)
 #endif
 
-#endif /* ASM_X86__DMA_H */
+#endif /* _ASM_X86_DMA_H */
similarity index 88%
rename from include/asm-x86/dmi.h
rename to arch/x86/include/asm/dmi.h
index 1cff6fe81fa5cb9d4f20954fca9e192cd99419a9..bc68212c6bc0097f66ae21b936c0af59e4c3f705 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__DMI_H
-#define ASM_X86__DMI_H
+#ifndef _ASM_X86_DMI_H
+#define _ASM_X86_DMI_H
 
 #include <asm/io.h>
 
@@ -23,4 +23,4 @@ static inline void *dmi_alloc(unsigned len)
 #define dmi_ioremap early_ioremap
 #define dmi_iounmap early_iounmap
 
-#endif /* ASM_X86__DMI_H */
+#endif /* _ASM_X86_DMI_H */
similarity index 98%
rename from include/asm-x86/ds.h
rename to arch/x86/include/asm/ds.h
index c3c953a45b215ba24b3c4216f4ee9def2e1f7c08..72c5a190bf48076d8b99b9f42f8a6f7a16a0e009 100644 (file)
@@ -20,8 +20,8 @@
  * Markus Metzger <markus.t.metzger@intel.com>, 2007-2008
  */
 
-#ifndef ASM_X86__DS_H
-#define ASM_X86__DS_H
+#ifndef _ASM_X86_DS_H
+#define _ASM_X86_DS_H
 
 #ifdef CONFIG_X86_DS
 
@@ -235,4 +235,4 @@ extern void ds_free(struct ds_context *context);
 #define ds_init_intel(config) do {} while (0)
 
 #endif /* CONFIG_X86_DS */
-#endif /* ASM_X86__DS_H */
+#endif /* _ASM_X86_DS_H */
similarity index 95%
rename from include/asm-x86/dwarf2.h
rename to arch/x86/include/asm/dwarf2.h
index 21d1bc32ad7c37ee7fa0213b2af692d73be0157a..804b6e6be9296aa5295018018404b2c9db05f6da 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__DWARF2_H
-#define ASM_X86__DWARF2_H
+#ifndef _ASM_X86_DWARF2_H
+#define _ASM_X86_DWARF2_H
 
 #ifndef __ASSEMBLY__
 #warning "asm/dwarf2.h should be only included in pure assembly files"
@@ -58,4 +58,4 @@
 
 #endif
 
-#endif /* ASM_X86__DWARF2_H */
+#endif /* _ASM_X86_DWARF2_H */
similarity index 98%
rename from include/asm-x86/e820.h
rename to arch/x86/include/asm/e820.h
index 5abbdec06bd2ed9e616530192a8b56f2ee041b7d..3d8ceddbd40729093cf2f303248a9a96202e609d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__E820_H
-#define ASM_X86__E820_H
+#ifndef _ASM_X86_E820_H
+#define _ASM_X86_E820_H
 #define E820MAP        0x2d0           /* our map */
 #define E820MAX        128             /* number of entries in E820MAP */
 
@@ -143,4 +143,4 @@ extern char *memory_setup(void);
 #define HIGH_MEMORY    (1024*1024)
 #endif /* __KERNEL__ */
 
-#endif /* ASM_X86__E820_H */
+#endif /* _ASM_X86_E820_H */
similarity index 82%
rename from include/asm-x86/edac.h
rename to arch/x86/include/asm/edac.h
index 9493c5b27bbdb4584bc60ff98b4fae0fd2dfc54f..e9b57ecc70c5c99f587ed4a3a44518481109bdbe 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__EDAC_H
-#define ASM_X86__EDAC_H
+#ifndef _ASM_X86_EDAC_H
+#define _ASM_X86_EDAC_H
 
 /* ECC atomic, DMA, SMP and interrupt safe scrub function */
 
@@ -15,4 +15,4 @@ static inline void atomic_scrub(void *va, u32 size)
                asm volatile("lock; addl $0, %0"::"m" (*virt_addr));
 }
 
-#endif /* ASM_X86__EDAC_H */
+#endif /* _ASM_X86_EDAC_H */
similarity index 87%
rename from include/asm-x86/efi.h
rename to arch/x86/include/asm/efi.h
index ed2de22e87050089bb8a8c02fb85bc0a204d2141..a2e545c91c359682e4583f1e4bdabd76ed91e7ed 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__EFI_H
-#define ASM_X86__EFI_H
+#ifndef _ASM_X86_EFI_H
+#define _ASM_X86_EFI_H
 
 #ifdef CONFIG_X86_32
 
@@ -94,4 +94,17 @@ extern void efi_reserve_early(void);
 extern void efi_call_phys_prelog(void);
 extern void efi_call_phys_epilog(void);
 
-#endif /* ASM_X86__EFI_H */
+#ifndef CONFIG_EFI
+/*
+ * IF EFI is not configured, have the EFI calls return -ENOSYS.
+ */
+#define efi_call0(_f)                                  (-ENOSYS)
+#define efi_call1(_f, _a1)                             (-ENOSYS)
+#define efi_call2(_f, _a1, _a2)                                (-ENOSYS)
+#define efi_call3(_f, _a1, _a2, _a3)                   (-ENOSYS)
+#define efi_call4(_f, _a1, _a2, _a3, _a4)              (-ENOSYS)
+#define efi_call5(_f, _a1, _a2, _a3, _a4, _a5)         (-ENOSYS)
+#define efi_call6(_f, _a1, _a2, _a3, _a4, _a5, _a6)    (-ENOSYS)
+#endif /* CONFIG_EFI */
+
+#endif /* _ASM_X86_EFI_H */
similarity index 99%
rename from include/asm-x86/elf.h
rename to arch/x86/include/asm/elf.h
index 26bc15f01e78a3faa7d7b4b540ab57741e3d94da..40ca1bea7916cc075448446887609b43e58dc670 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__ELF_H
-#define ASM_X86__ELF_H
+#ifndef _ASM_X86_ELF_H
+#define _ASM_X86_ELF_H
 
 /*
  * ELF register definitions..
@@ -333,4 +333,4 @@ extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
 extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 #define arch_randomize_brk arch_randomize_brk
 
-#endif /* ASM_X86__ELF_H */
+#endif /* _ASM_X86_ELF_H */
similarity index 65%
rename from include/asm-x86/emergency-restart.h
rename to arch/x86/include/asm/emergency-restart.h
index 190d0d8b71e330e35d1b0da257ab38132f218db3..94826cf874557acedd7afe248daa588a0c6383dd 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__EMERGENCY_RESTART_H
-#define ASM_X86__EMERGENCY_RESTART_H
+#ifndef _ASM_X86_EMERGENCY_RESTART_H
+#define _ASM_X86_EMERGENCY_RESTART_H
 
 enum reboot_type {
        BOOT_TRIPLE = 't',
@@ -15,4 +15,4 @@ extern enum reboot_type reboot_type;
 
 extern void machine_emergency_restart(void);
 
-#endif /* ASM_X86__EMERGENCY_RESTART_H */
+#endif /* _ASM_X86_EMERGENCY_RESTART_H */
similarity index 98%
rename from include/asm-x86/es7000/apic.h
rename to arch/x86/include/asm/es7000/apic.h
index aae50c2fb303db35d3bab0f2cfdd1a854f1b4fb2..380f0b4f17edfcf5c1e1440baed7231e07cdb684 100644 (file)
@@ -17,7 +17,6 @@ static inline cpumask_t target_cpus(void)
        return cpumask_of_cpu(smp_processor_id());
 #endif
 }
-#define TARGET_CPUS    (target_cpus())
 
 #if defined CONFIG_ES7000_CLUSTERED_APIC
 #define APIC_DFR_VALUE         (APIC_DFR_CLUSTER)
@@ -81,7 +80,7 @@ static inline void setup_apic_routing(void)
        int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id());
        printk("Enabling APIC mode:  %s.  Using %d I/O APICs, target cpus %lx\n",
                (apic_version[apic] == 0x14) ?
-               "Physical Cluster" : "Logical Cluster", nr_ioapics, cpus_addr(TARGET_CPUS)[0]);
+               "Physical Cluster" : "Logical Cluster", nr_ioapics, cpus_addr(target_cpus())[0]);
 }
 
 static inline int multi_timer_check(int apic, int irq)
similarity index 85%
rename from include/asm-x86/fb.h
rename to arch/x86/include/asm/fb.h
index aca38dbd9a644981541ef3cedeaea57d373d8d2c..53018464aea653a407dc32e6be3d95ac14230306 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__FB_H
-#define ASM_X86__FB_H
+#ifndef _ASM_X86_FB_H
+#define _ASM_X86_FB_H
 
 #include <linux/fb.h>
 #include <linux/fs.h>
@@ -18,4 +18,4 @@ extern int fb_is_primary_device(struct fb_info *info);
 static inline int fb_is_primary_device(struct fb_info *info) { return 0; }
 #endif
 
-#endif /* ASM_X86__FB_H */
+#endif /* _ASM_X86_FB_H */
similarity index 95%
rename from include/asm-x86/fixmap.h
rename to arch/x86/include/asm/fixmap.h
index 78e33a1bc591ea67357cc8bee1efdeb4d75463e6..8668a94f850e51e16f209e89f17f5e4b0d2afcf5 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__FIXMAP_H
-#define ASM_X86__FIXMAP_H
+#ifndef _ASM_X86_FIXMAP_H
+#define _ASM_X86_FIXMAP_H
 
 #ifdef CONFIG_X86_32
 # include "fixmap_32.h"
@@ -65,4 +65,4 @@ static inline unsigned long virt_to_fix(const unsigned long vaddr)
        BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
        return __virt_to_fix(vaddr);
 }
-#endif /* ASM_X86__FIXMAP_H */
+#endif /* _ASM_X86_FIXMAP_H */
similarity index 97%
rename from include/asm-x86/fixmap_32.h
rename to arch/x86/include/asm/fixmap_32.h
index 8844002da0e05df5e421846603c9b8a017bdd0a6..09f29ab5c139345f99596e294443c70e6b6086a6 100644 (file)
@@ -10,8 +10,8 @@
  * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
  */
 
-#ifndef ASM_X86__FIXMAP_32_H
-#define ASM_X86__FIXMAP_32_H
+#ifndef _ASM_X86_FIXMAP_32_H
+#define _ASM_X86_FIXMAP_32_H
 
 
 /* used by vmalloc.c, vsyscall.lds.S.
@@ -120,4 +120,4 @@ extern void reserve_top_address(unsigned long reserve);
 #define FIXADDR_BOOT_START     (FIXADDR_TOP - __FIXADDR_BOOT_SIZE)
 
 #endif /* !__ASSEMBLY__ */
-#endif /* ASM_X86__FIXMAP_32_H */
+#endif /* _ASM_X86_FIXMAP_32_H */
similarity index 96%
rename from include/asm-x86/fixmap_64.h
rename to arch/x86/include/asm/fixmap_64.h
index dab4751d13070491e66038af1264db9880eda7a2..00a30ab9b1a5ba466a44c165e1d553d36a77cd19 100644 (file)
@@ -8,8 +8,8 @@
  * Copyright (C) 1998 Ingo Molnar
  */
 
-#ifndef ASM_X86__FIXMAP_64_H
-#define ASM_X86__FIXMAP_64_H
+#ifndef _ASM_X86_FIXMAP_64_H
+#define _ASM_X86_FIXMAP_64_H
 
 #include <linux/kernel.h>
 #include <asm/acpi.h>
@@ -80,4 +80,4 @@ enum fixed_addresses {
 #define FIXADDR_USER_START     ((unsigned long)VSYSCALL32_VSYSCALL)
 #define FIXADDR_USER_END       (FIXADDR_USER_START + PAGE_SIZE)
 
-#endif /* ASM_X86__FIXMAP_64_H */
+#endif /* _ASM_X86_FIXMAP_64_H */
similarity index 98%
rename from include/asm-x86/floppy.h
rename to arch/x86/include/asm/floppy.h
index 7d83a3a83e3772ed54b5e0464c94aa8506421038..dbe82a5c5eacde33f9cdf3791dfe159228f151b6 100644 (file)
@@ -7,8 +7,8 @@
  *
  * Copyright (C) 1995
  */
-#ifndef ASM_X86__FLOPPY_H
-#define ASM_X86__FLOPPY_H
+#ifndef _ASM_X86_FLOPPY_H
+#define _ASM_X86_FLOPPY_H
 
 #include <linux/vmalloc.h>
 
@@ -278,4 +278,4 @@ static int FDC2 = -1;
 
 #define EXTRA_FLOPPY_PARAMS
 
-#endif /* ASM_X86__FLOPPY_H */
+#endif /* _ASM_X86_FLOPPY_H */
diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h
new file mode 100644 (file)
index 0000000..47f7e65
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef _ASM_X86_FTRACE_H
+#define _ASM_X86_FTRACE_H
+
+#ifdef CONFIG_FTRACE
+#define MCOUNT_ADDR            ((long)(mcount))
+#define MCOUNT_INSN_SIZE       5 /* sizeof mcount call */
+
+#ifndef __ASSEMBLY__
+extern void mcount(void);
+
+static inline unsigned long ftrace_call_adjust(unsigned long addr)
+{
+       /*
+        * call mcount is "e8 <4 byte offset>"
+        * The addr points to the 4 byte offset and the caller of this
+        * function wants the pointer to e8. Simply subtract one.
+        */
+       return addr - 1;
+}
+#endif
+
+#endif /* CONFIG_FTRACE */
+
+#endif /* _ASM_X86_FTRACE_H */
similarity index 97%
rename from include/asm-x86/futex.h
rename to arch/x86/include/asm/futex.h
index 06b924ef6fa5b928dc6a6d83889ee6ce98cc157c..1f11ce44e956dc41d3e33812821aa8249455a269 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__FUTEX_H
-#define ASM_X86__FUTEX_H
+#ifndef _ASM_X86_FUTEX_H
+#define _ASM_X86_FUTEX_H
 
 #ifdef __KERNEL__
 
@@ -137,4 +137,4 @@ static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
 }
 
 #endif
-#endif /* ASM_X86__FUTEX_H */
+#endif /* _ASM_X86_FUTEX_H */
similarity index 95%
rename from include/asm-x86/gart.h
rename to arch/x86/include/asm/gart.h
index 605edb39ef9e9472203644b4b168acafdf7541fd..74252264433d8fa3b628afe7f91a49365d377b8a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__GART_H
-#define ASM_X86__GART_H
+#ifndef _ASM_X86_GART_H
+#define _ASM_X86_GART_H
 
 #include <asm/e820.h>
 
@@ -70,4 +70,4 @@ static inline int aperture_valid(u64 aper_base, u32 aper_size, u32 min_size)
        return 1;
 }
 
-#endif /* ASM_X86__GART_H */
+#endif /* _ASM_X86_GART_H */
similarity index 95%
rename from include/asm-x86/genapic_32.h
rename to arch/x86/include/asm/genapic_32.h
index 34280f027664a57267d915bda709183b745ea9a5..5cbd4fcc06fd20425ce21ead1386c47d92d0b152 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__GENAPIC_32_H
-#define ASM_X86__GENAPIC_32_H
+#ifndef _ASM_X86_GENAPIC_32_H
+#define _ASM_X86_GENAPIC_32_H
 
 #include <asm/mpspec.h>
 
@@ -57,6 +57,7 @@ struct genapic {
        unsigned (*get_apic_id)(unsigned long x);
        unsigned long apic_id_mask;
        unsigned int (*cpu_mask_to_apicid)(cpumask_t cpumask);
+       cpumask_t (*vector_allocation_domain)(int cpu);
 
 #ifdef CONFIG_SMP
        /* ipi */
@@ -104,6 +105,7 @@ struct genapic {
        APICFUNC(get_apic_id)                           \
        .apic_id_mask = APIC_ID_MASK,                   \
        APICFUNC(cpu_mask_to_apicid)                    \
+       APICFUNC(vector_allocation_domain)                      \
        APICFUNC(acpi_madt_oem_check)                   \
        IPIFUNC(send_IPI_mask)                          \
        IPIFUNC(send_IPI_allbutself)                    \
@@ -121,4 +123,4 @@ enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC};
 #define uv_system_init()               do {} while (0)
 
 
-#endif /* ASM_X86__GENAPIC_32_H */
+#endif /* _ASM_X86_GENAPIC_32_H */
similarity index 94%
rename from include/asm-x86/genapic_64.h
rename to arch/x86/include/asm/genapic_64.h
index ed6a4886c0827ed44406f6eb2df2a0592afe5a62..13c4e96199ea17d1e52430dac24a85f4291f50d7 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__GENAPIC_64_H
-#define ASM_X86__GENAPIC_64_H
+#ifndef _ASM_X86_GENAPIC_64_H
+#define _ASM_X86_GENAPIC_64_H
 
 /*
  * Copyright 2004 James Cleverdon, IBM.
@@ -55,4 +55,4 @@ extern int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip);
 
 extern void setup_apic_routing(void);
 
-#endif /* ASM_X86__GENAPIC_64_H */
+#endif /* _ASM_X86_GENAPIC_64_H */
similarity index 98%
rename from include/asm-x86/geode.h
rename to arch/x86/include/asm/geode.h
index 3f3444be2638f7205d17dc432d723e5b58fcb3f1..ad3c2ed7548185f7c9891236e078bb98c62cb67c 100644 (file)
@@ -7,8 +7,8 @@
  * as published by the Free Software Foundation.
  */
 
-#ifndef ASM_X86__GEODE_H
-#define ASM_X86__GEODE_H
+#ifndef _ASM_X86_GEODE_H
+#define _ASM_X86_GEODE_H
 
 #include <asm/processor.h>
 #include <linux/io.h>
@@ -250,4 +250,4 @@ extern int __init mfgpt_timer_setup(void);
 static inline int mfgpt_timer_setup(void) { return 0; }
 #endif
 
-#endif /* ASM_X86__GEODE_H */
+#endif /* _ASM_X86_GEODE_H */
similarity index 92%
rename from include/asm-x86/gpio.h
rename to arch/x86/include/asm/gpio.h
index 497fb980d96245c72689ee3bd0eb630cf0c729a7..49dbfdfa50f9f3a80113c264b7c8fe0439746dc0 100644 (file)
@@ -13,8 +13,8 @@
  * (at your option) any later version.
  */
 
-#ifndef _ASM_I386_GPIO_H
-#define _ASM_I386_GPIO_H
+#ifndef _ASM_X86_GPIO_H
+#define _ASM_X86_GPIO_H
 
 #include <asm-generic/gpio.h>
 
@@ -53,4 +53,4 @@ static inline int irq_to_gpio(unsigned int irq)
 
 #endif /* CONFIG_GPIOLIB */
 
-#endif /* ASM_X86__GPIO_H */
+#endif /* _ASM_X86_GPIO_H */
similarity index 87%
rename from include/asm-x86/hardirq_32.h
rename to arch/x86/include/asm/hardirq_32.h
index 700fe230d9190dba5237d838581ec58485f793a7..5ca135e72f2b0952889c395eee74d865e7fbed26 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__HARDIRQ_32_H
-#define ASM_X86__HARDIRQ_32_H
+#ifndef _ASM_X86_HARDIRQ_32_H
+#define _ASM_X86_HARDIRQ_32_H
 
 #include <linux/threads.h>
 #include <linux/irq.h>
@@ -25,4 +25,4 @@ DECLARE_PER_CPU(irq_cpustat_t, irq_stat);
 void ack_bad_irq(unsigned int irq);
 #include <linux/irq_cpustat.h>
 
-#endif /* ASM_X86__HARDIRQ_32_H */
+#endif /* _ASM_X86_HARDIRQ_32_H */
similarity index 84%
rename from include/asm-x86/hardirq_64.h
rename to arch/x86/include/asm/hardirq_64.h
index f8bd2919a8ce88bcb98d6b7f24f51ecfda429fcd..1ba381fc51d38eca1012239b6949dedd59ad9f0d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__HARDIRQ_64_H
-#define ASM_X86__HARDIRQ_64_H
+#ifndef _ASM_X86_HARDIRQ_64_H
+#define _ASM_X86_HARDIRQ_64_H
 
 #include <linux/threads.h>
 #include <linux/irq.h>
@@ -20,4 +20,4 @@
 
 extern void ack_bad_irq(unsigned int irq);
 
-#endif /* ASM_X86__HARDIRQ_64_H */
+#endif /* _ASM_X86_HARDIRQ_64_H */
similarity index 96%
rename from include/asm-x86/highmem.h
rename to arch/x86/include/asm/highmem.h
index bc3f6a280316d5c33f41f9f48f70606e3f096021..a3b3b7c3027ba43bf6c366a8442064afddeaf7f3 100644 (file)
@@ -15,8 +15,8 @@
  * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
  */
 
-#ifndef ASM_X86__HIGHMEM_H
-#define ASM_X86__HIGHMEM_H
+#ifndef _ASM_X86_HIGHMEM_H
+#define _ASM_X86_HIGHMEM_H
 
 #ifdef __KERNEL__
 
@@ -79,4 +79,4 @@ extern void add_highpages_with_active_regions(int nid, unsigned long start_pfn,
 
 #endif /* __KERNEL__ */
 
-#endif /* ASM_X86__HIGHMEM_H */
+#endif /* _ASM_X86_HIGHMEM_H */
similarity index 80%
rename from include/asm-x86/hpet.h
rename to arch/x86/include/asm/hpet.h
index cbbbb6d4dd32bb838462864da48b26b1becbcd2d..1c22cb05ad6a9cdff814eaccd0d773600e4c05b5 100644 (file)
@@ -1,5 +1,7 @@
-#ifndef ASM_X86__HPET_H
-#define ASM_X86__HPET_H
+#ifndef _ASM_X86_HPET_H
+#define _ASM_X86_HPET_H
+
+#include <linux/msi.h>
 
 #ifdef CONFIG_HPET_TIMER
 
 #define HPET_CFG               0x010
 #define HPET_STATUS            0x020
 #define HPET_COUNTER           0x0f0
+
+#define HPET_Tn_CFG(n)         (0x100 + 0x20 * n)
+#define HPET_Tn_CMP(n)         (0x108 + 0x20 * n)
+#define HPET_Tn_ROUTE(n)       (0x110 + 0x20 * n)
+
 #define HPET_T0_CFG            0x100
 #define HPET_T0_CMP            0x108
 #define HPET_T0_ROUTE          0x110
@@ -65,6 +72,20 @@ extern void hpet_disable(void);
 extern unsigned long hpet_readl(unsigned long a);
 extern void force_hpet_resume(void);
 
+extern void hpet_msi_unmask(unsigned int irq);
+extern void hpet_msi_mask(unsigned int irq);
+extern void hpet_msi_write(unsigned int irq, struct msi_msg *msg);
+extern void hpet_msi_read(unsigned int irq, struct msi_msg *msg);
+
+#ifdef CONFIG_PCI_MSI
+extern int arch_setup_hpet_msi(unsigned int irq);
+#else
+static inline int arch_setup_hpet_msi(unsigned int irq)
+{
+       return -EINVAL;
+}
+#endif
+
 #ifdef CONFIG_HPET_EMULATE_RTC
 
 #include <linux/interrupt.h>
@@ -90,4 +111,4 @@ static inline int is_hpet_enabled(void) { return 0; }
 #define hpet_readl(a) 0
 
 #endif
-#endif /* ASM_X86__HPET_H */
+#endif /* _ASM_X86_HPET_H */
similarity index 95%
rename from include/asm-x86/hugetlb.h
rename to arch/x86/include/asm/hugetlb.h
index 0b7ec5dc08840df634deb5151e35279500a49577..439a9acc132d10f77b469fc24b250f3acc2f51d9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__HUGETLB_H
-#define ASM_X86__HUGETLB_H
+#ifndef _ASM_X86_HUGETLB_H
+#define _ASM_X86_HUGETLB_H
 
 #include <asm/page.h>
 
@@ -90,4 +90,4 @@ static inline void arch_release_hugepage(struct page *page)
 {
 }
 
-#endif /* ASM_X86__HUGETLB_H */
+#endif /* _ASM_X86_HUGETLB_H */
similarity index 91%
rename from include/asm-x86/hw_irq.h
rename to arch/x86/include/asm/hw_irq.h
index 50f6e0316b5029c4c2e5801bcd256119c3f037aa..b97aecb0b61d004de95bd769deb7bbd2d59e0774 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__HW_IRQ_H
-#define ASM_X86__HW_IRQ_H
+#ifndef _ASM_X86_HW_IRQ_H
+#define _ASM_X86_HW_IRQ_H
 
 /*
  * (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar
@@ -96,13 +96,8 @@ extern asmlinkage void qic_call_function_interrupt(void);
 
 /* SMP */
 extern void smp_apic_timer_interrupt(struct pt_regs *);
-#ifdef CONFIG_X86_32
 extern void smp_spurious_interrupt(struct pt_regs *);
 extern void smp_error_interrupt(struct pt_regs *);
-#else
-extern asmlinkage void smp_spurious_interrupt(void);
-extern asmlinkage void smp_error_interrupt(void);
-#endif
 #ifdef CONFIG_X86_SMP
 extern void smp_reschedule_interrupt(struct pt_regs *);
 extern void smp_call_function_interrupt(struct pt_regs *);
@@ -115,13 +110,13 @@ extern asmlinkage void smp_invalidate_interrupt(struct pt_regs *);
 #endif
 
 #ifdef CONFIG_X86_32
-extern void (*const interrupt[NR_IRQS])(void);
-#else
+extern void (*const interrupt[NR_VECTORS])(void);
+#endif
+
 typedef int vector_irq_t[NR_VECTORS];
 DECLARE_PER_CPU(vector_irq_t, vector_irq);
-#endif
 
-#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_X86_64)
+#ifdef CONFIG_X86_IO_APIC
 extern void lock_vector_lock(void);
 extern void unlock_vector_lock(void);
 extern void __setup_vector_irq(int cpu);
@@ -133,4 +128,4 @@ static inline void __setup_vector_irq(int cpu) {}
 
 #endif /* !ASSEMBLY_ */
 
-#endif /* ASM_X86__HW_IRQ_H */
+#endif /* _ASM_X86_HW_IRQ_H */
similarity index 91%
rename from include/asm-x86/hypertransport.h
rename to arch/x86/include/asm/hypertransport.h
index cc011a3bc1c280a1b7fb44b8cce834100c675d37..334b1a885d9c41cefe7549733f6fff96d81924db 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__HYPERTRANSPORT_H
-#define ASM_X86__HYPERTRANSPORT_H
+#ifndef _ASM_X86_HYPERTRANSPORT_H
+#define _ASM_X86_HYPERTRANSPORT_H
 
 /*
  * Constants for x86 Hypertransport Interrupts.
@@ -42,4 +42,4 @@
 #define HT_IRQ_HIGH_DEST_ID(v)                                         \
        ((((v) >> 8) << HT_IRQ_HIGH_DEST_ID_SHIFT) & HT_IRQ_HIGH_DEST_ID_MASK)
 
-#endif /* ASM_X86__HYPERTRANSPORT_H */
+#endif /* _ASM_X86_HYPERTRANSPORT_H */
similarity index 99%
rename from include/asm-x86/i387.h
rename to arch/x86/include/asm/i387.h
index 9ba862a4eac0327f8e0fce443ba7857edf9a0d08..48f0004db8c981175c0a900f659f4b41d1fa4dce 100644 (file)
@@ -7,8 +7,8 @@
  * x86-64 work by Andi Kleen 2002
  */
 
-#ifndef ASM_X86__I387_H
-#define ASM_X86__I387_H
+#ifndef _ASM_X86_I387_H
+#define _ASM_X86_I387_H
 
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
@@ -397,4 +397,4 @@ static inline unsigned short get_fpu_mxcsr(struct task_struct *tsk)
        }
 }
 
-#endif /* ASM_X86__I387_H */
+#endif /* _ASM_X86_I387_H */
similarity index 77%
rename from include/asm-x86/i8253.h
rename to arch/x86/include/asm/i8253.h
index 15a5b530044e85a56361f29c38ffd7eb75d1b38e..1edbf89680fd57e577e6ccae74e5ef110d285414 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__I8253_H
-#define ASM_X86__I8253_H
+#ifndef _ASM_X86_I8253_H
+#define _ASM_X86_I8253_H
 
 /* i8253A PIT registers */
 #define PIT_MODE               0x43
@@ -15,4 +15,4 @@ extern void setup_pit_timer(void);
 #define inb_pit                inb_p
 #define outb_pit       outb_p
 
-#endif /* ASM_X86__I8253_H */
+#endif /* _ASM_X86_I8253_H */
similarity index 95%
rename from include/asm-x86/i8259.h
rename to arch/x86/include/asm/i8259.h
index 23c1b3baaecd09284a9ff06b5f0375f8d1cf2e86..58d7091eeb1fc1e8955c87246121060fbb851d31 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__I8259_H
-#define ASM_X86__I8259_H
+#ifndef _ASM_X86_I8259_H
+#define _ASM_X86_I8259_H
 
 #include <linux/delay.h>
 
@@ -60,4 +60,4 @@ extern struct irq_chip i8259A_chip;
 extern void mask_8259A(void);
 extern void unmask_8259A(void);
 
-#endif /* ASM_X86__I8259_H */
+#endif /* _ASM_X86_I8259_H */
similarity index 97%
rename from include/asm-x86/ia32.h
rename to arch/x86/include/asm/ia32.h
index f932f7ad51ddb1c11e6c121c2dd2021a60c8abf2..97989c0e534c7a8af039805dc5a04ad11ed021a5 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__IA32_H
-#define ASM_X86__IA32_H
+#ifndef _ASM_X86_IA32_H
+#define _ASM_X86_IA32_H
 
 
 #ifdef CONFIG_IA32_EMULATION
@@ -167,4 +167,4 @@ extern void ia32_pick_mmap_layout(struct mm_struct *mm);
 
 #endif /* !CONFIG_IA32_SUPPORT */
 
-#endif /* ASM_X86__IA32_H */
+#endif /* _ASM_X86_IA32_H */
similarity index 81%
rename from include/asm-x86/ia32_unistd.h
rename to arch/x86/include/asm/ia32_unistd.h
index dbd887d8a5a5846183fcd966feafbc73fedf3f2d..976f6ecd2ce691da49d58e433f0b76b0348622b2 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__IA32_UNISTD_H
-#define ASM_X86__IA32_UNISTD_H
+#ifndef _ASM_X86_IA32_UNISTD_H
+#define _ASM_X86_IA32_UNISTD_H
 
 /*
  * This file contains the system call numbers of the ia32 port,
@@ -15,4 +15,4 @@
 #define __NR_ia32_sigreturn    119
 #define __NR_ia32_rt_sigreturn 173
 
-#endif /* ASM_X86__IA32_UNISTD_H */
+#endif /* _ASM_X86_IA32_UNISTD_H */
similarity index 59%
rename from include/asm-x86/idle.h
rename to arch/x86/include/asm/idle.h
index baa3f783d27dcb58c1de4fa66eb5f31deaecc872..44c89c3a23e9a1f9507536b4d84f0f6b3d225c61 100644 (file)
@@ -1,15 +1,16 @@
-#ifndef ASM_X86__IDLE_H
-#define ASM_X86__IDLE_H
+#ifndef _ASM_X86_IDLE_H
+#define _ASM_X86_IDLE_H
 
 #define IDLE_START 1
 #define IDLE_END 2
 
 struct notifier_block;
 void idle_notifier_register(struct notifier_block *n);
+void idle_notifier_unregister(struct notifier_block *n);
 
 void enter_idle(void);
 void exit_idle(void);
 
 void c1e_remove_cpu(int cpu);
 
-#endif /* ASM_X86__IDLE_H */
+#endif /* _ASM_X86_IDLE_H */
similarity index 87%
rename from include/asm-x86/intel_arch_perfmon.h
rename to arch/x86/include/asm/intel_arch_perfmon.h
index 07c03c6c9a169cdb5eeeab1d840f1a61cef2052e..fa0fd068bc2e29aeaaad694db8c0e570c43c0df5 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__INTEL_ARCH_PERFMON_H
-#define ASM_X86__INTEL_ARCH_PERFMON_H
+#ifndef _ASM_X86_INTEL_ARCH_PERFMON_H
+#define _ASM_X86_INTEL_ARCH_PERFMON_H
 
 #define MSR_ARCH_PERFMON_PERFCTR0              0xc1
 #define MSR_ARCH_PERFMON_PERFCTR1              0xc2
@@ -28,4 +28,4 @@ union cpuid10_eax {
        unsigned int full;
 };
 
-#endif /* ASM_X86__INTEL_ARCH_PERFMON_H */
+#endif /* _ASM_X86_INTEL_ARCH_PERFMON_H */
similarity index 97%
rename from include/asm-x86/io.h
rename to arch/x86/include/asm/io.h
index a233f835e0b52a49ed02077409a7e52de22aa9a0..5618a103f395c1bf16558b57115ef1c4ae976392 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__IO_H
-#define ASM_X86__IO_H
+#ifndef _ASM_X86_IO_H
+#define _ASM_X86_IO_H
 
 #define ARCH_HAS_IOREMAP_WC
 
@@ -88,4 +88,4 @@ extern void early_iounmap(void *addr, unsigned long size);
 extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys);
 
 
-#endif /* ASM_X86__IO_H */
+#endif /* _ASM_X86_IO_H */
similarity index 98%
rename from include/asm-x86/io_32.h
rename to arch/x86/include/asm/io_32.h
index 4f7d878bda1819a51541b67bda6dc7f4c53ac248..d8e242e1b396a0dedeb3810127628d2adbe5b949 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__IO_32_H
-#define ASM_X86__IO_32_H
+#ifndef _ASM_X86_IO_32_H
+#define _ASM_X86_IO_32_H
 
 #include <linux/string.h>
 #include <linux/compiler.h>
@@ -281,4 +281,4 @@ BUILDIO(b, b, char)
 BUILDIO(w, w, short)
 BUILDIO(l, , int)
 
-#endif /* ASM_X86__IO_32_H */
+#endif /* _ASM_X86_IO_32_H */
similarity index 98%
rename from include/asm-x86/io_64.h
rename to arch/x86/include/asm/io_64.h
index ee6e086b7dfec848998c241a21b6b3baca9be5f4..fea325a1122f4abf66d340113a9a82787a75832f 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__IO_64_H
-#define ASM_X86__IO_64_H
+#ifndef _ASM_X86_IO_64_H
+#define _ASM_X86_IO_64_H
 
 
 /*
@@ -241,4 +241,4 @@ void memset_io(volatile void __iomem *a, int b, size_t c);
 
 #endif /* __KERNEL__ */
 
-#endif /* ASM_X86__IO_64_H */
+#endif /* _ASM_X86_IO_64_H */
similarity index 93%
rename from include/asm-x86/io_apic.h
rename to arch/x86/include/asm/io_apic.h
index 8ec68a50cf103b3779da806b391978fb27fcdc2c..6afd9933a7dd96d96822a8ecb058cc2528ed09ac 100644 (file)
@@ -1,9 +1,10 @@
-#ifndef ASM_X86__IO_APIC_H
-#define ASM_X86__IO_APIC_H
+#ifndef _ASM_X86_IO_APIC_H
+#define _ASM_X86_IO_APIC_H
 
 #include <linux/types.h>
 #include <asm/mpspec.h>
 #include <asm/apicdef.h>
+#include <asm/irq_vectors.h>
 
 /*
  * Intel IO-APIC support for SMP and UP systems.
@@ -87,24 +88,8 @@ struct IO_APIC_route_entry {
                mask            :  1,   /* 0: enabled, 1: disabled */
                __reserved_2    : 15;
 
-#ifdef CONFIG_X86_32
-       union {
-               struct {
-                       __u32   __reserved_1    : 24,
-                               physical_dest   :  4,
-                               __reserved_2    :  4;
-               } physical;
-
-               struct {
-                       __u32   __reserved_1    : 24,
-                               logical_dest    :  8;
-               } logical;
-       } dest;
-#else
        __u32   __reserved_3    : 24,
                dest            :  8;
-#endif
-
 } __attribute__ ((packed));
 
 struct IR_IO_APIC_route_entry {
@@ -203,10 +188,17 @@ extern void restore_IO_APIC_setup(void);
 extern void reinit_intr_remapped_IO_APIC(int);
 #endif
 
+extern int probe_nr_irqs(void);
+
 #else  /* !CONFIG_X86_IO_APIC */
 #define io_apic_assign_pci_irqs 0
 static const int timer_through_8259 = 0;
 static inline void ioapic_init_mappings(void) { }
+
+static inline int probe_nr_irqs(void)
+{
+       return NR_IRQS;
+}
 #endif
 
-#endif /* ASM_X86__IO_APIC_H */
+#endif /* _ASM_X86_IO_APIC_H */
similarity index 97%
rename from include/asm-x86/ioctls.h
rename to arch/x86/include/asm/ioctls.h
index 06752a649044d2029c4c555f006635ff41d6b9f5..0d5b23b7b06e63a770cc022eccbd319baaf7d21e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__IOCTLS_H
-#define ASM_X86__IOCTLS_H
+#ifndef _ASM_X86_IOCTLS_H
+#define _ASM_X86_IOCTLS_H
 
 #include <asm/ioctl.h>
 
@@ -91,4 +91,4 @@
 
 #define TIOCSER_TEMT    0x01   /* Transmitter physically empty */
 
-#endif /* ASM_X86__IOCTLS_H */
+#endif /* _ASM_X86_IOCTLS_H */
similarity index 84%
rename from include/asm-x86/iommu.h
rename to arch/x86/include/asm/iommu.h
index 961e746da977d470092b9ab912cf1d3f2531a4b7..98e28ea8cd167afb5c1bf8bd3a04f320365e2edf 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__IOMMU_H
-#define ASM_X86__IOMMU_H
+#ifndef _ASM_X86_IOMMU_H
+#define _ASM_X86_IOMMU_H
 
 extern void pci_iommu_shutdown(void);
 extern void no_iommu_init(void);
@@ -7,9 +7,13 @@ extern struct dma_mapping_ops nommu_dma_ops;
 extern int force_iommu, no_iommu;
 extern int iommu_detected;
 extern int dmar_disabled;
+extern int forbid_dac;
 
 extern unsigned long iommu_nr_pages(unsigned long addr, unsigned long len);
 
+/* 10 seconds */
+#define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
+
 #ifdef CONFIG_GART_IOMMU
 extern int gart_iommu_aperture;
 extern int gart_iommu_aperture_allowed;
@@ -43,4 +47,4 @@ static inline void gart_iommu_hole_init(void)
 }
 #endif
 
-#endif /* ASM_X86__IOMMU_H */
+#endif /* _ASM_X86_IOMMU_H */
similarity index 86%
rename from include/asm-x86/ipcbuf.h
rename to arch/x86/include/asm/ipcbuf.h
index 910304fbdc8f289e7f92e37a4bd2089b540f585f..ee678fd51594e5100d42e244433f3e8dc1c70690 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__IPCBUF_H
-#define ASM_X86__IPCBUF_H
+#ifndef _ASM_X86_IPCBUF_H
+#define _ASM_X86_IPCBUF_H
 
 /*
  * The ipc64_perm structure for x86 architecture.
@@ -25,4 +25,4 @@ struct ipc64_perm {
        unsigned long           __unused2;
 };
 
-#endif /* ASM_X86__IPCBUF_H */
+#endif /* _ASM_X86_IPCBUF_H */
similarity index 97%
rename from include/asm-x86/ipi.h
rename to arch/x86/include/asm/ipi.h
index 30a692cfaff8f1a67c827f5bd58ed73b24fad9d7..f89dffb28aa93d3427c812ec059a538ac281aaef 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__IPI_H
-#define ASM_X86__IPI_H
+#ifndef _ASM_X86_IPI_H
+#define _ASM_X86_IPI_H
 
 /*
  * Copyright 2004 James Cleverdon, IBM.
@@ -135,4 +135,4 @@ static inline void send_IPI_mask_sequence(cpumask_t mask, int vector)
        local_irq_restore(flags);
 }
 
-#endif /* ASM_X86__IPI_H */
+#endif /* _ASM_X86_IPI_H */
similarity index 93%
rename from include/asm-x86/irq.h
rename to arch/x86/include/asm/irq.h
index 1e5f2909c1db8c7db9330412444cafb07c0d1149..bae0eda954864aa62e90b6ec438b82c8785129dc 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__IRQ_H
-#define ASM_X86__IRQ_H
+#ifndef _ASM_X86_IRQ_H
+#define _ASM_X86_IRQ_H
 /*
  *     (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar
  *
@@ -47,4 +47,4 @@ extern void native_init_IRQ(void);
 /* Interrupt vector management */
 extern DECLARE_BITMAP(used_vectors, NR_VECTORS);
 
-#endif /* ASM_X86__IRQ_H */
+#endif /* _ASM_X86_IRQ_H */
similarity index 84%
rename from include/asm-x86/irq_regs_32.h
rename to arch/x86/include/asm/irq_regs_32.h
index 316a3b2588715cd0cec869c51eaa4f6774972c64..af2f02d27fc7a51a8e0a5c8d4470b0f9bd90330e 100644 (file)
@@ -4,8 +4,8 @@
  *
  * Jeremy Fitzhardinge <jeremy@goop.org>
  */
-#ifndef ASM_X86__IRQ_REGS_32_H
-#define ASM_X86__IRQ_REGS_32_H
+#ifndef _ASM_X86_IRQ_REGS_32_H
+#define _ASM_X86_IRQ_REGS_32_H
 
 #include <asm/percpu.h>
 
@@ -26,4 +26,4 @@ static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs)
        return old_regs;
 }
 
-#endif /* ASM_X86__IRQ_REGS_32_H */
+#endif /* _ASM_X86_IRQ_REGS_32_H */
diff --git a/arch/x86/include/asm/irq_remapping.h b/arch/x86/include/asm/irq_remapping.h
new file mode 100644 (file)
index 0000000..20e1fd5
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _ASM_X86_IRQ_REMAPPING_H
+#define _ASM_X86_IRQ_REMAPPING_H
+
+extern int x2apic;
+
+#define IRTE_DEST(dest) ((x2apic) ? dest : dest << 8)
+
+#endif /* _ASM_X86_IRQ_REMAPPING_H */
similarity index 86%
rename from include/asm-x86/irq_vectors.h
rename to arch/x86/include/asm/irq_vectors.h
index c5d2d767a1f356366e7ee57716ffd057ff3deb4a..d843ed0e9b2ee49b2cc6bd8843cefe545bd0f0ce 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__IRQ_VECTORS_H
-#define ASM_X86__IRQ_VECTORS_H
+#ifndef _ASM_X86_IRQ_VECTORS_H
+#define _ASM_X86_IRQ_VECTORS_H
 
 #include <linux/threads.h>
 
 
 /*
  * Reserve the lowest usable priority level 0x20 - 0x2f for triggering
- * cleanup after irq migration on 64 bit.
+ * cleanup after irq migration.
  */
 #define IRQ_MOVE_CLEANUP_VECTOR        FIRST_EXTERNAL_VECTOR
 
 /*
- * Vectors 0x20-0x2f are used for ISA interrupts on 32 bit.
- * Vectors 0x30-0x3f are used for ISA interrupts on 64 bit.
+ * Vectors 0x30-0x3f are used for ISA interrupts.
  */
-#ifdef CONFIG_X86_32
-#define IRQ0_VECTOR            (FIRST_EXTERNAL_VECTOR)
-#else
 #define IRQ0_VECTOR            (FIRST_EXTERNAL_VECTOR + 0x10)
-#endif
 #define IRQ1_VECTOR            (IRQ0_VECTOR + 1)
 #define IRQ2_VECTOR            (IRQ0_VECTOR + 2)
 #define IRQ3_VECTOR            (IRQ0_VECTOR + 3)
  * start at 0x31(0x41) to spread out vectors evenly between priority
  * levels. (0x80 is the syscall vector)
  */
-#ifdef CONFIG_X86_32
-# define FIRST_DEVICE_VECTOR   0x31
-#else
-# define FIRST_DEVICE_VECTOR   (IRQ15_VECTOR + 2)
-#endif
+#define FIRST_DEVICE_VECTOR    (IRQ15_VECTOR + 2)
 
 #define NR_VECTORS             256
 
 # else
 #  define NR_IRQS (NR_VECTORS + (32 * MAX_IO_APICS))
 # endif
-# define NR_IRQ_VECTORS NR_IRQS
 
 #elif !defined(CONFIG_X86_VOYAGER)
 
 
 #  define NR_IRQS              224
 
-#  if (224 >= 32 * NR_CPUS)
-#   define NR_IRQ_VECTORS      NR_IRQS
-#  else
-#   define NR_IRQ_VECTORS      (32 * NR_CPUS)
-#  endif
-
 # else /* IO_APIC || PARAVIRT */
 
 #  define NR_IRQS              16
-#  define NR_IRQ_VECTORS       NR_IRQS
 
 # endif
 
 #else /* !VISWS && !VOYAGER */
 
 # define NR_IRQS               224
-# define NR_IRQ_VECTORS                NR_IRQS
 
 #endif /* VISWS */
 
 #define VIC_CPU_BOOT_ERRATA_CPI                (VIC_CPI_LEVEL0 + 8)
 
 
-#endif /* ASM_X86__IRQ_VECTORS_H */
+#endif /* _ASM_X86_IRQ_VECTORS_H */
similarity index 91%
rename from include/asm-x86/ist.h
rename to arch/x86/include/asm/ist.h
index 35a2fe9bc9212f799d3f3c2797af33d65b11eacd..7e5dff1de0e9fc8a98cab9810a69f4549dec3c17 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__IST_H
-#define ASM_X86__IST_H
+#ifndef _ASM_X86_IST_H
+#define _ASM_X86_IST_H
 
 /*
  * Include file for the interface to IST BIOS
@@ -31,4 +31,4 @@ struct ist_info {
 extern struct ist_info ist_info;
 
 #endif /* __KERNEL__ */
-#endif /* ASM_X86__IST_H */
+#endif /* _ASM_X86_IST_H */
similarity index 81%
rename from include/asm-x86/k8.h
rename to arch/x86/include/asm/k8.h
index 2bbaf4370a553b7aa6cff16b61c9f1f39e8b1009..54c8cc53b24dd732829da23805c96f64b92fa168 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__K8_H
-#define ASM_X86__K8_H
+#ifndef _ASM_X86_K8_H
+#define _ASM_X86_K8_H
 
 #include <linux/pci.h>
 
@@ -12,4 +12,4 @@ extern int cache_k8_northbridges(void);
 extern void k8_flush_garts(void);
 extern int k8_scan_nodes(unsigned long start, unsigned long end);
 
-#endif /* ASM_X86__K8_H */
+#endif /* _ASM_X86_K8_H */
similarity index 90%
rename from include/asm-x86/kdebug.h
rename to arch/x86/include/asm/kdebug.h
index fbbab66ee9dfb9c8385e2ff40f92e245b887f924..fa7c0b9747615ce6bd75c919b7ec884de076123c 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__KDEBUG_H
-#define ASM_X86__KDEBUG_H
+#ifndef _ASM_X86_KDEBUG_H
+#define _ASM_X86_KDEBUG_H
 
 #include <linux/notifier.h>
 
@@ -34,4 +34,4 @@ extern void show_regs(struct pt_regs *regs);
 extern unsigned long oops_begin(void);
 extern void oops_end(unsigned long, struct pt_regs *, int signr);
 
-#endif /* ASM_X86__KDEBUG_H */
+#endif /* _ASM_X86_KDEBUG_H */
similarity index 98%
rename from include/asm-x86/kexec.h
rename to arch/x86/include/asm/kexec.h
index ea09600d6129543392b09936962a873e4e2ac622..a1f22771a15a2d07a88d9e071b17ebb6860631ef 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__KEXEC_H
-#define ASM_X86__KEXEC_H
+#ifndef _ASM_X86_KEXEC_H
+#define _ASM_X86_KEXEC_H
 
 #ifdef CONFIG_X86_32
 # define PA_CONTROL_PAGE       0
@@ -172,4 +172,4 @@ relocate_kernel(unsigned long indirection_page,
 
 #endif /* __ASSEMBLY__ */
 
-#endif /* ASM_X86__KEXEC_H */
+#endif /* _ASM_X86_KEXEC_H */
similarity index 95%
rename from include/asm-x86/kgdb.h
rename to arch/x86/include/asm/kgdb.h
index d283863354de7279ce915bb0905680991b1ec250..e6c6c808489fc1bb5d9d6bf9920484749fb041db 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__KGDB_H
-#define ASM_X86__KGDB_H
+#ifndef _ASM_X86_KGDB_H
+#define _ASM_X86_KGDB_H
 
 /*
  * Copyright (C) 2001-2004 Amit S. Kale
@@ -76,4 +76,4 @@ static inline void arch_kgdb_breakpoint(void)
 #define BREAK_INSTR_SIZE       1
 #define CACHE_FLUSH_IS_SAFE    1
 
-#endif /* ASM_X86__KGDB_H */
+#endif /* _ASM_X86_KGDB_H */
similarity index 81%
rename from include/asm-x86/kmap_types.h
rename to arch/x86/include/asm/kmap_types.h
index 89f44493e6432ad192fa65faeac1b46c93ce6eb6..5759c165a5cf5516adc32d6cc6d841451cf55aaa 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__KMAP_TYPES_H
-#define ASM_X86__KMAP_TYPES_H
+#ifndef _ASM_X86_KMAP_TYPES_H
+#define _ASM_X86_KMAP_TYPES_H
 
 #if defined(CONFIG_X86_32) && defined(CONFIG_DEBUG_HIGHMEM)
 # define D(n) __KM_FENCE_##n ,
@@ -26,4 +26,4 @@ D(13) KM_TYPE_NR
 
 #undef D
 
-#endif /* ASM_X86__KMAP_TYPES_H */
+#endif /* _ASM_X86_KMAP_TYPES_H */
similarity index 96%
rename from include/asm-x86/kprobes.h
rename to arch/x86/include/asm/kprobes.h
index 8a0748d01036711c509e99d2d5121fbd81100380..4fe681de1e76c164eedb543bad7333aa57de4b6d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__KPROBES_H
-#define ASM_X86__KPROBES_H
+#ifndef _ASM_X86_KPROBES_H
+#define _ASM_X86_KPROBES_H
 /*
  *  Kernel Probes (KProbes)
  *
@@ -85,4 +85,4 @@ struct kprobe_ctlblk {
 extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
 extern int kprobe_exceptions_notify(struct notifier_block *self,
                                    unsigned long val, void *data);
-#endif /* ASM_X86__KPROBES_H */
+#endif /* _ASM_X86_KPROBES_H */
similarity index 98%
rename from include/asm-x86/kvm.h
rename to arch/x86/include/asm/kvm.h
index ba0dd791fadf2d20560b5f16b3c6c0ab72e39789..b95162af0bf63eba3ec0c0df979bdb861dc0b942 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__KVM_H
-#define ASM_X86__KVM_H
+#ifndef _ASM_X86_KVM_H
+#define _ASM_X86_KVM_H
 
 /*
  * KVM x86 specific structures and definitions
@@ -208,4 +208,4 @@ struct kvm_pit_channel_state {
 struct kvm_pit_state {
        struct kvm_pit_channel_state channels[3];
 };
-#endif /* ASM_X86__KVM_H */
+#endif /* _ASM_X86_KVM_H */
similarity index 99%
rename from include/asm-x86/kvm_host.h
rename to arch/x86/include/asm/kvm_host.h
index 411fb8cfb24e6b4d856dc234b5fe37309fb3a3cb..65679d006337a6d5951df565ac2ef50405a9c341 100644 (file)
@@ -8,8 +8,8 @@
  *
  */
 
-#ifndef ASM_X86__KVM_HOST_H
-#define ASM_X86__KVM_HOST_H
+#ifndef _ASM_X86_KVM_HOST_H
+#define _ASM_X86_KVM_HOST_H
 
 #include <linux/types.h>
 #include <linux/mm.h>
@@ -749,4 +749,4 @@ asmlinkage void kvm_handle_fault_on_reboot(void);
 int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
 int kvm_age_hva(struct kvm *kvm, unsigned long hva);
 
-#endif /* ASM_X86__KVM_HOST_H */
+#endif /* _ASM_X86_KVM_HOST_H */
similarity index 97%
rename from include/asm-x86/kvm_para.h
rename to arch/x86/include/asm/kvm_para.h
index 30054fded4fbbe325271e9ca2db0424eb3ebbdde..b8a3305ae093772f23a2dba14cdb4a446ae5a721 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__KVM_PARA_H
-#define ASM_X86__KVM_PARA_H
+#ifndef _ASM_X86_KVM_PARA_H
+#define _ASM_X86_KVM_PARA_H
 
 /* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx.  It
  * should be used to determine that a VM is running under KVM.
@@ -144,4 +144,4 @@ static inline unsigned int kvm_arch_para_features(void)
 
 #endif
 
-#endif /* ASM_X86__KVM_PARA_H */
+#endif /* _ASM_X86_KVM_PARA_H */
similarity index 98%
rename from include/asm-x86/kvm_x86_emulate.h
rename to arch/x86/include/asm/kvm_x86_emulate.h
index e2d9b030c1ac9460297c34c08a1e796b13afa85c..25179a29f208cdac80946c406635a2b8518e4dcd 100644 (file)
@@ -8,8 +8,8 @@
  * From: xen-unstable 10676:af9809f51f81a3c43f276f00c81a52ef558afda4
  */
 
-#ifndef ASM_X86__KVM_X86_EMULATE_H
-#define ASM_X86__KVM_X86_EMULATE_H
+#ifndef _ASM_X86_KVM_X86_EMULATE_H
+#define _ASM_X86_KVM_X86_EMULATE_H
 
 struct x86_emulate_ctxt;
 
@@ -181,4 +181,4 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt,
 int x86_emulate_insn(struct x86_emulate_ctxt *ctxt,
                     struct x86_emulate_ops *ops);
 
-#endif /* ASM_X86__KVM_X86_EMULATE_H */
+#endif /* _ASM_X86_KVM_X86_EMULATE_H */
similarity index 92%
rename from include/asm-x86/ldt.h
rename to arch/x86/include/asm/ldt.h
index a5228504d867e68045b52f6a514b8f2130efacec..46727eb37bfe20915242badc965a2b4985bd28b4 100644 (file)
@@ -3,8 +3,8 @@
  *
  * Definitions of structures used with the modify_ldt system call.
  */
-#ifndef ASM_X86__LDT_H
-#define ASM_X86__LDT_H
+#ifndef _ASM_X86_LDT_H
+#define _ASM_X86_LDT_H
 
 /* Maximum number of LDT entries supported. */
 #define LDT_ENTRIES    8192
@@ -37,4 +37,4 @@ struct user_desc {
 #define MODIFY_LDT_CONTENTS_CODE       2
 
 #endif /* !__ASSEMBLY__ */
-#endif /* ASM_X86__LDT_H */
+#endif /* _ASM_X86_LDT_H */
similarity index 96%
rename from include/asm-x86/lguest.h
rename to arch/x86/include/asm/lguest.h
index 7505e947ed2719a32a91c53a52598905a63818e4..d28a507cef3957eeccf5154d1e9b6b29103e21cc 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__LGUEST_H
-#define ASM_X86__LGUEST_H
+#ifndef _ASM_X86_LGUEST_H
+#define _ASM_X86_LGUEST_H
 
 #define GDT_ENTRY_LGUEST_CS    10
 #define GDT_ENTRY_LGUEST_DS    11
@@ -91,4 +91,4 @@ static inline void lguest_set_ts(void)
 
 #endif /* __ASSEMBLY__ */
 
-#endif /* ASM_X86__LGUEST_H */
+#endif /* _ASM_X86_LGUEST_H */
similarity index 95%
rename from include/asm-x86/lguest_hcall.h
rename to arch/x86/include/asm/lguest_hcall.h
index 8f034ba4b53ebf1b3e6df32be9e5252ccf433f76..43894428c3c2a7d871bd5d49bcc0b2e136405e13 100644 (file)
@@ -1,6 +1,6 @@
 /* Architecture specific portion of the lguest hypercalls */
-#ifndef ASM_X86__LGUEST_HCALL_H
-#define ASM_X86__LGUEST_HCALL_H
+#ifndef _ASM_X86_LGUEST_HCALL_H
+#define _ASM_X86_LGUEST_HCALL_H
 
 #define LHCALL_FLUSH_ASYNC     0
 #define LHCALL_LGUEST_INIT     1
@@ -68,4 +68,4 @@ struct hcall_args {
 };
 
 #endif /* !__ASSEMBLY__ */
-#endif /* ASM_X86__LGUEST_HCALL_H */
+#endif /* _ASM_X86_LGUEST_HCALL_H */
similarity index 95%
rename from include/asm-x86/linkage.h
rename to arch/x86/include/asm/linkage.h
index 42d8b62ee8abe72e842c55a3c337d0e947802561..f61ee8f937e4b3220e58f2851c749718fd1a4e16 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__LINKAGE_H
-#define ASM_X86__LINKAGE_H
+#ifndef _ASM_X86_LINKAGE_H
+#define _ASM_X86_LINKAGE_H
 
 #undef notrace
 #define notrace __attribute__((no_instrument_function))
@@ -57,5 +57,5 @@
 #define __ALIGN_STR ".align 16,0x90"
 #endif
 
-#endif /* ASM_X86__LINKAGE_H */
+#endif /* _ASM_X86_LINKAGE_H */
 
similarity index 98%
rename from include/asm-x86/local.h
rename to arch/x86/include/asm/local.h
index ae91994fd6c91dc607251a31d5e2df0db6d8f6af..47b9b6f1905750f5ecf8d0ec2f1f20f13470318b 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__LOCAL_H
-#define ASM_X86__LOCAL_H
+#ifndef _ASM_X86_LOCAL_H
+#define _ASM_X86_LOCAL_H
 
 #include <linux/percpu.h>
 
@@ -232,4 +232,4 @@ static inline long local_sub_return(long i, local_t *l)
 #define __cpu_local_add(i, l)  cpu_local_add((i), (l))
 #define __cpu_local_sub(i, l)  cpu_local_sub((i), (l))
 
-#endif /* ASM_X86__LOCAL_H */
+#endif /* _ASM_X86_LOCAL_H */
similarity index 93%
rename from include/asm-x86/mach-default/apm.h
rename to arch/x86/include/asm/mach-default/apm.h
index 2aa61b54fbd576f7c353eb4738904694e0844633..20370c6db74bb6dd09bbb78d4ded0b7adfd27d3e 100644 (file)
@@ -3,8 +3,8 @@
  *  Split out from apm.c by Osamu Tomita <tomita@cinet.co.jp>
  */
 
-#ifndef ASM_X86__MACH_DEFAULT__APM_H
-#define ASM_X86__MACH_DEFAULT__APM_H
+#ifndef _ASM_X86_MACH_DEFAULT_APM_H
+#define _ASM_X86_MACH_DEFAULT_APM_H
 
 #ifdef APM_ZERO_SEGS
 #      define APM_DO_ZERO_SEGS \
@@ -70,4 +70,4 @@ static inline u8 apm_bios_call_simple_asm(u32 func, u32 ebx_in,
        return error;
 }
 
-#endif /* ASM_X86__MACH_DEFAULT__APM_H */
+#endif /* _ASM_X86_MACH_DEFAULT_APM_H */
similarity index 94%
rename from include/asm-x86/mach-default/entry_arch.h
rename to arch/x86/include/asm/mach-default/entry_arch.h
index 9283b60a1dd2530a47f541e71296bd60d21fcfc1..6b1add8e31dde5a22e4e8f21c08eac11875c63c9 100644 (file)
@@ -14,6 +14,7 @@ BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR)
 BUILD_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR)
 BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR)
 BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR)
+BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR)
 #endif
 
 /*
similarity index 82%
rename from include/asm-x86/mach-default/mach_apic.h
rename to arch/x86/include/asm/mach-default/mach_apic.h
index 2a330a41b3dd703fcafc3d254e3aa3f664302c0d..ff3a6c236c00c940d3cbc94d0895399fd25828f8 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MACH_DEFAULT__MACH_APIC_H
-#define ASM_X86__MACH_DEFAULT__MACH_APIC_H
+#ifndef _ASM_X86_MACH_DEFAULT_MACH_APIC_H
+#define _ASM_X86_MACH_DEFAULT_MACH_APIC_H
 
 #ifdef CONFIG_X86_LOCAL_APIC
 
@@ -85,6 +85,20 @@ static inline int apicid_to_node(int logical_apicid)
        return 0;
 #endif
 }
+
+static inline cpumask_t vector_allocation_domain(int cpu)
+{
+        /* Careful. Some cpus do not strictly honor the set of cpus
+         * specified in the interrupt destination when using lowest
+         * priority interrupt delivery mode.
+         *
+         * In particular there was a hyperthreading cpu observed to
+         * deliver interrupts to the wrong hyperthread when only one
+         * hyperthread was specified in the interrupt desitination.
+         */
+        cpumask_t domain = { { [0] = APIC_ALL_CPUS, } };
+        return domain;
+}
 #endif
 
 static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
@@ -138,6 +152,5 @@ static inline int check_phys_apicid_present(int boot_cpu_physical_apicid)
 static inline void enable_apic_mode(void)
 {
 }
-
 #endif /* CONFIG_X86_LOCAL_APIC */
-#endif /* ASM_X86__MACH_DEFAULT__MACH_APIC_H */
+#endif /* _ASM_X86_MACH_DEFAULT_MACH_APIC_H */
similarity index 76%
rename from include/asm-x86/mach-default/mach_apicdef.h
rename to arch/x86/include/asm/mach-default/mach_apicdef.h
index 0c2d41c41b208fd0ac1762b414a13a354847448a..53179936d6c6daa890be686a58772e43860af11e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MACH_DEFAULT__MACH_APICDEF_H
-#define ASM_X86__MACH_DEFAULT__MACH_APICDEF_H
+#ifndef _ASM_X86_MACH_DEFAULT_MACH_APICDEF_H
+#define _ASM_X86_MACH_DEFAULT_MACH_APICDEF_H
 
 #include <asm/apic.h>
 
@@ -21,4 +21,4 @@ static inline unsigned get_apic_id(unsigned long x)
 #define                GET_APIC_ID(x)  get_apic_id(x)
 #endif
 
-#endif /* ASM_X86__MACH_DEFAULT__MACH_APICDEF_H */
+#endif /* _ASM_X86_MACH_DEFAULT_MACH_APICDEF_H */
similarity index 91%
rename from include/asm-x86/mach-default/mach_ipi.h
rename to arch/x86/include/asm/mach-default/mach_ipi.h
index 674bc7e50c356250348c5341a6aba2a9167920a1..fabca01ebacf29147f0174d00f220e7d64f8d32a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MACH_DEFAULT__MACH_IPI_H
-#define ASM_X86__MACH_DEFAULT__MACH_IPI_H
+#ifndef _ASM_X86_MACH_DEFAULT_MACH_IPI_H
+#define _ASM_X86_MACH_DEFAULT_MACH_IPI_H
 
 /* Avoid include hell */
 #define NMI_VECTOR 0x02
@@ -61,4 +61,4 @@ static inline void send_IPI_all(int vector)
 }
 #endif
 
-#endif /* ASM_X86__MACH_DEFAULT__MACH_IPI_H */
+#endif /* _ASM_X86_MACH_DEFAULT_MACH_IPI_H */
similarity index 62%
rename from include/asm-x86/mach-default/mach_mpparse.h
rename to arch/x86/include/asm/mach-default/mach_mpparse.h
index 9c381f2815acb9752359d1538e662ff2966bc50f..8c1ea21238a7e63b5414484744357547a102fc06 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MACH_DEFAULT__MACH_MPPARSE_H
-#define ASM_X86__MACH_DEFAULT__MACH_MPPARSE_H
+#ifndef _ASM_X86_MACH_DEFAULT_MACH_MPPARSE_H
+#define _ASM_X86_MACH_DEFAULT_MACH_MPPARSE_H
 
 static inline int mps_oem_check(struct mp_config_table *mpc, char *oem, 
                char *productid)
@@ -14,4 +14,4 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 }
 
 
-#endif /* ASM_X86__MACH_DEFAULT__MACH_MPPARSE_H */
+#endif /* _ASM_X86_MACH_DEFAULT_MACH_MPPARSE_H */
diff --git a/arch/x86/include/asm/mach-default/mach_mpspec.h b/arch/x86/include/asm/mach-default/mach_mpspec.h
new file mode 100644 (file)
index 0000000..e85ede6
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _ASM_X86_MACH_DEFAULT_MACH_MPSPEC_H
+#define _ASM_X86_MACH_DEFAULT_MACH_MPSPEC_H
+
+#define MAX_IRQ_SOURCES 256
+
+#if CONFIG_BASE_SMALL == 0
+#define MAX_MP_BUSSES 256
+#else
+#define MAX_MP_BUSSES 32
+#endif
+
+#endif /* _ASM_X86_MACH_DEFAULT_MACH_MPSPEC_H */
similarity index 91%
rename from include/asm-x86/mach-default/mach_timer.h
rename to arch/x86/include/asm/mach-default/mach_timer.h
index 990b15833834bf861ceef35d810d4adaa899a84d..853728519ae9b928bf113ead296d50c04388a737 100644 (file)
@@ -10,8 +10,8 @@
  * directly because of the awkward 8-bit access mechanism of the 82C54
  * device.
  */
-#ifndef ASM_X86__MACH_DEFAULT__MACH_TIMER_H
-#define ASM_X86__MACH_DEFAULT__MACH_TIMER_H
+#ifndef _ASM_X86_MACH_DEFAULT_MACH_TIMER_H
+#define _ASM_X86_MACH_DEFAULT_MACH_TIMER_H
 
 #define CALIBRATE_TIME_MSEC 30 /* 30 msecs */
 #define CALIBRATE_LATCH        \
@@ -45,4 +45,4 @@ static inline void mach_countup(unsigned long *count_p)
        *count_p = count;
 }
 
-#endif /* ASM_X86__MACH_DEFAULT__MACH_TIMER_H */
+#endif /* _ASM_X86_MACH_DEFAULT_MACH_TIMER_H */
similarity index 80%
rename from include/asm-x86/mach-default/mach_traps.h
rename to arch/x86/include/asm/mach-default/mach_traps.h
index ff8778f26b84e3a9125b4a4f383b69ab649c5b20..f7920601e4724487d33db72fae34f4240ef690ac 100644 (file)
@@ -2,8 +2,8 @@
  *  Machine specific NMI handling for generic.
  *  Split out from traps.c by Osamu Tomita <tomita@cinet.co.jp>
  */
-#ifndef ASM_X86__MACH_DEFAULT__MACH_TRAPS_H
-#define ASM_X86__MACH_DEFAULT__MACH_TRAPS_H
+#ifndef _ASM_X86_MACH_DEFAULT_MACH_TRAPS_H
+#define _ASM_X86_MACH_DEFAULT_MACH_TRAPS_H
 
 #include <asm/mc146818rtc.h>
 
@@ -30,4 +30,4 @@ static inline void reassert_nmi(void)
                unlock_cmos();
 }
 
-#endif /* ASM_X86__MACH_DEFAULT__MACH_TRAPS_H */
+#endif /* _ASM_X86_MACH_DEFAULT_MACH_TRAPS_H */
similarity index 85%
rename from include/asm-x86/mach-default/mach_wakecpu.h
rename to arch/x86/include/asm/mach-default/mach_wakecpu.h
index 361b810f5160a2e5a02e8ea66c365a9dc0abd0f1..d5c0b826a4ff2c742d887520a1585876bc5d26f1 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MACH_DEFAULT__MACH_WAKECPU_H
-#define ASM_X86__MACH_DEFAULT__MACH_WAKECPU_H
+#ifndef _ASM_X86_MACH_DEFAULT_MACH_WAKECPU_H
+#define _ASM_X86_MACH_DEFAULT_MACH_WAKECPU_H
 
 /* 
  * This file copes with machines that wakeup secondary CPUs by the
@@ -39,4 +39,4 @@ static inline void restore_NMI_vector(unsigned short *high, unsigned short *low)
  #define inquire_remote_apic(apicid) {}
 #endif
 
-#endif /* ASM_X86__MACH_DEFAULT__MACH_WAKECPU_H */
+#endif /* _ASM_X86_MACH_DEFAULT_MACH_WAKECPU_H */
similarity index 76%
rename from include/asm-x86/mach-generic/gpio.h
rename to arch/x86/include/asm/mach-generic/gpio.h
index 6ce0f7786ef8bebfe8ef51414de7553c908a6fd7..995c45efdb33edb699eaea81c2bb350e2c7343b1 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MACH_GENERIC__GPIO_H
-#define ASM_X86__MACH_GENERIC__GPIO_H
+#ifndef _ASM_X86_MACH_GENERIC_GPIO_H
+#define _ASM_X86_MACH_GENERIC_GPIO_H
 
 int gpio_request(unsigned gpio, const char *label);
 void gpio_free(unsigned gpio);
@@ -12,4 +12,4 @@ int irq_to_gpio(unsigned irq);
 
 #include <asm-generic/gpio.h>           /* cansleep wrappers */
 
-#endif /* ASM_X86__MACH_GENERIC__GPIO_H */
+#endif /* _ASM_X86_MACH_GENERIC_GPIO_H */
similarity index 86%
rename from include/asm-x86/mach-generic/mach_apic.h
rename to arch/x86/include/asm/mach-generic/mach_apic.h
index 5d010c6881dddc51bb9ad2a59503c79ad2837b14..5180bd7478fbc3d2cfc533f22e707a8099201e23 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MACH_GENERIC__MACH_APIC_H
-#define ASM_X86__MACH_GENERIC__MACH_APIC_H
+#ifndef _ASM_X86_MACH_GENERIC_MACH_APIC_H
+#define _ASM_X86_MACH_GENERIC_MACH_APIC_H
 
 #include <asm/genapic.h>
 
 #define check_phys_apicid_present (genapic->check_phys_apicid_present)
 #define check_apicid_used (genapic->check_apicid_used)
 #define cpu_mask_to_apicid (genapic->cpu_mask_to_apicid)
+#define vector_allocation_domain (genapic->vector_allocation_domain)
 #define enable_apic_mode (genapic->enable_apic_mode)
 #define phys_pkg_id (genapic->phys_pkg_id)
 
 extern void generic_bigsmp_probe(void);
 
-#endif /* ASM_X86__MACH_GENERIC__MACH_APIC_H */
+#endif /* _ASM_X86_MACH_GENERIC_MACH_APIC_H */
similarity index 50%
rename from include/asm-x86/mach-generic/mach_apicdef.h
rename to arch/x86/include/asm/mach-generic/mach_apicdef.h
index 1657f38b8f27e184bb930a24eb3b992eaf548bbb..68041f3802f4a8eec4e2e045c0500de1aa09d7ea 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MACH_GENERIC__MACH_APICDEF_H
-#define ASM_X86__MACH_GENERIC__MACH_APICDEF_H
+#ifndef _ASM_X86_MACH_GENERIC_MACH_APICDEF_H
+#define _ASM_X86_MACH_GENERIC_MACH_APICDEF_H
 
 #ifndef APIC_DEFINITION
 #include <asm/genapic.h>
@@ -8,4 +8,4 @@
 #define APIC_ID_MASK (genapic->apic_id_mask)
 #endif
 
-#endif /* ASM_X86__MACH_GENERIC__MACH_APICDEF_H */
+#endif /* _ASM_X86_MACH_GENERIC_MACH_APICDEF_H */
similarity index 57%
rename from include/asm-x86/mach-generic/mach_ipi.h
rename to arch/x86/include/asm/mach-generic/mach_ipi.h
index f67433dbd65f9f85b549ee4e34efdf68385725f3..ffd637e3c3d9e2fa190813cdab55bbacfe253257 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MACH_GENERIC__MACH_IPI_H
-#define ASM_X86__MACH_GENERIC__MACH_IPI_H
+#ifndef _ASM_X86_MACH_GENERIC_MACH_IPI_H
+#define _ASM_X86_MACH_GENERIC_MACH_IPI_H
 
 #include <asm/genapic.h>
 
@@ -7,4 +7,4 @@
 #define send_IPI_allbutself (genapic->send_IPI_allbutself)
 #define send_IPI_all (genapic->send_IPI_all)
 
-#endif /* ASM_X86__MACH_GENERIC__MACH_IPI_H */
+#endif /* _ASM_X86_MACH_GENERIC_MACH_IPI_H */
similarity index 52%
rename from include/asm-x86/mach-generic/mach_mpparse.h
rename to arch/x86/include/asm/mach-generic/mach_mpparse.h
index 3115564e557cfd6d6b25f6ea02bb585d17121e43..048f1d468535c9f370e7da8df7781ba2d62e5058 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MACH_GENERIC__MACH_MPPARSE_H
-#define ASM_X86__MACH_GENERIC__MACH_MPPARSE_H
+#ifndef _ASM_X86_MACH_GENERIC_MACH_MPPARSE_H
+#define _ASM_X86_MACH_GENERIC_MACH_MPPARSE_H
 
 
 extern int mps_oem_check(struct mp_config_table *mpc, char *oem,
@@ -7,4 +7,4 @@ extern int mps_oem_check(struct mp_config_table *mpc, char *oem,
 
 extern int acpi_madt_oem_check(char *oem_id, char *oem_table_id);
 
-#endif /* ASM_X86__MACH_GENERIC__MACH_MPPARSE_H */
+#endif /* _ASM_X86_MACH_GENERIC_MACH_MPPARSE_H */
similarity index 67%
rename from include/asm-x86/mach-generic/mach_mpspec.h
rename to arch/x86/include/asm/mach-generic/mach_mpspec.h
index 6061b153613e32ec75d0cf983091aa13dbea31d5..bbab5ccfd4fe44ef268125efb180c21ad0869ac3 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MACH_GENERIC__MACH_MPSPEC_H
-#define ASM_X86__MACH_GENERIC__MACH_MPSPEC_H
+#ifndef _ASM_X86_MACH_GENERIC_MACH_MPSPEC_H
+#define _ASM_X86_MACH_GENERIC_MACH_MPSPEC_H
 
 #define MAX_IRQ_SOURCES 256
 
@@ -9,4 +9,4 @@
 
 extern void numaq_mps_oem_check(struct mp_config_table *mpc, char *oem,
                                char *productid);
-#endif /* ASM_X86__MACH_GENERIC__MACH_MPSPEC_H */
+#endif /* _ASM_X86_MACH_GENERIC_MACH_MPSPEC_H */
similarity index 91%
rename from include/asm-x86/mach-rdc321x/gpio.h
rename to arch/x86/include/asm/mach-rdc321x/gpio.h
index 94b6cdf532e207f210fffa131dfd34e2fa82e414..c210ab5788b0750d7f0c1db511dfc6273425b3b0 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MACH_RDC321X__GPIO_H
-#define ASM_X86__MACH_RDC321X__GPIO_H
+#ifndef _ASM_X86_MACH_RDC321X_GPIO_H
+#define _ASM_X86_MACH_RDC321X_GPIO_H
 
 #include <linux/kernel.h>
 
@@ -57,4 +57,4 @@ static inline int irq_to_gpio(unsigned irq)
 /* For cansleep */
 #include <asm-generic/gpio.h>
 
-#endif /* ASM_X86__MACH_RDC321X__GPIO_H */
+#endif /* _ASM_X86_MACH_RDC321X_GPIO_H */
similarity index 86%
rename from include/asm-x86/math_emu.h
rename to arch/x86/include/asm/math_emu.h
index 5768d8e95c8c2b671ffb93383d13dd842a696208..5a65b107ad58350b4eb76bf6aaa4e639d2404b62 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MATH_EMU_H
-#define ASM_X86__MATH_EMU_H
+#ifndef _ASM_X86_MATH_EMU_H
+#define _ASM_X86_MATH_EMU_H
 
 /* This structure matches the layout of the data saved to the stack
    following a device-not-present interrupt, part of it saved
@@ -28,4 +28,4 @@ struct info {
        long ___vm86_fs;
        long ___vm86_gs;
 };
-#endif /* ASM_X86__MATH_EMU_H */
+#endif /* _ASM_X86_MATH_EMU_H */
similarity index 96%
rename from include/asm-x86/mc146818rtc.h
rename to arch/x86/include/asm/mc146818rtc.h
index a995f33176cd026f60f21c18008811f9a5a996a4..01fdf5674e24da868a04c717a7792be302717483 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Machine dependent access functions for RTC registers.
  */
-#ifndef ASM_X86__MC146818RTC_H
-#define ASM_X86__MC146818RTC_H
+#ifndef _ASM_X86_MC146818RTC_H
+#define _ASM_X86_MC146818RTC_H
 
 #include <asm/io.h>
 #include <asm/system.h>
@@ -101,4 +101,4 @@ extern unsigned long mach_get_cmos_time(void);
 
 #define RTC_IRQ 8
 
-#endif /* ASM_X86__MC146818RTC_H */
+#endif /* _ASM_X86_MC146818RTC_H */
similarity index 94%
rename from include/asm-x86/mca.h
rename to arch/x86/include/asm/mca.h
index 60d1ed287b1301c2907e910ab4c7c0e182df87bd..eedbb6cc1efb0cf86b72f78f827b9c717e77ccbc 100644 (file)
@@ -1,8 +1,8 @@
 /* -*- mode: c; c-basic-offset: 8 -*- */
 
 /* Platform specific MCA defines */
-#ifndef ASM_X86__MCA_H
-#define ASM_X86__MCA_H
+#ifndef _ASM_X86_MCA_H
+#define _ASM_X86_MCA_H
 
 /* Maximal number of MCA slots - actually, some machines have less, but
  * they all have sufficient number of POS registers to cover 8.
@@ -40,4 +40,4 @@
  */
 #define MCA_NUMADAPTERS (MCA_MAX_SLOT_NR+3)
 
-#endif /* ASM_X86__MCA_H */
+#endif /* _ASM_X86_MCA_H */
similarity index 98%
rename from include/asm-x86/mca_dma.h
rename to arch/x86/include/asm/mca_dma.h
index 49f22be237d29c0e76e520d33b1fdb654f8a3d5d..45271aef82ddd4ef606ea223ca78e212e7d87419 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MCA_DMA_H
-#define ASM_X86__MCA_DMA_H
+#ifndef _ASM_X86_MCA_DMA_H
+#define _ASM_X86_MCA_DMA_H
 
 #include <asm/io.h>
 #include <linux/ioport.h>
@@ -198,4 +198,4 @@ static inline void mca_set_dma_mode(unsigned int dmanr, unsigned int mode)
        outb(mode, MCA_DMA_REG_EXE);
 }
 
-#endif /* ASM_X86__MCA_DMA_H */
+#endif /* _ASM_X86_MCA_DMA_H */
similarity index 97%
rename from include/asm-x86/mce.h
rename to arch/x86/include/asm/mce.h
index 036133eaf7448e4625a713bab4b9ff3f53e98bb2..1d6e17c2f23a3be2ffffebf7f1df19c1786e9dd6 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MCE_H
-#define ASM_X86__MCE_H
+#ifndef _ASM_X86_MCE_H
+#define _ASM_X86_MCE_H
 
 #ifdef __x86_64__
 
@@ -127,4 +127,4 @@ extern void restart_mce(void);
 
 #endif /* __KERNEL__ */
 
-#endif /* ASM_X86__MCE_H */
+#endif /* _ASM_X86_MCE_H */
similarity index 91%
rename from include/asm-x86/microcode.h
rename to arch/x86/include/asm/microcode.h
index 62c793bb70cacf0fd7abd4d1d96057b6a5d77ed6..c882664716c1d13e5678aa188fb0ccf75d50acca 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MICROCODE_H
-#define ASM_X86__MICROCODE_H
+#ifndef _ASM_X86_MICROCODE_H
+#define _ASM_X86_MICROCODE_H
 
 struct cpu_signature {
        unsigned int sig;
@@ -44,4 +44,4 @@ static inline struct microcode_ops * __init init_amd_microcode(void)
 }
 #endif
 
-#endif /* ASM_X86__MICROCODE_H */
+#endif /* _ASM_X86_MICROCODE_H */
similarity index 90%
rename from include/asm-x86/mman.h
rename to arch/x86/include/asm/mman.h
index 4ef28e6de3837e38db2bd98a2af0116c67dd464b..90bc4108a4fdf917fc243502bd7fcf833f482a55 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MMAN_H
-#define ASM_X86__MMAN_H
+#ifndef _ASM_X86_MMAN_H
+#define _ASM_X86_MMAN_H
 
 #include <asm-generic/mman.h>
 
@@ -17,4 +17,4 @@
 #define MCL_CURRENT    1               /* lock all current mappings */
 #define MCL_FUTURE     2               /* lock all future mappings */
 
-#endif /* ASM_X86__MMAN_H */
+#endif /* _ASM_X86_MMAN_H */
similarity index 74%
rename from include/asm-x86/mmconfig.h
rename to arch/x86/include/asm/mmconfig.h
index fb79b1cf5d07bdcd24360a776a10cdca2d213274..9b119da1d105f18c4bb0e6cad2380a7b110d04c9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MMCONFIG_H
-#define ASM_X86__MMCONFIG_H
+#ifndef _ASM_X86_MMCONFIG_H
+#define _ASM_X86_MMCONFIG_H
 
 #ifdef CONFIG_PCI_MMCONFIG
 extern void __cpuinit fam10h_check_enable_mmcfg(void);
@@ -9,4 +9,4 @@ static inline void fam10h_check_enable_mmcfg(void) { }
 static inline void check_enable_amd_mmconf_dmi(void) { }
 #endif
 
-#endif /* ASM_X86__MMCONFIG_H */
+#endif /* _ASM_X86_MMCONFIG_H */
similarity index 81%
rename from include/asm-x86/mmu.h
rename to arch/x86/include/asm/mmu.h
index 9d5aff14334a9214401d064c0bc54952e72da9c7..80a1dee5bea5ec67bb77adf6db286f471d8006e8 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MMU_H
-#define ASM_X86__MMU_H
+#ifndef _ASM_X86_MMU_H
+#define _ASM_X86_MMU_H
 
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
@@ -23,4 +23,4 @@ static inline void leave_mm(int cpu)
 }
 #endif
 
-#endif /* ASM_X86__MMU_H */
+#endif /* _ASM_X86_MMU_H */
similarity index 87%
rename from include/asm-x86/mmu_context.h
rename to arch/x86/include/asm/mmu_context.h
index 8ec940bfd07902b858a9c31c00292fa429132653..8aeeb3fd73db8a90369b60adb747719cdeb8f58d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MMU_CONTEXT_H
-#define ASM_X86__MMU_CONTEXT_H
+#ifndef _ASM_X86_MMU_CONTEXT_H
+#define _ASM_X86_MMU_CONTEXT_H
 
 #include <asm/desc.h>
 #include <asm/atomic.h>
@@ -34,4 +34,4 @@ do {                                          \
 } while (0);
 
 
-#endif /* ASM_X86__MMU_CONTEXT_H */
+#endif /* _ASM_X86_MMU_CONTEXT_H */
similarity index 92%
rename from include/asm-x86/mmu_context_32.h
rename to arch/x86/include/asm/mmu_context_32.h
index cce6f6e4afd6dbc6c4c876fe505da7e828647384..8e10015781fb2d6794aa0cfabae334956b365c88 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MMU_CONTEXT_32_H
-#define ASM_X86__MMU_CONTEXT_32_H
+#ifndef _ASM_X86_MMU_CONTEXT_32_H
+#define _ASM_X86_MMU_CONTEXT_32_H
 
 static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
 {
@@ -53,4 +53,4 @@ static inline void switch_mm(struct mm_struct *prev,
 #define deactivate_mm(tsk, mm)                 \
        asm("movl %0,%%gs": :"r" (0));
 
-#endif /* ASM_X86__MMU_CONTEXT_32_H */
+#endif /* _ASM_X86_MMU_CONTEXT_32_H */
similarity index 92%
rename from include/asm-x86/mmu_context_64.h
rename to arch/x86/include/asm/mmu_context_64.h
index 26758673c828b15068ea138a9527699ec7ae03d5..677d36e9540ada7bc84f541f1b96b3a03095f173 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MMU_CONTEXT_64_H
-#define ASM_X86__MMU_CONTEXT_64_H
+#ifndef _ASM_X86_MMU_CONTEXT_64_H
+#define _ASM_X86_MMU_CONTEXT_64_H
 
 #include <asm/pda.h>
 
@@ -51,4 +51,4 @@ do {                                          \
        asm volatile("movl %0,%%fs"::"r"(0));   \
 } while (0)
 
-#endif /* ASM_X86__MMU_CONTEXT_64_H */
+#endif /* _ASM_X86_MMU_CONTEXT_64_H */
similarity index 75%
rename from include/asm-x86/mmx.h
rename to arch/x86/include/asm/mmx.h
index 2e7299bb3653639a00819fd72cea430c71d0b970..5cbf3135b9714cf444e51923d80ce03c6ca6910f 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MMX_H
-#define ASM_X86__MMX_H
+#ifndef _ASM_X86_MMX_H
+#define _ASM_X86_MMX_H
 
 /*
  *     MMX 3Dnow! helper operations
@@ -11,4 +11,4 @@ extern void *_mmx_memcpy(void *to, const void *from, size_t size);
 extern void mmx_clear_page(void *page);
 extern void mmx_copy_page(void *to, void *from);
 
-#endif /* ASM_X86__MMX_H */
+#endif /* _ASM_X86_MMX_H */
similarity index 97%
rename from include/asm-x86/mmzone_32.h
rename to arch/x86/include/asm/mmzone_32.h
index 121b65d61d868ca09a4a2c81d61a2c36154fbc52..485bdf059ffbeacb5703b71b5ef3b9ad1f35ad7c 100644 (file)
@@ -3,8 +3,8 @@
  *
  */
 
-#ifndef ASM_X86__MMZONE_32_H
-#define ASM_X86__MMZONE_32_H
+#ifndef _ASM_X86_MMZONE_32_H
+#define _ASM_X86_MMZONE_32_H
 
 #include <asm/smp.h>
 
@@ -131,4 +131,4 @@ static inline int pfn_valid(int pfn)
 })
 #endif /* CONFIG_NEED_MULTIPLE_NODES */
 
-#endif /* ASM_X86__MMZONE_32_H */
+#endif /* _ASM_X86_MMZONE_32_H */
similarity index 93%
rename from include/asm-x86/mmzone_64.h
rename to arch/x86/include/asm/mmzone_64.h
index 6480f3333b2a4edebecd7d76507dbd819c3da596..a5b3817d4b9e621e2615ddd16435b83011206548 100644 (file)
@@ -1,8 +1,8 @@
 /* K8 NUMA support */
 /* Copyright 2002,2003 by Andi Kleen, SuSE Labs */
 /* 2.5 Version loosely based on the NUMAQ Code by Pat Gaughen. */
-#ifndef ASM_X86__MMZONE_64_H
-#define ASM_X86__MMZONE_64_H
+#ifndef _ASM_X86_MMZONE_64_H
+#define _ASM_X86_MMZONE_64_H
 
 
 #ifdef CONFIG_NUMA
@@ -48,4 +48,4 @@ extern int early_pfn_to_nid(unsigned long pfn);
 #endif
 
 #endif
-#endif /* ASM_X86__MMZONE_64_H */
+#endif /* _ASM_X86_MMZONE_64_H */
similarity index 96%
rename from include/asm-x86/module.h
rename to arch/x86/include/asm/module.h
index 864f2005fc1d323f27bc853608ce74eefd32698e..47d62743c4d595b6ad88a058b4303666f226ce7d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MODULE_H
-#define ASM_X86__MODULE_H
+#ifndef _ASM_X86_MODULE_H
+#define _ASM_X86_MODULE_H
 
 /* x86_32/64 are simple */
 struct mod_arch_specific {};
@@ -77,4 +77,4 @@ struct mod_arch_specific {};
 # define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
 #endif
 
-#endif /* ASM_X86__MODULE_H */
+#endif /* _ASM_X86_MODULE_H */
similarity index 97%
rename from include/asm-x86/mpspec.h
rename to arch/x86/include/asm/mpspec.h
index be2241a818f1e536eda377b4ceb94d04ae2b171c..91885c28f66b3ae909b402886682202b5280b6a1 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MPSPEC_H
-#define ASM_X86__MPSPEC_H
+#ifndef _ASM_X86_MPSPEC_H
+#define _ASM_X86_MPSPEC_H
 
 #include <linux/init.h>
 
@@ -142,4 +142,4 @@ static inline void physid_set_mask_of_physid(int physid, physid_mask_t *map)
 
 extern physid_mask_t phys_cpu_present_map;
 
-#endif /* ASM_X86__MPSPEC_H */
+#endif /* _ASM_X86_MPSPEC_H */
similarity index 97%
rename from include/asm-x86/mpspec_def.h
rename to arch/x86/include/asm/mpspec_def.h
index 79166b04801231cf5d6526759113b071719a6226..e3ace7d1d35d83615b6961295276a9b92fc1a02a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MPSPEC_DEF_H
-#define ASM_X86__MPSPEC_DEF_H
+#ifndef _ASM_X86_MPSPEC_DEF_H
+#define _ASM_X86_MPSPEC_DEF_H
 
 /*
  * Structure definitions for SMP machines following the
@@ -177,4 +177,4 @@ enum mp_bustype {
        MP_BUS_PCI,
        MP_BUS_MCA,
 };
-#endif /* ASM_X86__MPSPEC_DEF_H */
+#endif /* _ASM_X86_MPSPEC_DEF_H */
similarity index 92%
rename from include/asm-x86/msgbuf.h
rename to arch/x86/include/asm/msgbuf.h
index 1b538c907a3de50b0fee5d87de36238560a9fce4..7e4e9481f51cff18dda6f96cfcadb5c9d9535eb9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MSGBUF_H
-#define ASM_X86__MSGBUF_H
+#ifndef _ASM_X86_MSGBUF_H
+#define _ASM_X86_MSGBUF_H
 
 /*
  * The msqid64_ds structure for i386 architecture.
@@ -36,4 +36,4 @@ struct msqid64_ds {
        unsigned long  __unused5;
 };
 
-#endif /* ASM_X86__MSGBUF_H */
+#endif /* _ASM_X86_MSGBUF_H */
similarity index 95%
rename from include/asm-x86/msidef.h
rename to arch/x86/include/asm/msidef.h
index ed91902468769a9efd074b20d529b47d046a25b6..6706b3006f13296ee02c5a4455268a967ca1c5f3 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MSIDEF_H
-#define ASM_X86__MSIDEF_H
+#ifndef _ASM_X86_MSIDEF_H
+#define _ASM_X86_MSIDEF_H
 
 /*
  * Constants for Intel APIC based MSI messages.
@@ -52,4 +52,4 @@
 #define MSI_ADDR_IR_SHV                        (1 << 3)
 #define MSI_ADDR_IR_INDEX1(index)      ((index & 0x8000) >> 13)
 #define MSI_ADDR_IR_INDEX2(index)      ((index & 0x7fff) << 5)
-#endif /* ASM_X86__MSIDEF_H */
+#endif /* _ASM_X86_MSIDEF_H */
similarity index 99%
rename from include/asm-x86/msr-index.h
rename to arch/x86/include/asm/msr-index.h
index dabd10f0bbee25359a54d7104344813371b742ab..e38859d577a117e1cc1ae2cf75e278c595cfb369 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MSR_INDEX_H
-#define ASM_X86__MSR_INDEX_H
+#ifndef _ASM_X86_MSR_INDEX_H
+#define _ASM_X86_MSR_INDEX_H
 
 /* CPU model specific register (MSR) numbers */
 
 #define MSR_IA32_VMX_PROCBASED_CTLS2    0x0000048b
 #define MSR_IA32_VMX_EPT_VPID_CAP       0x0000048c
 
-#endif /* ASM_X86__MSR_INDEX_H */
+#endif /* _ASM_X86_MSR_INDEX_H */
similarity index 98%
rename from include/asm-x86/msr.h
rename to arch/x86/include/asm/msr.h
index 530af1f6389e4b1f17ed1d6002cd0b617665f50b..46be2fa7ac266c513bfd3221b7f0d861e748238d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__MSR_H
-#define ASM_X86__MSR_H
+#ifndef _ASM_X86_MSR_H
+#define _ASM_X86_MSR_H
 
 #include <asm/msr-index.h>
 
@@ -244,4 +244,4 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
 #endif /* __KERNEL__ */
 
 
-#endif /* ASM_X86__MSR_H */
+#endif /* _ASM_X86_MSR_H */
similarity index 98%
rename from include/asm-x86/mtrr.h
rename to arch/x86/include/asm/mtrr.h
index 23a7f83da953e7dee776dd7abb001a0dd5ce1374..7c1e4258b31e208ce6edd67f94ef7e202044f920 100644 (file)
@@ -20,8 +20,8 @@
     The postal address is:
       Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
 */
-#ifndef ASM_X86__MTRR_H
-#define ASM_X86__MTRR_H
+#ifndef _ASM_X86_MTRR_H
+#define _ASM_X86_MTRR_H
 
 #include <linux/ioctl.h>
 #include <linux/errno.h>
@@ -170,4 +170,4 @@ struct mtrr_gentry32 {
 
 #endif /* __KERNEL__ */
 
-#endif /* ASM_X86__MTRR_H */
+#endif /* _ASM_X86_MTRR_H */
similarity index 97%
rename from include/asm-x86/mutex_32.h
rename to arch/x86/include/asm/mutex_32.h
index 25c16d8ba3c753995394e204258583a27eebbdf4..03f90c8a5a7c392b7f50ea0914cba04b0718fa76 100644 (file)
@@ -6,8 +6,8 @@
  *
  *  Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
  */
-#ifndef ASM_X86__MUTEX_32_H
-#define ASM_X86__MUTEX_32_H
+#ifndef _ASM_X86_MUTEX_32_H
+#define _ASM_X86_MUTEX_32_H
 
 #include <asm/alternative.h>
 
@@ -122,4 +122,4 @@ static inline int __mutex_fastpath_trylock(atomic_t *count,
 #endif
 }
 
-#endif /* ASM_X86__MUTEX_32_H */
+#endif /* _ASM_X86_MUTEX_32_H */
similarity index 96%
rename from include/asm-x86/mutex_64.h
rename to arch/x86/include/asm/mutex_64.h
index 918ba21ab9d9c5ec2c842e0479961694f379e2cd..68a87b0f8e29e491e4b71c3c9eb68d78efb6db3c 100644 (file)
@@ -6,8 +6,8 @@
  *
  *  Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
  */
-#ifndef ASM_X86__MUTEX_64_H
-#define ASM_X86__MUTEX_64_H
+#ifndef _ASM_X86_MUTEX_64_H
+#define _ASM_X86_MUTEX_64_H
 
 /**
  * __mutex_fastpath_lock - decrement and call function if negative
@@ -97,4 +97,4 @@ static inline int __mutex_fastpath_trylock(atomic_t *count,
                return 0;
 }
 
-#endif /* ASM_X86__MUTEX_64_H */
+#endif /* _ASM_X86_MUTEX_64_H */
similarity index 96%
rename from include/asm-x86/nmi.h
rename to arch/x86/include/asm/nmi.h
index a53f829a97c581c7b4a0d3cd77e4a0ea2cdf4ae3..c45a0a568dff092227b1436a48e7dab5434dc4fa 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__NMI_H
-#define ASM_X86__NMI_H
+#ifndef _ASM_X86_NMI_H
+#define _ASM_X86_NMI_H
 
 #include <linux/pm.h>
 #include <asm/irq.h>
@@ -78,4 +78,4 @@ void enable_lapic_nmi_watchdog(void);
 void stop_nmi(void);
 void restart_nmi(void);
 
-#endif /* ASM_X86__NMI_H */
+#endif /* _ASM_X86_NMI_H */
similarity index 97%
rename from include/asm-x86/nops.h
rename to arch/x86/include/asm/nops.h
index ae742721ae73e01cdfeb9ab4e1bc72310f5ec729..ad2668ee1aa7af8cc6fa62fdede3e58b08966ab1 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__NOPS_H
-#define ASM_X86__NOPS_H
+#ifndef _ASM_X86_NOPS_H
+#define _ASM_X86_NOPS_H
 
 /* Define nops for use with alternative() */
 
 
 #define ASM_NOP_MAX 8
 
-#endif /* ASM_X86__NOPS_H */
+#endif /* _ASM_X86_NOPS_H */
similarity index 62%
rename from include/asm-x86/numa_32.h
rename to arch/x86/include/asm/numa_32.h
index 44cb07855c5bcfd8ab4db962c3871316f5b9027c..e9f5db796244b200249802673bc30022b8d8cc94 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__NUMA_32_H
-#define ASM_X86__NUMA_32_H
+#ifndef _ASM_X86_NUMA_32_H
+#define _ASM_X86_NUMA_32_H
 
 extern int pxm_to_nid(int pxm);
 extern void numa_remove_cpu(int cpu);
@@ -8,4 +8,4 @@ extern void numa_remove_cpu(int cpu);
 extern void set_highmem_pages_init(void);
 #endif
 
-#endif /* ASM_X86__NUMA_32_H */
+#endif /* _ASM_X86_NUMA_32_H */
similarity index 92%
rename from include/asm-x86/numa_64.h
rename to arch/x86/include/asm/numa_64.h
index 15c990395b021b65c766b1321ea8801e4311f9f4..064ed6df4cbec292758631a4a5a36aa3b77260c0 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__NUMA_64_H
-#define ASM_X86__NUMA_64_H
+#ifndef _ASM_X86_NUMA_64_H
+#define _ASM_X86_NUMA_64_H
 
 #include <linux/nodemask.h>
 #include <asm/apicdef.h>
@@ -40,4 +40,4 @@ static inline void numa_add_cpu(int cpu, int node)    { }
 static inline void numa_remove_cpu(int cpu)            { }
 #endif
 
-#endif /* ASM_X86__NUMA_64_H */
+#endif /* _ASM_X86_NUMA_64_H */
similarity index 98%
rename from include/asm-x86/numaq.h
rename to arch/x86/include/asm/numaq.h
index 124bf7d4b70a86d483fc25409e0a6105a3acca52..1e8bd30b4c161137a68fcd242866169ce1048c62 100644 (file)
@@ -23,8 +23,8 @@
  * Send feedback to <gone@us.ibm.com>
  */
 
-#ifndef ASM_X86__NUMAQ_H
-#define ASM_X86__NUMAQ_H
+#ifndef _ASM_X86_NUMAQ_H
+#define _ASM_X86_NUMAQ_H
 
 #ifdef CONFIG_X86_NUMAQ
 
@@ -165,5 +165,5 @@ static inline int get_memcfg_numaq(void)
        return 0;
 }
 #endif /* CONFIG_X86_NUMAQ */
-#endif /* ASM_X86__NUMAQ_H */
+#endif /* _ASM_X86_NUMAQ_H */
 
similarity index 98%
rename from include/asm-x86/numaq/apic.h
rename to arch/x86/include/asm/numaq/apic.h
index a8344ba6ea15064cd4898423c9b3fcd8183b25e1..0bf2a06b7a4e66a33629cc930f6d59c9c9907c92 100644 (file)
@@ -12,8 +12,6 @@ static inline cpumask_t target_cpus(void)
        return CPU_MASK_ALL;
 }
 
-#define TARGET_CPUS (target_cpus())
-
 #define NO_BALANCE_IRQ (1)
 #define esr_disable (1)
 
similarity index 97%
rename from include/asm-x86/olpc.h
rename to arch/x86/include/asm/olpc.h
index d7328b1a05c1791dc9475a573a1574c65717ccd6..834a30295fabbb75740826a39c76e7bfbbe2fe37 100644 (file)
@@ -1,7 +1,7 @@
 /* OLPC machine specific definitions */
 
-#ifndef ASM_X86__OLPC_H
-#define ASM_X86__OLPC_H
+#ifndef _ASM_X86_OLPC_H
+#define _ASM_X86_OLPC_H
 
 #include <asm/geode.h>
 
@@ -129,4 +129,4 @@ extern int olpc_ec_mask_unset(uint8_t bits);
 #define OLPC_GPIO_LID          geode_gpio(26)
 #define OLPC_GPIO_ECSCI                geode_gpio(27)
 
-#endif /* ASM_X86__OLPC_H */
+#endif /* _ASM_X86_OLPC_H */
similarity index 98%
rename from include/asm-x86/page.h
rename to arch/x86/include/asm/page.h
index d4f1d5791fc186f29a9a60d4fe182d80f05038e4..e9873a2e86951d10c7a5576e3b908956d0e3e6f8 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PAGE_H
-#define ASM_X86__PAGE_H
+#ifndef _ASM_X86_PAGE_H
+#define _ASM_X86_PAGE_H
 
 #include <linux/const.h>
 
@@ -206,4 +206,4 @@ extern bool __virt_addr_valid(unsigned long kaddr);
 #define __HAVE_ARCH_GATE_AREA 1
 
 #endif /* __KERNEL__ */
-#endif /* ASM_X86__PAGE_H */
+#endif /* _ASM_X86_PAGE_H */
similarity index 97%
rename from include/asm-x86/page_32.h
rename to arch/x86/include/asm/page_32.h
index bdf5dba4cfb0a85d0d8aee9c4a557b6c1d4f4a15..bcde0d7b432547be4068715919cc58e2ebfd8af9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PAGE_32_H
-#define ASM_X86__PAGE_32_H
+#ifndef _ASM_X86_PAGE_32_H
+#define _ASM_X86_PAGE_32_H
 
 /*
  * This handles the memory map.
@@ -133,4 +133,4 @@ static inline void copy_page(void *to, void *from)
 #endif /* CONFIG_X86_3DNOW */
 #endif /* !__ASSEMBLY__ */
 
-#endif /* ASM_X86__PAGE_32_H */
+#endif /* _ASM_X86_PAGE_32_H */
similarity index 97%
rename from include/asm-x86/page_64.h
rename to arch/x86/include/asm/page_64.h
index 49380b8c7e25fbafa26243860abe03d105b7a97a..5ebca29f44f0d77890b4395d11313b589e386b9c 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PAGE_64_H
-#define ASM_X86__PAGE_64_H
+#ifndef _ASM_X86_PAGE_64_H
+#define _ASM_X86_PAGE_64_H
 
 #define PAGETABLE_LEVELS       4
 
@@ -102,4 +102,4 @@ extern void init_extra_mapping_wb(unsigned long phys, unsigned long size);
 #endif
 
 
-#endif /* ASM_X86__PAGE_64_H */
+#endif /* _ASM_X86_PAGE_64_H */
similarity index 82%
rename from include/asm-x86/param.h
rename to arch/x86/include/asm/param.h
index 0009cfb11a5f53bbba0c697a6695cb6bddfefa7d..6f0d0422f4ca0ffdcb07df874789dc565f3ac82f 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PARAM_H
-#define ASM_X86__PARAM_H
+#ifndef _ASM_X86_PARAM_H
+#define _ASM_X86_PARAM_H
 
 #ifdef __KERNEL__
 # define HZ            CONFIG_HZ       /* Internal kernel timer frequency */
@@ -19,4 +19,4 @@
 
 #define MAXHOSTNAMELEN 64      /* max length of hostname */
 
-#endif /* ASM_X86__PARAM_H */
+#endif /* _ASM_X86_PARAM_H */
similarity index 99%
rename from include/asm-x86/paravirt.h
rename to arch/x86/include/asm/paravirt.h
index 8d6ae2f760d0000553d50ad9884722df23973406..ba3e2ff6aedcb1a7c6648acdc9257ad0bb7e3202 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PARAVIRT_H
-#define ASM_X86__PARAVIRT_H
+#ifndef _ASM_X86_PARAVIRT_H
+#define _ASM_X86_PARAVIRT_H
 /* Various instructions on x86 need to be replaced for
  * para-virtualization: those hooks are defined here. */
 
@@ -1647,4 +1647,4 @@ static inline unsigned long __raw_local_irq_save(void)
 
 #endif /* __ASSEMBLY__ */
 #endif /* CONFIG_PARAVIRT */
-#endif /* ASM_X86__PARAVIRT_H */
+#endif /* _ASM_X86_PARAVIRT_H */
similarity index 70%
rename from include/asm-x86/parport.h
rename to arch/x86/include/asm/parport.h
index 2e3dda4dc3d9b9f4bc243ca5a5b82b15be18263c..3c4ffeb467e9886ad62b1a4c6bf60686fcb219a3 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PARPORT_H
-#define ASM_X86__PARPORT_H
+#ifndef _ASM_X86_PARPORT_H
+#define _ASM_X86_PARPORT_H
 
 static int __devinit parport_pc_find_isa_ports(int autoirq, int autodma);
 static int __devinit parport_pc_find_nonpci_ports(int autoirq, int autodma)
@@ -7,4 +7,4 @@ static int __devinit parport_pc_find_nonpci_ports(int autoirq, int autodma)
        return parport_pc_find_isa_ports(autoirq, autodma);
 }
 
-#endif /* ASM_X86__PARPORT_H */
+#endif /* _ASM_X86_PARPORT_H */
similarity index 86%
rename from include/asm-x86/pat.h
rename to arch/x86/include/asm/pat.h
index 482c3e3f9879b23f086274fbd7dc453c3701ed69..b8493b3b98901c811add567762a22b73aaa85c9a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PAT_H
-#define ASM_X86__PAT_H
+#ifndef _ASM_X86_PAT_H
+#define _ASM_X86_PAT_H
 
 #include <linux/types.h>
 
@@ -19,4 +19,4 @@ extern int free_memtype(u64 start, u64 end);
 
 extern void pat_disable(char *reason);
 
-#endif /* ASM_X86__PAT_H */
+#endif /* _ASM_X86_PAT_H */
similarity index 88%
rename from include/asm-x86/pci-direct.h
rename to arch/x86/include/asm/pci-direct.h
index da42be07b6907bbfcf6eecabeaa65a2546cb40a1..b1e7a45d868a52bfd0c729897879ab49b5ea9bac 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PCI_DIRECT_H
-#define ASM_X86__PCI_DIRECT_H
+#ifndef _ASM_X86_PCI_DIRECT_H
+#define _ASM_X86_PCI_DIRECT_H
 
 #include <linux/types.h>
 
@@ -18,4 +18,4 @@ extern int early_pci_allowed(void);
 extern unsigned int pci_early_dump_regs;
 extern void early_dump_pci_device(u8 bus, u8 slot, u8 func);
 extern void early_dump_pci_devices(void);
-#endif /* ASM_X86__PCI_DIRECT_H */
+#endif /* _ASM_X86_PCI_DIRECT_H */
similarity index 97%
rename from include/asm-x86/pci.h
rename to arch/x86/include/asm/pci.h
index 60258319299183fa10ba7127f8af81a4e45f4f4e..875b38edf19383f0e1176b9a73dede0f49f42c38 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PCI_H
-#define ASM_X86__PCI_H
+#ifndef _ASM_X86_PCI_H
+#define _ASM_X86_PCI_H
 
 #include <linux/mm.h> /* for struct page */
 #include <linux/types.h>
@@ -111,4 +111,4 @@ static inline cpumask_t __pcibus_to_cpumask(struct pci_bus *bus)
 }
 #endif
 
-#endif /* ASM_X86__PCI_H */
+#endif /* _ASM_X86_PCI_H */
similarity index 91%
rename from include/asm-x86/pci_32.h
rename to arch/x86/include/asm/pci_32.h
index 3f2288207c0cd0e664cce2037d7c25e4a1bf1166..6f1213a6ef4fee56d716938c722b506dab433146 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PCI_32_H
-#define ASM_X86__PCI_32_H
+#ifndef _ASM_X86_PCI_32_H
+#define _ASM_X86_PCI_32_H
 
 
 #ifdef __KERNEL__
@@ -31,4 +31,4 @@ struct pci_dev;
 #endif /* __KERNEL__ */
 
 
-#endif /* ASM_X86__PCI_32_H */
+#endif /* _ASM_X86_PCI_32_H */
similarity index 95%
rename from include/asm-x86/pci_64.h
rename to arch/x86/include/asm/pci_64.h
index f72e12d5770ef275aff119c8c136a70b75ed047a..5b28995d664e9a092b4054f770751b3413f50edf 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PCI_64_H
-#define ASM_X86__PCI_64_H
+#ifndef _ASM_X86_PCI_64_H
+#define _ASM_X86_PCI_64_H
 
 #ifdef __KERNEL__
 
@@ -63,4 +63,4 @@ extern void pci_iommu_alloc(void);
 
 #endif /* __KERNEL__ */
 
-#endif /* ASM_X86__PCI_64_H */
+#endif /* _ASM_X86_PCI_64_H */
similarity index 98%
rename from include/asm-x86/pda.h
rename to arch/x86/include/asm/pda.h
index 80860afffbdbbede4092bb18a6946e5b0a2831f9..2fbfff88df37b5dec026772c61ac2b11fa61e1be 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PDA_H
-#define ASM_X86__PDA_H
+#ifndef _ASM_X86_PDA_H
+#define _ASM_X86_PDA_H
 
 #ifndef __ASSEMBLY__
 #include <linux/stddef.h>
@@ -134,4 +134,4 @@ do {                                                                        \
 
 #define PDA_STACKOFFSET (5*8)
 
-#endif /* ASM_X86__PDA_H */
+#endif /* _ASM_X86_PDA_H */
similarity index 98%
rename from include/asm-x86/percpu.h
rename to arch/x86/include/asm/percpu.h
index e10a1d0678cfaa014ad702e1169e5d7417240f52..ece72053ba63b74cc79df41f88d5c9e49b77b69a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PERCPU_H
-#define ASM_X86__PERCPU_H
+#ifndef _ASM_X86_PERCPU_H
+#define _ASM_X86_PERCPU_H
 
 #ifdef CONFIG_X86_64
 #include <linux/compiler.h>
@@ -215,4 +215,4 @@ do {                                                        \
 
 #endif /* !CONFIG_SMP */
 
-#endif /* ASM_X86__PERCPU_H */
+#endif /* _ASM_X86_PERCPU_H */
similarity index 97%
rename from include/asm-x86/pgalloc.h
rename to arch/x86/include/asm/pgalloc.h
index 3cd23adedae851d13da954b3cb8574390102931a..cb7c151a8bff27aae0ec3e4cad447ff4003abbc6 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PGALLOC_H
-#define ASM_X86__PGALLOC_H
+#ifndef _ASM_X86_PGALLOC_H
+#define _ASM_X86_PGALLOC_H
 
 #include <linux/threads.h>
 #include <linux/mm.h>          /* for struct page */
@@ -111,4 +111,4 @@ extern void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud);
 #endif /* PAGETABLE_LEVELS > 3 */
 #endif /* PAGETABLE_LEVELS > 2 */
 
-#endif /* ASM_X86__PGALLOC_H */
+#endif /* _ASM_X86_PGALLOC_H */
similarity index 67%
rename from include/asm-x86/pgtable-2level-defs.h
rename to arch/x86/include/asm/pgtable-2level-defs.h
index 7ec48f4e53472a865eee5d9fb4c1b018bd3fcd8a..d77db8990eaaa9e7b8250f50134d22979fc4a1d7 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PGTABLE_2LEVEL_DEFS_H
-#define ASM_X86__PGTABLE_2LEVEL_DEFS_H
+#ifndef _ASM_X86_PGTABLE_2LEVEL_DEFS_H
+#define _ASM_X86_PGTABLE_2LEVEL_DEFS_H
 
 #define SHARED_KERNEL_PMD      0
 
@@ -17,4 +17,4 @@
 
 #define PTRS_PER_PTE   1024
 
-#endif /* ASM_X86__PGTABLE_2LEVEL_DEFS_H */
+#endif /* _ASM_X86_PGTABLE_2LEVEL_DEFS_H */
similarity index 94%
rename from include/asm-x86/pgtable-2level.h
rename to arch/x86/include/asm/pgtable-2level.h
index 81762081dcd88251464b4af812fe39239a14377d..b17edfd23628953139fa58778fa7ae2d66222222 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PGTABLE_2LEVEL_H
-#define ASM_X86__PGTABLE_2LEVEL_H
+#ifndef _ASM_X86_PGTABLE_2LEVEL_H
+#define _ASM_X86_PGTABLE_2LEVEL_H
 
 #define pte_ERROR(e) \
        printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte_low)
@@ -76,4 +76,4 @@ static inline pte_t native_ptep_get_and_clear(pte_t *xp)
 #define __pte_to_swp_entry(pte)                ((swp_entry_t) { (pte).pte_low })
 #define __swp_entry_to_pte(x)          ((pte_t) { .pte = (x).val })
 
-#endif /* ASM_X86__PGTABLE_2LEVEL_H */
+#endif /* _ASM_X86_PGTABLE_2LEVEL_H */
similarity index 78%
rename from include/asm-x86/pgtable-3level-defs.h
rename to arch/x86/include/asm/pgtable-3level-defs.h
index c05fe6ff37202ddd51c596b9c27e1b609f84fb3a..62561367653c31376fcbfe6e8f9f0f98087ea907 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PGTABLE_3LEVEL_DEFS_H
-#define ASM_X86__PGTABLE_3LEVEL_DEFS_H
+#ifndef _ASM_X86_PGTABLE_3LEVEL_DEFS_H
+#define _ASM_X86_PGTABLE_3LEVEL_DEFS_H
 
 #ifdef CONFIG_PARAVIRT
 #define SHARED_KERNEL_PMD      (pv_info.shared_kernel_pmd)
@@ -25,4 +25,4 @@
  */
 #define PTRS_PER_PTE   512
 
-#endif /* ASM_X86__PGTABLE_3LEVEL_DEFS_H */
+#endif /* _ASM_X86_PGTABLE_3LEVEL_DEFS_H */
similarity index 97%
rename from include/asm-x86/pgtable-3level.h
rename to arch/x86/include/asm/pgtable-3level.h
index 75f4276b5ddb9e2a7fba9b3403ce9765366b0eec..fb16cec702e40ad786f175eede096ffaf8e31116 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PGTABLE_3LEVEL_H
-#define ASM_X86__PGTABLE_3LEVEL_H
+#ifndef _ASM_X86_PGTABLE_3LEVEL_H
+#define _ASM_X86_PGTABLE_3LEVEL_H
 
 /*
  * Intel Physical Address Extension (PAE) Mode - three-level page
@@ -172,4 +172,4 @@ static inline int pte_none(pte_t pte)
 #define __pte_to_swp_entry(pte)                ((swp_entry_t){ (pte).pte_high })
 #define __swp_entry_to_pte(x)          ((pte_t){ { .pte_high = (x).val } })
 
-#endif /* ASM_X86__PGTABLE_3LEVEL_H */
+#endif /* _ASM_X86_PGTABLE_3LEVEL_H */
similarity index 99%
rename from include/asm-x86/pgtable.h
rename to arch/x86/include/asm/pgtable.h
index 88a53b1a17f03f486e9a22a138b30b2e422e6544..c012f3b11671574150720dcaee023780cd79d905 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PGTABLE_H
-#define ASM_X86__PGTABLE_H
+#ifndef _ASM_X86_PGTABLE_H
+#define _ASM_X86_PGTABLE_H
 
 #define FIRST_USER_ADDRESS     0
 
@@ -348,7 +348,8 @@ static inline void native_pagetable_setup_start(pgd_t *base) {}
 static inline void native_pagetable_setup_done(pgd_t *base) {}
 #endif
 
-extern int arch_report_meminfo(char *page);
+struct seq_file;
+extern void arch_report_meminfo(struct seq_file *m);
 
 #ifdef CONFIG_PARAVIRT
 #include <asm/paravirt.h>
@@ -558,4 +559,4 @@ static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
 #include <asm-generic/pgtable.h>
 #endif /* __ASSEMBLY__ */
 
-#endif /* ASM_X86__PGTABLE_H */
+#endif /* _ASM_X86_PGTABLE_H */
similarity index 98%
rename from include/asm-x86/pgtable_32.h
rename to arch/x86/include/asm/pgtable_32.h
index 8de702dc7d620bc625b5ff1fe8eee2d5e0f804a9..f9d5889b336be5eb5d9f575d22ac512be7d63f7e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PGTABLE_32_H
-#define ASM_X86__PGTABLE_32_H
+#ifndef _ASM_X86_PGTABLE_32_H
+#define _ASM_X86_PGTABLE_32_H
 
 
 /*
@@ -188,4 +188,4 @@ do {                                                \
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)        \
        remap_pfn_range(vma, vaddr, pfn, size, prot)
 
-#endif /* ASM_X86__PGTABLE_32_H */
+#endif /* _ASM_X86_PGTABLE_32_H */
similarity index 98%
rename from include/asm-x86/pgtable_64.h
rename to arch/x86/include/asm/pgtable_64.h
index fde9770e53d14193a7279c8e427dc50e3f7fc87c..545a0e042bb2d44268d7a240e97b2c14309568b9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PGTABLE_64_H
-#define ASM_X86__PGTABLE_64_H
+#ifndef _ASM_X86_PGTABLE_64_H
+#define _ASM_X86_PGTABLE_64_H
 
 #include <linux/const.h>
 #ifndef __ASSEMBLY__
@@ -282,4 +282,4 @@ extern void cleanup_highmap(void);
 #define __HAVE_ARCH_PTE_SAME
 #endif /* !__ASSEMBLY__ */
 
-#endif /* ASM_X86__PGTABLE_64_H */
+#endif /* _ASM_X86_PGTABLE_64_H */
similarity index 95%
rename from include/asm-x86/posix_types_32.h
rename to arch/x86/include/asm/posix_types_32.h
index 70cf2bb059393532401e0eb4bc49528b869c5f84..f7d9adf82e5396cce337b7e62d0821371361bdc9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__POSIX_TYPES_32_H
-#define ASM_X86__POSIX_TYPES_32_H
+#ifndef _ASM_X86_POSIX_TYPES_32_H
+#define _ASM_X86_POSIX_TYPES_32_H
 
 /*
  * This file is generally used by user-level software, so you need to
@@ -82,4 +82,4 @@ do {                                                          \
 
 #endif /* defined(__KERNEL__) */
 
-#endif /* ASM_X86__POSIX_TYPES_32_H */
+#endif /* _ASM_X86_POSIX_TYPES_32_H */
similarity index 96%
rename from include/asm-x86/posix_types_64.h
rename to arch/x86/include/asm/posix_types_64.h
index 388b4e7f4a440425173adfd5f6da9bd25ead676c..eb8d2d92b63e6e7a5cbad9b472d0f607a4c22a69 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__POSIX_TYPES_64_H
-#define ASM_X86__POSIX_TYPES_64_H
+#ifndef _ASM_X86_POSIX_TYPES_64_H
+#define _ASM_X86_POSIX_TYPES_64_H
 
 /*
  * This file is generally used by user-level software, so you need to
@@ -116,4 +116,4 @@ static inline void __FD_ZERO(__kernel_fd_set *p)
 
 #endif /* defined(__KERNEL__) */
 
-#endif /* ASM_X86__POSIX_TYPES_64_H */
+#endif /* _ASM_X86_POSIX_TYPES_64_H */
similarity index 58%
rename from include/asm-x86/prctl.h
rename to arch/x86/include/asm/prctl.h
index e7ae34eb4103357ac3a8b73352df7fce8caed93d..fe681147a4f78fcd5cc0235cff57616af81e3f38 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PRCTL_H
-#define ASM_X86__PRCTL_H
+#ifndef _ASM_X86_PRCTL_H
+#define _ASM_X86_PRCTL_H
 
 #define ARCH_SET_GS 0x1001
 #define ARCH_SET_FS 0x1002
@@ -7,4 +7,4 @@
 #define ARCH_GET_GS 0x1004
 
 
-#endif /* ASM_X86__PRCTL_H */
+#endif /* _ASM_X86_PRCTL_H */
similarity index 96%
rename from include/asm-x86/processor-flags.h
rename to arch/x86/include/asm/processor-flags.h
index dc5f0712f9fa450430718880447c23f6af4c9965..7a3e836eb2a984b751443666d8848185d7bb51f5 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PROCESSOR_FLAGS_H
-#define ASM_X86__PROCESSOR_FLAGS_H
+#ifndef _ASM_X86_PROCESSOR_FLAGS_H
+#define _ASM_X86_PROCESSOR_FLAGS_H
 /* Various flags defined: can be included from assembler. */
 
 /*
@@ -97,4 +97,4 @@
 #endif
 #endif
 
-#endif /* ASM_X86__PROCESSOR_FLAGS_H */
+#endif /* _ASM_X86_PROCESSOR_FLAGS_H */
similarity index 99%
rename from include/asm-x86/processor.h
rename to arch/x86/include/asm/processor.h
index ee7cbb30773ae05709518f0cc63307162407c90c..5ca01e3832699b0378c36d79a4d17361a3d27b88 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PROCESSOR_H
-#define ASM_X86__PROCESSOR_H
+#ifndef _ASM_X86_PROCESSOR_H
+#define _ASM_X86_PROCESSOR_H
 
 #include <asm/processor-flags.h>
 
@@ -933,4 +933,4 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_ip,
 extern int get_tsc_mode(unsigned long adr);
 extern int set_tsc_mode(unsigned int val);
 
-#endif /* ASM_X86__PROCESSOR_H */
+#endif /* _ASM_X86_PROCESSOR_H */
similarity index 88%
rename from include/asm-x86/proto.h
rename to arch/x86/include/asm/proto.h
index 6e89e8b4de0ec1c9f20f30ee2736116666a01d0e..d6a22f92ba7797a1f11b77e2b6ac90cd06499e07 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PROTO_H
-#define ASM_X86__PROTO_H
+#ifndef _ASM_X86_PROTO_H
+#define _ASM_X86_PROTO_H
 
 #include <asm/ldt.h>
 
@@ -29,4 +29,4 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr);
 #define round_up(x, y) (((x) + (y) - 1) & ~((y) - 1))
 #define round_down(x, y) ((x) & ~((y) - 1))
 
-#endif /* ASM_X86__PROTO_H */
+#endif /* _ASM_X86_PROTO_H */
similarity index 97%
rename from include/asm-x86/ptrace-abi.h
rename to arch/x86/include/asm/ptrace-abi.h
index 4298b8882a782ab23ac101fcf48322eb78ea2cbb..25f1bb8fc626ab00b14ba65fa56e4477e74afd30 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PTRACE_ABI_H
-#define ASM_X86__PTRACE_ABI_H
+#ifndef _ASM_X86_PTRACE_ABI_H
+#define _ASM_X86_PTRACE_ABI_H
 
 #ifdef __i386__
 
@@ -142,4 +142,4 @@ struct ptrace_bts_config {
 */
 #endif /* CONFIG_X86_PTRACE_BTS */
 
-#endif /* ASM_X86__PTRACE_ABI_H */
+#endif /* _ASM_X86_PTRACE_ABI_H */
similarity index 98%
rename from include/asm-x86/ptrace.h
rename to arch/x86/include/asm/ptrace.h
index a2025525a15ab20dca199a9e3acf95b2d1d7fcff..d1531c8480b78fdb42feb018c88e122ad93191b4 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PTRACE_H
-#define ASM_X86__PTRACE_H
+#ifndef _ASM_X86_PTRACE_H
+#define _ASM_X86_PTRACE_H
 
 #include <linux/compiler.h>    /* For __user */
 #include <asm/ptrace-abi.h>
@@ -277,4 +277,4 @@ extern int do_set_thread_area(struct task_struct *p, int idx,
 
 #endif /* !__ASSEMBLY__ */
 
-#endif /* ASM_X86__PTRACE_H */
+#endif /* _ASM_X86_PTRACE_H */
similarity index 92%
rename from include/asm-x86/pvclock-abi.h
rename to arch/x86/include/asm/pvclock-abi.h
index edb3b4ecfc81687e46ff5aa8f24fb1a696349932..6d93508f262602eba40417dda7a0357d1ff47cb6 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PVCLOCK_ABI_H
-#define ASM_X86__PVCLOCK_ABI_H
+#ifndef _ASM_X86_PVCLOCK_ABI_H
+#define _ASM_X86_PVCLOCK_ABI_H
 #ifndef __ASSEMBLY__
 
 /*
@@ -39,4 +39,4 @@ struct pvclock_wall_clock {
 } __attribute__((__packed__));
 
 #endif /* __ASSEMBLY__ */
-#endif /* ASM_X86__PVCLOCK_ABI_H */
+#endif /* _ASM_X86_PVCLOCK_ABI_H */
similarity index 82%
rename from include/asm-x86/pvclock.h
rename to arch/x86/include/asm/pvclock.h
index ad29e277fd6d6dd9d114e33b6113c42d03bf5d2c..53235fd5f8ce67cf4f085c092e611fa19fa04684 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__PVCLOCK_H
-#define ASM_X86__PVCLOCK_H
+#ifndef _ASM_X86_PVCLOCK_H
+#define _ASM_X86_PVCLOCK_H
 
 #include <linux/clocksource.h>
 #include <asm/pvclock-abi.h>
@@ -11,4 +11,4 @@ void pvclock_read_wallclock(struct pvclock_wall_clock *wall,
                            struct pvclock_vcpu_time_info *vcpu,
                            struct timespec *ts);
 
-#endif /* ASM_X86__PVCLOCK_H */
+#endif /* _ASM_X86_PVCLOCK_H */
similarity index 83%
rename from include/asm-x86/reboot.h
rename to arch/x86/include/asm/reboot.h
index 1c2f0ce9e31e44b2c7cd8ab8a30e708f95db44c6..df7710354f851dc957c497b30a77f4c6468c01df 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__REBOOT_H
-#define ASM_X86__REBOOT_H
+#ifndef _ASM_X86_REBOOT_H
+#define _ASM_X86_REBOOT_H
 
 struct pt_regs;
 
@@ -18,4 +18,4 @@ void native_machine_crash_shutdown(struct pt_regs *regs);
 void native_machine_shutdown(void);
 void machine_real_restart(const unsigned char *code, int length);
 
-#endif /* ASM_X86__REBOOT_H */
+#endif /* _ASM_X86_REBOOT_H */
diff --git a/arch/x86/include/asm/reboot_fixups.h b/arch/x86/include/asm/reboot_fixups.h
new file mode 100644 (file)
index 0000000..765debe
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _ASM_X86_REBOOT_FIXUPS_H
+#define _ASM_X86_REBOOT_FIXUPS_H
+
+extern void mach_reboot_fixups(void);
+
+#endif /* _ASM_X86_REBOOT_FIXUPS_H */
similarity index 94%
rename from include/asm-x86/required-features.h
rename to arch/x86/include/asm/required-features.h
index a01c4e376331ab48f65df1cd979439022fbd7cde..d5cd6c586881f89639d486a92033d3ce19442ca0 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__REQUIRED_FEATURES_H
-#define ASM_X86__REQUIRED_FEATURES_H
+#ifndef _ASM_X86_REQUIRED_FEATURES_H
+#define _ASM_X86_REQUIRED_FEATURES_H
 
 /* Define minimum CPUID feature set for kernel These bits are checked
    really early to actually display a visible error message before the
@@ -79,4 +79,4 @@
 #define REQUIRED_MASK6 0
 #define REQUIRED_MASK7 0
 
-#endif /* ASM_X86__REQUIRED_FEATURES_H */
+#endif /* _ASM_X86_REQUIRED_FEATURES_H */
similarity index 81%
rename from include/asm-x86/resume-trace.h
rename to arch/x86/include/asm/resume-trace.h
index e39376d7de50f8e33b3bf22fb2c3d32c82bd89f9..3ff1c2cb1da574d7bf36dabfb215da168d674d58 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__RESUME_TRACE_H
-#define ASM_X86__RESUME_TRACE_H
+#ifndef _ASM_X86_RESUME_TRACE_H
+#define _ASM_X86_RESUME_TRACE_H
 
 #include <asm/asm.h>
 
@@ -18,4 +18,4 @@ do {                                                          \
        }                                                       \
 } while (0)
 
-#endif /* ASM_X86__RESUME_TRACE_H */
+#endif /* _ASM_X86_RESUME_TRACE_H */
similarity index 97%
rename from include/asm-x86/rio.h
rename to arch/x86/include/asm/rio.h
index 5e1256bdee83b791499000cb873b0135437e826f..97bab6388a92ec3ea7ae7c006544d649fb6b56d6 100644 (file)
@@ -5,8 +5,8 @@
  * Author: Laurent Vivier <Laurent.Vivier@bull.net>
  */
 
-#ifndef ASM_X86__RIO_H
-#define ASM_X86__RIO_H
+#ifndef _ASM_X86_RIO_H
+#define _ASM_X86_RIO_H
 
 #define RIO_TABLE_VERSION      3
 
@@ -60,4 +60,4 @@ enum {
        ALT_CALGARY     = 5,    /* Second Planar Calgary      */
 };
 
-#endif /* ASM_X86__RIO_H */
+#endif /* _ASM_X86_RIO_H */
similarity index 55%
rename from include/asm-x86/rwlock.h
rename to arch/x86/include/asm/rwlock.h
index 48a3109e1a7d83e1101c13864c444dcad3741fad..6a8c0d6451080658c6b2bee54fad409b11d47a9a 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef ASM_X86__RWLOCK_H
-#define ASM_X86__RWLOCK_H
+#ifndef _ASM_X86_RWLOCK_H
+#define _ASM_X86_RWLOCK_H
 
 #define RW_LOCK_BIAS            0x01000000
 
 /* Actual code is in asm/spinlock.h or in arch/x86/lib/rwlock.S */
 
-#endif /* ASM_X86__RWLOCK_H */
+#endif /* _ASM_X86_RWLOCK_H */
similarity index 98%
rename from include/asm-x86/rwsem.h
rename to arch/x86/include/asm/rwsem.h
index 3ff3015b71a8367f738cb8c1974c09665b569ed3..ca7517d3377634b6251ce727326d06dd30627fc5 100644 (file)
@@ -29,8 +29,8 @@
  * front, then they'll all be woken up, but no other readers will be.
  */
 
-#ifndef ASM_X86__RWSEM_H
-#define ASM_X86__RWSEM_H
+#ifndef _ASM_X86_RWSEM_H
+#define _ASM_X86_RWSEM_H
 
 #ifndef _LINUX_RWSEM_H
 #error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead"
@@ -262,4 +262,4 @@ static inline int rwsem_is_locked(struct rw_semaphore *sem)
 }
 
 #endif /* __KERNEL__ */
-#endif /* ASM_X86__RWSEM_H */
+#endif /* _ASM_X86_RWSEM_H */
similarity index 87%
rename from include/asm-x86/scatterlist.h
rename to arch/x86/include/asm/scatterlist.h
index ee48f880005d13e8244c56bf6a59cb68845fdd2e..263d397d2eefec625804871ddf7163d951bbc869 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SCATTERLIST_H
-#define ASM_X86__SCATTERLIST_H
+#ifndef _ASM_X86_SCATTERLIST_H
+#define _ASM_X86_SCATTERLIST_H
 
 #include <asm/types.h>
 
@@ -30,4 +30,4 @@ struct scatterlist {
 # define sg_dma_len(sg)                ((sg)->dma_length)
 #endif
 
-#endif /* ASM_X86__SCATTERLIST_H */
+#endif /* _ASM_X86_SCATTERLIST_H */
similarity index 74%
rename from include/asm-x86/seccomp_32.h
rename to arch/x86/include/asm/seccomp_32.h
index cf9ab2dbcef1f07c0e3f864579d8f75c721a6005..a6ad87b352c448e8b1f2c2b3e3dd9591fe593248 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SECCOMP_32_H
-#define ASM_X86__SECCOMP_32_H
+#ifndef _ASM_X86_SECCOMP_32_H
+#define _ASM_X86_SECCOMP_32_H
 
 #include <linux/thread_info.h>
 
@@ -14,4 +14,4 @@
 #define __NR_seccomp_exit __NR_exit
 #define __NR_seccomp_sigreturn __NR_sigreturn
 
-#endif /* ASM_X86__SECCOMP_32_H */
+#endif /* _ASM_X86_SECCOMP_32_H */
similarity index 84%
rename from include/asm-x86/seccomp_64.h
rename to arch/x86/include/asm/seccomp_64.h
index 03274cea751f78e460afdd6fa66bb4c1937cb3c1..4171bb794e9e736bbfcb60588a4e9d81d1edcb31 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SECCOMP_64_H
-#define ASM_X86__SECCOMP_64_H
+#ifndef _ASM_X86_SECCOMP_64_H
+#define _ASM_X86_SECCOMP_64_H
 
 #include <linux/thread_info.h>
 
@@ -22,4 +22,4 @@
 #define __NR_seccomp_exit_32 __NR_ia32_exit
 #define __NR_seccomp_sigreturn_32 __NR_ia32_sigreturn
 
-#endif /* ASM_X86__SECCOMP_64_H */
+#endif /* _ASM_X86_SECCOMP_64_H */
similarity index 98%
rename from include/asm-x86/segment.h
rename to arch/x86/include/asm/segment.h
index 5d6e6945489152932b8e0f1216a035fc53e9fb33..1dc1b51ac6232f12b4de181c9c343328cc7bfd07 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SEGMENT_H
-#define ASM_X86__SEGMENT_H
+#ifndef _ASM_X86_SEGMENT_H
+#define _ASM_X86_SEGMENT_H
 
 /* Constructor for a conventional segment GDT (or LDT) entry */
 /* This is a macro so it can be used in initializers */
@@ -206,4 +206,4 @@ extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][10];
 #endif
 #endif
 
-#endif /* ASM_X86__SEGMENT_H */
+#endif /* _ASM_X86_SEGMENT_H */
similarity index 88%
rename from include/asm-x86/sembuf.h
rename to arch/x86/include/asm/sembuf.h
index 81f06b7e5a3f2685a88a1b7103253c3a69e34c79..ee50c801f7b7eda1d4ea2aeea1f99cfaf1b03ccd 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SEMBUF_H
-#define ASM_X86__SEMBUF_H
+#ifndef _ASM_X86_SEMBUF_H
+#define _ASM_X86_SEMBUF_H
 
 /*
  * The semid64_ds structure for x86 architecture.
@@ -21,4 +21,4 @@ struct semid64_ds {
        unsigned long   __unused4;
 };
 
-#endif /* ASM_X86__SEMBUF_H */
+#endif /* _ASM_X86_SEMBUF_H */
similarity index 92%
rename from include/asm-x86/serial.h
rename to arch/x86/include/asm/serial.h
index 303660b671e5cf6d07d02201578225cc0dfcb3ee..628c801535ea912c00a57654310a832acca2e67f 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SERIAL_H
-#define ASM_X86__SERIAL_H
+#ifndef _ASM_X86_SERIAL_H
+#define _ASM_X86_SERIAL_H
 
 /*
  * This assumes you have a 1.8432 MHz clock for your UART.
@@ -26,4 +26,4 @@
        { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },      /* ttyS2 */     \
        { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },     /* ttyS3 */
 
-#endif /* ASM_X86__SERIAL_H */
+#endif /* _ASM_X86_SERIAL_H */
similarity index 96%
rename from include/asm-x86/setup.h
rename to arch/x86/include/asm/setup.h
index 11b6cc14b289686f3eff7ae2d908540fc866b747..f12d37237465df8b0a181d37685b212c0dd70cd1 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SETUP_H
-#define ASM_X86__SETUP_H
+#ifndef _ASM_X86_SETUP_H
+#define _ASM_X86_SETUP_H
 
 #define COMMAND_LINE_SIZE 2048
 
@@ -102,4 +102,4 @@ void __init x86_64_start_reservations(char *real_mode_data);
 #endif /* __ASSEMBLY__ */
 #endif  /*  __KERNEL__  */
 
-#endif /* ASM_X86__SETUP_H */
+#endif /* _ASM_X86_SETUP_H */
similarity index 93%
rename from include/asm-x86/shmbuf.h
rename to arch/x86/include/asm/shmbuf.h
index f51aec2298e9998f919d87bc734da9d994d82860..b51413b749711f133882d9e21c432d4c28a68463 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SHMBUF_H
-#define ASM_X86__SHMBUF_H
+#ifndef _ASM_X86_SHMBUF_H
+#define _ASM_X86_SHMBUF_H
 
 /*
  * The shmid64_ds structure for x86 architecture.
@@ -48,4 +48,4 @@ struct shminfo64 {
        unsigned long   __unused4;
 };
 
-#endif /* ASM_X86__SHMBUF_H */
+#endif /* _ASM_X86_SHMBUF_H */
diff --git a/arch/x86/include/asm/shmparam.h b/arch/x86/include/asm/shmparam.h
new file mode 100644 (file)
index 0000000..0880cf0
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _ASM_X86_SHMPARAM_H
+#define _ASM_X86_SHMPARAM_H
+
+#define SHMLBA PAGE_SIZE        /* attach addr a multiple of this */
+
+#endif /* _ASM_X86_SHMPARAM_H */
similarity index 98%
rename from include/asm-x86/sigcontext.h
rename to arch/x86/include/asm/sigcontext.h
index ee813f4fe5d531f13aff53defed8a581ce5913fc..0afcb5e58acc51e8cc06959abcf66d0d5a25ea95 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SIGCONTEXT_H
-#define ASM_X86__SIGCONTEXT_H
+#ifndef _ASM_X86_SIGCONTEXT_H
+#define _ASM_X86_SIGCONTEXT_H
 
 #include <linux/compiler.h>
 #include <asm/types.h>
@@ -281,4 +281,4 @@ struct _xstate {
        /* new processor state extensions go here */
 };
 
-#endif /* ASM_X86__SIGCONTEXT_H */
+#endif /* _ASM_X86_SIGCONTEXT_H */
similarity index 93%
rename from include/asm-x86/sigcontext32.h
rename to arch/x86/include/asm/sigcontext32.h
index 8c347032c2f28d5a390d75306100d0105b74c5ad..6126188cf3a9faa2aa3fa28bb3358fdd209cc908 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SIGCONTEXT32_H
-#define ASM_X86__SIGCONTEXT32_H
+#ifndef _ASM_X86_SIGCONTEXT32_H
+#define _ASM_X86_SIGCONTEXT32_H
 
 /* signal context for 32bit programs. */
 
@@ -72,4 +72,4 @@ struct sigcontext_ia32 {
        unsigned int cr2;
 };
 
-#endif /* ASM_X86__SIGCONTEXT32_H */
+#endif /* _ASM_X86_SIGCONTEXT32_H */
similarity index 56%
rename from include/asm-x86/siginfo.h
rename to arch/x86/include/asm/siginfo.h
index 808bdfb2958c600628df8fbc52317169033e6492..fc1aa553564604c405569eea428d3a10398bcc55 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SIGINFO_H
-#define ASM_X86__SIGINFO_H
+#ifndef _ASM_X86_SIGINFO_H
+#define _ASM_X86_SIGINFO_H
 
 #ifdef __x86_64__
 # define __ARCH_SI_PREAMBLE_SIZE       (4 * sizeof(int))
@@ -7,4 +7,4 @@
 
 #include <asm-generic/siginfo.h>
 
-#endif /* ASM_X86__SIGINFO_H */
+#endif /* _ASM_X86_SIGINFO_H */
similarity index 98%
rename from include/asm-x86/signal.h
rename to arch/x86/include/asm/signal.h
index 65acc82d267a6f3b75a42f856ae9b0ec007cf70a..96ac44f275da40f24a73b5180b9e4c240d5fc8ba 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SIGNAL_H
-#define ASM_X86__SIGNAL_H
+#ifndef _ASM_X86_SIGNAL_H
+#define _ASM_X86_SIGNAL_H
 
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
@@ -259,4 +259,4 @@ struct pt_regs;
 #endif /* __KERNEL__ */
 #endif /* __ASSEMBLY__ */
 
-#endif /* ASM_X86__SIGNAL_H */
+#endif /* _ASM_X86_SIGNAL_H */
similarity index 98%
rename from include/asm-x86/smp.h
rename to arch/x86/include/asm/smp.h
index a6afc29f2dd9981e713a36d3ec14b507796415bf..2766021aef80fc75453492ab611f683397e6aa16 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SMP_H
-#define ASM_X86__SMP_H
+#ifndef _ASM_X86_SMP_H
+#define _ASM_X86_SMP_H
 #ifndef __ASSEMBLY__
 #include <linux/cpumask.h>
 #include <linux/init.h>
@@ -226,4 +226,4 @@ static inline int hard_smp_processor_id(void)
 #endif /* CONFIG_X86_LOCAL_APIC */
 
 #endif /* __ASSEMBLY__ */
-#endif /* ASM_X86__SMP_H */
+#endif /* _ASM_X86_SMP_H */
similarity index 93%
rename from include/asm-x86/socket.h
rename to arch/x86/include/asm/socket.h
index db73274c83c3b3ea302dff7a233fab452745c838..8ab9cc8b2eccb8949e99f7e2adb19144dedbebb3 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SOCKET_H
-#define ASM_X86__SOCKET_H
+#ifndef _ASM_X86_SOCKET_H
+#define _ASM_X86_SOCKET_H
 
 #include <asm/sockios.h>
 
@@ -54,4 +54,4 @@
 
 #define SO_MARK                        36
 
-#endif /* ASM_X86__SOCKET_H */
+#endif /* _ASM_X86_SOCKET_H */
similarity index 76%
rename from include/asm-x86/sockios.h
rename to arch/x86/include/asm/sockios.h
index a006704fdc8427cf4b4cd134bf9695375dbc3af5..49cc72b5d3c914fa5bb98f181e37768018cc6782 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SOCKIOS_H
-#define ASM_X86__SOCKIOS_H
+#ifndef _ASM_X86_SOCKIOS_H
+#define _ASM_X86_SOCKIOS_H
 
 /* Socket-level I/O control calls. */
 #define FIOSETOWN      0x8901
@@ -10,4 +10,4 @@
 #define SIOCGSTAMP     0x8906          /* Get stamp (timeval) */
 #define SIOCGSTAMPNS   0x8907          /* Get stamp (timespec) */
 
-#endif /* ASM_X86__SOCKIOS_H */
+#endif /* _ASM_X86_SOCKIOS_H */
similarity index 89%
rename from include/asm-x86/sparsemem.h
rename to arch/x86/include/asm/sparsemem.h
index 38f8e6bc3186bb52ce64245870d651f20c24d6fd..be44f7dab395ad87492e0021cbf7adb99cadb1d2 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SPARSEMEM_H
-#define ASM_X86__SPARSEMEM_H
+#ifndef _ASM_X86_SPARSEMEM_H
+#define _ASM_X86_SPARSEMEM_H
 
 #ifdef CONFIG_SPARSEMEM
 /*
@@ -31,4 +31,4 @@
 #endif
 
 #endif /* CONFIG_SPARSEMEM */
-#endif /* ASM_X86__SPARSEMEM_H */
+#endif /* _ASM_X86_SPARSEMEM_H */
similarity index 99%
rename from include/asm-x86/spinlock.h
rename to arch/x86/include/asm/spinlock.h
index 157ff7fab97aba964216472e6f67aac147e3b901..d17c91981da2f1c94a5fb045067f821ece61b4fe 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SPINLOCK_H
-#define ASM_X86__SPINLOCK_H
+#ifndef _ASM_X86_SPINLOCK_H
+#define _ASM_X86_SPINLOCK_H
 
 #include <asm/atomic.h>
 #include <asm/rwlock.h>
@@ -361,4 +361,4 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw)
 #define _raw_read_relax(lock)  cpu_relax()
 #define _raw_write_relax(lock) cpu_relax()
 
-#endif /* ASM_X86__SPINLOCK_H */
+#endif /* _ASM_X86_SPINLOCK_H */
similarity index 74%
rename from include/asm-x86/spinlock_types.h
rename to arch/x86/include/asm/spinlock_types.h
index 6aa9b562c5080ae0ac7295a0adefea9ff31c138b..845f81c87091b6d63075faefecc1d74a93c45d85 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SPINLOCK_TYPES_H
-#define ASM_X86__SPINLOCK_TYPES_H
+#ifndef _ASM_X86_SPINLOCK_TYPES_H
+#define _ASM_X86_SPINLOCK_TYPES_H
 
 #ifndef __LINUX_SPINLOCK_TYPES_H
 # error "please don't include this file directly"
@@ -17,4 +17,4 @@ typedef struct {
 
 #define __RAW_RW_LOCK_UNLOCKED         { RW_LOCK_BIAS }
 
-#endif /* ASM_X86__SPINLOCK_TYPES_H */
+#endif /* _ASM_X86_SPINLOCK_TYPES_H */
similarity index 93%
rename from include/asm-x86/srat.h
rename to arch/x86/include/asm/srat.h
index 5363e4f7e1cddb7b52f0db52be72eb185f5a2a5a..b508d639d1a72b654119236a9356131824d749e0 100644 (file)
@@ -24,8 +24,8 @@
  * Send feedback to Pat Gaughen <gone@us.ibm.com>
  */
 
-#ifndef ASM_X86__SRAT_H
-#define ASM_X86__SRAT_H
+#ifndef _ASM_X86_SRAT_H
+#define _ASM_X86_SRAT_H
 
 #ifdef CONFIG_ACPI_NUMA
 extern int get_memcfg_from_srat(void);
@@ -36,4 +36,4 @@ static inline int get_memcfg_from_srat(void)
 }
 #endif
 
-#endif /* ASM_X86__SRAT_H */
+#endif /* _ASM_X86_SRAT_H */
similarity index 85%
rename from include/asm-x86/stacktrace.h
rename to arch/x86/include/asm/stacktrace.h
index f43517e28532fd930a6cf017591ac7f1bee5febc..f517944b2b176618f51d9791adb9fed4f08864ae 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__STACKTRACE_H
-#define ASM_X86__STACKTRACE_H
+#ifndef _ASM_X86_STACKTRACE_H
+#define _ASM_X86_STACKTRACE_H
 
 extern int kstack_depth_to_print;
 
@@ -18,4 +18,4 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
                unsigned long *stack, unsigned long bp,
                const struct stacktrace_ops *ops, void *data);
 
-#endif /* ASM_X86__STACKTRACE_H */
+#endif /* _ASM_X86_STACKTRACE_H */
similarity index 96%
rename from include/asm-x86/stat.h
rename to arch/x86/include/asm/stat.h
index 1e120f62890546f58311c213d8f46d8ec2f0d065..e0b1d9bbcbc66b2b1717949537795c2688cd09bc 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__STAT_H
-#define ASM_X86__STAT_H
+#ifndef _ASM_X86_STAT_H
+#define _ASM_X86_STAT_H
 
 #define STAT_HAVE_NSEC 1
 
@@ -111,4 +111,4 @@ struct __old_kernel_stat {
 #endif
 };
 
-#endif /* ASM_X86__STAT_H */
+#endif /* _ASM_X86_STAT_H */
similarity index 76%
rename from include/asm-x86/statfs.h
rename to arch/x86/include/asm/statfs.h
index ca5dc19dd461f95368b38fc9fb8c96bebd86d58d..2d0adbf99a8e2ce94a7e5a3a13a936c16283b815 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__STATFS_H
-#define ASM_X86__STATFS_H
+#ifndef _ASM_X86_STATFS_H
+#define _ASM_X86_STATFS_H
 
 /*
  * We need compat_statfs64 to be packed, because the i386 ABI won't
@@ -9,4 +9,4 @@
 #define ARCH_PACK_COMPAT_STATFS64 __attribute__((packed,aligned(4)))
 
 #include <asm-generic/statfs.h>
-#endif /* ASM_X86__STATFS_H */
+#endif /* _ASM_X86_STATFS_H */
similarity index 98%
rename from include/asm-x86/string_32.h
rename to arch/x86/include/asm/string_32.h
index 487843ed245a54bd91dadaca58413b650b0976cb..0e0e3ba827f74dcad11f51f898bf1f1311afa805 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__STRING_32_H
-#define ASM_X86__STRING_32_H
+#ifndef _ASM_X86_STRING_32_H
+#define _ASM_X86_STRING_32_H
 
 #ifdef __KERNEL__
 
@@ -323,4 +323,4 @@ extern void *memscan(void *addr, int c, size_t size);
 
 #endif /* __KERNEL__ */
 
-#endif /* ASM_X86__STRING_32_H */
+#endif /* _ASM_X86_STRING_32_H */
similarity index 94%
rename from include/asm-x86/string_64.h
rename to arch/x86/include/asm/string_64.h
index a2add11d3b66a6424f528cd365aaf6818db9556a..2afe164bf1e67a73f622c751adaeed870e12075f 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__STRING_64_H
-#define ASM_X86__STRING_64_H
+#ifndef _ASM_X86_STRING_64_H
+#define _ASM_X86_STRING_64_H
 
 #ifdef __KERNEL__
 
@@ -57,4 +57,4 @@ int strcmp(const char *cs, const char *ct);
 
 #endif /* __KERNEL__ */
 
-#endif /* ASM_X86__STRING_64_H */
+#endif /* _ASM_X86_STRING_64_H */
similarity index 99%
rename from include/asm-x86/summit/apic.h
rename to arch/x86/include/asm/summit/apic.h
index 394b00bb5e72542b3bfd4ecc2efbee58157cf3a9..9b3070f1c2ac6fb80f0b53edf9b33b080af0f081 100644 (file)
@@ -22,7 +22,6 @@ static inline cpumask_t target_cpus(void)
         */
        return cpumask_of_cpu(0);
 }
-#define TARGET_CPUS    (target_cpus())
 
 #define INT_DELIVERY_MODE (dest_LowestPrio)
 #define INT_DEST_MODE 1     /* logical delivery broadcast to all procs */
similarity index 92%
rename from include/asm-x86/suspend_32.h
rename to arch/x86/include/asm/suspend_32.h
index acb6d4d491f4d35b704b2dac6e52ce21cb409161..a5074bd0f8be5a268888237d14668b5ea9eb4ab4 100644 (file)
@@ -3,8 +3,8 @@
  * Based on code
  * Copyright 2001 Patrick Mochel <mochel@osdl.org>
  */
-#ifndef ASM_X86__SUSPEND_32_H
-#define ASM_X86__SUSPEND_32_H
+#ifndef _ASM_X86_SUSPEND_32_H
+#define _ASM_X86_SUSPEND_32_H
 
 #include <asm/desc.h>
 #include <asm/i387.h>
@@ -48,4 +48,4 @@ static inline void acpi_save_register_state(unsigned long return_point)
 extern int acpi_save_state_mem(void);
 #endif
 
-#endif /* ASM_X86__SUSPEND_32_H */
+#endif /* _ASM_X86_SUSPEND_32_H */
similarity index 92%
rename from include/asm-x86/suspend_64.h
rename to arch/x86/include/asm/suspend_64.h
index cf821dd310e81c9bf8858452188f70152bfe17a3..06284f42b7599a8f46669fc3e4f6c9d8bbea7eb7 100644 (file)
@@ -3,8 +3,8 @@
  * Based on code
  * Copyright 2001 Patrick Mochel <mochel@osdl.org>
  */
-#ifndef ASM_X86__SUSPEND_64_H
-#define ASM_X86__SUSPEND_64_H
+#ifndef _ASM_X86_SUSPEND_64_H
+#define _ASM_X86_SUSPEND_64_H
 
 #include <asm/desc.h>
 #include <asm/i387.h>
@@ -49,4 +49,4 @@ extern int acpi_save_state_mem(void);
 extern char core_restore_code;
 extern char restore_registers;
 
-#endif /* ASM_X86__SUSPEND_64_H */
+#endif /* _ASM_X86_SUSPEND_64_H */
similarity index 95%
rename from include/asm-x86/swiotlb.h
rename to arch/x86/include/asm/swiotlb.h
index 1e20adbcad4b0cff70243b4ed71c7182e2371c64..51fb2c76ad7492c01a66c60f6dd99816c2f0351b 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SWIOTLB_H
-#define ASM_X86__SWIOTLB_H
+#ifndef _ASM_X86_SWIOTLB_H
+#define _ASM_X86_SWIOTLB_H
 
 #include <asm/dma-mapping.h>
 
@@ -55,4 +55,4 @@ static inline void pci_swiotlb_init(void)
 
 static inline void dma_mark_clean(void *addr, size_t size) {}
 
-#endif /* ASM_X86__SWIOTLB_H */
+#endif /* _ASM_X86_SWIOTLB_H */
similarity index 97%
rename from include/asm-x86/sync_bitops.h
rename to arch/x86/include/asm/sync_bitops.h
index b689bee71104da4ba5b9eff3fa597606cfdd9de3..9d09b4073b60f137e970be710ebc171a4b001125 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SYNC_BITOPS_H
-#define ASM_X86__SYNC_BITOPS_H
+#ifndef _ASM_X86_SYNC_BITOPS_H
+#define _ASM_X86_SYNC_BITOPS_H
 
 /*
  * Copyright 1992, Linus Torvalds.
@@ -127,4 +127,4 @@ static inline int sync_test_and_change_bit(int nr, volatile unsigned long *addr)
 
 #undef ADDR
 
-#endif /* ASM_X86__SYNC_BITOPS_H */
+#endif /* _ASM_X86_SYNC_BITOPS_H */
similarity index 96%
rename from include/asm-x86/syscall.h
rename to arch/x86/include/asm/syscall.h
index 04c47dc5597cf9f002408ca2590210b0477fa74b..d82f39bb7905e8f14d3cbd1dc0365ba98f03eea6 100644 (file)
@@ -10,8 +10,8 @@
  * See asm-generic/syscall.h for descriptions of what we must do here.
  */
 
-#ifndef _ASM_SYSCALL_H
-#define _ASM_SYSCALL_H 1
+#ifndef _ASM_X86_SYSCALL_H
+#define _ASM_X86_SYSCALL_H
 
 #include <linux/sched.h>
 #include <linux/err.h>
@@ -93,26 +93,26 @@ static inline void syscall_get_arguments(struct task_struct *task,
 {
 # ifdef CONFIG_IA32_EMULATION
        if (task_thread_info(task)->status & TS_COMPAT)
-               switch (i + n) {
-               case 6:
+               switch (i) {
+               case 0:
                        if (!n--) break;
-                       *args++ = regs->bp;
-               case 5:
+                       *args++ = regs->bx;
+               case 1:
                        if (!n--) break;
-                       *args++ = regs->di;
-               case 4:
+                       *args++ = regs->cx;
+               case 2:
                        if (!n--) break;
-                       *args++ = regs->si;
+                       *args++ = regs->dx;
                case 3:
                        if (!n--) break;
-                       *args++ = regs->dx;
-               case 2:
+                       *args++ = regs->si;
+               case 4:
                        if (!n--) break;
-                       *args++ = regs->cx;
-               case 1:
+                       *args++ = regs->di;
+               case 5:
                        if (!n--) break;
-                       *args++ = regs->bx;
-               case 0:
+                       *args++ = regs->bp;
+               case 6:
                        if (!n--) break;
                default:
                        BUG();
@@ -120,26 +120,26 @@ static inline void syscall_get_arguments(struct task_struct *task,
                }
        else
 # endif
-               switch (i + n) {
-               case 6:
+               switch (i) {
+               case 0:
                        if (!n--) break;
-                       *args++ = regs->r9;
-               case 5:
+                       *args++ = regs->di;
+               case 1:
                        if (!n--) break;
-                       *args++ = regs->r8;
-               case 4:
+                       *args++ = regs->si;
+               case 2:
                        if (!n--) break;
-                       *args++ = regs->r10;
+                       *args++ = regs->dx;
                case 3:
                        if (!n--) break;
-                       *args++ = regs->dx;
-               case 2:
+                       *args++ = regs->r10;
+               case 4:
                        if (!n--) break;
-                       *args++ = regs->si;
-               case 1:
+                       *args++ = regs->r8;
+               case 5:
                        if (!n--) break;
-                       *args++ = regs->di;
-               case 0:
+                       *args++ = regs->r9;
+               case 6:
                        if (!n--) break;
                default:
                        BUG();
@@ -154,58 +154,60 @@ static inline void syscall_set_arguments(struct task_struct *task,
 {
 # ifdef CONFIG_IA32_EMULATION
        if (task_thread_info(task)->status & TS_COMPAT)
-               switch (i + n) {
-               case 6:
+               switch (i) {
+               case 0:
                        if (!n--) break;
-                       regs->bp = *args++;
-               case 5:
+                       regs->bx = *args++;
+               case 1:
                        if (!n--) break;
-                       regs->di = *args++;
-               case 4:
+                       regs->cx = *args++;
+               case 2:
                        if (!n--) break;
-                       regs->si = *args++;
+                       regs->dx = *args++;
                case 3:
                        if (!n--) break;
-                       regs->dx = *args++;
-               case 2:
+                       regs->si = *args++;
+               case 4:
                        if (!n--) break;
-                       regs->cx = *args++;
-               case 1:
+                       regs->di = *args++;
+               case 5:
                        if (!n--) break;
-                       regs->bx = *args++;
-               case 0:
+                       regs->bp = *args++;
+               case 6:
                        if (!n--) break;
                default:
                        BUG();
+                       break;
                }
        else
 # endif
-               switch (i + n) {
-               case 6:
+               switch (i) {
+               case 0:
                        if (!n--) break;
-                       regs->r9 = *args++;
-               case 5:
+                       regs->di = *args++;
+               case 1:
                        if (!n--) break;
-                       regs->r8 = *args++;
-               case 4:
+                       regs->si = *args++;
+               case 2:
                        if (!n--) break;
-                       regs->r10 = *args++;
+                       regs->dx = *args++;
                case 3:
                        if (!n--) break;
-                       regs->dx = *args++;
-               case 2:
+                       regs->r10 = *args++;
+               case 4:
                        if (!n--) break;
-                       regs->si = *args++;
-               case 1:
+                       regs->r8 = *args++;
+               case 5:
                        if (!n--) break;
-                       regs->di = *args++;
-               case 0:
+                       regs->r9 = *args++;
+               case 6:
                        if (!n--) break;
                default:
                        BUG();
+                       break;
                }
 }
 
 #endif /* CONFIG_X86_32 */
 
-#endif /* _ASM_SYSCALL_H */
+#endif /* _ASM_X86_SYSCALL_H */
similarity index 99%
rename from include/asm-x86/system.h
rename to arch/x86/include/asm/system.h
index b20c894660f95ee1d056d86a238e2bb116cb673c..2ed3f0f44ff73519a149b37c9bd658a26361c8de 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SYSTEM_H
-#define ASM_X86__SYSTEM_H
+#ifndef _ASM_X86_SYSTEM_H
+#define _ASM_X86_SYSTEM_H
 
 #include <asm/asm.h>
 #include <asm/segment.h>
@@ -422,4 +422,4 @@ static inline void rdtsc_barrier(void)
        alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC);
 }
 
-#endif /* ASM_X86__SYSTEM_H */
+#endif /* _ASM_X86_SYSTEM_H */
similarity index 77%
rename from include/asm-x86/system_64.h
rename to arch/x86/include/asm/system_64.h
index 5aedb8bffc5a0c50fc3e6ac4576efc4686a94b37..1159e091ad09c66a9f3efab3a387e9536493165d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__SYSTEM_64_H
-#define ASM_X86__SYSTEM_64_H
+#ifndef _ASM_X86_SYSTEM_64_H
+#define _ASM_X86_SYSTEM_64_H
 
 #include <asm/segment.h>
 #include <asm/cmpxchg.h>
@@ -19,4 +19,4 @@ static inline void write_cr8(unsigned long val)
 
 #include <linux/irqflags.h>
 
-#endif /* ASM_X86__SYSTEM_64_H */
+#endif /* _ASM_X86_SYSTEM_64_H */
similarity index 95%
rename from include/asm-x86/tce.h
rename to arch/x86/include/asm/tce.h
index e7932d7fbbab9d10ccff23b170f54d20a9e15a32..7a6677c1a7156b5caba4695d236c310f892b5171 100644 (file)
@@ -21,8 +21,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-#ifndef ASM_X86__TCE_H
-#define ASM_X86__TCE_H
+#ifndef _ASM_X86_TCE_H
+#define _ASM_X86_TCE_H
 
 extern unsigned int specified_table_size;
 struct iommu_table;
@@ -45,4 +45,4 @@ extern void * __init alloc_tce_table(void);
 extern void __init free_tce_table(void *tbl);
 extern int __init build_tce_table(struct pci_dev *dev, void __iomem *bbar);
 
-#endif /* ASM_X86__TCE_H */
+#endif /* _ASM_X86_TCE_H */
similarity index 98%
rename from include/asm-x86/termbits.h
rename to arch/x86/include/asm/termbits.h
index 3d00dc5e0c717967fb0b5a73663df7850c695a58..af1b70ea440fe2e4d6fded733d86a91bcb4d89af 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__TERMBITS_H
-#define ASM_X86__TERMBITS_H
+#ifndef _ASM_X86_TERMBITS_H
+#define _ASM_X86_TERMBITS_H
 
 #include <linux/posix_types.h>
 
@@ -195,4 +195,4 @@ struct ktermios {
 #define        TCSADRAIN       1
 #define        TCSAFLUSH       2
 
-#endif /* ASM_X86__TERMBITS_H */
+#endif /* _ASM_X86_TERMBITS_H */
similarity index 97%
rename from include/asm-x86/termios.h
rename to arch/x86/include/asm/termios.h
index e235db248071f4cbc14a881049e215b2ab6bd038..f72956331c49349623014bffc4c241f01c361eee 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__TERMIOS_H
-#define ASM_X86__TERMIOS_H
+#ifndef _ASM_X86_TERMIOS_H
+#define _ASM_X86_TERMIOS_H
 
 #include <asm/termbits.h>
 #include <asm/ioctls.h>
@@ -110,4 +110,4 @@ static inline int kernel_termios_to_user_termios_1(struct termios __user *u,
 
 #endif /* __KERNEL__ */
 
-#endif /* ASM_X86__TERMIOS_H */
+#endif /* _ASM_X86_TERMIOS_H */
diff --git a/arch/x86/include/asm/therm_throt.h b/arch/x86/include/asm/therm_throt.h
new file mode 100644 (file)
index 0000000..c62349e
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _ASM_X86_THERM_THROT_H
+#define _ASM_X86_THERM_THROT_H
+
+#include <asm/atomic.h>
+
+extern atomic_t therm_throt_en;
+int therm_throt_process(int curr);
+
+#endif /* _ASM_X86_THERM_THROT_H */
similarity index 98%
rename from include/asm-x86/thread_info.h
rename to arch/x86/include/asm/thread_info.h
index 3f4e52bb77f56449adc92d2bd08f48da4803a78c..e44d379faad2b891245ef9cc2332dcaf8f8491c5 100644 (file)
@@ -4,8 +4,8 @@
  * - Incorporating suggestions made by Linus Torvalds and Dave Miller
  */
 
-#ifndef ASM_X86__THREAD_INFO_H
-#define ASM_X86__THREAD_INFO_H
+#ifndef _ASM_X86_THREAD_INFO_H
+#define _ASM_X86_THREAD_INFO_H
 
 #include <linux/compiler.h>
 #include <asm/page.h>
@@ -261,4 +261,4 @@ extern void free_thread_info(struct thread_info *ti);
 extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
 #define arch_task_cache_init arch_task_cache_init
 #endif
-#endif /* ASM_X86__THREAD_INFO_H */
+#endif /* _ASM_X86_THREAD_INFO_H */
similarity index 93%
rename from include/asm-x86/time.h
rename to arch/x86/include/asm/time.h
index 3e724eef7ac468f118bb8c7c95edac31577cc739..50c733aac421b2a850238590fd0820a186bfcab7 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__TIME_H
-#define ASM_X86__TIME_H
+#ifndef _ASM_X86_TIME_H
+#define _ASM_X86_TIME_H
 
 extern void hpet_time_init(void);
 
@@ -60,4 +60,4 @@ extern void time_init(void);
 
 extern unsigned long __init calibrate_cpu(void);
 
-#endif /* ASM_X86__TIME_H */
+#endif /* _ASM_X86_TIME_H */
similarity index 95%
rename from include/asm-x86/timer.h
rename to arch/x86/include/asm/timer.h
index d0babce4b47a6ecbc9d3ca62bf084665c49a02b9..2bb6a835c453c0ced2d9b7e78e998e7fde5d8c3e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__TIMER_H
-#define ASM_X86__TIMER_H
+#ifndef _ASM_X86_TIMER_H
+#define _ASM_X86_TIMER_H
 #include <linux/init.h>
 #include <linux/pm.h>
 #include <linux/percpu.h>
@@ -63,4 +63,4 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc)
        return ns;
 }
 
-#endif /* ASM_X86__TIMER_H */
+#endif /* _ASM_X86_TIMER_H */
similarity index 84%
rename from include/asm-x86/timex.h
rename to arch/x86/include/asm/timex.h
index d1ce2416a5da14e61d151150622e4dbe7491c866..1287dc1347d67417918454fcbc59d1959bf48e7e 100644 (file)
@@ -1,6 +1,6 @@
 /* x86 architecture timex specifications */
-#ifndef ASM_X86__TIMEX_H
-#define ASM_X86__TIMEX_H
+#ifndef _ASM_X86_TIMEX_H
+#define _ASM_X86_TIMEX_H
 
 #include <asm/processor.h>
 #include <asm/tsc.h>
@@ -16,4 +16,4 @@
 
 #define ARCH_HAS_READ_CURRENT_TIMER
 
-#endif /* ASM_X86__TIMEX_H */
+#endif /* _ASM_X86_TIMEX_H */
similarity index 76%
rename from include/asm-x86/tlb.h
rename to arch/x86/include/asm/tlb.h
index db36e9e89e873c7d65a2115c119ec7d828aa6133..829215fef9eeba089e4d3a315d5a6cf0bf9c3c21 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__TLB_H
-#define ASM_X86__TLB_H
+#ifndef _ASM_X86_TLB_H
+#define _ASM_X86_TLB_H
 
 #define tlb_start_vma(tlb, vma) do { } while (0)
 #define tlb_end_vma(tlb, vma) do { } while (0)
@@ -8,4 +8,4 @@
 
 #include <asm-generic/tlb.h>
 
-#endif /* ASM_X86__TLB_H */
+#endif /* _ASM_X86_TLB_H */
similarity index 97%
rename from include/asm-x86/tlbflush.h
rename to arch/x86/include/asm/tlbflush.h
index 3cdd08b5bdb741d0dc55352295a6efa0058bb944..0e7bbb5491169f69c4b0b0e2d0e98a8445d95fcd 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__TLBFLUSH_H
-#define ASM_X86__TLBFLUSH_H
+#ifndef _ASM_X86_TLBFLUSH_H
+#define _ASM_X86_TLBFLUSH_H
 
 #include <linux/mm.h>
 #include <linux/sched.h>
@@ -175,4 +175,4 @@ static inline void flush_tlb_kernel_range(unsigned long start,
        flush_tlb_all();
 }
 
-#endif /* ASM_X86__TLBFLUSH_H */
+#endif /* _ASM_X86_TLBFLUSH_H */
similarity index 98%
rename from include/asm-x86/topology.h
rename to arch/x86/include/asm/topology.h
index 7eca9bc022b2dd40568f6ff963dcd271a17de616..90ac7718469a5b416bfd90350b24ade716698925 100644 (file)
@@ -22,8 +22,8 @@
  *
  * Send feedback to <colpatch@us.ibm.com>
  */
-#ifndef ASM_X86__TOPOLOGY_H
-#define ASM_X86__TOPOLOGY_H
+#ifndef _ASM_X86_TOPOLOGY_H
+#define _ASM_X86_TOPOLOGY_H
 
 #ifdef CONFIG_X86_32
 # ifdef CONFIG_X86_HT
@@ -255,4 +255,4 @@ static inline void set_mp_bus_to_node(int busnum, int node)
 }
 #endif
 
-#endif /* ASM_X86__TOPOLOGY_H */
+#endif /* _ASM_X86_TOPOLOGY_H */
similarity index 79%
rename from include/asm-x86/trampoline.h
rename to arch/x86/include/asm/trampoline.h
index 0406bbd898a9601efbb5af853340712ed53e19a9..fa0d79facdbc4b0175db51082d1afcaad3f4a060 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__TRAMPOLINE_H
-#define ASM_X86__TRAMPOLINE_H
+#ifndef _ASM_X86_TRAMPOLINE_H
+#define _ASM_X86_TRAMPOLINE_H
 
 #ifndef __ASSEMBLY__
 
@@ -18,4 +18,4 @@ extern unsigned long setup_trampoline(void);
 
 #endif /* __ASSEMBLY__ */
 
-#endif /* ASM_X86__TRAMPOLINE_H */
+#endif /* _ASM_X86_TRAMPOLINE_H */
similarity index 97%
rename from include/asm-x86/traps.h
rename to arch/x86/include/asm/traps.h
index 6c3dc2c65751fbb832d8c7fa26dc318c401c80b2..45dee286e45cda98bc1fe20e79c30ccded41ff5d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__TRAPS_H
-#define ASM_X86__TRAPS_H
+#ifndef _ASM_X86_TRAPS_H
+#define _ASM_X86_TRAPS_H
 
 #include <asm/debugreg.h>
 
@@ -78,4 +78,4 @@ unsigned long patch_espfix_desc(unsigned long, unsigned long);
 asmlinkage void math_emulate(long);
 #endif
 
-#endif /* ASM_X86__TRAPS_H */
+#endif /* _ASM_X86_TRAPS_H */
similarity index 93%
rename from include/asm-x86/tsc.h
rename to arch/x86/include/asm/tsc.h
index ad0f5c41e78cde2ba21c653cc4a159faed9e27d7..38ae163cc91b00bf029d5ed5e29cd8ba96bd461b 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * x86 TSC related functions
  */
-#ifndef ASM_X86__TSC_H
-#define ASM_X86__TSC_H
+#ifndef _ASM_X86_TSC_H
+#define _ASM_X86_TSC_H
 
 #include <asm/processor.h>
 
@@ -59,4 +59,4 @@ extern void check_tsc_sync_target(void);
 
 extern int notsc_setup(char *);
 
-#endif /* ASM_X86__TSC_H */
+#endif /* _ASM_X86_TSC_H */
similarity index 87%
rename from include/asm-x86/types.h
rename to arch/x86/include/asm/types.h
index e78b52e17444ac245618369c52d34514805481f9..e6f7363200773e13f94b02ef53a8dab57d974bef 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__TYPES_H
-#define ASM_X86__TYPES_H
+#ifndef _ASM_X86_TYPES_H
+#define _ASM_X86_TYPES_H
 
 #include <asm-generic/int-ll64.h>
 
@@ -33,4 +33,4 @@ typedef u32 dma_addr_t;
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 
-#endif /* ASM_X86__TYPES_H */
+#endif /* _ASM_X86_TYPES_H */
similarity index 99%
rename from include/asm-x86/uaccess.h
rename to arch/x86/include/asm/uaccess.h
index 48ebc0ad40ec17b66b700812c5c4792662227a8f..35c54921b2e434cdd95bbd223077f2b1155d0f1f 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__UACCESS_H
-#define ASM_X86__UACCESS_H
+#ifndef _ASM_X86_UACCESS_H
+#define _ASM_X86_UACCESS_H
 /*
  * User space memory access functions
  */
@@ -450,5 +450,5 @@ extern struct movsl_mask {
 # include "uaccess_64.h"
 #endif
 
-#endif /* ASM_X86__UACCESS_H */
+#endif /* _ASM_X86_UACCESS_H */
 
similarity index 98%
rename from include/asm-x86/uaccess_32.h
rename to arch/x86/include/asm/uaccess_32.h
index 6b5b57d9c6d1f9ee55cf15cebf75090696c63f45..d095a3aeea1b44d3063f0165c956d0a156c6ca38 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__UACCESS_32_H
-#define ASM_X86__UACCESS_32_H
+#ifndef _ASM_X86_UACCESS_32_H
+#define _ASM_X86_UACCESS_32_H
 
 /*
  * User space memory access functions
@@ -215,4 +215,4 @@ long strnlen_user(const char __user *str, long n);
 unsigned long __must_check clear_user(void __user *mem, unsigned long len);
 unsigned long __must_check __clear_user(void __user *mem, unsigned long len);
 
-#endif /* ASM_X86__UACCESS_32_H */
+#endif /* _ASM_X86_UACCESS_32_H */
similarity index 98%
rename from include/asm-x86/uaccess_64.h
rename to arch/x86/include/asm/uaccess_64.h
index c96c1f5d07a2c88e4f5ca547ea0f7154ac68583c..664f15280f14354dc057e1d97954db6baab4b959 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__UACCESS_64_H
-#define ASM_X86__UACCESS_64_H
+#ifndef _ASM_X86_UACCESS_64_H
+#define _ASM_X86_UACCESS_64_H
 
 /*
  * User space memory access functions
@@ -199,4 +199,4 @@ static inline int __copy_from_user_inatomic_nocache(void *dst,
 unsigned long
 copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest);
 
-#endif /* ASM_X86__UACCESS_64_H */
+#endif /* _ASM_X86_UACCESS_64_H */
similarity index 81%
rename from include/asm-x86/ucontext.h
rename to arch/x86/include/asm/ucontext.h
index 89eaa5456a7e1e86f25f92c41bd85d2bc629ec33..87324cf439d9bd83e918460213dddb3c55765c61 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__UCONTEXT_H
-#define ASM_X86__UCONTEXT_H
+#ifndef _ASM_X86_UCONTEXT_H
+#define _ASM_X86_UCONTEXT_H
 
 #define UC_FP_XSTATE   0x1     /* indicates the presence of extended state
                                 * information in the memory layout pointed
@@ -15,4 +15,4 @@ struct ucontext {
        sigset_t          uc_sigmask;   /* mask last for extensibility */
 };
 
-#endif /* ASM_X86__UCONTEXT_H */
+#endif /* _ASM_X86_UCONTEXT_H */
similarity index 69%
rename from include/asm-x86/unaligned.h
rename to arch/x86/include/asm/unaligned.h
index 59dcdec37160a02127780c1b7f9a76743c2041e0..a7bd416b4763832f0a9851df49e92c938b8c5232 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__UNALIGNED_H
-#define ASM_X86__UNALIGNED_H
+#ifndef _ASM_X86_UNALIGNED_H
+#define _ASM_X86_UNALIGNED_H
 
 /*
  * The x86 can do unaligned accesses itself.
@@ -11,4 +11,4 @@
 #define get_unaligned __get_unaligned_le
 #define put_unaligned __put_unaligned_le
 
-#endif /* ASM_X86__UNALIGNED_H */
+#endif /* _ASM_X86_UNALIGNED_H */
similarity index 99%
rename from include/asm-x86/unistd_32.h
rename to arch/x86/include/asm/unistd_32.h
index 017f4a87c9132bbce98f194b55d80c95ea3bfd65..f2bba78430a4d2628ca83203e193dcb6ee78a247 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__UNISTD_32_H
-#define ASM_X86__UNISTD_32_H
+#ifndef _ASM_X86_UNISTD_32_H
+#define _ASM_X86_UNISTD_32_H
 
 /*
  * This file contains the system call numbers.
 #endif
 
 #endif /* __KERNEL__ */
-#endif /* ASM_X86__UNISTD_32_H */
+#endif /* _ASM_X86_UNISTD_32_H */
similarity index 99%
rename from include/asm-x86/unistd_64.h
rename to arch/x86/include/asm/unistd_64.h
index ace83f1f678730134569f1efb3656a1d869156d4..834b2c1d89fb1a51cb32a47f647ad8b1e3c1bc4d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__UNISTD_64_H
-#define ASM_X86__UNISTD_64_H
+#ifndef _ASM_X86_UNISTD_64_H
+#define _ASM_X86_UNISTD_64_H
 
 #ifndef __SYSCALL
 #define __SYSCALL(a, b)
@@ -690,4 +690,4 @@ __SYSCALL(__NR_inotify_init1, sys_inotify_init1)
 #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
 #endif /* __KERNEL__ */
 
-#endif /* ASM_X86__UNISTD_64_H */
+#endif /* _ASM_X86_UNISTD_64_H */
similarity index 70%
rename from include/asm-x86/unwind.h
rename to arch/x86/include/asm/unwind.h
index a2151567db44388a2465bc32924f7399942a821d..8b064bd9c5535fa741c404b6e202445a8a9a003b 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__UNWIND_H
-#define ASM_X86__UNWIND_H
+#ifndef _ASM_X86_UNWIND_H
+#define _ASM_X86_UNWIND_H
 
 #define UNW_PC(frame) ((void)(frame), 0UL)
 #define UNW_SP(frame) ((void)(frame), 0UL)
@@ -10,4 +10,4 @@ static inline int arch_unw_user_mode(const void *info)
        return 0;
 }
 
-#endif /* ASM_X86__UNWIND_H */
+#endif /* _ASM_X86_UNWIND_H */
similarity index 96%
rename from include/asm-x86/user32.h
rename to arch/x86/include/asm/user32.h
index aa66c1857f06580e80160b5f8c4f1a1d0495b1df..14cbb73ebcba488c730662f7129d6cff7c4997a2 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__USER32_H
-#define ASM_X86__USER32_H
+#ifndef _ASM_X86_USER32_H
+#define _ASM_X86_USER32_H
 
 /* IA32 compatible user structures for ptrace.
  * These should be used for 32bit coredumps too. */
@@ -67,4 +67,4 @@ struct user32 {
 };
 
 
-#endif /* ASM_X86__USER32_H */
+#endif /* _ASM_X86_USER32_H */
similarity index 98%
rename from include/asm-x86/user_32.h
rename to arch/x86/include/asm/user_32.h
index e0fe2f55f1a6c736bcc2e568b9f355c50ede638c..bebfd86440162d04f6022acbe98ecaf314765a00 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__USER_32_H
-#define ASM_X86__USER_32_H
+#ifndef _ASM_X86_USER_32_H
+#define _ASM_X86_USER_32_H
 
 #include <asm/page.h>
 /* Core file format: The core file is written in such a way that gdb
@@ -128,4 +128,4 @@ struct user{
 #define HOST_TEXT_START_ADDR (u.start_code)
 #define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
 
-#endif /* ASM_X86__USER_32_H */
+#endif /* _ASM_X86_USER_32_H */
similarity index 98%
rename from include/asm-x86/user_64.h
rename to arch/x86/include/asm/user_64.h
index 38b5799863b455ecd911ceb23685a9ec5bcde74b..faf2cd3e0d765166351d5487abd9075f8ab6f991 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__USER_64_H
-#define ASM_X86__USER_64_H
+#ifndef _ASM_X86_USER_64_H
+#define _ASM_X86_USER_64_H
 
 #include <asm/types.h>
 #include <asm/page.h>
@@ -134,4 +134,4 @@ struct user {
 #define HOST_TEXT_START_ADDR (u.start_code)
 #define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
 
-#endif /* ASM_X86__USER_64_H */
+#endif /* _ASM_X86_USER_64_H */
diff --git a/arch/x86/include/asm/uv/bios.h b/arch/x86/include/asm/uv/bios.h
new file mode 100644 (file)
index 0000000..d931d3b
--- /dev/null
@@ -0,0 +1,94 @@
+#ifndef _ASM_X86_UV_BIOS_H
+#define _ASM_X86_UV_BIOS_H
+
+/*
+ * UV BIOS layer definitions.
+ *
+ *  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) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ *  Copyright (c) Russ Anderson
+ */
+
+#include <linux/rtc.h>
+
+/*
+ * Values for the BIOS calls.  It is passed as the first * argument in the
+ * BIOS call.  Passing any other value in the first argument will result
+ * in a BIOS_STATUS_UNIMPLEMENTED return status.
+ */
+enum uv_bios_cmd {
+       UV_BIOS_COMMON,
+       UV_BIOS_GET_SN_INFO,
+       UV_BIOS_FREQ_BASE
+};
+
+/*
+ * Status values returned from a BIOS call.
+ */
+enum {
+       BIOS_STATUS_SUCCESS             =  0,
+       BIOS_STATUS_UNIMPLEMENTED       = -ENOSYS,
+       BIOS_STATUS_EINVAL              = -EINVAL,
+       BIOS_STATUS_UNAVAIL             = -EBUSY
+};
+
+/*
+ * The UV system table describes specific firmware
+ * capabilities available to the Linux kernel at runtime.
+ */
+struct uv_systab {
+       char signature[4];      /* must be "UVST" */
+       u32 revision;           /* distinguish different firmware revs */
+       u64 function;           /* BIOS runtime callback function ptr */
+};
+
+enum {
+       BIOS_FREQ_BASE_PLATFORM = 0,
+       BIOS_FREQ_BASE_INTERVAL_TIMER = 1,
+       BIOS_FREQ_BASE_REALTIME_CLOCK = 2
+};
+
+union partition_info_u {
+       u64     val;
+       struct {
+               u64     hub_version     :  8,
+                       partition_id    : 16,
+                       coherence_id    : 16,
+                       region_size     : 24;
+       };
+};
+
+/*
+ * bios calls have 6 parameters
+ */
+extern s64 uv_bios_call(enum uv_bios_cmd, u64, u64, u64, u64, u64);
+extern s64 uv_bios_call_irqsave(enum uv_bios_cmd, u64, u64, u64, u64, u64);
+extern s64 uv_bios_call_reentrant(enum uv_bios_cmd, u64, u64, u64, u64, u64);
+
+extern s64 uv_bios_get_sn_info(int, int *, long *, long *, long *);
+extern s64 uv_bios_freq_base(u64, u64 *);
+
+extern void uv_bios_init(void);
+
+extern int uv_type;
+extern long sn_partition_id;
+extern long uv_coherency_id;
+extern long uv_region_size;
+#define partition_coherence_id()       (uv_coherency_id)
+
+extern struct kobject *sgi_uv_kobj;    /* /sys/firmware/sgi_uv */
+
+#endif /* _ASM_X86_UV_BIOS_H */
similarity index 99%
rename from include/asm-x86/uv/uv_bau.h
rename to arch/x86/include/asm/uv/uv_bau.h
index 77153fb18f5e085c5b518cdee6e27a587d01a938..e2363253bbbf21431467516d99404c64eaeaec34 100644 (file)
@@ -8,8 +8,8 @@
  * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved.
  */
 
-#ifndef ASM_X86__UV__UV_BAU_H
-#define ASM_X86__UV__UV_BAU_H
+#ifndef _ASM_X86_UV_UV_BAU_H
+#define _ASM_X86_UV_UV_BAU_H
 
 #include <linux/bitmap.h>
 #define BITSPERBYTE 8
@@ -329,4 +329,4 @@ extern int uv_flush_tlb_others(cpumask_t *, struct mm_struct *, unsigned long);
 extern void uv_bau_message_intr1(void);
 extern void uv_bau_timeout_intr1(void);
 
-#endif /* ASM_X86__UV__UV_BAU_H */
+#endif /* _ASM_X86_UV_UV_BAU_H */
similarity index 99%
rename from include/asm-x86/uv/uv_hub.h
rename to arch/x86/include/asm/uv/uv_hub.h
index bdb5b01afbf591d66f5b1ec87ee859886459f594..c6ad93e315c815c46cce4388e9034190ee86300f 100644 (file)
@@ -8,8 +8,8 @@
  * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved.
  */
 
-#ifndef ASM_X86__UV__UV_HUB_H
-#define ASM_X86__UV__UV_HUB_H
+#ifndef _ASM_X86_UV_UV_HUB_H
+#define _ASM_X86_UV_UV_HUB_H
 
 #include <linux/numa.h>
 #include <linux/percpu.h>
@@ -350,5 +350,5 @@ static inline int uv_num_possible_blades(void)
        return uv_possible_blades;
 }
 
-#endif /* ASM_X86__UV__UV_HUB_H */
+#endif /* _ASM_X86_UV_UV_HUB_H */
 
diff --git a/arch/x86/include/asm/uv/uv_irq.h b/arch/x86/include/asm/uv/uv_irq.h
new file mode 100644 (file)
index 0000000..9613c8c
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ *
+ * SGI UV IRQ definitions
+ *
+ * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#ifndef _ASM_X86_UV_UV_IRQ_H
+#define _ASM_X86_UV_UV_IRQ_H
+
+/* If a generic version of this structure gets defined, eliminate this one. */
+struct uv_IO_APIC_route_entry {
+       __u64   vector          :  8,
+               delivery_mode   :  3,
+               dest_mode       :  1,
+               delivery_status :  1,
+               polarity        :  1,
+               __reserved_1    :  1,
+               trigger         :  1,
+               mask            :  1,
+               __reserved_2    : 15,
+               dest            : 32;
+};
+
+extern struct irq_chip uv_irq_chip;
+
+extern int arch_enable_uv_irq(char *, unsigned int, int, int, unsigned long);
+extern void arch_disable_uv_irq(int, unsigned long);
+
+extern int uv_setup_irq(char *, int, int, unsigned long);
+extern void uv_teardown_irq(unsigned int, int, unsigned long);
+
+#endif /* _ASM_X86_UV_UV_IRQ_H */
similarity index 99%
rename from include/asm-x86/uv/uv_mmrs.h
rename to arch/x86/include/asm/uv/uv_mmrs.h
index 8b03d89d2459e8f3664bf1dbca34593b40457407..dd627793a23444d109fa966cda31bc43d14a83e2 100644 (file)
@@ -8,8 +8,8 @@
  * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved.
  */
 
-#ifndef ASM_X86__UV__UV_MMRS_H
-#define ASM_X86__UV__UV_MMRS_H
+#ifndef _ASM_X86_UV_UV_MMRS_H
+#define _ASM_X86_UV_UV_MMRS_H
 
 #define UV_MMR_ENABLE          (1UL << 63)
 
@@ -1292,4 +1292,4 @@ union uvh_si_alias2_overlay_config_u {
 };
 
 
-#endif /* ASM_X86__UV__UV_MMRS_H */
+#endif /* _ASM_X86_UV_UV_MMRS_H */
similarity index 94%
rename from include/asm-x86/vdso.h
rename to arch/x86/include/asm/vdso.h
index 4ab320913ea3abcef82fc8313127501249a201bb..9064052b73ded033f961c2756a981ad1789678f0 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__VDSO_H
-#define ASM_X86__VDSO_H
+#ifndef _ASM_X86_VDSO_H
+#define _ASM_X86_VDSO_H
 
 #ifdef CONFIG_X86_64
 extern const char VDSO64_PRELINK[];
@@ -44,4 +44,4 @@ extern const char vdso32_int80_start, vdso32_int80_end;
 extern const char vdso32_syscall_start, vdso32_syscall_end;
 extern const char vdso32_sysenter_start, vdso32_sysenter_end;
 
-#endif /* ASM_X86__VDSO_H */
+#endif /* _ASM_X86_VDSO_H */
similarity index 81%
rename from include/asm-x86/vga.h
rename to arch/x86/include/asm/vga.h
index b9e493d07d07a1478ec8d42538cf55fe54e3b970..c4b9dc2f67c5f6f7a095dd7d4a3a6bb7fd7b3975 100644 (file)
@@ -4,8 +4,8 @@
  *     (c) 1998 Martin Mares <mj@ucw.cz>
  */
 
-#ifndef ASM_X86__VGA_H
-#define ASM_X86__VGA_H
+#ifndef _ASM_X86_VGA_H
+#define _ASM_X86_VGA_H
 
 /*
  *     On the PC, we can just recalculate addresses and then
@@ -17,4 +17,4 @@
 #define vga_readb(x) (*(x))
 #define vga_writeb(x, y) (*(y) = (x))
 
-#endif /* ASM_X86__VGA_H */
+#endif /* _ASM_X86_VGA_H */
similarity index 87%
rename from include/asm-x86/vgtod.h
rename to arch/x86/include/asm/vgtod.h
index 38fd133640211790b4dfe3e0b31a7f171d52e88c..dc27a69e5d2ab1754153afb9281d6023caa18cd4 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__VGTOD_H
-#define ASM_X86__VGTOD_H
+#ifndef _ASM_X86_VGTOD_H
+#define _ASM_X86_VGTOD_H
 
 #include <asm/vsyscall.h>
 #include <linux/clocksource.h>
@@ -26,4 +26,4 @@ extern struct vsyscall_gtod_data __vsyscall_gtod_data
 __section_vsyscall_gtod_data;
 extern struct vsyscall_gtod_data vsyscall_gtod_data;
 
-#endif /* ASM_X86__VGTOD_H */
+#endif /* _ASM_X86_VGTOD_H */
similarity index 97%
rename from include/asm-x86/visws/cobalt.h
rename to arch/x86/include/asm/visws/cobalt.h
index 9627a8fe84e9275a28728fd81158ff465ac1cba9..166adf61e770927e6b33ccc4d013104ad82fb906 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__VISWS__COBALT_H
-#define ASM_X86__VISWS__COBALT_H
+#ifndef _ASM_X86_VISWS_COBALT_H
+#define _ASM_X86_VISWS_COBALT_H
 
 #include <asm/fixmap.h>
 
@@ -122,4 +122,4 @@ extern char visws_board_type;
 
 extern char visws_board_rev;
 
-#endif /* ASM_X86__VISWS__COBALT_H */
+#endif /* _ASM_X86_VISWS_COBALT_H */
similarity index 92%
rename from include/asm-x86/visws/lithium.h
rename to arch/x86/include/asm/visws/lithium.h
index b36d3b378c6353dd2c62811ae8d94afafa8e55fd..a10d89bc12707af65dcce88ebfea9460f84b4b31 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__VISWS__LITHIUM_H
-#define ASM_X86__VISWS__LITHIUM_H
+#ifndef _ASM_X86_VISWS_LITHIUM_H
+#define _ASM_X86_VISWS_LITHIUM_H
 
 #include <asm/fixmap.h>
 
@@ -49,5 +49,5 @@ static inline unsigned short li_pcib_read16(unsigned long reg)
        return *((volatile unsigned short *)(LI_PCIB_VADDR+reg));
 }
 
-#endif /* ASM_X86__VISWS__LITHIUM_H */
+#endif /* _ASM_X86_VISWS_LITHIUM_H */
 
similarity index 96%
rename from include/asm-x86/visws/piix4.h
rename to arch/x86/include/asm/visws/piix4.h
index 61c938045ec95175dc74f81a9b414defb731bc03..d0af4d338e7f201510f169a762d7a5ea56a1b702 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__VISWS__PIIX4_H
-#define ASM_X86__VISWS__PIIX4_H
+#ifndef _ASM_X86_VISWS_PIIX4_H
+#define _ASM_X86_VISWS_PIIX4_H
 
 /*
  * PIIX4 as used on SGI Visual Workstations
  */
 #define        PIIX_GPI_STPCLK         0x4     // STPCLK signal routed back in
 
-#endif /* ASM_X86__VISWS__PIIX4_H */
+#endif /* _ASM_X86_VISWS_PIIX4_H */
similarity index 98%
rename from include/asm-x86/vm86.h
rename to arch/x86/include/asm/vm86.h
index 998bd18eb737d5911b8e3ffa62725957aae9a2d5..f9303602fbc09b733e3f52319d43e0c3c65c8de3 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__VM86_H
-#define ASM_X86__VM86_H
+#ifndef _ASM_X86_VM86_H
+#define _ASM_X86_VM86_H
 
 /*
  * I'm guessing at the VIF/VIP flag usage, but hope that this is how
@@ -205,4 +205,4 @@ static inline int handle_vm86_trap(struct kernel_vm86_regs *a, long b, int c)
 
 #endif /* __KERNEL__ */
 
-#endif /* ASM_X86__VM86_H */
+#endif /* _ASM_X86_VM86_H */
similarity index 97%
rename from include/asm-x86/vmi_time.h
rename to arch/x86/include/asm/vmi_time.h
index b2d39e6a08b73a0aec01c226e2a78c2e9ed02652..c6e0bee93e3c1859a1a801b1129d8b39938da50e 100644 (file)
@@ -22,8 +22,8 @@
  *
  */
 
-#ifndef ASM_X86__VMI_TIME_H
-#define ASM_X86__VMI_TIME_H
+#ifndef _ASM_X86_VMI_TIME_H
+#define _ASM_X86_VMI_TIME_H
 
 /*
  * Raw VMI call indices for timer functions
@@ -95,4 +95,4 @@ extern void __devinit vmi_time_ap_init(void);
 
 #define CONFIG_VMI_ALARM_HZ    100
 
-#endif /* ASM_X86__VMI_TIME_H */
+#endif /* _ASM_X86_VMI_TIME_H */
similarity index 92%
rename from include/asm-x86/vsyscall.h
rename to arch/x86/include/asm/vsyscall.h
index dcd4682413de06bb0c9e41126fbb4f6d8597b104..d0983d255fbdd13d1830bd8e9aa39cbd8c8ceae5 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__VSYSCALL_H
-#define ASM_X86__VSYSCALL_H
+#ifndef _ASM_X86_VSYSCALL_H
+#define _ASM_X86_VSYSCALL_H
 
 enum vsyscall_num {
        __NR_vgettimeofday,
@@ -41,4 +41,4 @@ extern void map_vsyscall(void);
 
 #endif /* __KERNEL__ */
 
-#endif /* ASM_X86__VSYSCALL_H */
+#endif /* _ASM_X86_VSYSCALL_H */
similarity index 78%
rename from include/asm-x86/xen/events.h
rename to arch/x86/include/asm/xen/events.h
index 8151f5b8b6cb577588b15f8cb0ef9eb1f42da451..19144184983aba9ba73bf022453a8ef85e6665db 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__XEN__EVENTS_H
-#define ASM_X86__XEN__EVENTS_H
+#ifndef _ASM_X86_XEN_EVENTS_H
+#define _ASM_X86_XEN_EVENTS_H
 
 enum ipi_vector {
        XEN_RESCHEDULE_VECTOR,
@@ -21,4 +21,4 @@ static inline void xen_do_IRQ(int irq, struct pt_regs *regs)
        do_IRQ(regs);
 }
 
-#endif /* ASM_X86__XEN__EVENTS_H */
+#endif /* _ASM_X86_XEN_EVENTS_H */
diff --git a/arch/x86/include/asm/xen/grant_table.h b/arch/x86/include/asm/xen/grant_table.h
new file mode 100644 (file)
index 0000000..fdbbb45
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _ASM_X86_XEN_GRANT_TABLE_H
+#define _ASM_X86_XEN_GRANT_TABLE_H
+
+#define xen_alloc_vm_area(size)        alloc_vm_area(size)
+#define xen_free_vm_area(area) free_vm_area(area)
+
+#endif /* _ASM_X86_XEN_GRANT_TABLE_H */
similarity index 99%
rename from include/asm-x86/xen/hypercall.h
rename to arch/x86/include/asm/xen/hypercall.h
index 44f4259bee3f0d72a9de91a90c6adfaf0bec6abf..3f6000d95fe21f38dae31ff2dbfb8945703d91f4 100644 (file)
@@ -30,8 +30,8 @@
  * IN THE SOFTWARE.
  */
 
-#ifndef ASM_X86__XEN__HYPERCALL_H
-#define ASM_X86__XEN__HYPERCALL_H
+#ifndef _ASM_X86_XEN_HYPERCALL_H
+#define _ASM_X86_XEN_HYPERCALL_H
 
 #include <linux/errno.h>
 #include <linux/string.h>
@@ -524,4 +524,4 @@ MULTI_stack_switch(struct multicall_entry *mcl,
        mcl->args[1] = esp;
 }
 
-#endif /* ASM_X86__XEN__HYPERCALL_H */
+#endif /* _ASM_X86_XEN_HYPERCALL_H */
similarity index 96%
rename from include/asm-x86/xen/hypervisor.h
rename to arch/x86/include/asm/xen/hypervisor.h
index 445a247595606919e331875acfc34903eff380a9..a38d25ac87d2abdbfb6e077f304210aef43d78f8 100644 (file)
@@ -30,8 +30,8 @@
  * IN THE SOFTWARE.
  */
 
-#ifndef ASM_X86__XEN__HYPERVISOR_H
-#define ASM_X86__XEN__HYPERVISOR_H
+#ifndef _ASM_X86_XEN_HYPERVISOR_H
+#define _ASM_X86_XEN_HYPERVISOR_H
 
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -79,4 +79,4 @@ extern enum xen_domain_type xen_domain_type;
 #define xen_initial_domain()   (xen_pv_domain() && xen_start_info->flags & SIF_INITDOMAIN)
 #define xen_hvm_domain()       (xen_domain_type == XEN_HVM_DOMAIN)
 
-#endif /* ASM_X86__XEN__HYPERVISOR_H */
+#endif /* _ASM_X86_XEN_HYPERVISOR_H */
similarity index 98%
rename from include/asm-x86/xen/interface.h
rename to arch/x86/include/asm/xen/interface.h
index d077bba96da9753d4db566f511575ea8fe0b23db..e8506c1f0c55115e8282ef5b8177b824f88df282 100644 (file)
@@ -6,8 +6,8 @@
  * Copyright (c) 2004, K A Fraser
  */
 
-#ifndef ASM_X86__XEN__INTERFACE_H
-#define ASM_X86__XEN__INTERFACE_H
+#ifndef _ASM_X86_XEN_INTERFACE_H
+#define _ASM_X86_XEN_INTERFACE_H
 
 #ifdef __XEN__
 #define __DEFINE_GUEST_HANDLE(name, type) \
@@ -172,4 +172,4 @@ DEFINE_GUEST_HANDLE_STRUCT(vcpu_guest_context);
 #define XEN_CPUID          XEN_EMULATE_PREFIX "cpuid"
 #endif
 
-#endif /* ASM_X86__XEN__INTERFACE_H */
+#endif /* _ASM_X86_XEN_INTERFACE_H */
similarity index 95%
rename from include/asm-x86/xen/interface_32.h
rename to arch/x86/include/asm/xen/interface_32.h
index 08167e19fc66cdefbdc3e50c3457750a8c324115..42a7e004ae5ca5372553fec8a9059378ab6a55c4 100644 (file)
@@ -6,8 +6,8 @@
  * Copyright (c) 2004, K A Fraser
  */
 
-#ifndef ASM_X86__XEN__INTERFACE_32_H
-#define ASM_X86__XEN__INTERFACE_32_H
+#ifndef _ASM_X86_XEN_INTERFACE_32_H
+#define _ASM_X86_XEN_INTERFACE_32_H
 
 
 /*
@@ -94,4 +94,4 @@ typedef struct xen_callback xen_callback_t;
 #define xen_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20))
 #define xen_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20))
 
-#endif /* ASM_X86__XEN__INTERFACE_32_H */
+#endif /* _ASM_X86_XEN_INTERFACE_32_H */
similarity index 97%
rename from include/asm-x86/xen/interface_64.h
rename to arch/x86/include/asm/xen/interface_64.h
index 046c0f1e01d4095574ce63716f34f104bfc1d8fc..100d2662b97c3c8a821fc6039e93a06b7a2924c7 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__XEN__INTERFACE_64_H
-#define ASM_X86__XEN__INTERFACE_64_H
+#ifndef _ASM_X86_XEN_INTERFACE_64_H
+#define _ASM_X86_XEN_INTERFACE_64_H
 
 /*
  * 64-bit segment selectors
@@ -156,4 +156,4 @@ typedef unsigned long xen_callback_t;
 #endif /* !__ASSEMBLY__ */
 
 
-#endif /* ASM_X86__XEN__INTERFACE_64_H */
+#endif /* _ASM_X86_XEN_INTERFACE_64_H */
similarity index 98%
rename from include/asm-x86/xen/page.h
rename to arch/x86/include/asm/xen/page.h
index d5eada0a48d9bea73e8dcadeaf2379dc69ee3639..bc628998a1b9dc896a416d6ea0ef5293463c8a24 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__XEN__PAGE_H
-#define ASM_X86__XEN__PAGE_H
+#ifndef _ASM_X86_XEN_PAGE_H
+#define _ASM_X86_XEN_PAGE_H
 
 #include <linux/pfn.h>
 
@@ -162,4 +162,4 @@ xmaddr_t arbitrary_virt_to_machine(void *address);
 void make_lowmem_page_readonly(void *vaddr);
 void make_lowmem_page_readwrite(void *vaddr);
 
-#endif /* ASM_X86__XEN__PAGE_H */
+#endif /* _ASM_X86_XEN_PAGE_H */
similarity index 99%
rename from include/asm-x86/xor_32.h
rename to arch/x86/include/asm/xor_32.h
index 921b458404495b2ace1ee3f201f5040e2179a2ee..133b40a0f495fb69ba4fcc4c7f378b04391f28d7 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__XOR_32_H
-#define ASM_X86__XOR_32_H
+#ifndef _ASM_X86_XOR_32_H
+#define _ASM_X86_XOR_32_H
 
 /*
  * Optimized RAID-5 checksumming functions for MMX and SSE.
@@ -885,4 +885,4 @@ do {                                                        \
 #define XOR_SELECT_TEMPLATE(FASTEST)                   \
        (cpu_has_xmm ? &xor_block_pIII_sse : FASTEST)
 
-#endif /* ASM_X86__XOR_32_H */
+#endif /* _ASM_X86_XOR_32_H */
similarity index 98%
rename from include/asm-x86/xor_64.h
rename to arch/x86/include/asm/xor_64.h
index 2d3a18de295b5aa03e82fe209ae6c667f97abfd6..1549b5e261f616945ed1fdbcc5af8c7961a5dbb4 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86__XOR_64_H
-#define ASM_X86__XOR_64_H
+#ifndef _ASM_X86_XOR_64_H
+#define _ASM_X86_XOR_64_H
 
 /*
  * Optimized RAID-5 checksumming functions for MMX and SSE.
@@ -358,4 +358,4 @@ do {                                                \
    deals with a load to a line that is being prefetched.  */
 #define XOR_SELECT_TEMPLATE(FASTEST) (&xor_block_sse)
 
-#endif /* ASM_X86__XOR_64_H */
+#endif /* _ASM_X86_XOR_64_H */
index 0d41f0343dc0753e5be4c97fd8b36460bc0ab2a5..d7e5a58ee22f376c13caab451ac1dcf6d4e33b08 100644 (file)
@@ -23,7 +23,7 @@ CFLAGS_hpet.o         := $(nostackp)
 CFLAGS_tsc.o           := $(nostackp)
 
 obj-y                  := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o
-obj-y                  += traps.o irq_$(BITS).o dumpstack_$(BITS).o
+obj-y                  += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
 obj-y                  += time_$(BITS).o ioport.o ldt.o
 obj-y                  += setup.o i8259.o irqinit_$(BITS).o setup_percpu.o
 obj-$(CONFIG_X86_VISWS)        += visws_quirks.o
@@ -60,8 +60,8 @@ obj-$(CONFIG_X86_32_SMP)      += smpcommon.o
 obj-$(CONFIG_X86_64_SMP)       += tsc_sync.o smpcommon.o
 obj-$(CONFIG_X86_TRAMPOLINE)   += trampoline_$(BITS).o
 obj-$(CONFIG_X86_MPPARSE)      += mpparse.o
-obj-$(CONFIG_X86_LOCAL_APIC)   += apic_$(BITS).o nmi.o
-obj-$(CONFIG_X86_IO_APIC)      += io_apic_$(BITS).o
+obj-$(CONFIG_X86_LOCAL_APIC)   += apic.o nmi.o
+obj-$(CONFIG_X86_IO_APIC)      += io_apic.o
 obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o
 obj-$(CONFIG_DYNAMIC_FTRACE)   += ftrace.o
 obj-$(CONFIG_KEXEC)            += machine_kexec_$(BITS).o
@@ -108,7 +108,7 @@ obj-$(CONFIG_MICROCODE)                     += microcode.o
 # 64 bit specific files
 ifeq ($(CONFIG_X86_64),y)
         obj-y                          += genapic_64.o genapic_flat_64.o genx2apic_uv_x.o tlb_uv.o
-       obj-y                           += bios_uv.o
+       obj-y                           += bios_uv.o uv_irq.o uv_sysfs.o
         obj-y                          += genx2apic_cluster.o
         obj-y                          += genx2apic_phys.o
         obj-$(CONFIG_X86_PM_TIMER)     += pmtimer_64.o
index eb875cdc7367c3aee3fcb285606c1e993cc808af..8c1f76abae9eac1b28d3a90abb26d6fb39fb8496 100644 (file)
@@ -153,12 +153,13 @@ char *__init __acpi_map_table(unsigned long phys, unsigned long size)
 }
 
 #ifdef CONFIG_PCI_MMCONFIG
+
+static int acpi_mcfg_64bit_base_addr __initdata = FALSE;
+
 /* The physical address of the MMCONFIG aperture.  Set from ACPI tables. */
 struct acpi_mcfg_allocation *pci_mmcfg_config;
 int pci_mmcfg_config_num;
 
-static int acpi_mcfg_64bit_base_addr __initdata = FALSE;
-
 static int __init acpi_mcfg_oem_check(struct acpi_table_mcfg *mcfg)
 {
        if (!strcmp(mcfg->header.oem_id, "SGI"))
@@ -1136,7 +1137,7 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
                return gsi;
        }
        if (test_bit(ioapic_pin, mp_ioapic_routing[ioapic].pin_programmed)) {
-               pr_debug(KERN_DEBUG "Pin %d-%d already programmed\n",
+               pr_debug("Pin %d-%d already programmed\n",
                         mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
 #ifdef CONFIG_X86_32
                return (gsi < IRQ_COMPRESSION_START ? gsi : gsi_to_irq[gsi]);
@@ -1256,7 +1257,7 @@ static int __init acpi_parse_madt_ioapic_entries(void)
 
        count =
            acpi_table_parse_madt(ACPI_MADT_TYPE_INTERRUPT_OVERRIDE, acpi_parse_int_src_ovr,
-                                 NR_IRQ_VECTORS);
+                                 nr_irqs);
        if (count < 0) {
                printk(KERN_ERR PREFIX
                       "Error parsing interrupt source overrides entry\n");
@@ -1276,7 +1277,7 @@ static int __init acpi_parse_madt_ioapic_entries(void)
 
        count =
            acpi_table_parse_madt(ACPI_MADT_TYPE_NMI_SOURCE, acpi_parse_nmi_src,
-                                 NR_IRQ_VECTORS);
+                                 nr_irqs);
        if (count < 0) {
                printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
                /* TBD: Cleanup to allow fallback to MPS */
@@ -1598,6 +1599,11 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = {
                     DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
                     },
         },
+       {}
+};
+
+/* second table for DMI checks that should run after early-quirks */
+static struct dmi_system_id __initdata acpi_dmi_table_late[] = {
        /*
         * HP laptops which use a DSDT reporting as HP/SB400/10000,
         * which includes some code which overrides all temperature
@@ -1726,6 +1732,9 @@ int __init early_acpi_boot_init(void)
 
 int __init acpi_boot_init(void)
 {
+       /* those are executed after early-quirks are executed */
+       dmi_check_system(acpi_dmi_table_late);
+
        /*
         * If acpi_disabled, bail out
         * One exception: acpi=ht continues far enough to enumerate LAPICs
index 426e5d91b63a55d9b49d3387e2c40bb56306f104..806b4e9051b4e5ce2ae00576fa06a980ed6bbe08 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/dmi.h>
 #include <linux/cpumask.h>
 #include <asm/segment.h>
+#include <asm/desc.h>
 
 #include "realmode/wakeup.h"
 #include "sleep.h"
@@ -21,7 +22,7 @@ unsigned long acpi_realmode_flags;
 static unsigned long acpi_realmode;
 
 #if defined(CONFIG_SMP) && defined(CONFIG_64BIT)
-static char temp_stack[10240];
+static char temp_stack[4096];
 #endif
 
 /**
@@ -97,7 +98,9 @@ int acpi_save_state_mem(void)
 #else /* CONFIG_64BIT */
        header->trampoline_segment = setup_trampoline() >> 4;
 #ifdef CONFIG_SMP
-       stack_start.sp = temp_stack + 4096;
+       stack_start.sp = temp_stack + sizeof(temp_stack);
+       early_gdt_descr.address =
+                       (unsigned long)get_cpu_gdt_table(smp_processor_id());
 #endif
        initial_code = (unsigned long)wakeup_long64;
        saved_magic = 0x123456789abcdef0;
index 4cd8083c58be75d2eea19124ddf3758b15e860aa..0cdcda35a05fbcd01d6d4b32f6ba935f6e9d7cb4 100644 (file)
@@ -212,7 +212,7 @@ static void __init iommu_set_exclusion_range(struct amd_iommu *iommu)
 /* Programs the physical address of the device table into the IOMMU hardware */
 static void __init iommu_set_device_table(struct amd_iommu *iommu)
 {
-       u32 entry;
+       u64 entry;
 
        BUG_ON(iommu->mmio_base == NULL);
 
similarity index 79%
rename from arch/x86/kernel/apic_32.c
rename to arch/x86/kernel/apic.c
index 21c831d96af3d8f8ef63e6403f56fd0e71f5730c..04a7f960bbc0a2408907a959af527382dae477a5 100644 (file)
 #include <linux/mc146818rtc.h>
 #include <linux/kernel_stat.h>
 #include <linux/sysdev.h>
+#include <linux/ioport.h>
 #include <linux/cpu.h>
 #include <linux/clockchips.h>
 #include <linux/acpi_pmtmr.h>
 #include <linux/module.h>
 #include <linux/dmi.h>
+#include <linux/dmar.h>
 
 #include <asm/atomic.h>
 #include <asm/smp.h>
 #include <asm/desc.h>
 #include <asm/arch_hooks.h>
 #include <asm/hpet.h>
+#include <asm/pgalloc.h>
 #include <asm/i8253.h>
 #include <asm/nmi.h>
+#include <asm/idle.h>
+#include <asm/proto.h>
+#include <asm/timex.h>
+#include <asm/apic.h>
+#include <asm/i8259.h>
 
 #include <mach_apic.h>
 #include <mach_apicdef.h>
 # error SPURIOUS_APIC_VECTOR definition error
 #endif
 
-unsigned long mp_lapic_addr;
-
+#ifdef CONFIG_X86_32
 /*
  * Knob to control our willingness to enable the local APIC.
  *
  * +1=force-enable
  */
 static int force_enable_local_apic;
-int disable_apic;
+/*
+ * APIC command line parameters
+ */
+static int __init parse_lapic(char *arg)
+{
+       force_enable_local_apic = 1;
+       return 0;
+}
+early_param("lapic", parse_lapic);
+/* Local APIC was disabled by the BIOS and enabled by the kernel */
+static int enabled_via_apicbase;
+
+#endif
+
+#ifdef CONFIG_X86_64
+static int apic_calibrate_pmtmr __initdata;
+static __init int setup_apicpmtimer(char *s)
+{
+       apic_calibrate_pmtmr = 1;
+       notsc_setup(NULL);
+       return 0;
+}
+__setup("apicpmtimer", setup_apicpmtimer);
+#endif
+
+#ifdef CONFIG_X86_64
+#define HAVE_X2APIC
+#endif
+
+#ifdef HAVE_X2APIC
+int x2apic;
+/* x2apic enabled before OS handover */
+int x2apic_preenabled;
+int disable_x2apic;
+static __init int setup_nox2apic(char *str)
+{
+       disable_x2apic = 1;
+       setup_clear_cpu_cap(X86_FEATURE_X2APIC);
+       return 0;
+}
+early_param("nox2apic", setup_nox2apic);
+#endif
 
+unsigned long mp_lapic_addr;
+int disable_apic;
 /* Disable local APIC timer from the kernel commandline or via dmi quirk */
 static int disable_apic_timer __cpuinitdata;
 /* Local APIC timer works in C2 */
@@ -110,9 +160,6 @@ static struct clock_event_device lapic_clockevent = {
 };
 static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
 
-/* Local APIC was disabled by the BIOS and enabled by the kernel */
-static int enabled_via_apicbase;
-
 static unsigned long apic_phys;
 
 /*
@@ -202,6 +249,42 @@ static struct apic_ops xapic_ops = {
 struct apic_ops __read_mostly *apic_ops = &xapic_ops;
 EXPORT_SYMBOL_GPL(apic_ops);
 
+#ifdef HAVE_X2APIC
+static void x2apic_wait_icr_idle(void)
+{
+       /* no need to wait for icr idle in x2apic */
+       return;
+}
+
+static u32 safe_x2apic_wait_icr_idle(void)
+{
+       /* no need to wait for icr idle in x2apic */
+       return 0;
+}
+
+void x2apic_icr_write(u32 low, u32 id)
+{
+       wrmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), ((__u64) id) << 32 | low);
+}
+
+u64 x2apic_icr_read(void)
+{
+       unsigned long val;
+
+       rdmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), val);
+       return val;
+}
+
+static struct apic_ops x2apic_ops = {
+       .read = native_apic_msr_read,
+       .write = native_apic_msr_write,
+       .icr_read = x2apic_icr_read,
+       .icr_write = x2apic_icr_write,
+       .wait_icr_idle = x2apic_wait_icr_idle,
+       .safe_wait_icr_idle = safe_x2apic_wait_icr_idle,
+};
+#endif
+
 /**
  * enable_NMI_through_LVT0 - enable NMI through local vector table 0
  */
@@ -219,6 +302,7 @@ void __cpuinit enable_NMI_through_LVT0(void)
        apic_write(APIC_LVT0, v);
 }
 
+#ifdef CONFIG_X86_32
 /**
  * get_physical_broadcast - Get number of physical broadcast IDs
  */
@@ -226,6 +310,7 @@ int get_physical_broadcast(void)
 {
        return modern_apic() ? 0xff : 0xf;
 }
+#endif
 
 /**
  * lapic_get_maxlvt - get the maximum number of local vector table entries
@@ -247,11 +332,7 @@ int lapic_get_maxlvt(void)
  */
 
 /* Clock divisor */
-#ifdef CONFG_X86_64
-#define APIC_DIVISOR 1
-#else
 #define APIC_DIVISOR 16
-#endif
 
 /*
  * This function sets up the local APIC timer, with a timeout of
@@ -383,7 +464,7 @@ static void lapic_timer_broadcast(cpumask_t mask)
  * Setup the local APIC timer for this CPU. Copy the initilized values
  * of the boot CPU and register the clock event in the framework.
  */
-static void __devinit setup_APIC_timer(void)
+static void __cpuinit setup_APIC_timer(void)
 {
        struct clock_event_device *levt = &__get_cpu_var(lapic_events);
 
@@ -453,14 +534,51 @@ static void __init lapic_cal_handler(struct clock_event_device *dev)
        }
 }
 
+static int __init calibrate_by_pmtimer(long deltapm, long *delta)
+{
+       const long pm_100ms = PMTMR_TICKS_PER_SEC / 10;
+       const long pm_thresh = pm_100ms / 100;
+       unsigned long mult;
+       u64 res;
+
+#ifndef CONFIG_X86_PM_TIMER
+       return -1;
+#endif
+
+       apic_printk(APIC_VERBOSE, "... PM timer delta = %ld\n", deltapm);
+
+       /* Check, if the PM timer is available */
+       if (!deltapm)
+               return -1;
+
+       mult = clocksource_hz2mult(PMTMR_TICKS_PER_SEC, 22);
+
+       if (deltapm > (pm_100ms - pm_thresh) &&
+           deltapm < (pm_100ms + pm_thresh)) {
+               apic_printk(APIC_VERBOSE, "... PM timer result ok\n");
+       } else {
+               res = (((u64)deltapm) *  mult) >> 22;
+               do_div(res, 1000000);
+               printk(KERN_WARNING "APIC calibration not consistent "
+                       "with PM Timer: %ldms instead of 100ms\n",
+                       (long)res);
+               /* Correct the lapic counter value */
+               res = (((u64)(*delta)) * pm_100ms);
+               do_div(res, deltapm);
+               printk(KERN_INFO "APIC delta adjusted to PM-Timer: "
+                       "%lu (%ld)\n", (unsigned long)res, *delta);
+               *delta = (long)res;
+       }
+
+       return 0;
+}
+
 static int __init calibrate_APIC_clock(void)
 {
        struct clock_event_device *levt = &__get_cpu_var(lapic_events);
-       const long pm_100ms = PMTMR_TICKS_PER_SEC/10;
-       const long pm_thresh = pm_100ms/100;
        void (*real_handler)(struct clock_event_device *dev);
        unsigned long deltaj;
-       long delta, deltapm;
+       long delta;
        int pm_referenced = 0;
 
        local_irq_disable();
@@ -470,10 +588,10 @@ static int __init calibrate_APIC_clock(void)
        global_clock_event->event_handler = lapic_cal_handler;
 
        /*
-        * Setup the APIC counter to 1e9. There is no way the lapic
+        * Setup the APIC counter to maximum. There is no way the lapic
         * can underflow in the 100ms detection time frame
         */
-       __setup_APIC_LVTT(1000000000, 0, 0);
+       __setup_APIC_LVTT(0xffffffff, 0, 0);
 
        /* Let the interrupts run */
        local_irq_enable();
@@ -490,34 +608,9 @@ static int __init calibrate_APIC_clock(void)
        delta = lapic_cal_t1 - lapic_cal_t2;
        apic_printk(APIC_VERBOSE, "... lapic delta = %ld\n", delta);
 
-       /* Check, if the PM timer is available */
-       deltapm = lapic_cal_pm2 - lapic_cal_pm1;
-       apic_printk(APIC_VERBOSE, "... PM timer delta = %ld\n", deltapm);
-
-       if (deltapm) {
-               unsigned long mult;
-               u64 res;
-
-               mult = clocksource_hz2mult(PMTMR_TICKS_PER_SEC, 22);
-
-               if (deltapm > (pm_100ms - pm_thresh) &&
-                   deltapm < (pm_100ms + pm_thresh)) {
-                       apic_printk(APIC_VERBOSE, "... PM timer result ok\n");
-               } else {
-                       res = (((u64) deltapm) *  mult) >> 22;
-                       do_div(res, 1000000);
-                       printk(KERN_WARNING "APIC calibration not consistent "
-                              "with PM Timer: %ldms instead of 100ms\n",
-                              (long)res);
-                       /* Correct the lapic counter value */
-                       res = (((u64) delta) * pm_100ms);
-                       do_div(res, deltapm);
-                       printk(KERN_INFO "APIC delta adjusted to PM-Timer: "
-                              "%lu (%ld)\n", (unsigned long) res, delta);
-                       delta = (long) res;
-               }
-               pm_referenced = 1;
-       }
+       /* we trust the PM based calibration if possible */
+       pm_referenced = !calibrate_by_pmtimer(lapic_cal_pm2 - lapic_cal_pm1,
+                                       &delta);
 
        /* Calculate the scaled math multiplication factor */
        lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS,
@@ -559,7 +652,10 @@ static int __init calibrate_APIC_clock(void)
 
        levt->features &= ~CLOCK_EVT_FEAT_DUMMY;
 
-       /* We trust the pm timer based calibration */
+       /*
+        * PM timer calibration failed or not turned on
+        * so lets try APIC timer based calibration
+        */
        if (!pm_referenced) {
                apic_printk(APIC_VERBOSE, "... verify APIC timer\n");
 
@@ -652,7 +748,7 @@ void __init setup_boot_APIC_clock(void)
        setup_APIC_timer();
 }
 
-void __devinit setup_secondary_APIC_clock(void)
+void __cpuinit setup_secondary_APIC_clock(void)
 {
        setup_APIC_timer();
 }
@@ -718,6 +814,9 @@ void smp_apic_timer_interrupt(struct pt_regs *regs)
         * Besides, if we don't timer interrupts ignore the global
         * interrupt lock, which is the WrongThing (tm) to do.
         */
+#ifdef CONFIG_X86_64
+       exit_idle();
+#endif
        irq_enter();
        local_apic_timer_interrupt();
        irq_exit();
@@ -991,40 +1090,43 @@ void __init init_bsp_APIC(void)
 
 static void __cpuinit lapic_setup_esr(void)
 {
-       unsigned long oldvalue, value, maxlvt;
-       if (lapic_is_integrated() && !esr_disable) {
-               if (esr_disable) {
-                       /*
-                        * Something untraceable is creating bad interrupts on
-                        * secondary quads ... for the moment, just leave the
-                        * ESR disabled - we can't do anything useful with the
-                        * errors anyway - mbligh
-                        */
-                       printk(KERN_INFO "Leaving ESR disabled.\n");
-                       return;
-               }
-               /* !82489DX */
-               maxlvt = lapic_get_maxlvt();
-               if (maxlvt > 3)         /* Due to the Pentium erratum 3AP. */
-                       apic_write(APIC_ESR, 0);
-               oldvalue = apic_read(APIC_ESR);
+       unsigned int oldvalue, value, maxlvt;
+
+       if (!lapic_is_integrated()) {
+               printk(KERN_INFO "No ESR for 82489DX.\n");
+               return;
+       }
 
-               /* enables sending errors */
-               value = ERROR_APIC_VECTOR;
-               apic_write(APIC_LVTERR, value);
+       if (esr_disable) {
                /*
-                * spec says clear errors after enabling vector.
+                * Something untraceable is creating bad interrupts on
+                * secondary quads ... for the moment, just leave the
+                * ESR disabled - we can't do anything useful with the
+                * errors anyway - mbligh
                 */
-               if (maxlvt > 3)
-                       apic_write(APIC_ESR, 0);
-               value = apic_read(APIC_ESR);
-               if (value != oldvalue)
-                       apic_printk(APIC_VERBOSE, "ESR value before enabling "
-                               "vector: 0x%08lx  after: 0x%08lx\n",
-                               oldvalue, value);
-       } else {
-               printk(KERN_INFO "No ESR for 82489DX.\n");
+               printk(KERN_INFO "Leaving ESR disabled.\n");
+               return;
        }
+
+       maxlvt = lapic_get_maxlvt();
+       if (maxlvt > 3)         /* Due to the Pentium erratum 3AP. */
+               apic_write(APIC_ESR, 0);
+       oldvalue = apic_read(APIC_ESR);
+
+       /* enables sending errors */
+       value = ERROR_APIC_VECTOR;
+       apic_write(APIC_LVTERR, value);
+
+       /*
+        * spec says clear errors after enabling vector.
+        */
+       if (maxlvt > 3)
+               apic_write(APIC_ESR, 0);
+       value = apic_read(APIC_ESR);
+       if (value != oldvalue)
+               apic_printk(APIC_VERBOSE, "ESR value before enabling "
+                       "vector: 0x%08x  after: 0x%08x\n",
+                       oldvalue, value);
 }
 
 
@@ -1033,24 +1135,27 @@ static void __cpuinit lapic_setup_esr(void)
  */
 void __cpuinit setup_local_APIC(void)
 {
-       unsigned long value, integrated;
+       unsigned int value;
        int i, j;
 
+#ifdef CONFIG_X86_32
        /* Pound the ESR really hard over the head with a big hammer - mbligh */
-       if (esr_disable) {
+       if (lapic_is_integrated() && esr_disable) {
                apic_write(APIC_ESR, 0);
                apic_write(APIC_ESR, 0);
                apic_write(APIC_ESR, 0);
                apic_write(APIC_ESR, 0);
        }
+#endif
 
-       integrated = lapic_is_integrated();
+       preempt_disable();
 
        /*
         * Double-check whether this APIC is really registered.
+        * This is meaningless in clustered apic mode, so we skip it.
         */
        if (!apic_id_registered())
-               WARN_ON_ONCE(1);
+               BUG();
 
        /*
         * Intel recommends to set DFR, LDR and TPR before enabling
@@ -1096,6 +1201,7 @@ void __cpuinit setup_local_APIC(void)
         */
        value |= APIC_SPIV_APIC_ENABLED;
 
+#ifdef CONFIG_X86_32
        /*
         * Some unknown Intel IO/APIC (or APIC) errata is biting us with
         * certain networking cards. If high frequency interrupts are
@@ -1116,8 +1222,13 @@ void __cpuinit setup_local_APIC(void)
         * See also the comment in end_level_ioapic_irq().  --macro
         */
 
-       /* Enable focus processor (bit==0) */
+       /*
+        * - enable focus processor (bit==0)
+        * - 64bit mode always use processor focus
+        *   so no need to set it
+        */
        value &= ~APIC_SPIV_FOCUS_DISABLED;
+#endif
 
        /*
         * Set spurious IRQ vector
@@ -1154,9 +1265,11 @@ void __cpuinit setup_local_APIC(void)
                value = APIC_DM_NMI;
        else
                value = APIC_DM_NMI | APIC_LVT_MASKED;
-       if (!integrated)                /* 82489DX */
+       if (!lapic_is_integrated())             /* 82489DX */
                value |= APIC_LVT_LEVEL_TRIGGER;
        apic_write(APIC_LVT1, value);
+
+       preempt_enable();
 }
 
 void __cpuinit end_local_APIC_setup(void)
@@ -1177,6 +1290,153 @@ void __cpuinit end_local_APIC_setup(void)
        apic_pm_activate();
 }
 
+#ifdef HAVE_X2APIC
+void check_x2apic(void)
+{
+       int msr, msr2;
+
+       rdmsr(MSR_IA32_APICBASE, msr, msr2);
+
+       if (msr & X2APIC_ENABLE) {
+               printk("x2apic enabled by BIOS, switching to x2apic ops\n");
+               x2apic_preenabled = x2apic = 1;
+               apic_ops = &x2apic_ops;
+       }
+}
+
+void enable_x2apic(void)
+{
+       int msr, msr2;
+
+       rdmsr(MSR_IA32_APICBASE, msr, msr2);
+       if (!(msr & X2APIC_ENABLE)) {
+               printk("Enabling x2apic\n");
+               wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0);
+       }
+}
+
+void enable_IR_x2apic(void)
+{
+#ifdef CONFIG_INTR_REMAP
+       int ret;
+       unsigned long flags;
+
+       if (!cpu_has_x2apic)
+               return;
+
+       if (!x2apic_preenabled && disable_x2apic) {
+               printk(KERN_INFO
+                      "Skipped enabling x2apic and Interrupt-remapping "
+                      "because of nox2apic\n");
+               return;
+       }
+
+       if (x2apic_preenabled && disable_x2apic)
+               panic("Bios already enabled x2apic, can't enforce nox2apic");
+
+       if (!x2apic_preenabled && skip_ioapic_setup) {
+               printk(KERN_INFO
+                      "Skipped enabling x2apic and Interrupt-remapping "
+                      "because of skipping io-apic setup\n");
+               return;
+       }
+
+       ret = dmar_table_init();
+       if (ret) {
+               printk(KERN_INFO
+                      "dmar_table_init() failed with %d:\n", ret);
+
+               if (x2apic_preenabled)
+                       panic("x2apic enabled by bios. But IR enabling failed");
+               else
+                       printk(KERN_INFO
+                              "Not enabling x2apic,Intr-remapping\n");
+               return;
+       }
+
+       local_irq_save(flags);
+       mask_8259A();
+
+       ret = save_mask_IO_APIC_setup();
+       if (ret) {
+               printk(KERN_INFO "Saving IO-APIC state failed: %d\n", ret);
+               goto end;
+       }
+
+       ret = enable_intr_remapping(1);
+
+       if (ret && x2apic_preenabled) {
+               local_irq_restore(flags);
+               panic("x2apic enabled by bios. But IR enabling failed");
+       }
+
+       if (ret)
+               goto end_restore;
+
+       if (!x2apic) {
+               x2apic = 1;
+               apic_ops = &x2apic_ops;
+               enable_x2apic();
+       }
+
+end_restore:
+       if (ret)
+               /*
+                * IR enabling failed
+                */
+               restore_IO_APIC_setup();
+       else
+               reinit_intr_remapped_IO_APIC(x2apic_preenabled);
+
+end:
+       unmask_8259A();
+       local_irq_restore(flags);
+
+       if (!ret) {
+               if (!x2apic_preenabled)
+                       printk(KERN_INFO
+                              "Enabled x2apic and interrupt-remapping\n");
+               else
+                       printk(KERN_INFO
+                              "Enabled Interrupt-remapping\n");
+       } else
+               printk(KERN_ERR
+                      "Failed to enable Interrupt-remapping and x2apic\n");
+#else
+       if (!cpu_has_x2apic)
+               return;
+
+       if (x2apic_preenabled)
+               panic("x2apic enabled prior OS handover,"
+                     " enable CONFIG_INTR_REMAP");
+
+       printk(KERN_INFO "Enable CONFIG_INTR_REMAP for enabling intr-remapping "
+              " and x2apic\n");
+#endif
+
+       return;
+}
+#endif /* HAVE_X2APIC */
+
+#ifdef CONFIG_X86_64
+/*
+ * Detect and enable local APICs on non-SMP boards.
+ * Original code written by Keir Fraser.
+ * On AMD64 we trust the BIOS - if it says no APIC it is likely
+ * not correctly set up (usually the APIC timer won't work etc.)
+ */
+static int __init detect_init_APIC(void)
+{
+       if (!cpu_has_apic) {
+               printk(KERN_INFO "No local APIC present\n");
+               return -1;
+       }
+
+       mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
+       boot_cpu_physical_apicid = 0;
+       return 0;
+}
+#else
 /*
  * Detect and initialize APIC
  */
@@ -1255,12 +1515,46 @@ no_apic:
        printk(KERN_INFO "No local APIC present or hardware disabled\n");
        return -1;
 }
+#endif
+
+#ifdef CONFIG_X86_64
+void __init early_init_lapic_mapping(void)
+{
+       unsigned long phys_addr;
+
+       /*
+        * If no local APIC can be found then go out
+        * : it means there is no mpatable and MADT
+        */
+       if (!smp_found_config)
+               return;
+
+       phys_addr = mp_lapic_addr;
+
+       set_fixmap_nocache(FIX_APIC_BASE, phys_addr);
+       apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
+                   APIC_BASE, phys_addr);
+
+       /*
+        * Fetch the APIC ID of the BSP in case we have a
+        * default configuration (or the MP table is broken).
+        */
+       boot_cpu_physical_apicid = read_apic_id();
+}
+#endif
 
 /**
  * init_apic_mappings - initialize APIC mappings
  */
 void __init init_apic_mappings(void)
 {
+#ifdef HAVE_X2APIC
+       if (x2apic) {
+               boot_cpu_physical_apicid = read_apic_id();
+               return;
+       }
+#endif
+
        /*
         * If no local APIC can be found then set up a fake all
         * zeroes page to simulate the local APIC and another
@@ -1273,8 +1567,8 @@ void __init init_apic_mappings(void)
                apic_phys = mp_lapic_addr;
 
        set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
-       printk(KERN_DEBUG "mapped APIC to %08lx (%08lx)\n", APIC_BASE,
-              apic_phys);
+       apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n",
+                               APIC_BASE, apic_phys);
 
        /*
         * Fetch the APIC ID of the BSP in case we have a
@@ -1282,18 +1576,27 @@ void __init init_apic_mappings(void)
         */
        if (boot_cpu_physical_apicid == -1U)
                boot_cpu_physical_apicid = read_apic_id();
-
 }
 
 /*
  * This initializes the IO-APIC and APIC hardware if this is
  * a UP kernel.
  */
-
 int apic_version[MAX_APICS];
 
 int __init APIC_init_uniprocessor(void)
 {
+#ifdef CONFIG_X86_64
+       if (disable_apic) {
+               printk(KERN_INFO "Apic disabled\n");
+               return -1;
+       }
+       if (!cpu_has_apic) {
+               disable_apic = 1;
+               printk(KERN_INFO "Apic disabled by BIOS\n");
+               return -1;
+       }
+#else
        if (!smp_found_config && !cpu_has_apic)
                return -1;
 
@@ -1302,39 +1605,68 @@ int __init APIC_init_uniprocessor(void)
         */
        if (!cpu_has_apic &&
            APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
-               printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
+               printk(KERN_ERR "BIOS bug, local APIC 0x%x not detected!...\n",
                       boot_cpu_physical_apicid);
                clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
                return -1;
        }
+#endif
 
-       verify_local_APIC();
+#ifdef HAVE_X2APIC
+       enable_IR_x2apic();
+#endif
+#ifdef CONFIG_X86_64
+       setup_apic_routing();
+#endif
 
+       verify_local_APIC();
        connect_bsp_APIC();
 
+#ifdef CONFIG_X86_64
+       apic_write(APIC_ID, SET_APIC_ID(boot_cpu_physical_apicid));
+#else
        /*
         * Hack: In case of kdump, after a crash, kernel might be booting
         * on a cpu with non-zero lapic id. But boot_cpu_physical_apicid
         * might be zero if read from MP tables. Get it from LAPIC.
         */
-#ifdef CONFIG_CRASH_DUMP
+# ifdef CONFIG_CRASH_DUMP
        boot_cpu_physical_apicid = read_apic_id();
+# endif
 #endif
        physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map);
-
        setup_local_APIC();
 
+#ifdef CONFIG_X86_64
+       /*
+        * Now enable IO-APICs, actually call clear_IO_APIC
+        * We need clear_IO_APIC before enabling vector on BP
+        */
+       if (!skip_ioapic_setup && nr_ioapics)
+               enable_IO_APIC();
+#endif
+
 #ifdef CONFIG_X86_IO_APIC
        if (!smp_found_config || skip_ioapic_setup || !nr_ioapics)
 #endif
                localise_nmi_watchdog();
        end_local_APIC_setup();
+
 #ifdef CONFIG_X86_IO_APIC
-       if (smp_found_config)
-               if (!skip_ioapic_setup && nr_ioapics)
-                       setup_IO_APIC();
+       if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
+               setup_IO_APIC();
+# ifdef CONFIG_X86_64
+       else
+               nr_ioapics = 0;
+# endif
 #endif
+
+#ifdef CONFIG_X86_64
+       setup_boot_APIC_clock();
+       check_nmi_watchdog();
+#else
        setup_boot_clock();
+#endif
 
        return 0;
 }
@@ -1348,8 +1680,11 @@ int __init APIC_init_uniprocessor(void)
  */
 void smp_spurious_interrupt(struct pt_regs *regs)
 {
-       unsigned long v;
+       u32 v;
 
+#ifdef CONFIG_X86_64
+       exit_idle();
+#endif
        irq_enter();
        /*
         * Check if this really is a spurious interrupt and ACK it
@@ -1360,10 +1695,14 @@ void smp_spurious_interrupt(struct pt_regs *regs)
        if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f)))
                ack_APIC_irq();
 
+#ifdef CONFIG_X86_64
+       add_pda(irq_spurious_count, 1);
+#else
        /* see sw-dev-man vol 3, chapter 7.4.13.5 */
        printk(KERN_INFO "spurious APIC interrupt on CPU#%d, "
               "should never happen.\n", smp_processor_id());
        __get_cpu_var(irq_stat).irq_spurious_count++;
+#endif
        irq_exit();
 }
 
@@ -1372,8 +1711,11 @@ void smp_spurious_interrupt(struct pt_regs *regs)
  */
 void smp_error_interrupt(struct pt_regs *regs)
 {
-       unsigned long v, v1;
+       u32 v, v1;
 
+#ifdef CONFIG_X86_64
+       exit_idle();
+#endif
        irq_enter();
        /* First tickle the hardware, only then report what went on. -- REW */
        v = apic_read(APIC_ESR);
@@ -1392,7 +1734,7 @@ void smp_error_interrupt(struct pt_regs *regs)
           6: Received illegal vector
           7: Illegal register address
        */
-       printk(KERN_DEBUG "APIC error on CPU%d: %02lx(%02lx)\n",
+       printk(KERN_DEBUG "APIC error on CPU%d: %02x(%02x)\n",
                smp_processor_id(), v , v1);
        irq_exit();
 }
@@ -1565,6 +1907,13 @@ void __cpuinit generic_processor_info(int apicid, int version)
        cpu_set(cpu, cpu_present_map);
 }
 
+#ifdef CONFIG_X86_64
+int hard_smp_processor_id(void)
+{
+       return read_apic_id();
+}
+#endif
+
 /*
  * Power management
  */
@@ -1640,7 +1989,7 @@ static int lapic_resume(struct sys_device *dev)
 
        local_irq_save(flags);
 
-#ifdef CONFIG_X86_64
+#ifdef HAVE_X2APIC
        if (x2apic)
                enable_x2apic();
        else
@@ -1702,7 +2051,7 @@ static struct sys_device device_lapic = {
        .cls    = &lapic_sysclass,
 };
 
-static void __devinit apic_pm_activate(void)
+static void __cpuinit apic_pm_activate(void)
 {
        apic_pm_state.active = 1;
 }
@@ -1728,16 +2077,87 @@ static void apic_pm_activate(void) { }
 
 #endif /* CONFIG_PM */
 
+#ifdef CONFIG_X86_64
 /*
- * APIC command line parameters
+ * apic_is_clustered_box() -- Check if we can expect good TSC
+ *
+ * Thus far, the major user of this is IBM's Summit2 series:
+ *
+ * Clustered boxes may have unsynced TSC problems if they are
+ * multi-chassis. Use available data to take a good guess.
+ * If in doubt, go HPET.
  */
-static int __init parse_lapic(char *arg)
+__cpuinit int apic_is_clustered_box(void)
 {
-       force_enable_local_apic = 1;
-       return 0;
+       int i, clusters, zeros;
+       unsigned id;
+       u16 *bios_cpu_apicid;
+       DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS);
+
+       /*
+        * there is not this kind of box with AMD CPU yet.
+        * Some AMD box with quadcore cpu and 8 sockets apicid
+        * will be [4, 0x23] or [8, 0x27] could be thought to
+        * vsmp box still need checking...
+        */
+       if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && !is_vsmp_box())
+               return 0;
+
+       bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid);
+       bitmap_zero(clustermap, NUM_APIC_CLUSTERS);
+
+       for (i = 0; i < NR_CPUS; i++) {
+               /* are we being called early in kernel startup? */
+               if (bios_cpu_apicid) {
+                       id = bios_cpu_apicid[i];
+               }
+               else if (i < nr_cpu_ids) {
+                       if (cpu_present(i))
+                               id = per_cpu(x86_bios_cpu_apicid, i);
+                       else
+                               continue;
+               }
+               else
+                       break;
+
+               if (id != BAD_APICID)
+                       __set_bit(APIC_CLUSTERID(id), clustermap);
+       }
+
+       /* Problem:  Partially populated chassis may not have CPUs in some of
+        * the APIC clusters they have been allocated.  Only present CPUs have
+        * x86_bios_cpu_apicid entries, thus causing zeroes in the bitmap.
+        * Since clusters are allocated sequentially, count zeros only if
+        * they are bounded by ones.
+        */
+       clusters = 0;
+       zeros = 0;
+       for (i = 0; i < NUM_APIC_CLUSTERS; i++) {
+               if (test_bit(i, clustermap)) {
+                       clusters += 1 + zeros;
+                       zeros = 0;
+               } else
+                       ++zeros;
+       }
+
+       /* ScaleMP vSMPowered boxes have one cluster per board and TSCs are
+        * not guaranteed to be synced between boards
+        */
+       if (is_vsmp_box() && clusters > 1)
+               return 1;
+
+       /*
+        * If clusters > 2, then should be multi-chassis.
+        * May have to revisit this when multi-core + hyperthreaded CPUs come
+        * out, but AFAIK this will work even for them.
+        */
+       return (clusters > 2);
 }
-early_param("lapic", parse_lapic);
+#endif
 
+/*
+ * APIC command line parameters
+ */
 static int __init setup_disableapic(char *arg)
 {
        disable_apic = 1;
@@ -1779,7 +2199,6 @@ static int __init apic_set_verbosity(char *arg)
        if (!arg)  {
 #ifdef CONFIG_X86_64
                skip_ioapic_setup = 0;
-               ioapic_force = 1;
                return 0;
 #endif
                return -EINVAL;
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c
deleted file mode 100644 (file)
index 94ddb69..0000000
+++ /dev/null
@@ -1,1848 +0,0 @@
-/*
- *     Local APIC handling, local APIC timers
- *
- *     (c) 1999, 2000 Ingo Molnar <mingo@redhat.com>
- *
- *     Fixes
- *     Maciej W. Rozycki       :       Bits for genuine 82489DX APICs;
- *                                     thanks to Eric Gilmore
- *                                     and Rolf G. Tews
- *                                     for testing these extensively.
- *     Maciej W. Rozycki       :       Various updates and fixes.
- *     Mikael Pettersson       :       Power Management for UP-APIC.
- *     Pavel Machek and
- *     Mikael Pettersson       :       PM converted to driver model.
- */
-
-#include <linux/init.h>
-
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/bootmem.h>
-#include <linux/interrupt.h>
-#include <linux/mc146818rtc.h>
-#include <linux/kernel_stat.h>
-#include <linux/sysdev.h>
-#include <linux/ioport.h>
-#include <linux/clockchips.h>
-#include <linux/acpi_pmtmr.h>
-#include <linux/module.h>
-#include <linux/dmar.h>
-
-#include <asm/atomic.h>
-#include <asm/smp.h>
-#include <asm/mtrr.h>
-#include <asm/mpspec.h>
-#include <asm/hpet.h>
-#include <asm/pgalloc.h>
-#include <asm/nmi.h>
-#include <asm/idle.h>
-#include <asm/proto.h>
-#include <asm/timex.h>
-#include <asm/apic.h>
-#include <asm/i8259.h>
-
-#include <mach_ipi.h>
-#include <mach_apic.h>
-
-/* Disable local APIC timer from the kernel commandline or via dmi quirk */
-static int disable_apic_timer __cpuinitdata;
-static int apic_calibrate_pmtmr __initdata;
-int disable_apic;
-int disable_x2apic;
-int x2apic;
-
-/* x2apic enabled before OS handover */
-int x2apic_preenabled;
-
-/* Local APIC timer works in C2 */
-int local_apic_timer_c2_ok;
-EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);
-
-/*
- * Debug level, exported for io_apic.c
- */
-unsigned int apic_verbosity;
-
-/* Have we found an MP table */
-int smp_found_config;
-
-static struct resource lapic_resource = {
-       .name = "Local APIC",
-       .flags = IORESOURCE_MEM | IORESOURCE_BUSY,
-};
-
-static unsigned int calibration_result;
-
-static int lapic_next_event(unsigned long delta,
-                           struct clock_event_device *evt);
-static void lapic_timer_setup(enum clock_event_mode mode,
-                             struct clock_event_device *evt);
-static void lapic_timer_broadcast(cpumask_t mask);
-static void apic_pm_activate(void);
-
-/*
- * The local apic timer can be used for any function which is CPU local.
- */
-static struct clock_event_device lapic_clockevent = {
-       .name           = "lapic",
-       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT
-                       | CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_DUMMY,
-       .shift          = 32,
-       .set_mode       = lapic_timer_setup,
-       .set_next_event = lapic_next_event,
-       .broadcast      = lapic_timer_broadcast,
-       .rating         = 100,
-       .irq            = -1,
-};
-static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
-
-static unsigned long apic_phys;
-
-unsigned long mp_lapic_addr;
-
-/*
- * Get the LAPIC version
- */
-static inline int lapic_get_version(void)
-{
-       return GET_APIC_VERSION(apic_read(APIC_LVR));
-}
-
-/*
- * Check, if the APIC is integrated or a separate chip
- */
-static inline int lapic_is_integrated(void)
-{
-#ifdef CONFIG_X86_64
-       return 1;
-#else
-       return APIC_INTEGRATED(lapic_get_version());
-#endif
-}
-
-/*
- * Check, whether this is a modern or a first generation APIC
- */
-static int modern_apic(void)
-{
-       /* AMD systems use old APIC versions, so check the CPU */
-       if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
-           boot_cpu_data.x86 >= 0xf)
-               return 1;
-       return lapic_get_version() >= 0x14;
-}
-
-/*
- * Paravirt kernels also might be using these below ops. So we still
- * use generic apic_read()/apic_write(), which might be pointing to different
- * ops in PARAVIRT case.
- */
-void xapic_wait_icr_idle(void)
-{
-       while (apic_read(APIC_ICR) & APIC_ICR_BUSY)
-               cpu_relax();
-}
-
-u32 safe_xapic_wait_icr_idle(void)
-{
-       u32 send_status;
-       int timeout;
-
-       timeout = 0;
-       do {
-               send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
-               if (!send_status)
-                       break;
-               udelay(100);
-       } while (timeout++ < 1000);
-
-       return send_status;
-}
-
-void xapic_icr_write(u32 low, u32 id)
-{
-       apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(id));
-       apic_write(APIC_ICR, low);
-}
-
-u64 xapic_icr_read(void)
-{
-       u32 icr1, icr2;
-
-       icr2 = apic_read(APIC_ICR2);
-       icr1 = apic_read(APIC_ICR);
-
-       return icr1 | ((u64)icr2 << 32);
-}
-
-static struct apic_ops xapic_ops = {
-       .read = native_apic_mem_read,
-       .write = native_apic_mem_write,
-       .icr_read = xapic_icr_read,
-       .icr_write = xapic_icr_write,
-       .wait_icr_idle = xapic_wait_icr_idle,
-       .safe_wait_icr_idle = safe_xapic_wait_icr_idle,
-};
-
-struct apic_ops __read_mostly *apic_ops = &xapic_ops;
-EXPORT_SYMBOL_GPL(apic_ops);
-
-static void x2apic_wait_icr_idle(void)
-{
-       /* no need to wait for icr idle in x2apic */
-       return;
-}
-
-static u32 safe_x2apic_wait_icr_idle(void)
-{
-       /* no need to wait for icr idle in x2apic */
-       return 0;
-}
-
-void x2apic_icr_write(u32 low, u32 id)
-{
-       wrmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), ((__u64) id) << 32 | low);
-}
-
-u64 x2apic_icr_read(void)
-{
-       unsigned long val;
-
-       rdmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), val);
-       return val;
-}
-
-static struct apic_ops x2apic_ops = {
-       .read = native_apic_msr_read,
-       .write = native_apic_msr_write,
-       .icr_read = x2apic_icr_read,
-       .icr_write = x2apic_icr_write,
-       .wait_icr_idle = x2apic_wait_icr_idle,
-       .safe_wait_icr_idle = safe_x2apic_wait_icr_idle,
-};
-
-/**
- * enable_NMI_through_LVT0 - enable NMI through local vector table 0
- */
-void __cpuinit enable_NMI_through_LVT0(void)
-{
-       unsigned int v;
-
-       /* unmask and set to NMI */
-       v = APIC_DM_NMI;
-
-       /* Level triggered for 82489DX (32bit mode) */
-       if (!lapic_is_integrated())
-               v |= APIC_LVT_LEVEL_TRIGGER;
-
-       apic_write(APIC_LVT0, v);
-}
-
-/**
- * lapic_get_maxlvt - get the maximum number of local vector table entries
- */
-int lapic_get_maxlvt(void)
-{
-       unsigned int v;
-
-       v = apic_read(APIC_LVR);
-       /*
-        * - we always have APIC integrated on 64bit mode
-        * - 82489DXs do not report # of LVT entries
-        */
-       return APIC_INTEGRATED(GET_APIC_VERSION(v)) ? GET_APIC_MAXLVT(v) : 2;
-}
-
-/*
- * Local APIC timer
- */
-
-/* Clock divisor */
-#ifdef CONFG_X86_64
-#define APIC_DIVISOR 1
-#else
-#define APIC_DIVISOR 16
-#endif
-
-/*
- * This function sets up the local APIC timer, with a timeout of
- * 'clocks' APIC bus clock. During calibration we actually call
- * this function twice on the boot CPU, once with a bogus timeout
- * value, second time for real. The other (noncalibrating) CPUs
- * call this function only once, with the real, calibrated value.
- *
- * We do reads before writes even if unnecessary, to get around the
- * P5 APIC double write bug.
- */
-static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
-{
-       unsigned int lvtt_value, tmp_value;
-
-       lvtt_value = LOCAL_TIMER_VECTOR;
-       if (!oneshot)
-               lvtt_value |= APIC_LVT_TIMER_PERIODIC;
-       if (!lapic_is_integrated())
-               lvtt_value |= SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV);
-
-       if (!irqen)
-               lvtt_value |= APIC_LVT_MASKED;
-
-       apic_write(APIC_LVTT, lvtt_value);
-
-       /*
-        * Divide PICLK by 16
-        */
-       tmp_value = apic_read(APIC_TDCR);
-       apic_write(APIC_TDCR,
-               (tmp_value & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) |
-               APIC_TDR_DIV_16);
-
-       if (!oneshot)
-               apic_write(APIC_TMICT, clocks / APIC_DIVISOR);
-}
-
-/*
- * Setup extended LVT, AMD specific (K8, family 10h)
- *
- * Vector mappings are hard coded. On K8 only offset 0 (APIC500) and
- * MCE interrupts are supported. Thus MCE offset must be set to 0.
- *
- * If mask=1, the LVT entry does not generate interrupts while mask=0
- * enables the vector. See also the BKDGs.
- */
-
-#define APIC_EILVT_LVTOFF_MCE 0
-#define APIC_EILVT_LVTOFF_IBS 1
-
-static void setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask)
-{
-       unsigned long reg = (lvt_off << 4) + APIC_EILVT0;
-       unsigned int  v   = (mask << 16) | (msg_type << 8) | vector;
-
-       apic_write(reg, v);
-}
-
-u8 setup_APIC_eilvt_mce(u8 vector, u8 msg_type, u8 mask)
-{
-       setup_APIC_eilvt(APIC_EILVT_LVTOFF_MCE, vector, msg_type, mask);
-       return APIC_EILVT_LVTOFF_MCE;
-}
-
-u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask)
-{
-       setup_APIC_eilvt(APIC_EILVT_LVTOFF_IBS, vector, msg_type, mask);
-       return APIC_EILVT_LVTOFF_IBS;
-}
-EXPORT_SYMBOL_GPL(setup_APIC_eilvt_ibs);
-
-/*
- * Program the next event, relative to now
- */
-static int lapic_next_event(unsigned long delta,
-                           struct clock_event_device *evt)
-{
-       apic_write(APIC_TMICT, delta);
-       return 0;
-}
-
-/*
- * Setup the lapic timer in periodic or oneshot mode
- */
-static void lapic_timer_setup(enum clock_event_mode mode,
-                             struct clock_event_device *evt)
-{
-       unsigned long flags;
-       unsigned int v;
-
-       /* Lapic used as dummy for broadcast ? */
-       if (evt->features & CLOCK_EVT_FEAT_DUMMY)
-               return;
-
-       local_irq_save(flags);
-
-       switch (mode) {
-       case CLOCK_EVT_MODE_PERIODIC:
-       case CLOCK_EVT_MODE_ONESHOT:
-               __setup_APIC_LVTT(calibration_result,
-                                 mode != CLOCK_EVT_MODE_PERIODIC, 1);
-               break;
-       case CLOCK_EVT_MODE_UNUSED:
-       case CLOCK_EVT_MODE_SHUTDOWN:
-               v = apic_read(APIC_LVTT);
-               v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
-               apic_write(APIC_LVTT, v);
-               break;
-       case CLOCK_EVT_MODE_RESUME:
-               /* Nothing to do here */
-               break;
-       }
-
-       local_irq_restore(flags);
-}
-
-/*
- * Local APIC timer broadcast function
- */
-static void lapic_timer_broadcast(cpumask_t mask)
-{
-#ifdef CONFIG_SMP
-       send_IPI_mask(mask, LOCAL_TIMER_VECTOR);
-#endif
-}
-
-/*
- * Setup the local APIC timer for this CPU. Copy the initilized values
- * of the boot CPU and register the clock event in the framework.
- */
-static void setup_APIC_timer(void)
-{
-       struct clock_event_device *levt = &__get_cpu_var(lapic_events);
-
-       memcpy(levt, &lapic_clockevent, sizeof(*levt));
-       levt->cpumask = cpumask_of_cpu(smp_processor_id());
-
-       clockevents_register_device(levt);
-}
-
-/*
- * In this function we calibrate APIC bus clocks to the external
- * timer. Unfortunately we cannot use jiffies and the timer irq
- * to calibrate, since some later bootup code depends on getting
- * the first irq? Ugh.
- *
- * We want to do the calibration only once since we
- * want to have local timer irqs syncron. CPUs connected
- * by the same APIC bus have the very same bus frequency.
- * And we want to have irqs off anyways, no accidental
- * APIC irq that way.
- */
-
-#define TICK_COUNT 100000000
-
-static int __init calibrate_APIC_clock(void)
-{
-       unsigned apic, apic_start;
-       unsigned long tsc, tsc_start;
-       int result;
-
-       local_irq_disable();
-
-       /*
-        * Put whatever arbitrary (but long enough) timeout
-        * value into the APIC clock, we just want to get the
-        * counter running for calibration.
-        *
-        * No interrupt enable !
-        */
-       __setup_APIC_LVTT(250000000, 0, 0);
-
-       apic_start = apic_read(APIC_TMCCT);
-#ifdef CONFIG_X86_PM_TIMER
-       if (apic_calibrate_pmtmr && pmtmr_ioport) {
-               pmtimer_wait(5000);  /* 5ms wait */
-               apic = apic_read(APIC_TMCCT);
-               result = (apic_start - apic) * 1000L / 5;
-       } else
-#endif
-       {
-               rdtscll(tsc_start);
-
-               do {
-                       apic = apic_read(APIC_TMCCT);
-                       rdtscll(tsc);
-               } while ((tsc - tsc_start) < TICK_COUNT &&
-                               (apic_start - apic) < TICK_COUNT);
-
-               result = (apic_start - apic) * 1000L * tsc_khz /
-                                       (tsc - tsc_start);
-       }
-
-       local_irq_enable();
-
-       printk(KERN_DEBUG "APIC timer calibration result %d\n", result);
-
-       printk(KERN_INFO "Detected %d.%03d MHz APIC timer.\n",
-               result / 1000 / 1000, result / 1000 % 1000);
-
-       /* Calculate the scaled math multiplication factor */
-       lapic_clockevent.mult = div_sc(result, NSEC_PER_SEC,
-                                      lapic_clockevent.shift);
-       lapic_clockevent.max_delta_ns =
-               clockevent_delta2ns(0x7FFFFF, &lapic_clockevent);
-       lapic_clockevent.min_delta_ns =
-               clockevent_delta2ns(0xF, &lapic_clockevent);
-
-       calibration_result = (result * APIC_DIVISOR) / HZ;
-
-       /*
-        * Do a sanity check on the APIC calibration result
-        */
-       if (calibration_result < (1000000 / HZ)) {
-               printk(KERN_WARNING
-                       "APIC frequency too slow, disabling apic timer\n");
-               return -1;
-       }
-
-       return 0;
-}
-
-/*
- * Setup the boot APIC
- *
- * Calibrate and verify the result.
- */
-void __init setup_boot_APIC_clock(void)
-{
-       /*
-        * The local apic timer can be disabled via the kernel
-        * commandline or from the CPU detection code. Register the lapic
-        * timer as a dummy clock event source on SMP systems, so the
-        * broadcast mechanism is used. On UP systems simply ignore it.
-        */
-       if (disable_apic_timer) {
-               printk(KERN_INFO "Disabling APIC timer\n");
-               /* No broadcast on UP ! */
-               if (num_possible_cpus() > 1) {
-                       lapic_clockevent.mult = 1;
-                       setup_APIC_timer();
-               }
-               return;
-       }
-
-       apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
-                   "calibrating APIC timer ...\n");
-
-       if (calibrate_APIC_clock()) {
-               /* No broadcast on UP ! */
-               if (num_possible_cpus() > 1)
-                       setup_APIC_timer();
-               return;
-       }
-
-       /*
-        * If nmi_watchdog is set to IO_APIC, we need the
-        * PIT/HPET going.  Otherwise register lapic as a dummy
-        * device.
-        */
-       if (nmi_watchdog != NMI_IO_APIC)
-               lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
-       else
-               printk(KERN_WARNING "APIC timer registered as dummy,"
-                       " due to nmi_watchdog=%d!\n", nmi_watchdog);
-
-       /* Setup the lapic or request the broadcast */
-       setup_APIC_timer();
-}
-
-void __cpuinit setup_secondary_APIC_clock(void)
-{
-       setup_APIC_timer();
-}
-
-/*
- * The guts of the apic timer interrupt
- */
-static void local_apic_timer_interrupt(void)
-{
-       int cpu = smp_processor_id();
-       struct clock_event_device *evt = &per_cpu(lapic_events, cpu);
-
-       /*
-        * Normally we should not be here till LAPIC has been initialized but
-        * in some cases like kdump, its possible that there is a pending LAPIC
-        * timer interrupt from previous kernel's context and is delivered in
-        * new kernel the moment interrupts are enabled.
-        *
-        * Interrupts are enabled early and LAPIC is setup much later, hence
-        * its possible that when we get here evt->event_handler is NULL.
-        * Check for event_handler being NULL and discard the interrupt as
-        * spurious.
-        */
-       if (!evt->event_handler) {
-               printk(KERN_WARNING
-                      "Spurious LAPIC timer interrupt on cpu %d\n", cpu);
-               /* Switch it off */
-               lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, evt);
-               return;
-       }
-
-       /*
-        * the NMI deadlock-detector uses this.
-        */
-#ifdef CONFIG_X86_64
-       add_pda(apic_timer_irqs, 1);
-#else
-       per_cpu(irq_stat, cpu).apic_timer_irqs++;
-#endif
-
-       evt->event_handler(evt);
-}
-
-/*
- * Local APIC timer interrupt. This is the most natural way for doing
- * local interrupts, but local timer interrupts can be emulated by
- * broadcast interrupts too. [in case the hw doesn't support APIC timers]
- *
- * [ if a single-CPU system runs an SMP kernel then we call the local
- *   interrupt as well. Thus we cannot inline the local irq ... ]
- */
-void smp_apic_timer_interrupt(struct pt_regs *regs)
-{
-       struct pt_regs *old_regs = set_irq_regs(regs);
-
-       /*
-        * NOTE! We'd better ACK the irq immediately,
-        * because timer handling can be slow.
-        */
-       ack_APIC_irq();
-       /*
-        * update_process_times() expects us to have done irq_enter().
-        * Besides, if we don't timer interrupts ignore the global
-        * interrupt lock, which is the WrongThing (tm) to do.
-        */
-       exit_idle();
-       irq_enter();
-       local_apic_timer_interrupt();
-       irq_exit();
-
-       set_irq_regs(old_regs);
-}
-
-int setup_profiling_timer(unsigned int multiplier)
-{
-       return -EINVAL;
-}
-
-
-/*
- * Local APIC start and shutdown
- */
-
-/**
- * clear_local_APIC - shutdown the local APIC
- *
- * This is called, when a CPU is disabled and before rebooting, so the state of
- * the local APIC has no dangling leftovers. Also used to cleanout any BIOS
- * leftovers during boot.
- */
-void clear_local_APIC(void)
-{
-       int maxlvt;
-       u32 v;
-
-       /* APIC hasn't been mapped yet */
-       if (!apic_phys)
-               return;
-
-       maxlvt = lapic_get_maxlvt();
-       /*
-        * Masking an LVT entry can trigger a local APIC error
-        * if the vector is zero. Mask LVTERR first to prevent this.
-        */
-       if (maxlvt >= 3) {
-               v = ERROR_APIC_VECTOR; /* any non-zero vector will do */
-               apic_write(APIC_LVTERR, v | APIC_LVT_MASKED);
-       }
-       /*
-        * Careful: we have to set masks only first to deassert
-        * any level-triggered sources.
-        */
-       v = apic_read(APIC_LVTT);
-       apic_write(APIC_LVTT, v | APIC_LVT_MASKED);
-       v = apic_read(APIC_LVT0);
-       apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
-       v = apic_read(APIC_LVT1);
-       apic_write(APIC_LVT1, v | APIC_LVT_MASKED);
-       if (maxlvt >= 4) {
-               v = apic_read(APIC_LVTPC);
-               apic_write(APIC_LVTPC, v | APIC_LVT_MASKED);
-       }
-
-       /* lets not touch this if we didn't frob it */
-#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(X86_MCE_INTEL)
-       if (maxlvt >= 5) {
-               v = apic_read(APIC_LVTTHMR);
-               apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED);
-       }
-#endif
-       /*
-        * Clean APIC state for other OSs:
-        */
-       apic_write(APIC_LVTT, APIC_LVT_MASKED);
-       apic_write(APIC_LVT0, APIC_LVT_MASKED);
-       apic_write(APIC_LVT1, APIC_LVT_MASKED);
-       if (maxlvt >= 3)
-               apic_write(APIC_LVTERR, APIC_LVT_MASKED);
-       if (maxlvt >= 4)
-               apic_write(APIC_LVTPC, APIC_LVT_MASKED);
-
-       /* Integrated APIC (!82489DX) ? */
-       if (lapic_is_integrated()) {
-               if (maxlvt > 3)
-                       /* Clear ESR due to Pentium errata 3AP and 11AP */
-                       apic_write(APIC_ESR, 0);
-               apic_read(APIC_ESR);
-       }
-}
-
-/**
- * disable_local_APIC - clear and disable the local APIC
- */
-void disable_local_APIC(void)
-{
-       unsigned int value;
-
-       clear_local_APIC();
-
-       /*
-        * Disable APIC (implies clearing of registers
-        * for 82489DX!).
-        */
-       value = apic_read(APIC_SPIV);
-       value &= ~APIC_SPIV_APIC_ENABLED;
-       apic_write(APIC_SPIV, value);
-
-#ifdef CONFIG_X86_32
-       /*
-        * When LAPIC was disabled by the BIOS and enabled by the kernel,
-        * restore the disabled state.
-        */
-       if (enabled_via_apicbase) {
-               unsigned int l, h;
-
-               rdmsr(MSR_IA32_APICBASE, l, h);
-               l &= ~MSR_IA32_APICBASE_ENABLE;
-               wrmsr(MSR_IA32_APICBASE, l, h);
-       }
-#endif
-}
-
-/*
- * If Linux enabled the LAPIC against the BIOS default disable it down before
- * re-entering the BIOS on shutdown.  Otherwise the BIOS may get confused and
- * not power-off.  Additionally clear all LVT entries before disable_local_APIC
- * for the case where Linux didn't enable the LAPIC.
- */
-void lapic_shutdown(void)
-{
-       unsigned long flags;
-
-       if (!cpu_has_apic)
-               return;
-
-       local_irq_save(flags);
-
-#ifdef CONFIG_X86_32
-       if (!enabled_via_apicbase)
-               clear_local_APIC();
-       else
-#endif
-               disable_local_APIC();
-
-
-       local_irq_restore(flags);
-}
-
-/*
- * This is to verify that we're looking at a real local APIC.
- * Check these against your board if the CPUs aren't getting
- * started for no apparent reason.
- */
-int __init verify_local_APIC(void)
-{
-       unsigned int reg0, reg1;
-
-       /*
-        * The version register is read-only in a real APIC.
-        */
-       reg0 = apic_read(APIC_LVR);
-       apic_printk(APIC_DEBUG, "Getting VERSION: %x\n", reg0);
-       apic_write(APIC_LVR, reg0 ^ APIC_LVR_MASK);
-       reg1 = apic_read(APIC_LVR);
-       apic_printk(APIC_DEBUG, "Getting VERSION: %x\n", reg1);
-
-       /*
-        * The two version reads above should print the same
-        * numbers.  If the second one is different, then we
-        * poke at a non-APIC.
-        */
-       if (reg1 != reg0)
-               return 0;
-
-       /*
-        * Check if the version looks reasonably.
-        */
-       reg1 = GET_APIC_VERSION(reg0);
-       if (reg1 == 0x00 || reg1 == 0xff)
-               return 0;
-       reg1 = lapic_get_maxlvt();
-       if (reg1 < 0x02 || reg1 == 0xff)
-               return 0;
-
-       /*
-        * The ID register is read/write in a real APIC.
-        */
-       reg0 = apic_read(APIC_ID);
-       apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0);
-       apic_write(APIC_ID, reg0 ^ APIC_ID_MASK);
-       reg1 = apic_read(APIC_ID);
-       apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg1);
-       apic_write(APIC_ID, reg0);
-       if (reg1 != (reg0 ^ APIC_ID_MASK))
-               return 0;
-
-       /*
-        * The next two are just to see if we have sane values.
-        * They're only really relevant if we're in Virtual Wire
-        * compatibility mode, but most boxes are anymore.
-        */
-       reg0 = apic_read(APIC_LVT0);
-       apic_printk(APIC_DEBUG, "Getting LVT0: %x\n", reg0);
-       reg1 = apic_read(APIC_LVT1);
-       apic_printk(APIC_DEBUG, "Getting LVT1: %x\n", reg1);
-
-       return 1;
-}
-
-/**
- * sync_Arb_IDs - synchronize APIC bus arbitration IDs
- */
-void __init sync_Arb_IDs(void)
-{
-       /*
-        * Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 And not
-        * needed on AMD.
-        */
-       if (modern_apic() || boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
-               return;
-
-       /*
-        * Wait for idle.
-        */
-       apic_wait_icr_idle();
-
-       apic_printk(APIC_DEBUG, "Synchronizing Arb IDs.\n");
-       apic_write(APIC_ICR, APIC_DEST_ALLINC |
-                       APIC_INT_LEVELTRIG | APIC_DM_INIT);
-}
-
-/*
- * An initial setup of the virtual wire mode.
- */
-void __init init_bsp_APIC(void)
-{
-       unsigned int value;
-
-       /*
-        * Don't do the setup now if we have a SMP BIOS as the
-        * through-I/O-APIC virtual wire mode might be active.
-        */
-       if (smp_found_config || !cpu_has_apic)
-               return;
-
-       /*
-        * Do not trust the local APIC being empty at bootup.
-        */
-       clear_local_APIC();
-
-       /*
-        * Enable APIC.
-        */
-       value = apic_read(APIC_SPIV);
-       value &= ~APIC_VECTOR_MASK;
-       value |= APIC_SPIV_APIC_ENABLED;
-
-#ifdef CONFIG_X86_32
-       /* This bit is reserved on P4/Xeon and should be cleared */
-       if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
-           (boot_cpu_data.x86 == 15))
-               value &= ~APIC_SPIV_FOCUS_DISABLED;
-       else
-#endif
-               value |= APIC_SPIV_FOCUS_DISABLED;
-       value |= SPURIOUS_APIC_VECTOR;
-       apic_write(APIC_SPIV, value);
-
-       /*
-        * Set up the virtual wire mode.
-        */
-       apic_write(APIC_LVT0, APIC_DM_EXTINT);
-       value = APIC_DM_NMI;
-       if (!lapic_is_integrated())             /* 82489DX */
-               value |= APIC_LVT_LEVEL_TRIGGER;
-       apic_write(APIC_LVT1, value);
-}
-
-static void __cpuinit lapic_setup_esr(void)
-{
-       unsigned long oldvalue, value, maxlvt;
-       if (lapic_is_integrated() && !esr_disable) {
-               if (esr_disable) {
-                       /*
-                        * Something untraceable is creating bad interrupts on
-                        * secondary quads ... for the moment, just leave the
-                        * ESR disabled - we can't do anything useful with the
-                        * errors anyway - mbligh
-                        */
-                       printk(KERN_INFO "Leaving ESR disabled.\n");
-                       return;
-               }
-               /* !82489DX */
-               maxlvt = lapic_get_maxlvt();
-               if (maxlvt > 3)         /* Due to the Pentium erratum 3AP. */
-                       apic_write(APIC_ESR, 0);
-               oldvalue = apic_read(APIC_ESR);
-
-               /* enables sending errors */
-               value = ERROR_APIC_VECTOR;
-               apic_write(APIC_LVTERR, value);
-               /*
-                * spec says clear errors after enabling vector.
-                */
-               if (maxlvt > 3)
-                       apic_write(APIC_ESR, 0);
-               value = apic_read(APIC_ESR);
-               if (value != oldvalue)
-                       apic_printk(APIC_VERBOSE, "ESR value before enabling "
-                               "vector: 0x%08lx  after: 0x%08lx\n",
-                               oldvalue, value);
-       } else {
-               printk(KERN_INFO "No ESR for 82489DX.\n");
-       }
-}
-
-
-/**
- * setup_local_APIC - setup the local APIC
- */
-void __cpuinit setup_local_APIC(void)
-{
-       unsigned int value;
-       int i, j;
-
-       preempt_disable();
-       value = apic_read(APIC_LVR);
-
-       BUILD_BUG_ON((SPURIOUS_APIC_VECTOR & 0x0f) != 0x0f);
-
-       /*
-        * Double-check whether this APIC is really registered.
-        * This is meaningless in clustered apic mode, so we skip it.
-        */
-       if (!apic_id_registered())
-               BUG();
-
-       /*
-        * Intel recommends to set DFR, LDR and TPR before enabling
-        * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
-        * document number 292116).  So here it goes...
-        */
-       init_apic_ldr();
-
-       /*
-        * Set Task Priority to 'accept all'. We never change this
-        * later on.
-        */
-       value = apic_read(APIC_TASKPRI);
-       value &= ~APIC_TPRI_MASK;
-       apic_write(APIC_TASKPRI, value);
-
-       /*
-        * After a crash, we no longer service the interrupts and a pending
-        * interrupt from previous kernel might still have ISR bit set.
-        *
-        * Most probably by now CPU has serviced that pending interrupt and
-        * it might not have done the ack_APIC_irq() because it thought,
-        * interrupt came from i8259 as ExtInt. LAPIC did not get EOI so it
-        * does not clear the ISR bit and cpu thinks it has already serivced
-        * the interrupt. Hence a vector might get locked. It was noticed
-        * for timer irq (vector 0x31). Issue an extra EOI to clear ISR.
-        */
-       for (i = APIC_ISR_NR - 1; i >= 0; i--) {
-               value = apic_read(APIC_ISR + i*0x10);
-               for (j = 31; j >= 0; j--) {
-                       if (value & (1<<j))
-                               ack_APIC_irq();
-               }
-       }
-
-       /*
-        * Now that we are all set up, enable the APIC
-        */
-       value = apic_read(APIC_SPIV);
-       value &= ~APIC_VECTOR_MASK;
-       /*
-        * Enable APIC
-        */
-       value |= APIC_SPIV_APIC_ENABLED;
-
-       /* We always use processor focus */
-
-       /*
-        * Set spurious IRQ vector
-        */
-       value |= SPURIOUS_APIC_VECTOR;
-       apic_write(APIC_SPIV, value);
-
-       /*
-        * Set up LVT0, LVT1:
-        *
-        * set up through-local-APIC on the BP's LINT0. This is not
-        * strictly necessary in pure symmetric-IO mode, but sometimes
-        * we delegate interrupts to the 8259A.
-        */
-       /*
-        * TODO: set up through-local-APIC from through-I/O-APIC? --macro
-        */
-       value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
-       if (!smp_processor_id() && !value) {
-               value = APIC_DM_EXTINT;
-               apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n",
-                           smp_processor_id());
-       } else {
-               value = APIC_DM_EXTINT | APIC_LVT_MASKED;
-               apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n",
-                           smp_processor_id());
-       }
-       apic_write(APIC_LVT0, value);
-
-       /*
-        * only the BP should see the LINT1 NMI signal, obviously.
-        */
-       if (!smp_processor_id())
-               value = APIC_DM_NMI;
-       else
-               value = APIC_DM_NMI | APIC_LVT_MASKED;
-       apic_write(APIC_LVT1, value);
-       preempt_enable();
-}
-
-void __cpuinit end_local_APIC_setup(void)
-{
-       lapic_setup_esr();
-
-#ifdef CONFIG_X86_32
-       {
-               unsigned int value;
-               /* Disable the local apic timer */
-               value = apic_read(APIC_LVTT);
-               value |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
-               apic_write(APIC_LVTT, value);
-       }
-#endif
-
-       setup_apic_nmi_watchdog(NULL);
-       apic_pm_activate();
-}
-
-void check_x2apic(void)
-{
-       int msr, msr2;
-
-       rdmsr(MSR_IA32_APICBASE, msr, msr2);
-
-       if (msr & X2APIC_ENABLE) {
-               printk("x2apic enabled by BIOS, switching to x2apic ops\n");
-               x2apic_preenabled = x2apic = 1;
-               apic_ops = &x2apic_ops;
-       }
-}
-
-void enable_x2apic(void)
-{
-       int msr, msr2;
-
-       rdmsr(MSR_IA32_APICBASE, msr, msr2);
-       if (!(msr & X2APIC_ENABLE)) {
-               printk("Enabling x2apic\n");
-               wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0);
-       }
-}
-
-void enable_IR_x2apic(void)
-{
-#ifdef CONFIG_INTR_REMAP
-       int ret;
-       unsigned long flags;
-
-       if (!cpu_has_x2apic)
-               return;
-
-       if (!x2apic_preenabled && disable_x2apic) {
-               printk(KERN_INFO
-                      "Skipped enabling x2apic and Interrupt-remapping "
-                      "because of nox2apic\n");
-               return;
-       }
-
-       if (x2apic_preenabled && disable_x2apic)
-               panic("Bios already enabled x2apic, can't enforce nox2apic");
-
-       if (!x2apic_preenabled && skip_ioapic_setup) {
-               printk(KERN_INFO
-                      "Skipped enabling x2apic and Interrupt-remapping "
-                      "because of skipping io-apic setup\n");
-               return;
-       }
-
-       ret = dmar_table_init();
-       if (ret) {
-               printk(KERN_INFO
-                      "dmar_table_init() failed with %d:\n", ret);
-
-               if (x2apic_preenabled)
-                       panic("x2apic enabled by bios. But IR enabling failed");
-               else
-                       printk(KERN_INFO
-                              "Not enabling x2apic,Intr-remapping\n");
-               return;
-       }
-
-       local_irq_save(flags);
-       mask_8259A();
-       save_mask_IO_APIC_setup();
-
-       ret = enable_intr_remapping(1);
-
-       if (ret && x2apic_preenabled) {
-               local_irq_restore(flags);
-               panic("x2apic enabled by bios. But IR enabling failed");
-       }
-
-       if (ret)
-               goto end;
-
-       if (!x2apic) {
-               x2apic = 1;
-               apic_ops = &x2apic_ops;
-               enable_x2apic();
-       }
-end:
-       if (ret)
-               /*
-                * IR enabling failed
-                */
-               restore_IO_APIC_setup();
-       else
-               reinit_intr_remapped_IO_APIC(x2apic_preenabled);
-
-       unmask_8259A();
-       local_irq_restore(flags);
-
-       if (!ret) {
-               if (!x2apic_preenabled)
-                       printk(KERN_INFO
-                              "Enabled x2apic and interrupt-remapping\n");
-               else
-                       printk(KERN_INFO
-                              "Enabled Interrupt-remapping\n");
-       } else
-               printk(KERN_ERR
-                      "Failed to enable Interrupt-remapping and x2apic\n");
-#else
-       if (!cpu_has_x2apic)
-               return;
-
-       if (x2apic_preenabled)
-               panic("x2apic enabled prior OS handover,"
-                     " enable CONFIG_INTR_REMAP");
-
-       printk(KERN_INFO "Enable CONFIG_INTR_REMAP for enabling intr-remapping "
-              " and x2apic\n");
-#endif
-
-       return;
-}
-
-/*
- * Detect and enable local APICs on non-SMP boards.
- * Original code written by Keir Fraser.
- * On AMD64 we trust the BIOS - if it says no APIC it is likely
- * not correctly set up (usually the APIC timer won't work etc.)
- */
-static int __init detect_init_APIC(void)
-{
-       if (!cpu_has_apic) {
-               printk(KERN_INFO "No local APIC present\n");
-               return -1;
-       }
-
-       mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
-       boot_cpu_physical_apicid = 0;
-       return 0;
-}
-
-void __init early_init_lapic_mapping(void)
-{
-       unsigned long phys_addr;
-
-       /*
-        * If no local APIC can be found then go out
-        * : it means there is no mpatable and MADT
-        */
-       if (!smp_found_config)
-               return;
-
-       phys_addr = mp_lapic_addr;
-
-       set_fixmap_nocache(FIX_APIC_BASE, phys_addr);
-       apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
-                   APIC_BASE, phys_addr);
-
-       /*
-        * Fetch the APIC ID of the BSP in case we have a
-        * default configuration (or the MP table is broken).
-        */
-       boot_cpu_physical_apicid = read_apic_id();
-}
-
-/**
- * init_apic_mappings - initialize APIC mappings
- */
-void __init init_apic_mappings(void)
-{
-       if (x2apic) {
-               boot_cpu_physical_apicid = read_apic_id();
-               return;
-       }
-
-       /*
-        * If no local APIC can be found then set up a fake all
-        * zeroes page to simulate the local APIC and another
-        * one for the IO-APIC.
-        */
-       if (!smp_found_config && detect_init_APIC()) {
-               apic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
-               apic_phys = __pa(apic_phys);
-       } else
-               apic_phys = mp_lapic_addr;
-
-       set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
-       apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
-                               APIC_BASE, apic_phys);
-
-       /*
-        * Fetch the APIC ID of the BSP in case we have a
-        * default configuration (or the MP table is broken).
-        */
-       boot_cpu_physical_apicid = read_apic_id();
-}
-
-/*
- * This initializes the IO-APIC and APIC hardware if this is
- * a UP kernel.
- */
-int apic_version[MAX_APICS];
-
-int __init APIC_init_uniprocessor(void)
-{
-       if (disable_apic) {
-               printk(KERN_INFO "Apic disabled\n");
-               return -1;
-       }
-       if (!cpu_has_apic) {
-               disable_apic = 1;
-               printk(KERN_INFO "Apic disabled by BIOS\n");
-               return -1;
-       }
-
-       enable_IR_x2apic();
-       setup_apic_routing();
-
-       verify_local_APIC();
-
-       connect_bsp_APIC();
-
-       physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map);
-       apic_write(APIC_ID, SET_APIC_ID(boot_cpu_physical_apicid));
-
-       setup_local_APIC();
-
-       /*
-        * Now enable IO-APICs, actually call clear_IO_APIC
-        * We need clear_IO_APIC before enabling vector on BP
-        */
-       if (!skip_ioapic_setup && nr_ioapics)
-               enable_IO_APIC();
-
-       if (!smp_found_config || skip_ioapic_setup || !nr_ioapics)
-               localise_nmi_watchdog();
-       end_local_APIC_setup();
-
-       if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
-               setup_IO_APIC();
-       else
-               nr_ioapics = 0;
-       setup_boot_APIC_clock();
-       check_nmi_watchdog();
-       return 0;
-}
-
-/*
- * Local APIC interrupts
- */
-
-/*
- * This interrupt should _never_ happen with our APIC/SMP architecture
- */
-asmlinkage void smp_spurious_interrupt(void)
-{
-       unsigned int v;
-       exit_idle();
-       irq_enter();
-       /*
-        * Check if this really is a spurious interrupt and ACK it
-        * if it is a vectored one.  Just in case...
-        * Spurious interrupts should not be ACKed.
-        */
-       v = apic_read(APIC_ISR + ((SPURIOUS_APIC_VECTOR & ~0x1f) >> 1));
-       if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f)))
-               ack_APIC_irq();
-
-       add_pda(irq_spurious_count, 1);
-       irq_exit();
-}
-
-/*
- * This interrupt should never happen with our APIC/SMP architecture
- */
-asmlinkage void smp_error_interrupt(void)
-{
-       unsigned int v, v1;
-
-       exit_idle();
-       irq_enter();
-       /* First tickle the hardware, only then report what went on. -- REW */
-       v = apic_read(APIC_ESR);
-       apic_write(APIC_ESR, 0);
-       v1 = apic_read(APIC_ESR);
-       ack_APIC_irq();
-       atomic_inc(&irq_err_count);
-
-       /* Here is what the APIC error bits mean:
-          0: Send CS error
-          1: Receive CS error
-          2: Send accept error
-          3: Receive accept error
-          4: Reserved
-          5: Send illegal vector
-          6: Received illegal vector
-          7: Illegal register address
-       */
-       printk(KERN_DEBUG "APIC error on CPU%d: %02x(%02x)\n",
-               smp_processor_id(), v , v1);
-       irq_exit();
-}
-
-/**
- * connect_bsp_APIC - attach the APIC to the interrupt system
- */
-void __init connect_bsp_APIC(void)
-{
-#ifdef CONFIG_X86_32
-       if (pic_mode) {
-               /*
-                * Do not trust the local APIC being empty at bootup.
-                */
-               clear_local_APIC();
-               /*
-                * PIC mode, enable APIC mode in the IMCR, i.e.  connect BSP's
-                * local APIC to INT and NMI lines.
-                */
-               apic_printk(APIC_VERBOSE, "leaving PIC mode, "
-                               "enabling APIC mode.\n");
-               outb(0x70, 0x22);
-               outb(0x01, 0x23);
-       }
-#endif
-       enable_apic_mode();
-}
-
-/**
- * disconnect_bsp_APIC - detach the APIC from the interrupt system
- * @virt_wire_setup:   indicates, whether virtual wire mode is selected
- *
- * Virtual wire mode is necessary to deliver legacy interrupts even when the
- * APIC is disabled.
- */
-void disconnect_bsp_APIC(int virt_wire_setup)
-{
-       unsigned int value;
-
-#ifdef CONFIG_X86_32
-       if (pic_mode) {
-               /*
-                * Put the board back into PIC mode (has an effect only on
-                * certain older boards).  Note that APIC interrupts, including
-                * IPIs, won't work beyond this point!  The only exception are
-                * INIT IPIs.
-                */
-               apic_printk(APIC_VERBOSE, "disabling APIC mode, "
-                               "entering PIC mode.\n");
-               outb(0x70, 0x22);
-               outb(0x00, 0x23);
-               return;
-       }
-#endif
-
-       /* Go back to Virtual Wire compatibility mode */
-
-       /* For the spurious interrupt use vector F, and enable it */
-       value = apic_read(APIC_SPIV);
-       value &= ~APIC_VECTOR_MASK;
-       value |= APIC_SPIV_APIC_ENABLED;
-       value |= 0xf;
-       apic_write(APIC_SPIV, value);
-
-       if (!virt_wire_setup) {
-               /*
-                * For LVT0 make it edge triggered, active high,
-                * external and enabled
-                */
-               value = apic_read(APIC_LVT0);
-               value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
-                       APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
-                       APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
-               value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
-               value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
-               apic_write(APIC_LVT0, value);
-       } else {
-               /* Disable LVT0 */
-               apic_write(APIC_LVT0, APIC_LVT_MASKED);
-       }
-
-       /*
-        * For LVT1 make it edge triggered, active high,
-        * nmi and enabled
-        */
-       value = apic_read(APIC_LVT1);
-       value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
-                       APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
-                       APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
-       value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
-       value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
-       apic_write(APIC_LVT1, value);
-}
-
-void __cpuinit generic_processor_info(int apicid, int version)
-{
-       int cpu;
-       cpumask_t tmp_map;
-
-       /*
-        * Validate version
-        */
-       if (version == 0x0) {
-               printk(KERN_WARNING "BIOS bug, APIC version is 0 for CPU#%d! "
-                               "fixing up to 0x10. (tell your hw vendor)\n",
-                               version);
-               version = 0x10;
-       }
-       apic_version[apicid] = version;
-
-       if (num_processors >= NR_CPUS) {
-               printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached."
-                       "  Processor ignored.\n", NR_CPUS);
-               return;
-       }
-
-       num_processors++;
-       cpus_complement(tmp_map, cpu_present_map);
-       cpu = first_cpu(tmp_map);
-
-       physid_set(apicid, phys_cpu_present_map);
-       if (apicid == boot_cpu_physical_apicid) {
-               /*
-                * x86_bios_cpu_apicid is required to have processors listed
-                * in same order as logical cpu numbers. Hence the first
-                * entry is BSP, and so on.
-                */
-               cpu = 0;
-       }
-       if (apicid > max_physical_apicid)
-               max_physical_apicid = apicid;
-
-#ifdef CONFIG_X86_32
-       /*
-        * Would be preferable to switch to bigsmp when CONFIG_HOTPLUG_CPU=y
-        * but we need to work other dependencies like SMP_SUSPEND etc
-        * before this can be done without some confusion.
-        * if (CPU_HOTPLUG_ENABLED || num_processors > 8)
-        *       - Ashok Raj <ashok.raj@intel.com>
-        */
-       if (max_physical_apicid >= 8) {
-               switch (boot_cpu_data.x86_vendor) {
-               case X86_VENDOR_INTEL:
-                       if (!APIC_XAPIC(version)) {
-                               def_to_bigsmp = 0;
-                               break;
-                       }
-                       /* If P4 and above fall through */
-               case X86_VENDOR_AMD:
-                       def_to_bigsmp = 1;
-               }
-       }
-#endif
-
-#if defined(CONFIG_X86_SMP) || defined(CONFIG_X86_64)
-       /* are we being called early in kernel startup? */
-       if (early_per_cpu_ptr(x86_cpu_to_apicid)) {
-               u16 *cpu_to_apicid = early_per_cpu_ptr(x86_cpu_to_apicid);
-               u16 *bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid);
-
-               cpu_to_apicid[cpu] = apicid;
-               bios_cpu_apicid[cpu] = apicid;
-       } else {
-               per_cpu(x86_cpu_to_apicid, cpu) = apicid;
-               per_cpu(x86_bios_cpu_apicid, cpu) = apicid;
-       }
-#endif
-
-       cpu_set(cpu, cpu_possible_map);
-       cpu_set(cpu, cpu_present_map);
-}
-
-int hard_smp_processor_id(void)
-{
-       return read_apic_id();
-}
-
-/*
- * Power management
- */
-#ifdef CONFIG_PM
-
-static struct {
-       /*
-        * 'active' is true if the local APIC was enabled by us and
-        * not the BIOS; this signifies that we are also responsible
-        * for disabling it before entering apm/acpi suspend
-        */
-       int active;
-       /* r/w apic fields */
-       unsigned int apic_id;
-       unsigned int apic_taskpri;
-       unsigned int apic_ldr;
-       unsigned int apic_dfr;
-       unsigned int apic_spiv;
-       unsigned int apic_lvtt;
-       unsigned int apic_lvtpc;
-       unsigned int apic_lvt0;
-       unsigned int apic_lvt1;
-       unsigned int apic_lvterr;
-       unsigned int apic_tmict;
-       unsigned int apic_tdcr;
-       unsigned int apic_thmr;
-} apic_pm_state;
-
-static int lapic_suspend(struct sys_device *dev, pm_message_t state)
-{
-       unsigned long flags;
-       int maxlvt;
-
-       if (!apic_pm_state.active)
-               return 0;
-
-       maxlvt = lapic_get_maxlvt();
-
-       apic_pm_state.apic_id = apic_read(APIC_ID);
-       apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI);
-       apic_pm_state.apic_ldr = apic_read(APIC_LDR);
-       apic_pm_state.apic_dfr = apic_read(APIC_DFR);
-       apic_pm_state.apic_spiv = apic_read(APIC_SPIV);
-       apic_pm_state.apic_lvtt = apic_read(APIC_LVTT);
-       if (maxlvt >= 4)
-               apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC);
-       apic_pm_state.apic_lvt0 = apic_read(APIC_LVT0);
-       apic_pm_state.apic_lvt1 = apic_read(APIC_LVT1);
-       apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR);
-       apic_pm_state.apic_tmict = apic_read(APIC_TMICT);
-       apic_pm_state.apic_tdcr = apic_read(APIC_TDCR);
-#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL)
-       if (maxlvt >= 5)
-               apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR);
-#endif
-
-       local_irq_save(flags);
-       disable_local_APIC();
-       local_irq_restore(flags);
-       return 0;
-}
-
-static int lapic_resume(struct sys_device *dev)
-{
-       unsigned int l, h;
-       unsigned long flags;
-       int maxlvt;
-
-       if (!apic_pm_state.active)
-               return 0;
-
-       maxlvt = lapic_get_maxlvt();
-
-       local_irq_save(flags);
-
-#ifdef CONFIG_X86_64
-       if (x2apic)
-               enable_x2apic();
-       else
-#endif
-       {
-               /*
-                * Make sure the APICBASE points to the right address
-                *
-                * FIXME! This will be wrong if we ever support suspend on
-                * SMP! We'll need to do this as part of the CPU restore!
-                */
-               rdmsr(MSR_IA32_APICBASE, l, h);
-               l &= ~MSR_IA32_APICBASE_BASE;
-               l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr;
-               wrmsr(MSR_IA32_APICBASE, l, h);
-       }
-
-       apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED);
-       apic_write(APIC_ID, apic_pm_state.apic_id);
-       apic_write(APIC_DFR, apic_pm_state.apic_dfr);
-       apic_write(APIC_LDR, apic_pm_state.apic_ldr);
-       apic_write(APIC_TASKPRI, apic_pm_state.apic_taskpri);
-       apic_write(APIC_SPIV, apic_pm_state.apic_spiv);
-       apic_write(APIC_LVT0, apic_pm_state.apic_lvt0);
-       apic_write(APIC_LVT1, apic_pm_state.apic_lvt1);
-#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL)
-       if (maxlvt >= 5)
-               apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr);
-#endif
-       if (maxlvt >= 4)
-               apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc);
-       apic_write(APIC_LVTT, apic_pm_state.apic_lvtt);
-       apic_write(APIC_TDCR, apic_pm_state.apic_tdcr);
-       apic_write(APIC_TMICT, apic_pm_state.apic_tmict);
-       apic_write(APIC_ESR, 0);
-       apic_read(APIC_ESR);
-       apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr);
-       apic_write(APIC_ESR, 0);
-       apic_read(APIC_ESR);
-
-       local_irq_restore(flags);
-
-       return 0;
-}
-
-/*
- * This device has no shutdown method - fully functioning local APICs
- * are needed on every CPU up until machine_halt/restart/poweroff.
- */
-
-static struct sysdev_class lapic_sysclass = {
-       .name           = "lapic",
-       .resume         = lapic_resume,
-       .suspend        = lapic_suspend,
-};
-
-static struct sys_device device_lapic = {
-       .id     = 0,
-       .cls    = &lapic_sysclass,
-};
-
-static void __cpuinit apic_pm_activate(void)
-{
-       apic_pm_state.active = 1;
-}
-
-static int __init init_lapic_sysfs(void)
-{
-       int error;
-
-       if (!cpu_has_apic)
-               return 0;
-       /* XXX: remove suspend/resume procs if !apic_pm_state.active? */
-
-       error = sysdev_class_register(&lapic_sysclass);
-       if (!error)
-               error = sysdev_register(&device_lapic);
-       return error;
-}
-device_initcall(init_lapic_sysfs);
-
-#else  /* CONFIG_PM */
-
-static void apic_pm_activate(void) { }
-
-#endif /* CONFIG_PM */
-
-/*
- * apic_is_clustered_box() -- Check if we can expect good TSC
- *
- * Thus far, the major user of this is IBM's Summit2 series:
- *
- * Clustered boxes may have unsynced TSC problems if they are
- * multi-chassis. Use available data to take a good guess.
- * If in doubt, go HPET.
- */
-__cpuinit int apic_is_clustered_box(void)
-{
-       int i, clusters, zeros;
-       unsigned id;
-       u16 *bios_cpu_apicid;
-       DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS);
-
-       /*
-        * there is not this kind of box with AMD CPU yet.
-        * Some AMD box with quadcore cpu and 8 sockets apicid
-        * will be [4, 0x23] or [8, 0x27] could be thought to
-        * vsmp box still need checking...
-        */
-       if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && !is_vsmp_box())
-               return 0;
-
-       bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid);
-       bitmap_zero(clustermap, NUM_APIC_CLUSTERS);
-
-       for (i = 0; i < NR_CPUS; i++) {
-               /* are we being called early in kernel startup? */
-               if (bios_cpu_apicid) {
-                       id = bios_cpu_apicid[i];
-               }
-               else if (i < nr_cpu_ids) {
-                       if (cpu_present(i))
-                               id = per_cpu(x86_bios_cpu_apicid, i);
-                       else
-                               continue;
-               }
-               else
-                       break;
-
-               if (id != BAD_APICID)
-                       __set_bit(APIC_CLUSTERID(id), clustermap);
-       }
-
-       /* Problem:  Partially populated chassis may not have CPUs in some of
-        * the APIC clusters they have been allocated.  Only present CPUs have
-        * x86_bios_cpu_apicid entries, thus causing zeroes in the bitmap.
-        * Since clusters are allocated sequentially, count zeros only if
-        * they are bounded by ones.
-        */
-       clusters = 0;
-       zeros = 0;
-       for (i = 0; i < NUM_APIC_CLUSTERS; i++) {
-               if (test_bit(i, clustermap)) {
-                       clusters += 1 + zeros;
-                       zeros = 0;
-               } else
-                       ++zeros;
-       }
-
-       /* ScaleMP vSMPowered boxes have one cluster per board and TSCs are
-        * not guaranteed to be synced between boards
-        */
-       if (is_vsmp_box() && clusters > 1)
-               return 1;
-
-       /*
-        * If clusters > 2, then should be multi-chassis.
-        * May have to revisit this when multi-core + hyperthreaded CPUs come
-        * out, but AFAIK this will work even for them.
-        */
-       return (clusters > 2);
-}
-
-static __init int setup_nox2apic(char *str)
-{
-       disable_x2apic = 1;
-       clear_cpu_cap(&boot_cpu_data, X86_FEATURE_X2APIC);
-       return 0;
-}
-early_param("nox2apic", setup_nox2apic);
-
-
-/*
- * APIC command line parameters
- */
-static int __init setup_disableapic(char *arg)
-{
-       disable_apic = 1;
-       setup_clear_cpu_cap(X86_FEATURE_APIC);
-       return 0;
-}
-early_param("disableapic", setup_disableapic);
-
-/* same as disableapic, for compatibility */
-static int __init setup_nolapic(char *arg)
-{
-       return setup_disableapic(arg);
-}
-early_param("nolapic", setup_nolapic);
-
-static int __init parse_lapic_timer_c2_ok(char *arg)
-{
-       local_apic_timer_c2_ok = 1;
-       return 0;
-}
-early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok);
-
-static int __init parse_disable_apic_timer(char *arg)
-{
-       disable_apic_timer = 1;
-       return 0;
-}
-early_param("noapictimer", parse_disable_apic_timer);
-
-static int __init parse_nolapic_timer(char *arg)
-{
-       disable_apic_timer = 1;
-       return 0;
-}
-early_param("nolapic_timer", parse_nolapic_timer);
-
-static __init int setup_apicpmtimer(char *s)
-{
-       apic_calibrate_pmtmr = 1;
-       notsc_setup(NULL);
-       return 0;
-}
-__setup("apicpmtimer", setup_apicpmtimer);
-
-static int __init apic_set_verbosity(char *arg)
-{
-       if (!arg)  {
-#ifdef CONFIG_X86_64
-               skip_ioapic_setup = 0;
-               ioapic_force = 1;
-               return 0;
-#endif
-               return -EINVAL;
-       }
-
-       if (strcmp("debug", arg) == 0)
-               apic_verbosity = APIC_DEBUG;
-       else if (strcmp("verbose", arg) == 0)
-               apic_verbosity = APIC_VERBOSE;
-       else {
-               printk(KERN_WARNING "APIC Verbosity level %s not recognised"
-                       " use apic=verbose or apic=debug\n", arg);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-early_param("apic", apic_set_verbosity);
-
-static int __init lapic_insert_resource(void)
-{
-       if (!apic_phys)
-               return -1;
-
-       /* Put local APIC into the resource map. */
-       lapic_resource.start = apic_phys;
-       lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1;
-       insert_resource(&iomem_resource, &lapic_resource);
-
-       return 0;
-}
-
-/*
- * need call insert after e820_reserve_resources()
- * that is using request_resource
- */
-late_initcall(lapic_insert_resource);
index 505543a75a561f1cfc207d4f88dffbd2718bc724..7fcf63d22f8b28c4457b6f8e7fb2eae54b071b1f 100644 (file)
@@ -22,7 +22,7 @@
 
 #define __NO_STUBS 1
 #undef __SYSCALL
-#undef ASM_X86__UNISTD_64_H
+#undef _ASM_X86_UNISTD_64_H
 #define __SYSCALL(nr, sym) [nr] = 1,
 static char syscalls[] = {
 #include <asm/unistd.h>
index fdd585f9c53dd371d41392b4e955278d913979f0..f0dfe6f17e7eabbe41f90a8afd75c54766081fa2 100644 (file)
@@ -1,8 +1,6 @@
 /*
  * BIOS run time interface routines.
  *
- *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
- *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation; either version 2 of the License, or
  *  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) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ *  Copyright (c) Russ Anderson
  */
 
+#include <linux/efi.h>
+#include <asm/efi.h>
+#include <linux/io.h>
 #include <asm/uv/bios.h>
+#include <asm/uv/uv_hub.h>
+
+struct uv_systab uv_systab;
 
-const char *
-x86_bios_strerror(long status)
+s64 uv_bios_call(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5)
 {
-       const char *str;
-       switch (status) {
-       case  0: str = "Call completed without error";  break;
-       case -1: str = "Not implemented";               break;
-       case -2: str = "Invalid argument";              break;
-       case -3: str = "Call completed with error";     break;
-       default: str = "Unknown BIOS status code";      break;
-       }
-       return str;
+       struct uv_systab *tab = &uv_systab;
+
+       if (!tab->function)
+               /*
+                * BIOS does not support UV systab
+                */
+               return BIOS_STATUS_UNIMPLEMENTED;
+
+       return efi_call6((void *)__va(tab->function),
+                                       (u64)which, a1, a2, a3, a4, a5);
 }
 
-long
-x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
-                  unsigned long *drift_info)
+s64 uv_bios_call_irqsave(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3,
+                                       u64 a4, u64 a5)
 {
-       struct uv_bios_retval isrv;
+       unsigned long bios_flags;
+       s64 ret;
 
-       BIOS_CALL(isrv, BIOS_FREQ_BASE, which, 0, 0, 0, 0, 0, 0);
-       *ticks_per_second = isrv.v0;
-       *drift_info = isrv.v1;
-       return isrv.status;
+       local_irq_save(bios_flags);
+       ret = uv_bios_call(which, a1, a2, a3, a4, a5);
+       local_irq_restore(bios_flags);
+
+       return ret;
 }
-EXPORT_SYMBOL_GPL(x86_bios_freq_base);
+
+s64 uv_bios_call_reentrant(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3,
+                                       u64 a4, u64 a5)
+{
+       s64 ret;
+
+       preempt_disable();
+       ret = uv_bios_call(which, a1, a2, a3, a4, a5);
+       preempt_enable();
+
+       return ret;
+}
+
+
+long sn_partition_id;
+EXPORT_SYMBOL_GPL(sn_partition_id);
+long uv_coherency_id;
+EXPORT_SYMBOL_GPL(uv_coherency_id);
+long uv_region_size;
+EXPORT_SYMBOL_GPL(uv_region_size);
+int uv_type;
+
+
+s64 uv_bios_get_sn_info(int fc, int *uvtype, long *partid, long *coher,
+               long *region)
+{
+       s64 ret;
+       u64 v0, v1;
+       union partition_info_u part;
+
+       ret = uv_bios_call_irqsave(UV_BIOS_GET_SN_INFO, fc,
+                               (u64)(&v0), (u64)(&v1), 0, 0);
+       if (ret != BIOS_STATUS_SUCCESS)
+               return ret;
+
+       part.val = v0;
+       if (uvtype)
+               *uvtype = part.hub_version;
+       if (partid)
+               *partid = part.partition_id;
+       if (coher)
+               *coher = part.coherence_id;
+       if (region)
+               *region = part.region_size;
+       return ret;
+}
+
+
+s64 uv_bios_freq_base(u64 clock_type, u64 *ticks_per_second)
+{
+       return uv_bios_call(UV_BIOS_FREQ_BASE, clock_type,
+                          (u64)ticks_per_second, 0, 0, 0);
+}
+EXPORT_SYMBOL_GPL(uv_bios_freq_base);
+
+
+#ifdef CONFIG_EFI
+void uv_bios_init(void)
+{
+       struct uv_systab *tab;
+
+       if ((efi.uv_systab == EFI_INVALID_TABLE_ADDR) ||
+           (efi.uv_systab == (unsigned long)NULL)) {
+               printk(KERN_CRIT "No EFI UV System Table.\n");
+               uv_systab.function = (unsigned long)NULL;
+               return;
+       }
+
+       tab = (struct uv_systab *)ioremap(efi.uv_systab,
+                                       sizeof(struct uv_systab));
+       if (strncmp(tab->signature, "UVST", 4) != 0)
+               printk(KERN_ERR "bad signature in UV system table!");
+
+       /*
+        * Copy table to permanent spot for later use.
+        */
+       memcpy(&uv_systab, tab, sizeof(struct uv_systab));
+       iounmap(tab);
+
+       printk(KERN_INFO "EFI UV System Table Revision %d\n", tab->revision);
+}
+#else  /* !CONFIG_EFI */
+
+void uv_bios_init(void) { }
+#endif
+
index 7f0b45a5d7887cf393452c7983073a683390f0e4..82ec6075c057b695cf6904a28a58fb8c60c37d7a 100644 (file)
@@ -25,7 +25,7 @@ obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o
 quiet_cmd_mkcapflags = MKCAP   $@
       cmd_mkcapflags = $(PERL) $(srctree)/$(src)/mkcapflags.pl $< $@
 
-cpufeature = $(src)/../../../../include/asm-x86/cpufeature.h
+cpufeature = $(src)/../../include/asm/cpufeature.h
 
 targets += capflags.c
 $(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.pl FORCE
index 32e73520adf7540525c033bca414bde159dc5536..8f1e31db2ad56d4f178881fff4d86b777349173c 100644 (file)
@@ -249,7 +249,7 @@ static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)
        }
        numa_set_node(cpu, node);
 
-       printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node);
+       printk(KERN_INFO "CPU %d/0x%x -> Node %d\n", cpu, apicid, node);
 #endif
 }
 
index c24c4a487b7cb05f8ec6ad73998a2e0e01439d32..8e48c5d4467df61d3652a39b06b85e7389143c54 100644 (file)
@@ -780,6 +780,9 @@ static int __init acpi_cpufreq_init(void)
 {
        int ret;
 
+       if (acpi_disabled)
+               return 0;
+
        dprintk("acpi_cpufreq_init\n");
 
        ret = acpi_cpufreq_early_init();
index 06fcce516d51d44a97349f9140507f82b6d20ef2..b0461856acfb1ca4b236bd355c4cd94604b36503 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  (C) 2001-2004  Dave Jones. <davej@codemonkey.org.uk>
+ *  (C) 2001-2004  Dave Jones. <davej@redhat.com>
  *  (C) 2002  Padraig Brady. <padraig@antefacto.com>
  *
  *  Licensed under the terms of the GNU GPL License version 2.
@@ -1019,7 +1019,7 @@ MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor");
 module_param(revid_errata, int, 0644);
 MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID");
 
-MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
+MODULE_AUTHOR ("Dave Jones <davej@redhat.com>");
 MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors.");
 MODULE_LICENSE ("GPL");
 
index b5ced806a316d66b1c4bb1fcc6120f855617a266..c1ac5790c63e34ec65cfe062f6fbf34c6d3607ce 100644 (file)
@@ -246,7 +246,7 @@ static void __exit powernow_k6_exit(void)
 }
 
 
-MODULE_AUTHOR("Arjan van de Ven <arjanv@redhat.com>, Dave Jones <davej@codemonkey.org.uk>, Dominik Brodowski <linux@brodo.de>");
+MODULE_AUTHOR("Arjan van de Ven, Dave Jones <davej@redhat.com>, Dominik Brodowski <linux@brodo.de>");
 MODULE_DESCRIPTION("PowerNow! driver for AMD K6-2+ / K6-3+ processors.");
 MODULE_LICENSE("GPL");
 
index 0a61159d7b71389c8e8bcdbae7b913463b0f318c..7c7d56b43136a6a416085fb7cc4b27f25839ec3c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  AMD K7 Powernow driver.
- *  (C) 2003 Dave Jones <davej@codemonkey.org.uk> on behalf of SuSE Labs.
+ *  (C) 2003 Dave Jones on behalf of SuSE Labs.
  *  (C) 2003-2004 Dave Jones <davej@redhat.com>
  *
  *  Licensed under the terms of the GNU GPL License version 2.
@@ -692,7 +692,7 @@ static void __exit powernow_exit (void)
 module_param(acpi_force,  int, 0444);
 MODULE_PARM_DESC(acpi_force, "Force ACPI to be used.");
 
-MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
+MODULE_AUTHOR ("Dave Jones <davej@redhat.com>");
 MODULE_DESCRIPTION ("Powernow driver for AMD K7 processors.");
 MODULE_LICENSE ("GPL");
 
index 84bb395038d879823d5beb4e4bf2e181b8bd6b91..d3dcd58b87cd50654d7a065e5d42b05300103f09 100644 (file)
@@ -7,7 +7,7 @@
  *  Support : mark.langsdorf@amd.com
  *
  *  Based on the powernow-k7.c module written by Dave Jones.
- *  (C) 2003 Dave Jones <davej@codemonkey.org.uk> on behalf of SuSE Labs
+ *  (C) 2003 Dave Jones on behalf of SuSE Labs
  *  (C) 2004 Dominik Brodowski <linux@brodo.de>
  *  (C) 2004 Pavel Machek <pavel@suse.cz>
  *  Licensed under the terms of the GNU GPL License version 2.
@@ -45,7 +45,6 @@
 #endif
 
 #define PFX "powernow-k8: "
-#define BFX PFX "BIOS error: "
 #define VERSION "version 2.20.00"
 #include "powernow-k8.h"
 
@@ -536,35 +535,40 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8
 
        for (j = 0; j < data->numps; j++) {
                if (pst[j].vid > LEAST_VID) {
-                       printk(KERN_ERR PFX "vid %d invalid : 0x%x\n", j, pst[j].vid);
+                       printk(KERN_ERR FW_BUG PFX "vid %d invalid : 0x%x\n",
+                              j, pst[j].vid);
                        return -EINVAL;
                }
                if (pst[j].vid < data->rvo) {   /* vid + rvo >= 0 */
-                       printk(KERN_ERR BFX "0 vid exceeded with pstate %d\n", j);
+                       printk(KERN_ERR FW_BUG PFX "0 vid exceeded with pstate"
+                              " %d\n", j);
                        return -ENODEV;
                }
                if (pst[j].vid < maxvid + data->rvo) {  /* vid + rvo >= maxvid */
-                       printk(KERN_ERR BFX "maxvid exceeded with pstate %d\n", j);
+                       printk(KERN_ERR FW_BUG PFX "maxvid exceeded with pstate"
+                              " %d\n", j);
                        return -ENODEV;
                }
                if (pst[j].fid > MAX_FID) {
-                       printk(KERN_ERR BFX "maxfid exceeded with pstate %d\n", j);
+                       printk(KERN_ERR FW_BUG PFX "maxfid exceeded with pstate"
+                              " %d\n", j);
                        return -ENODEV;
                }
                if (j && (pst[j].fid < HI_FID_TABLE_BOTTOM)) {
                        /* Only first fid is allowed to be in "low" range */
-                       printk(KERN_ERR BFX "two low fids - %d : 0x%x\n", j, pst[j].fid);
+                       printk(KERN_ERR FW_BUG PFX "two low fids - %d : "
+                              "0x%x\n", j, pst[j].fid);
                        return -EINVAL;
                }
                if (pst[j].fid < lastfid)
                        lastfid = pst[j].fid;
        }
        if (lastfid & 1) {
-               printk(KERN_ERR BFX "lastfid invalid\n");
+               printk(KERN_ERR FW_BUG PFX "lastfid invalid\n");
                return -EINVAL;
        }
        if (lastfid > LO_FID_TABLE_TOP)
-               printk(KERN_INFO BFX  "first fid not from lo freq table\n");
+               printk(KERN_INFO FW_BUG PFX  "first fid not from lo freq table\n");
 
        return 0;
 }
@@ -672,13 +676,13 @@ static int find_psb_table(struct powernow_k8_data *data)
 
                dprintk("table vers: 0x%x\n", psb->tableversion);
                if (psb->tableversion != PSB_VERSION_1_4) {
-                       printk(KERN_ERR BFX "PSB table is not v1.4\n");
+                       printk(KERN_ERR FW_BUG PFX "PSB table is not v1.4\n");
                        return -ENODEV;
                }
 
                dprintk("flags: 0x%x\n", psb->flags1);
                if (psb->flags1) {
-                       printk(KERN_ERR BFX "unknown flags\n");
+                       printk(KERN_ERR FW_BUG PFX "unknown flags\n");
                        return -ENODEV;
                }
 
@@ -705,7 +709,7 @@ static int find_psb_table(struct powernow_k8_data *data)
                        }
                }
                if (cpst != 1) {
-                       printk(KERN_ERR BFX "numpst must be 1\n");
+                       printk(KERN_ERR FW_BUG PFX "numpst must be 1\n");
                        return -ENODEV;
                }
 
@@ -1130,17 +1134,19 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
                               "ACPI Processor module before starting this "
                               "driver.\n");
 #else
-                       printk(KERN_ERR PFX "Your BIOS does not provide ACPI "
-                              "_PSS objects in a way that Linux understands. "
-                              "Please report this to the Linux ACPI maintainers"
-                              " and complain to your BIOS vendor.\n");
+                       printk(KERN_ERR FW_BUG PFX "Your BIOS does not provide"
+                              " ACPI _PSS objects in a way that Linux "
+                              "understands. Please report this to the Linux "
+                              "ACPI maintainers and complain to your BIOS "
+                              "vendor.\n");
 #endif
                        kfree(data);
                        return -ENODEV;
                }
                if (pol->cpu != 0) {
-                       printk(KERN_ERR PFX "No ACPI _PSS objects for CPU other than "
-                              "CPU0. Complain to your BIOS vendor.\n");
+                       printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for "
+                              "CPU other than CPU0. Complain to your BIOS "
+                              "vendor.\n");
                        kfree(data);
                        return -ENODEV;
                }
@@ -1193,7 +1199,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
 
        /* min/max the cpu is capable of */
        if (cpufreq_frequency_table_cpuinfo(pol, data->powernow_table)) {
-               printk(KERN_ERR PFX "invalid powernow_table\n");
+               printk(KERN_ERR FW_BUG PFX "invalid powernow_table\n");
                powernow_k8_cpu_exit_acpi(data);
                kfree(data->powernow_table);
                kfree(data);
index 191f7263c61dce1b42864cd4709e249773339243..04d0376b64b0dfa9a292a0784afddc07de475720 100644 (file)
@@ -431,7 +431,7 @@ static void __exit speedstep_exit(void)
 }
 
 
-MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>, Dominik Brodowski <linux@brodo.de>");
+MODULE_AUTHOR ("Dave Jones <davej@redhat.com>, Dominik Brodowski <linux@brodo.de>");
 MODULE_DESCRIPTION ("Speedstep driver for Intel mobile processors on chipsets with ICH-M southbridges.");
 MODULE_LICENSE ("GPL");
 
index 99468dbd08da3edbb2c97b5cbb803918c85329d6..cce0b6118d550e015a34c5e1b0f9bc60de1f8b3d 100644 (file)
@@ -174,7 +174,7 @@ static void __cpuinit srat_detect_node(void)
                node = first_node(node_online_map);
        numa_set_node(cpu, node);
 
-       printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node);
+       printk(KERN_INFO "CPU %d/0x%x -> Node %d\n", cpu, apicid, node);
 #endif
 }
 
index f390c9f66351ae850ca169b5e399b32d555bd266..dd3af6e7b39a078835abd589feeaeee0b6184907 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * Athlon/Hammer specific Machine Check Exception Reporting
- * (C) Copyright 2002 Dave Jones <davej@codemonkey.org.uk>
+ * Athlon specific Machine Check Exception Reporting
+ * (C) Copyright 2002 Dave Jones <davej@redhat.com>
  */
 
 #include <linux/init.h>
index 774d87cfd8cd8fe0524bb9d1bc4c4a076f8c306d..0ebf3fc6a6108e8c9eedb239f2aba01a76e5902d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * mce.c - x86 Machine Check Exception Reporting
- * (c) 2002 Alan Cox <alan@redhat.com>, Dave Jones <davej@codemonkey.org.uk>
+ * (c) 2002 Alan Cox <alan@redhat.com>, Dave Jones <davej@redhat.com>
  */
 
 #include <linux/init.h>
index cc1fccdd31e08ce56b6538692004475a7f44bf66..a74af128efc917384909d44b51834aaf40282647 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Non Fatal Machine Check Exception Reporting
  *
- * (C) Copyright 2002 Dave Jones. <davej@codemonkey.org.uk>
+ * (C) Copyright 2002 Dave Jones. <davej@redhat.com>
  *
  * This file contains routines to check for non-fatal MCEs every 15s
  *
index 6bff382094f58a2a40b0adebdf5fb264905614ba..9abd48b2267413a4212b18d0cb627325703b90de 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/bitops.h>
 #include <linux/smp.h>
 #include <linux/nmi.h>
+#include <linux/kprobes.h>
+
 #include <asm/apic.h>
 #include <asm/intel_arch_perfmon.h>
 
@@ -336,7 +338,8 @@ static void single_msr_unreserve(void)
        release_perfctr_nmi(wd_ops->perfctr);
 }
 
-static void single_msr_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz)
+static void __kprobes
+single_msr_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz)
 {
        /* start the cycle over again */
        write_watchdog_counter(wd->perfctr_msr, NULL, nmi_hz);
@@ -401,7 +404,7 @@ static int setup_p6_watchdog(unsigned nmi_hz)
        return 1;
 }
 
-static void p6_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz)
+static void __kprobes p6_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz)
 {
        /*
         * P6 based Pentium M need to re-unmask
@@ -605,7 +608,7 @@ static void p4_unreserve(void)
        release_perfctr_nmi(MSR_P4_IQ_PERFCTR0);
 }
 
-static void p4_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz)
+static void __kprobes p4_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz)
 {
        unsigned dummy;
        /*
@@ -784,7 +787,7 @@ unsigned lapic_adjust_nmi_hz(unsigned hz)
        return hz;
 }
 
-int lapic_wd_event(unsigned nmi_hz)
+int __kprobes lapic_wd_event(unsigned nmi_hz)
 {
        struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
        u64 ctr;
index a26c480b94915a2b460c0963bf38f9693c911641..01b1244ef1c0f47456a246f89324973b4f74269e 100644 (file)
@@ -160,14 +160,16 @@ static void *c_start(struct seq_file *m, loff_t *pos)
 {
        if (*pos == 0)  /* just in case, cpu 0 is not the first */
                *pos = first_cpu(cpu_online_map);
-       if ((*pos) < nr_cpu_ids && cpu_online(*pos))
+       else
+               *pos = next_cpu_nr(*pos - 1, cpu_online_map);
+       if ((*pos) < nr_cpu_ids)
                return &cpu_data(*pos);
        return NULL;
 }
 
 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 {
-       *pos = next_cpu(*pos, cpu_online_map);
+       (*pos)++;
        return c_start(m, pos);
 }
 
index 1a78180f08d39aa2a87a2b2738e7a6b488a4d5dc..b3614752197b6c6e3c0cf53c7b718dd0167fbdea 100644 (file)
@@ -405,7 +405,6 @@ die_nmi(char *str, struct pt_regs *regs, int do_panic)
                panic("Non maskable interrupt");
        console_silent();
        spin_unlock(&nmi_print_lock);
-       bust_spinlocks(0);
 
        /*
         * If we are in kernel we are probably nested up pretty bad
@@ -416,6 +415,7 @@ die_nmi(char *str, struct pt_regs *regs, int do_panic)
                crash_kexec(regs);
        }
 
+       bust_spinlocks(0);
        do_exit(SIGSEGV);
 }
 
index 733c4f8d42ea587437191881974c786bc6e9186e..3ce029ffaa55b2085ef4de993b427f86a3cdfdb7 100644 (file)
@@ -95,7 +95,8 @@ static void __init nvidia_bugs(int num, int slot, int func)
 
 }
 
-static u32 ati_ixp4x0_rev(int num, int slot, int func)
+#if defined(CONFIG_ACPI) && defined(CONFIG_X86_IO_APIC)
+static u32 __init ati_ixp4x0_rev(int num, int slot, int func)
 {
        u32 d;
        u8  b;
@@ -115,7 +116,6 @@ static u32 ati_ixp4x0_rev(int num, int slot, int func)
 
 static void __init ati_bugs(int num, int slot, int func)
 {
-#if defined(CONFIG_ACPI) && defined (CONFIG_X86_IO_APIC)
        u32 d;
        u8  b;
 
@@ -138,9 +138,56 @@ static void __init ati_bugs(int num, int slot, int func)
                printk(KERN_INFO "If you got timer trouble "
                       "try acpi_use_timer_override\n");
        }
-#endif
 }
 
+static u32 __init ati_sbx00_rev(int num, int slot, int func)
+{
+       u32 old, d;
+
+       d = read_pci_config(num, slot, func, 0x70);
+       old = d;
+       d &= ~(1<<8);
+       write_pci_config(num, slot, func, 0x70, d);
+       d = read_pci_config(num, slot, func, 0x8);
+       d &= 0xff;
+       write_pci_config(num, slot, func, 0x70, old);
+
+       return d;
+}
+
+static void __init ati_bugs_contd(int num, int slot, int func)
+{
+       u32 d, rev;
+
+       if (acpi_use_timer_override)
+               return;
+
+       rev = ati_sbx00_rev(num, slot, func);
+       if (rev > 0x13)
+               return;
+
+       /* check for IRQ0 interrupt swap */
+       d = read_pci_config(num, slot, func, 0x64);
+       if (!(d & (1<<14)))
+               acpi_skip_timer_override = 1;
+
+       if (acpi_skip_timer_override) {
+               printk(KERN_INFO "SB600 revision 0x%x\n", rev);
+               printk(KERN_INFO "Ignoring ACPI timer override.\n");
+               printk(KERN_INFO "If you got timer trouble "
+                      "try acpi_use_timer_override\n");
+       }
+}
+#else
+static void __init ati_bugs(int num, int slot, int func)
+{
+}
+
+static void __init ati_bugs_contd(int num, int slot, int func)
+{
+}
+#endif
+
 #ifdef CONFIG_DMAR
 static void __init intel_g33_dmar(int num, int slot, int func)
 {
@@ -176,6 +223,8 @@ static struct chipset early_qrk[] __initdata = {
          PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, fix_hypertransport_config },
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS,
          PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs },
+       { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS,
+         PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs_contd },
 #ifdef CONFIG_DMAR
        { PCI_VENDOR_ID_INTEL, 0x29c0,
          PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, intel_g33_dmar },
index 945a31cdd81f5493d0de00bf39214f0df371b976..1119d247fe11d87aceaa2e42f770bd773a9c1ea2 100644 (file)
@@ -366,6 +366,10 @@ void __init efi_init(void)
                                        SMBIOS_TABLE_GUID)) {
                        efi.smbios = config_tables[i].table;
                        printk(" SMBIOS=0x%lx ", config_tables[i].table);
+               } else if (!efi_guidcmp(config_tables[i].guid,
+                                       UV_SYSTEM_TABLE_GUID)) {
+                       efi.uv_systab = config_tables[i].table;
+                       printk(" UVsystab=0x%lx ", config_tables[i].table);
                } else if (!efi_guidcmp(config_tables[i].guid,
                                        HCDP_TABLE_GUID)) {
                        efi.hcdp = config_tables[i].table;
index b21fbfaffe391a974d10d7417a9f00c99ab05228..dd65143941a841de0f55a4830732be7a0fcada4b 100644 (file)
@@ -629,7 +629,7 @@ ENTRY(interrupt)
 ENTRY(irq_entries_start)
        RING0_INT_FRAME
 vector=0
-.rept NR_IRQS
+.rept NR_VECTORS
        ALIGN
  .if vector
        CFI_ADJUST_CFA_OFFSET -4
@@ -1024,7 +1024,7 @@ ENTRY(machine_check)
        RING0_INT_FRAME
        pushl $0
        CFI_ADJUST_CFA_OFFSET 4
-       pushl $do_machine_check
+       pushl machine_check_vector
        CFI_ADJUST_CFA_OFFSET 4
        jmp error_code
        CFI_ENDPROC
@@ -1153,20 +1153,6 @@ ENDPROC(xen_failsafe_callback)
 #ifdef CONFIG_DYNAMIC_FTRACE
 
 ENTRY(mcount)
-       pushl %eax
-       pushl %ecx
-       pushl %edx
-       movl 0xc(%esp), %eax
-       subl $MCOUNT_INSN_SIZE, %eax
-
-.globl mcount_call
-mcount_call:
-       call ftrace_stub
-
-       popl %edx
-       popl %ecx
-       popl %eax
-
        ret
 END(mcount)
 
index 1db6ce4314e19325a740e15fc1ec60db3de8cf38..09e7145484c5ba971f72af1f7411c286f41ee5ef 100644 (file)
 #ifdef CONFIG_FTRACE
 #ifdef CONFIG_DYNAMIC_FTRACE
 ENTRY(mcount)
-
-       subq $0x38, %rsp
-       movq %rax, (%rsp)
-       movq %rcx, 8(%rsp)
-       movq %rdx, 16(%rsp)
-       movq %rsi, 24(%rsp)
-       movq %rdi, 32(%rsp)
-       movq %r8, 40(%rsp)
-       movq %r9, 48(%rsp)
-
-       movq 0x38(%rsp), %rdi
-       subq $MCOUNT_INSN_SIZE, %rdi
-
-.globl mcount_call
-mcount_call:
-       call ftrace_stub
-
-       movq 48(%rsp), %r9
-       movq 40(%rsp), %r8
-       movq 32(%rsp), %rdi
-       movq 24(%rsp), %rsi
-       movq 16(%rsp), %rdx
-       movq 8(%rsp), %rcx
-       movq (%rsp), %rax
-       addq $0x38, %rsp
-
        retq
 END(mcount)
 
index ab115cd15fdfbb2cc06182385b4a60b8521f617c..d073d981a730306f970aabdf5f7174453c24d226 100644 (file)
 
 #include <linux/spinlock.h>
 #include <linux/hardirq.h>
+#include <linux/uaccess.h>
 #include <linux/ftrace.h>
 #include <linux/percpu.h>
 #include <linux/init.h>
 #include <linux/list.h>
 
-#include <asm/alternative.h>
 #include <asm/ftrace.h>
+#include <asm/nops.h>
 
 
 /* Long is fine, even if it is only 4 bytes ;-) */
-static long *ftrace_nop;
+static unsigned long *ftrace_nop;
 
 union ftrace_code_union {
        char code[MCOUNT_INSN_SIZE];
@@ -60,11 +61,7 @@ notrace int
 ftrace_modify_code(unsigned long ip, unsigned char *old_code,
                   unsigned char *new_code)
 {
-       unsigned replaced;
-       unsigned old = *(unsigned *)old_code; /* 4 bytes */
-       unsigned new = *(unsigned *)new_code; /* 4 bytes */
-       unsigned char newch = new_code[4];
-       int faulted = 0;
+       unsigned char replaced[MCOUNT_INSN_SIZE];
 
        /*
         * Note: Due to modules and __init, code can
@@ -72,29 +69,20 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code,
         *  as well as code changing.
         *
         * No real locking needed, this code is run through
-        * kstop_machine.
+        * kstop_machine, or before SMP starts.
         */
-       asm volatile (
-               "1: lock\n"
-               "   cmpxchg %3, (%2)\n"
-               "   jnz 2f\n"
-               "   movb %b4, 4(%2)\n"
-               "2:\n"
-               ".section .fixup, \"ax\"\n"
-               "3:     movl $1, %0\n"
-               "       jmp 2b\n"
-               ".previous\n"
-               _ASM_EXTABLE(1b, 3b)
-               : "=r"(faulted), "=a"(replaced)
-               : "r"(ip), "r"(new), "c"(newch),
-                 "0"(faulted), "a"(old)
-               : "memory");
-       sync_core();
+       if (__copy_from_user_inatomic(replaced, (char __user *)ip, MCOUNT_INSN_SIZE))
+               return 1;
+
+       if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0)
+               return 2;
 
-       if (replaced != old && replaced != new)
-               faulted = 2;
+       WARN_ON_ONCE(__copy_to_user_inatomic((char __user *)ip, new_code,
+                                   MCOUNT_INSN_SIZE));
 
-       return faulted;
+       sync_core();
+
+       return 0;
 }
 
 notrace int ftrace_update_ftrace_func(ftrace_func_t func)
@@ -112,30 +100,76 @@ notrace int ftrace_update_ftrace_func(ftrace_func_t func)
 
 notrace int ftrace_mcount_set(unsigned long *data)
 {
-       unsigned long ip = (long)(&mcount_call);
-       unsigned long *addr = data;
-       unsigned char old[MCOUNT_INSN_SIZE], *new;
-
-       /*
-        * Replace the mcount stub with a pointer to the
-        * ip recorder function.
-        */
-       memcpy(old, &mcount_call, MCOUNT_INSN_SIZE);
-       new = ftrace_call_replace(ip, *addr);
-       *addr = ftrace_modify_code(ip, old, new);
-
+       /* mcount is initialized as a nop */
+       *data = 0;
        return 0;
 }
 
 int __init ftrace_dyn_arch_init(void *data)
 {
-       const unsigned char *const *noptable = find_nop_table();
-
-       /* This is running in kstop_machine */
-
-       ftrace_mcount_set(data);
+       extern const unsigned char ftrace_test_p6nop[];
+       extern const unsigned char ftrace_test_nop5[];
+       extern const unsigned char ftrace_test_jmp[];
+       int faulted = 0;
 
-       ftrace_nop = (unsigned long *)noptable[MCOUNT_INSN_SIZE];
+       /*
+        * There is no good nop for all x86 archs.
+        * We will default to using the P6_NOP5, but first we
+        * will test to make sure that the nop will actually
+        * work on this CPU. If it faults, we will then
+        * go to a lesser efficient 5 byte nop. If that fails
+        * we then just use a jmp as our nop. This isn't the most
+        * efficient nop, but we can not use a multi part nop
+        * since we would then risk being preempted in the middle
+        * of that nop, and if we enabled tracing then, it might
+        * cause a system crash.
+        *
+        * TODO: check the cpuid to determine the best nop.
+        */
+       asm volatile (
+               "jmp ftrace_test_jmp\n"
+               /* This code needs to stay around */
+               ".section .text, \"ax\"\n"
+               "ftrace_test_jmp:"
+               "jmp ftrace_test_p6nop\n"
+               "nop\n"
+               "nop\n"
+               "nop\n"  /* 2 byte jmp + 3 bytes */
+               "ftrace_test_p6nop:"
+               P6_NOP5
+               "jmp 1f\n"
+               "ftrace_test_nop5:"
+               ".byte 0x66,0x66,0x66,0x66,0x90\n"
+               "jmp 1f\n"
+               ".previous\n"
+               "1:"
+               ".section .fixup, \"ax\"\n"
+               "2:     movl $1, %0\n"
+               "       jmp ftrace_test_nop5\n"
+               "3:     movl $2, %0\n"
+               "       jmp 1b\n"
+               ".previous\n"
+               _ASM_EXTABLE(ftrace_test_p6nop, 2b)
+               _ASM_EXTABLE(ftrace_test_nop5, 3b)
+               : "=r"(faulted) : "0" (faulted));
+
+       switch (faulted) {
+       case 0:
+               pr_info("ftrace: converting mcount calls to 0f 1f 44 00 00\n");
+               ftrace_nop = (unsigned long *)ftrace_test_p6nop;
+               break;
+       case 1:
+               pr_info("ftrace: converting mcount calls to 66 66 66 66 90\n");
+               ftrace_nop = (unsigned long *)ftrace_test_nop5;
+               break;
+       case 2:
+               pr_info("ftrace: converting mcount calls to jmp . + 5\n");
+               ftrace_nop = (unsigned long *)ftrace_test_jmp;
+               break;
+       }
+
+       /* The return code is retured via data */
+       *(unsigned long *)data = 0;
 
        return 0;
 }
index 9eca5ba7a6b1dcfe543fc644ab049e40b9139a9f..c0262791bda40e5cd10960fb496360ca8298b879 100644 (file)
@@ -25,7 +25,7 @@
 #include <acpi/acpi_bus.h>
 #endif
 
-static int __init flat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+static int flat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
        return 1;
 }
@@ -170,7 +170,7 @@ struct genapic apic_flat =  {
  * We cannot use logical delivery in this case because the mask
  * overflows, so use physical mode.
  */
-static int __init physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
 #ifdef CONFIG_ACPI
        /*
@@ -179,8 +179,10 @@ static int __init physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
         * is an example).
         */
        if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID &&
-               (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL))
+               (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) {
+               printk(KERN_DEBUG "system APIC only can use physical flat");
                return 1;
+       }
 #endif
 
        return 0;
index e4bf2cc0d743998b069925574ff93c559f7c24f3..f6a2c8eb48a6bb1706212636246539d5f1ce64dc 100644 (file)
@@ -12,7 +12,7 @@
 
 DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid);
 
-static int __init x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
        if (cpu_has_x2apic)
                return 1;
index 8f1343df2627116e1c254f59ccd6f5525ed5f8b2..d042211768b74243f0c7b7dbfd321be707109f04 100644 (file)
@@ -19,7 +19,7 @@ static int set_x2apic_phys_mode(char *arg)
 }
 early_param("x2apic_phys", set_x2apic_phys_mode);
 
-static int __init x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
        if (cpu_has_x2apic && x2apic_phys)
                return 1;
index 33581d94a90e5bebea90a9a26d413524947c7340..680a06557c5e6c255fa9ea2e5c4decc155d68a73 100644 (file)
@@ -30,7 +30,7 @@ DEFINE_PER_CPU(int, x2apic_extra_bits);
 
 static enum uv_system_type uv_system_type;
 
-static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+static int uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
        if (!strcmp(oem_id, "SGI")) {
                if (!strcmp(oem_table_id, "UVL"))
@@ -341,12 +341,12 @@ static __init void map_mmioh_high(int max_pnode)
 
 static __init void uv_rtc_init(void)
 {
-       long status, ticks_per_sec, drift;
+       long status;
+       u64 ticks_per_sec;
 
-       status =
-           x86_bios_freq_base(BIOS_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec,
-                                       &drift);
-       if (status != 0 || ticks_per_sec < 100000) {
+       status = uv_bios_freq_base(BIOS_FREQ_BASE_REALTIME_CLOCK,
+                                       &ticks_per_sec);
+       if (status != BIOS_STATUS_SUCCESS || ticks_per_sec < 100000) {
                printk(KERN_WARNING
                        "unable to determine platform RTC clock frequency, "
                        "guessing.\n");
@@ -356,7 +356,22 @@ static __init void uv_rtc_init(void)
                sn_rtc_cycles_per_second = ticks_per_sec;
 }
 
-static bool uv_system_inited;
+/*
+ * Called on each cpu to initialize the per_cpu UV data area.
+ *     ZZZ hotplug not supported yet
+ */
+void __cpuinit uv_cpu_init(void)
+{
+       /* CPU 0 initilization will be done via uv_system_init. */
+       if (!uv_blade_info)
+               return;
+
+       uv_blade_info[uv_numa_blade_id()].nr_online_cpus++;
+
+       if (get_uv_system_type() == UV_NON_UNIQUE_APIC)
+               set_x2apic_extra_bits(uv_hub_info->pnode);
+}
+
 
 void __init uv_system_init(void)
 {
@@ -412,6 +427,9 @@ void __init uv_system_init(void)
        gnode_upper = (((unsigned long)node_id.s.node_id) &
                       ~((1 << n_val) - 1)) << m_val;
 
+       uv_bios_init();
+       uv_bios_get_sn_info(0, &uv_type, &sn_partition_id,
+                           &uv_coherency_id, &uv_region_size);
        uv_rtc_init();
 
        for_each_present_cpu(cpu) {
@@ -433,7 +451,7 @@ void __init uv_system_init(void)
                uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1;
                uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper;
                uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base;
-               uv_cpu_hub_info(cpu)->coherency_domain_number = 0;/* ZZZ */
+               uv_cpu_hub_info(cpu)->coherency_domain_number = uv_coherency_id;
                uv_node_to_blade[nid] = blade;
                uv_cpu_to_blade[cpu] = blade;
                max_pnode = max(pnode, max_pnode);
@@ -448,21 +466,6 @@ void __init uv_system_init(void)
        map_mmr_high(max_pnode);
        map_config_high(max_pnode);
        map_mmioh_high(max_pnode);
-       uv_system_inited = true;
-}
 
-/*
- * Called on each cpu to initialize the per_cpu UV data area.
- *     ZZZ hotplug not supported yet
- */
-void __cpuinit uv_cpu_init(void)
-{
-       BUG_ON(!uv_system_inited);
-
-       uv_blade_info[uv_numa_blade_id()].nr_online_cpus++;
-
-       if (get_uv_system_type() == UV_NON_UNIQUE_APIC)
-               set_x2apic_extra_bits(uv_hub_info->pnode);
+       uv_cpu_init();
 }
-
-
index acf62fc233da6c0ee8196d18c53a9a55d31bd10f..77017e834cf7178b4fceb957a7e706ec4f2d220a 100644 (file)
@@ -1,29 +1,49 @@
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/sysdev.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/hpet.h>
 #include <linux/init.h>
-#include <linux/sysdev.h>
+#include <linux/cpu.h>
 #include <linux/pm.h>
+#include <linux/io.h>
 
 #include <asm/fixmap.h>
-#include <asm/hpet.h>
 #include <asm/i8253.h>
-#include <asm/io.h>
+#include <asm/hpet.h>
 
-#define HPET_MASK      CLOCKSOURCE_MASK(32)
-#define HPET_SHIFT     22
+#define HPET_MASK                      CLOCKSOURCE_MASK(32)
+#define HPET_SHIFT                     22
 
 /* FSEC = 10^-15
    NSEC = 10^-9 */
-#define FSEC_PER_NSEC  1000000L
+#define FSEC_PER_NSEC                  1000000L
+
+#define HPET_DEV_USED_BIT              2
+#define HPET_DEV_USED                  (1 << HPET_DEV_USED_BIT)
+#define HPET_DEV_VALID                 0x8
+#define HPET_DEV_FSB_CAP               0x1000
+#define HPET_DEV_PERI_CAP              0x2000
+
+#define EVT_TO_HPET_DEV(evt) container_of(evt, struct hpet_dev, evt)
 
 /*
  * HPET address is set in acpi/boot.c, when an ACPI entry exists
  */
-unsigned long hpet_address;
-static void __iomem *hpet_virt_address;
+unsigned long                          hpet_address;
+unsigned long                          hpet_num_timers;
+static void __iomem                    *hpet_virt_address;
+
+struct hpet_dev {
+       struct clock_event_device       evt;
+       unsigned int                    num;
+       int                             cpu;
+       unsigned int                    irq;
+       unsigned int                    flags;
+       char                            name[10];
+};
 
 unsigned long hpet_readl(unsigned long a)
 {
@@ -59,7 +79,7 @@ static inline void hpet_clear_mapping(void)
 static int boot_hpet_disable;
 int hpet_force_user;
 
-static int __init hpet_setup(charstr)
+static int __init hpet_setup(char *str)
 {
        if (str) {
                if (!strncmp("disable", str, 7))
@@ -80,7 +100,7 @@ __setup("nohpet", disable_hpet);
 
 static inline int is_hpet_capable(void)
 {
-       return (!boot_hpet_disable && hpet_address);
+       return !boot_hpet_disable && hpet_address;
 }
 
 /*
@@ -102,6 +122,9 @@ EXPORT_SYMBOL_GPL(is_hpet_enabled);
  * timer 0 and timer 1 in case of RTC emulation.
  */
 #ifdef CONFIG_HPET
+
+static void hpet_reserve_msi_timers(struct hpet_data *hd);
+
 static void hpet_reserve_platform_timers(unsigned long id)
 {
        struct hpet __iomem *hpet = hpet_virt_address;
@@ -111,10 +134,10 @@ static void hpet_reserve_platform_timers(unsigned long id)
 
        nrtimers = ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT) + 1;
 
-       memset(&hd, 0, sizeof (hd));
-       hd.hd_phys_address = hpet_address;
-       hd.hd_address = hpet;
-       hd.hd_nirqs = nrtimers;
+       memset(&hd, 0, sizeof(hd));
+       hd.hd_phys_address      = hpet_address;
+       hd.hd_address           = hpet;
+       hd.hd_nirqs             = nrtimers;
        hpet_reserve_timer(&hd, 0);
 
 #ifdef CONFIG_HPET_EMULATE_RTC
@@ -130,10 +153,12 @@ static void hpet_reserve_platform_timers(unsigned long id)
        hd.hd_irq[1] = HPET_LEGACY_RTC;
 
        for (i = 2; i < nrtimers; timer++, i++) {
-               hd.hd_irq[i] = (readl(&timer->hpet_config) & Tn_INT_ROUTE_CNF_MASK) >>
-                       Tn_INT_ROUTE_CNF_SHIFT;
+               hd.hd_irq[i] = (readl(&timer->hpet_config) &
+                       Tn_INT_ROUTE_CNF_MASK) >> Tn_INT_ROUTE_CNF_SHIFT;
        }
 
+       hpet_reserve_msi_timers(&hd);
+
        hpet_alloc(&hd);
 
 }
@@ -227,60 +252,70 @@ static void hpet_legacy_clockevent_register(void)
        printk(KERN_DEBUG "hpet clockevent registered\n");
 }
 
-static void hpet_legacy_set_mode(enum clock_event_mode mode,
-                         struct clock_event_device *evt)
+static int hpet_setup_msi_irq(unsigned int irq);
+
+static void hpet_set_mode(enum clock_event_mode mode,
+                         struct clock_event_device *evt, int timer)
 {
        unsigned long cfg, cmp, now;
        uint64_t delta;
 
-       switch(mode) {
+       switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
-               delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * hpet_clockevent.mult;
-               delta >>= hpet_clockevent.shift;
+               delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * evt->mult;
+               delta >>= evt->shift;
                now = hpet_readl(HPET_COUNTER);
                cmp = now + (unsigned long) delta;
-               cfg = hpet_readl(HPET_T0_CFG);
+               cfg = hpet_readl(HPET_Tn_CFG(timer));
                cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |
                       HPET_TN_SETVAL | HPET_TN_32BIT;
-               hpet_writel(cfg, HPET_T0_CFG);
+               hpet_writel(cfg, HPET_Tn_CFG(timer));
                /*
                 * The first write after writing TN_SETVAL to the
                 * config register sets the counter value, the second
                 * write sets the period.
                 */
-               hpet_writel(cmp, HPET_T0_CMP);
+               hpet_writel(cmp, HPET_Tn_CMP(timer));
                udelay(1);
-               hpet_writel((unsigned long) delta, HPET_T0_CMP);
+               hpet_writel((unsigned long) delta, HPET_Tn_CMP(timer));
                break;
 
        case CLOCK_EVT_MODE_ONESHOT:
-               cfg = hpet_readl(HPET_T0_CFG);
+               cfg = hpet_readl(HPET_Tn_CFG(timer));
                cfg &= ~HPET_TN_PERIODIC;
                cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
-               hpet_writel(cfg, HPET_T0_CFG);
+               hpet_writel(cfg, HPET_Tn_CFG(timer));
                break;
 
        case CLOCK_EVT_MODE_UNUSED:
        case CLOCK_EVT_MODE_SHUTDOWN:
-               cfg = hpet_readl(HPET_T0_CFG);
+               cfg = hpet_readl(HPET_Tn_CFG(timer));
                cfg &= ~HPET_TN_ENABLE;
-               hpet_writel(cfg, HPET_T0_CFG);
+               hpet_writel(cfg, HPET_Tn_CFG(timer));
                break;
 
        case CLOCK_EVT_MODE_RESUME:
-               hpet_enable_legacy_int();
+               if (timer == 0) {
+                       hpet_enable_legacy_int();
+               } else {
+                       struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt);
+                       hpet_setup_msi_irq(hdev->irq);
+                       disable_irq(hdev->irq);
+                       irq_set_affinity(hdev->irq, cpumask_of_cpu(hdev->cpu));
+                       enable_irq(hdev->irq);
+               }
                break;
        }
 }
 
-static int hpet_legacy_next_event(unsigned long delta,
-                                 struct clock_event_device *evt)
+static int hpet_next_event(unsigned long delta,
+                          struct clock_event_device *evt, int timer)
 {
        u32 cnt;
 
        cnt = hpet_readl(HPET_COUNTER);
        cnt += (u32) delta;
-       hpet_writel(cnt, HPET_T0_CMP);
+       hpet_writel(cnt, HPET_Tn_CMP(timer));
 
        /*
         * We need to read back the CMP register to make sure that
@@ -292,6 +327,347 @@ static int hpet_legacy_next_event(unsigned long delta,
        return (s32)((u32)hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
 }
 
+static void hpet_legacy_set_mode(enum clock_event_mode mode,
+                       struct clock_event_device *evt)
+{
+       hpet_set_mode(mode, evt, 0);
+}
+
+static int hpet_legacy_next_event(unsigned long delta,
+                       struct clock_event_device *evt)
+{
+       return hpet_next_event(delta, evt, 0);
+}
+
+/*
+ * HPET MSI Support
+ */
+#ifdef CONFIG_PCI_MSI
+
+static DEFINE_PER_CPU(struct hpet_dev *, cpu_hpet_dev);
+static struct hpet_dev *hpet_devs;
+
+void hpet_msi_unmask(unsigned int irq)
+{
+       struct hpet_dev *hdev = get_irq_data(irq);
+       unsigned long cfg;
+
+       /* unmask it */
+       cfg = hpet_readl(HPET_Tn_CFG(hdev->num));
+       cfg |= HPET_TN_FSB;
+       hpet_writel(cfg, HPET_Tn_CFG(hdev->num));
+}
+
+void hpet_msi_mask(unsigned int irq)
+{
+       unsigned long cfg;
+       struct hpet_dev *hdev = get_irq_data(irq);
+
+       /* mask it */
+       cfg = hpet_readl(HPET_Tn_CFG(hdev->num));
+       cfg &= ~HPET_TN_FSB;
+       hpet_writel(cfg, HPET_Tn_CFG(hdev->num));
+}
+
+void hpet_msi_write(unsigned int irq, struct msi_msg *msg)
+{
+       struct hpet_dev *hdev = get_irq_data(irq);
+
+       hpet_writel(msg->data, HPET_Tn_ROUTE(hdev->num));
+       hpet_writel(msg->address_lo, HPET_Tn_ROUTE(hdev->num) + 4);
+}
+
+void hpet_msi_read(unsigned int irq, struct msi_msg *msg)
+{
+       struct hpet_dev *hdev = get_irq_data(irq);
+
+       msg->data = hpet_readl(HPET_Tn_ROUTE(hdev->num));
+       msg->address_lo = hpet_readl(HPET_Tn_ROUTE(hdev->num) + 4);
+       msg->address_hi = 0;
+}
+
+static void hpet_msi_set_mode(enum clock_event_mode mode,
+                               struct clock_event_device *evt)
+{
+       struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt);
+       hpet_set_mode(mode, evt, hdev->num);
+}
+
+static int hpet_msi_next_event(unsigned long delta,
+                               struct clock_event_device *evt)
+{
+       struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt);
+       return hpet_next_event(delta, evt, hdev->num);
+}
+
+static int hpet_setup_msi_irq(unsigned int irq)
+{
+       if (arch_setup_hpet_msi(irq)) {
+               destroy_irq(irq);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int hpet_assign_irq(struct hpet_dev *dev)
+{
+       unsigned int irq;
+
+       irq = create_irq();
+       if (!irq)
+               return -EINVAL;
+
+       set_irq_data(irq, dev);
+
+       if (hpet_setup_msi_irq(irq))
+               return -EINVAL;
+
+       dev->irq = irq;
+       return 0;
+}
+
+static irqreturn_t hpet_interrupt_handler(int irq, void *data)
+{
+       struct hpet_dev *dev = (struct hpet_dev *)data;
+       struct clock_event_device *hevt = &dev->evt;
+
+       if (!hevt->event_handler) {
+               printk(KERN_INFO "Spurious HPET timer interrupt on HPET timer %d\n",
+                               dev->num);
+               return IRQ_HANDLED;
+       }
+
+       hevt->event_handler(hevt);
+       return IRQ_HANDLED;
+}
+
+static int hpet_setup_irq(struct hpet_dev *dev)
+{
+
+       if (request_irq(dev->irq, hpet_interrupt_handler,
+                       IRQF_SHARED|IRQF_NOBALANCING, dev->name, dev))
+               return -1;
+
+       disable_irq(dev->irq);
+       irq_set_affinity(dev->irq, cpumask_of_cpu(dev->cpu));
+       enable_irq(dev->irq);
+
+       printk(KERN_DEBUG "hpet: %s irq %d for MSI\n",
+                        dev->name, dev->irq);
+
+       return 0;
+}
+
+/* This should be called in specific @cpu */
+static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu)
+{
+       struct clock_event_device *evt = &hdev->evt;
+       uint64_t hpet_freq;
+
+       WARN_ON(cpu != smp_processor_id());
+       if (!(hdev->flags & HPET_DEV_VALID))
+               return;
+
+       if (hpet_setup_msi_irq(hdev->irq))
+               return;
+
+       hdev->cpu = cpu;
+       per_cpu(cpu_hpet_dev, cpu) = hdev;
+       evt->name = hdev->name;
+       hpet_setup_irq(hdev);
+       evt->irq = hdev->irq;
+
+       evt->rating = 110;
+       evt->features = CLOCK_EVT_FEAT_ONESHOT;
+       if (hdev->flags & HPET_DEV_PERI_CAP)
+               evt->features |= CLOCK_EVT_FEAT_PERIODIC;
+
+       evt->set_mode = hpet_msi_set_mode;
+       evt->set_next_event = hpet_msi_next_event;
+       evt->shift = 32;
+
+       /*
+        * The period is a femto seconds value. We need to calculate the
+        * scaled math multiplication factor for nanosecond to hpet tick
+        * conversion.
+        */
+       hpet_freq = 1000000000000000ULL;
+       do_div(hpet_freq, hpet_period);
+       evt->mult = div_sc((unsigned long) hpet_freq,
+                                     NSEC_PER_SEC, evt->shift);
+       /* Calculate the max delta */
+       evt->max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, evt);
+       /* 5 usec minimum reprogramming delta. */
+       evt->min_delta_ns = 5000;
+
+       evt->cpumask = cpumask_of_cpu(hdev->cpu);
+       clockevents_register_device(evt);
+}
+
+#ifdef CONFIG_HPET
+/* Reserve at least one timer for userspace (/dev/hpet) */
+#define RESERVE_TIMERS 1
+#else
+#define RESERVE_TIMERS 0
+#endif
+
+static void hpet_msi_capability_lookup(unsigned int start_timer)
+{
+       unsigned int id;
+       unsigned int num_timers;
+       unsigned int num_timers_used = 0;
+       int i;
+
+       id = hpet_readl(HPET_ID);
+
+       num_timers = ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT);
+       num_timers++; /* Value read out starts from 0 */
+
+       hpet_devs = kzalloc(sizeof(struct hpet_dev) * num_timers, GFP_KERNEL);
+       if (!hpet_devs)
+               return;
+
+       hpet_num_timers = num_timers;
+
+       for (i = start_timer; i < num_timers - RESERVE_TIMERS; i++) {
+               struct hpet_dev *hdev = &hpet_devs[num_timers_used];
+               unsigned long cfg = hpet_readl(HPET_Tn_CFG(i));
+
+               /* Only consider HPET timer with MSI support */
+               if (!(cfg & HPET_TN_FSB_CAP))
+                       continue;
+
+               hdev->flags = 0;
+               if (cfg & HPET_TN_PERIODIC_CAP)
+                       hdev->flags |= HPET_DEV_PERI_CAP;
+               hdev->num = i;
+
+               sprintf(hdev->name, "hpet%d", i);
+               if (hpet_assign_irq(hdev))
+                       continue;
+
+               hdev->flags |= HPET_DEV_FSB_CAP;
+               hdev->flags |= HPET_DEV_VALID;
+               num_timers_used++;
+               if (num_timers_used == num_possible_cpus())
+                       break;
+       }
+
+       printk(KERN_INFO "HPET: %d timers in total, %d timers will be used for per-cpu timer\n",
+               num_timers, num_timers_used);
+}
+
+#ifdef CONFIG_HPET
+static void hpet_reserve_msi_timers(struct hpet_data *hd)
+{
+       int i;
+
+       if (!hpet_devs)
+               return;
+
+       for (i = 0; i < hpet_num_timers; i++) {
+               struct hpet_dev *hdev = &hpet_devs[i];
+
+               if (!(hdev->flags & HPET_DEV_VALID))
+                       continue;
+
+               hd->hd_irq[hdev->num] = hdev->irq;
+               hpet_reserve_timer(hd, hdev->num);
+       }
+}
+#endif
+
+static struct hpet_dev *hpet_get_unused_timer(void)
+{
+       int i;
+
+       if (!hpet_devs)
+               return NULL;
+
+       for (i = 0; i < hpet_num_timers; i++) {
+               struct hpet_dev *hdev = &hpet_devs[i];
+
+               if (!(hdev->flags & HPET_DEV_VALID))
+                       continue;
+               if (test_and_set_bit(HPET_DEV_USED_BIT,
+                       (unsigned long *)&hdev->flags))
+                       continue;
+               return hdev;
+       }
+       return NULL;
+}
+
+struct hpet_work_struct {
+       struct delayed_work work;
+       struct completion complete;
+};
+
+static void hpet_work(struct work_struct *w)
+{
+       struct hpet_dev *hdev;
+       int cpu = smp_processor_id();
+       struct hpet_work_struct *hpet_work;
+
+       hpet_work = container_of(w, struct hpet_work_struct, work.work);
+
+       hdev = hpet_get_unused_timer();
+       if (hdev)
+               init_one_hpet_msi_clockevent(hdev, cpu);
+
+       complete(&hpet_work->complete);
+}
+
+static int hpet_cpuhp_notify(struct notifier_block *n,
+               unsigned long action, void *hcpu)
+{
+       unsigned long cpu = (unsigned long)hcpu;
+       struct hpet_work_struct work;
+       struct hpet_dev *hdev = per_cpu(cpu_hpet_dev, cpu);
+
+       switch (action & 0xf) {
+       case CPU_ONLINE:
+               INIT_DELAYED_WORK(&work.work, hpet_work);
+               init_completion(&work.complete);
+               /* FIXME: add schedule_work_on() */
+               schedule_delayed_work_on(cpu, &work.work, 0);
+               wait_for_completion(&work.complete);
+               break;
+       case CPU_DEAD:
+               if (hdev) {
+                       free_irq(hdev->irq, hdev);
+                       hdev->flags &= ~HPET_DEV_USED;
+                       per_cpu(cpu_hpet_dev, cpu) = NULL;
+               }
+               break;
+       }
+       return NOTIFY_OK;
+}
+#else
+
+static int hpet_setup_msi_irq(unsigned int irq)
+{
+       return 0;
+}
+static void hpet_msi_capability_lookup(unsigned int start_timer)
+{
+       return;
+}
+
+#ifdef CONFIG_HPET
+static void hpet_reserve_msi_timers(struct hpet_data *hd)
+{
+       return;
+}
+#endif
+
+static int hpet_cpuhp_notify(struct notifier_block *n,
+               unsigned long action, void *hcpu)
+{
+       return NOTIFY_OK;
+}
+
+#endif
+
 /*
  * Clock source related code
  */
@@ -427,8 +803,10 @@ int __init hpet_enable(void)
 
        if (id & HPET_ID_LEGSUP) {
                hpet_legacy_clockevent_register();
+               hpet_msi_capability_lookup(2);
                return 1;
        }
+       hpet_msi_capability_lookup(0);
        return 0;
 
 out_nohpet:
@@ -445,6 +823,8 @@ out_nohpet:
  */
 static __init int hpet_late_init(void)
 {
+       int cpu;
+
        if (boot_hpet_disable)
                return -ENODEV;
 
@@ -460,6 +840,13 @@ static __init int hpet_late_init(void)
 
        hpet_reserve_platform_timers(hpet_readl(HPET_ID));
 
+       for_each_online_cpu(cpu) {
+               hpet_cpuhp_notify(NULL, CPU_ONLINE, (void *)(long)cpu);
+       }
+
+       /* This notifier should be called after workqueue is ready */
+       hotcpu_notifier(hpet_cpuhp_notify, -20);
+
        return 0;
 }
 fs_initcall(hpet_late_init);
similarity index 68%
rename from arch/x86/kernel/io_apic_64.c
rename to arch/x86/kernel/io_apic.c
index 02063ae042f72ae979a13b57035bd0d91f1dcb59..b764d7429c6168a4eb70b151dc3b07cd553f8afd 100644 (file)
 #include <linux/sched.h>
 #include <linux/pci.h>
 #include <linux/mc146818rtc.h>
+#include <linux/compiler.h>
 #include <linux/acpi.h>
+#include <linux/module.h>
 #include <linux/sysdev.h>
 #include <linux/msi.h>
 #include <linux/htirq.h>
-#include <linux/dmar.h>
-#include <linux/jiffies.h>
+#include <linux/freezer.h>
+#include <linux/kthread.h>
+#include <linux/jiffies.h>     /* time_after() */
 #ifdef CONFIG_ACPI
 #include <acpi/acpi_bus.h>
 #endif
 #include <linux/bootmem.h>
 #include <linux/dmar.h>
+#include <linux/hpet.h>
 
 #include <asm/idle.h>
 #include <asm/io.h>
 #include <asm/proto.h>
 #include <asm/acpi.h>
 #include <asm/dma.h>
+#include <asm/timer.h>
 #include <asm/i8259.h>
 #include <asm/nmi.h>
 #include <asm/msidef.h>
 #include <asm/hypertransport.h>
+#include <asm/setup.h>
 #include <asm/irq_remapping.h>
+#include <asm/hpet.h>
+#include <asm/uv/uv_hub.h>
+#include <asm/uv/uv_irq.h>
 
 #include <mach_ipi.h>
 #include <mach_apic.h>
+#include <mach_apicdef.h>
 
 #define __apicdebuginit(type) static type __init
 
-struct irq_cfg {
-       cpumask_t domain;
-       cpumask_t old_domain;
-       unsigned move_cleanup_count;
-       u8 vector;
-       u8 move_in_progress : 1;
-};
-
-/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
-static struct irq_cfg irq_cfg[NR_IRQS] __read_mostly = {
-       [0]  = { .domain = CPU_MASK_ALL, .vector = IRQ0_VECTOR,  },
-       [1]  = { .domain = CPU_MASK_ALL, .vector = IRQ1_VECTOR,  },
-       [2]  = { .domain = CPU_MASK_ALL, .vector = IRQ2_VECTOR,  },
-       [3]  = { .domain = CPU_MASK_ALL, .vector = IRQ3_VECTOR,  },
-       [4]  = { .domain = CPU_MASK_ALL, .vector = IRQ4_VECTOR,  },
-       [5]  = { .domain = CPU_MASK_ALL, .vector = IRQ5_VECTOR,  },
-       [6]  = { .domain = CPU_MASK_ALL, .vector = IRQ6_VECTOR,  },
-       [7]  = { .domain = CPU_MASK_ALL, .vector = IRQ7_VECTOR,  },
-       [8]  = { .domain = CPU_MASK_ALL, .vector = IRQ8_VECTOR,  },
-       [9]  = { .domain = CPU_MASK_ALL, .vector = IRQ9_VECTOR,  },
-       [10] = { .domain = CPU_MASK_ALL, .vector = IRQ10_VECTOR, },
-       [11] = { .domain = CPU_MASK_ALL, .vector = IRQ11_VECTOR, },
-       [12] = { .domain = CPU_MASK_ALL, .vector = IRQ12_VECTOR, },
-       [13] = { .domain = CPU_MASK_ALL, .vector = IRQ13_VECTOR, },
-       [14] = { .domain = CPU_MASK_ALL, .vector = IRQ14_VECTOR, },
-       [15] = { .domain = CPU_MASK_ALL, .vector = IRQ15_VECTOR, },
-};
-
-static int assign_irq_vector(int irq, cpumask_t mask);
-
-int first_system_vector = 0xfe;
-
-char system_vectors[NR_VECTORS] = { [0 ... NR_VECTORS-1] = SYS_VECTOR_FREE};
-
-int sis_apic_bug; /* not actually supported, dummy for compile */
-
-static int no_timer_check;
-
-static int disable_timer_pin_1 __initdata;
-
-int timer_through_8259 __initdata;
-
-/* Where if anywhere is the i8259 connect in external int mode */
-static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
+/*
+ *      Is the SiS APIC rmw bug present ?
+ *      -1 = don't know, 0 = no, 1 = yes
+ */
+int sis_apic_bug = -1;
 
 static DEFINE_SPINLOCK(ioapic_lock);
 static DEFINE_SPINLOCK(vector_lock);
@@ -110,9 +81,6 @@ static DEFINE_SPINLOCK(vector_lock);
  */
 int nr_ioapic_registers[MAX_IO_APICS];
 
-/* I/O APIC RTE contents at the OS boot up */
-struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS];
-
 /* I/O APIC entries */
 struct mp_config_ioapic mp_ioapics[MAX_IO_APICS];
 int nr_ioapics;
@@ -123,11 +91,69 @@ struct mp_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
 /* # of MP IRQ source entries */
 int mp_irq_entries;
 
+#if defined (CONFIG_MCA) || defined (CONFIG_EISA)
+int mp_bus_id_to_type[MAX_MP_BUSSES];
+#endif
+
 DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
 
+int skip_ioapic_setup;
+
+static int __init parse_noapic(char *str)
+{
+       /* disable IO-APIC */
+       disable_ioapic_setup();
+       return 0;
+}
+early_param("noapic", parse_noapic);
+
+struct irq_pin_list;
+struct irq_cfg {
+       unsigned int irq;
+       struct irq_pin_list *irq_2_pin;
+       cpumask_t domain;
+       cpumask_t old_domain;
+       unsigned move_cleanup_count;
+       u8 vector;
+       u8 move_in_progress : 1;
+};
+
+/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
+static struct irq_cfg irq_cfgx[NR_IRQS] = {
+       [0]  = { .irq =  0, .domain = CPU_MASK_ALL, .vector = IRQ0_VECTOR,  },
+       [1]  = { .irq =  1, .domain = CPU_MASK_ALL, .vector = IRQ1_VECTOR,  },
+       [2]  = { .irq =  2, .domain = CPU_MASK_ALL, .vector = IRQ2_VECTOR,  },
+       [3]  = { .irq =  3, .domain = CPU_MASK_ALL, .vector = IRQ3_VECTOR,  },
+       [4]  = { .irq =  4, .domain = CPU_MASK_ALL, .vector = IRQ4_VECTOR,  },
+       [5]  = { .irq =  5, .domain = CPU_MASK_ALL, .vector = IRQ5_VECTOR,  },
+       [6]  = { .irq =  6, .domain = CPU_MASK_ALL, .vector = IRQ6_VECTOR,  },
+       [7]  = { .irq =  7, .domain = CPU_MASK_ALL, .vector = IRQ7_VECTOR,  },
+       [8]  = { .irq =  8, .domain = CPU_MASK_ALL, .vector = IRQ8_VECTOR,  },
+       [9]  = { .irq =  9, .domain = CPU_MASK_ALL, .vector = IRQ9_VECTOR,  },
+       [10] = { .irq = 10, .domain = CPU_MASK_ALL, .vector = IRQ10_VECTOR, },
+       [11] = { .irq = 11, .domain = CPU_MASK_ALL, .vector = IRQ11_VECTOR, },
+       [12] = { .irq = 12, .domain = CPU_MASK_ALL, .vector = IRQ12_VECTOR, },
+       [13] = { .irq = 13, .domain = CPU_MASK_ALL, .vector = IRQ13_VECTOR, },
+       [14] = { .irq = 14, .domain = CPU_MASK_ALL, .vector = IRQ14_VECTOR, },
+       [15] = { .irq = 15, .domain = CPU_MASK_ALL, .vector = IRQ15_VECTOR, },
+};
+
+#define for_each_irq_cfg(irq, cfg)             \
+       for (irq = 0, cfg = irq_cfgx; irq < nr_irqs; irq++, cfg++)
+
+static struct irq_cfg *irq_cfg(unsigned int irq)
+{
+       return irq < nr_irqs ? irq_cfgx + irq : NULL;
+}
+
+static struct irq_cfg *irq_cfg_alloc(unsigned int irq)
+{
+       return irq_cfg(irq);
+}
+
 /*
- * Rough estimation of how many shared IRQs there are, can
- * be changed anytime.
+ * Rough estimation of how many shared IRQs there are, can be changed
+ * anytime.
  */
 #define MAX_PLUS_SHARED_IRQS NR_IRQS
 #define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + NR_IRQS)
@@ -139,9 +165,36 @@ DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
  * between pins and IRQs.
  */
 
-static struct irq_pin_list {
-       short apic, pin, next;
-} irq_2_pin[PIN_MAP_SIZE];
+struct irq_pin_list {
+       int apic, pin;
+       struct irq_pin_list *next;
+};
+
+static struct irq_pin_list irq_2_pin_head[PIN_MAP_SIZE];
+static struct irq_pin_list *irq_2_pin_ptr;
+
+static void __init irq_2_pin_init(void)
+{
+       struct irq_pin_list *pin = irq_2_pin_head;
+       int i;
+
+       for (i = 1; i < PIN_MAP_SIZE; i++)
+               pin[i-1].next = &pin[i];
+
+       irq_2_pin_ptr = &pin[0];
+}
+
+static struct irq_pin_list *get_one_free_irq_2_pin(void)
+{
+       struct irq_pin_list *pin = irq_2_pin_ptr;
+
+       if (!pin)
+               panic("can not get more irq_2_pin\n");
+
+       irq_2_pin_ptr = pin->next;
+       pin->next = NULL;
+       return pin;
+}
 
 struct io_apic {
        unsigned int index;
@@ -172,10 +225,15 @@ static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned i
 /*
  * Re-write a value: to be used for read-modify-write
  * cycles where the read already set up the index register.
+ *
+ * Older SiS APIC requires we rewrite the index register
  */
-static inline void io_apic_modify(unsigned int apic, unsigned int value)
+static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value)
 {
        struct io_apic __iomem *io_apic = io_apic_base(apic);
+
+       if (sis_apic_bug)
+               writel(reg, &io_apic->index);
        writel(value, &io_apic->data);
 }
 
@@ -183,16 +241,17 @@ static bool io_apic_level_ack_pending(unsigned int irq)
 {
        struct irq_pin_list *entry;
        unsigned long flags;
+       struct irq_cfg *cfg = irq_cfg(irq);
 
        spin_lock_irqsave(&ioapic_lock, flags);
-       entry = irq_2_pin + irq;
+       entry = cfg->irq_2_pin;
        for (;;) {
                unsigned int reg;
                int pin;
 
-               pin = entry->pin;
-               if (pin == -1)
+               if (!entry)
                        break;
+               pin = entry->pin;
                reg = io_apic_read(entry->apic, 0x10 + pin*2);
                /* Is the remote IRR bit set? */
                if (reg & IO_APIC_REDIR_REMOTE_IRR) {
@@ -201,45 +260,13 @@ static bool io_apic_level_ack_pending(unsigned int irq)
                }
                if (!entry->next)
                        break;
-               entry = irq_2_pin + entry->next;
+               entry = entry->next;
        }
        spin_unlock_irqrestore(&ioapic_lock, flags);
 
        return false;
 }
 
-/*
- * Synchronize the IO-APIC and the CPU by doing
- * a dummy read from the IO-APIC
- */
-static inline void io_apic_sync(unsigned int apic)
-{
-       struct io_apic __iomem *io_apic = io_apic_base(apic);
-       readl(&io_apic->data);
-}
-
-#define __DO_ACTION(R, ACTION, FINAL)                                  \
-                                                                       \
-{                                                                      \
-       int pin;                                                        \
-       struct irq_pin_list *entry = irq_2_pin + irq;                   \
-                                                                       \
-       BUG_ON(irq >= NR_IRQS);                                         \
-       for (;;) {                                                      \
-               unsigned int reg;                                       \
-               pin = entry->pin;                                       \
-               if (pin == -1)                                          \
-                       break;                                          \
-               reg = io_apic_read(entry->apic, 0x10 + R + pin*2);      \
-               reg ACTION;                                             \
-               io_apic_modify(entry->apic, reg);                       \
-               FINAL;                                                  \
-               if (!entry->next)                                       \
-                       break;                                          \
-               entry = irq_2_pin + entry->next;                        \
-       }                                                               \
-}
-
 union entry_union {
        struct { u32 w1, w2; };
        struct IO_APIC_route_entry entry;
@@ -299,59 +326,71 @@ static void ioapic_mask_entry(int apic, int pin)
 static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, u8 vector)
 {
        int apic, pin;
-       struct irq_pin_list *entry = irq_2_pin + irq;
+       struct irq_cfg *cfg;
+       struct irq_pin_list *entry;
 
-       BUG_ON(irq >= NR_IRQS);
+       cfg = irq_cfg(irq);
+       entry = cfg->irq_2_pin;
        for (;;) {
                unsigned int reg;
+
+               if (!entry)
+                       break;
+
                apic = entry->apic;
                pin = entry->pin;
-               if (pin == -1)
-                       break;
+#ifdef CONFIG_INTR_REMAP
                /*
                 * With interrupt-remapping, destination information comes
                 * from interrupt-remapping table entry.
                 */
                if (!irq_remapped(irq))
                        io_apic_write(apic, 0x11 + pin*2, dest);
+#else
+               io_apic_write(apic, 0x11 + pin*2, dest);
+#endif
                reg = io_apic_read(apic, 0x10 + pin*2);
                reg &= ~IO_APIC_REDIR_VECTOR_MASK;
                reg |= vector;
-               io_apic_modify(apic, reg);
+               io_apic_modify(apic, 0x10 + pin*2, reg);
                if (!entry->next)
                        break;
-               entry = irq_2_pin + entry->next;
+               entry = entry->next;
        }
 }
 
+static int assign_irq_vector(int irq, cpumask_t mask);
+
 static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
 {
-       struct irq_cfg *cfg = irq_cfg + irq;
+       struct irq_cfg *cfg;
        unsigned long flags;
        unsigned int dest;
        cpumask_t tmp;
+       struct irq_desc *desc;
 
        cpus_and(tmp, mask, cpu_online_map);
        if (cpus_empty(tmp))
                return;
 
+       cfg = irq_cfg(irq);
        if (assign_irq_vector(irq, mask))
                return;
 
        cpus_and(tmp, cfg->domain, mask);
        dest = cpu_mask_to_apicid(tmp);
-
        /*
         * Only the high 8 bits are valid.
         */
        dest = SET_APIC_LOGICAL_ID(dest);
 
+       desc = irq_to_desc(irq);
        spin_lock_irqsave(&ioapic_lock, flags);
        __target_IO_APIC_irq(irq, dest, cfg->vector);
-       irq_desc[irq].affinity = mask;
+       desc->affinity = mask;
        spin_unlock_irqrestore(&ioapic_lock, flags);
 }
-#endif
+#endif /* CONFIG_SMP */
 
 /*
  * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
@@ -360,19 +399,30 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
  */
 static void add_pin_to_irq(unsigned int irq, int apic, int pin)
 {
-       static int first_free_entry = NR_IRQS;
-       struct irq_pin_list *entry = irq_2_pin + irq;
+       struct irq_cfg *cfg;
+       struct irq_pin_list *entry;
 
-       BUG_ON(irq >= NR_IRQS);
-       while (entry->next)
-               entry = irq_2_pin + entry->next;
+       /* first time to refer irq_cfg, so with new */
+       cfg = irq_cfg_alloc(irq);
+       entry = cfg->irq_2_pin;
+       if (!entry) {
+               entry = get_one_free_irq_2_pin();
+               cfg->irq_2_pin = entry;
+               entry->apic = apic;
+               entry->pin = pin;
+               return;
+       }
+
+       while (entry->next) {
+               /* not again, please */
+               if (entry->apic == apic && entry->pin == pin)
+                       return;
 
-       if (entry->pin != -1) {
-               entry->next = first_free_entry;
-               entry = irq_2_pin + entry->next;
-               if (++first_free_entry >= PIN_MAP_SIZE)
-                       panic("io_apic.c: ran out of irq_2_pin entries!");
+               entry = entry->next;
        }
+
+       entry->next = get_one_free_irq_2_pin();
+       entry = entry->next;
        entry->apic = apic;
        entry->pin = pin;
 }
@@ -384,30 +434,86 @@ static void __init replace_pin_at_irq(unsigned int irq,
                                      int oldapic, int oldpin,
                                      int newapic, int newpin)
 {
-       struct irq_pin_list *entry = irq_2_pin + irq;
+       struct irq_cfg *cfg = irq_cfg(irq);
+       struct irq_pin_list *entry = cfg->irq_2_pin;
+       int replaced = 0;
 
-       while (1) {
+       while (entry) {
                if (entry->apic == oldapic && entry->pin == oldpin) {
                        entry->apic = newapic;
                        entry->pin = newpin;
-               }
-               if (!entry->next)
+                       replaced = 1;
+                       /* every one is different, right? */
                        break;
-               entry = irq_2_pin + entry->next;
+               }
+               entry = entry->next;
        }
+
+       /* why? call replace before add? */
+       if (!replaced)
+               add_pin_to_irq(irq, newapic, newpin);
 }
 
+static inline void io_apic_modify_irq(unsigned int irq,
+                               int mask_and, int mask_or,
+                               void (*final)(struct irq_pin_list *entry))
+{
+       int pin;
+       struct irq_cfg *cfg;
+       struct irq_pin_list *entry;
 
-#define DO_ACTION(name,R,ACTION, FINAL)                                        \
-                                                                       \
-       static void name##_IO_APIC_irq (unsigned int irq)               \
-       __DO_ACTION(R, ACTION, FINAL)
+       cfg = irq_cfg(irq);
+       for (entry = cfg->irq_2_pin; entry != NULL; entry = entry->next) {
+               unsigned int reg;
+               pin = entry->pin;
+               reg = io_apic_read(entry->apic, 0x10 + pin * 2);
+               reg &= mask_and;
+               reg |= mask_or;
+               io_apic_modify(entry->apic, 0x10 + pin * 2, reg);
+               if (final)
+                       final(entry);
+       }
+}
 
-/* mask = 1 */
-DO_ACTION(__mask,      0, |= IO_APIC_REDIR_MASKED, io_apic_sync(entry->apic))
+static void __unmask_IO_APIC_irq(unsigned int irq)
+{
+       io_apic_modify_irq(irq, ~IO_APIC_REDIR_MASKED, 0, NULL);
+}
 
-/* mask = 0 */
-DO_ACTION(__unmask,    0, &= ~IO_APIC_REDIR_MASKED, )
+#ifdef CONFIG_X86_64
+void io_apic_sync(struct irq_pin_list *entry)
+{
+       /*
+        * Synchronize the IO-APIC and the CPU by doing
+        * a dummy read from the IO-APIC
+        */
+       struct io_apic __iomem *io_apic;
+       io_apic = io_apic_base(entry->apic);
+       readl(&io_apic->data);
+}
+
+static void __mask_IO_APIC_irq(unsigned int irq)
+{
+       io_apic_modify_irq(irq, ~0, IO_APIC_REDIR_MASKED, &io_apic_sync);
+}
+#else /* CONFIG_X86_32 */
+static void __mask_IO_APIC_irq(unsigned int irq)
+{
+       io_apic_modify_irq(irq, ~0, IO_APIC_REDIR_MASKED, NULL);
+}
+
+static void __mask_and_edge_IO_APIC_irq(unsigned int irq)
+{
+       io_apic_modify_irq(irq, ~IO_APIC_REDIR_LEVEL_TRIGGER,
+                       IO_APIC_REDIR_MASKED, NULL);
+}
+
+static void __unmask_and_level_IO_APIC_irq(unsigned int irq)
+{
+       io_apic_modify_irq(irq, ~IO_APIC_REDIR_MASKED,
+                       IO_APIC_REDIR_LEVEL_TRIGGER, NULL);
+}
+#endif /* CONFIG_X86_32 */
 
 static void mask_IO_APIC_irq (unsigned int irq)
 {
@@ -450,6 +556,68 @@ static void clear_IO_APIC (void)
                        clear_IO_APIC_pin(apic, pin);
 }
 
+#if !defined(CONFIG_SMP) && defined(CONFIG_X86_32)
+void send_IPI_self(int vector)
+{
+       unsigned int cfg;
+
+       /*
+        * Wait for idle.
+        */
+       apic_wait_icr_idle();
+       cfg = APIC_DM_FIXED | APIC_DEST_SELF | vector | APIC_DEST_LOGICAL;
+       /*
+        * Send the IPI. The write to APIC_ICR fires this off.
+        */
+       apic_write(APIC_ICR, cfg);
+}
+#endif /* !CONFIG_SMP && CONFIG_X86_32*/
+
+#ifdef CONFIG_X86_32
+/*
+ * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to
+ * specific CPU-side IRQs.
+ */
+
+#define MAX_PIRQS 8
+static int pirq_entries [MAX_PIRQS];
+static int pirqs_enabled;
+
+static int __init ioapic_pirq_setup(char *str)
+{
+       int i, max;
+       int ints[MAX_PIRQS+1];
+
+       get_options(str, ARRAY_SIZE(ints), ints);
+
+       for (i = 0; i < MAX_PIRQS; i++)
+               pirq_entries[i] = -1;
+
+       pirqs_enabled = 1;
+       apic_printk(APIC_VERBOSE, KERN_INFO
+                       "PIRQ redirection, working around broken MP-BIOS.\n");
+       max = MAX_PIRQS;
+       if (ints[0] < MAX_PIRQS)
+               max = ints[0];
+
+       for (i = 0; i < max; i++) {
+               apic_printk(APIC_VERBOSE, KERN_DEBUG
+                               "... PIRQ%d -> IRQ %d\n", i, ints[i+1]);
+               /*
+                * PIRQs are mapped upside down, usually.
+                */
+               pirq_entries[MAX_PIRQS-i-1] = ints[i+1];
+       }
+       return 1;
+}
+
+__setup("pirq=", ioapic_pirq_setup);
+#endif /* CONFIG_X86_32 */
+
+#ifdef CONFIG_INTR_REMAP
+/* I/O APIC RTE contents at the OS boot up */
+static struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS];
+
 /*
  * Saves and masks all the unmasked IO-APIC RTE's
  */
@@ -474,7 +642,7 @@ int save_mask_IO_APIC_setup(void)
                        kzalloc(sizeof(struct IO_APIC_route_entry) *
                                nr_ioapic_registers[apic], GFP_KERNEL);
                if (!early_ioapic_entries[apic])
-                       return -ENOMEM;
+                       goto nomem;
        }
 
        for (apic = 0; apic < nr_ioapics; apic++)
@@ -488,17 +656,31 @@ int save_mask_IO_APIC_setup(void)
                                ioapic_write_entry(apic, pin, entry);
                        }
                }
+
        return 0;
+
+nomem:
+       while (apic >= 0)
+               kfree(early_ioapic_entries[apic--]);
+       memset(early_ioapic_entries, 0,
+               ARRAY_SIZE(early_ioapic_entries));
+
+       return -ENOMEM;
 }
 
 void restore_IO_APIC_setup(void)
 {
        int apic, pin;
 
-       for (apic = 0; apic < nr_ioapics; apic++)
+       for (apic = 0; apic < nr_ioapics; apic++) {
+               if (!early_ioapic_entries[apic])
+                       break;
                for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
                        ioapic_write_entry(apic, pin,
                                           early_ioapic_entries[apic][pin]);
+               kfree(early_ioapic_entries[apic]);
+               early_ioapic_entries[apic] = NULL;
+       }
 }
 
 void reinit_intr_remapped_IO_APIC(int intr_remapping)
@@ -512,25 +694,7 @@ void reinit_intr_remapped_IO_APIC(int intr_remapping)
         */
        restore_IO_APIC_setup();
 }
-
-int skip_ioapic_setup;
-int ioapic_force;
-
-static int __init parse_noapic(char *str)
-{
-       disable_ioapic_setup();
-       return 0;
-}
-early_param("noapic", parse_noapic);
-
-/* Actually the next is obsolete, but keep it for paranoid reasons -AK */
-static int __init disable_timer_pin_setup(char *arg)
-{
-       disable_timer_pin_1 = 1;
-       return 1;
-}
-__setup("disable_timer_pin_1", disable_timer_pin_setup);
-
+#endif
 
 /*
  * Find the IRQ entry number of a certain pin.
@@ -634,22 +798,54 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
                                best_guess = irq;
                }
        }
-       BUG_ON(best_guess >= NR_IRQS);
        return best_guess;
 }
 
+EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
+
+#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
+/*
+ * EISA Edge/Level control register, ELCR
+ */
+static int EISA_ELCR(unsigned int irq)
+{
+       if (irq < 16) {
+               unsigned int port = 0x4d0 + (irq >> 3);
+               return (inb(port) >> (irq & 7)) & 1;
+       }
+       apic_printk(APIC_VERBOSE, KERN_INFO
+                       "Broken MPtable reports ISA irq %d\n", irq);
+       return 0;
+}
+
+#endif
+
 /* ISA interrupts are always polarity zero edge triggered,
  * when listed as conforming in the MP table. */
 
 #define default_ISA_trigger(idx)       (0)
 #define default_ISA_polarity(idx)      (0)
 
+/* EISA interrupts are always polarity zero and can be edge or level
+ * trigger depending on the ELCR value.  If an interrupt is listed as
+ * EISA conforming in the MP table, that means its trigger type must
+ * be read in from the ELCR */
+
+#define default_EISA_trigger(idx)      (EISA_ELCR(mp_irqs[idx].mp_srcbusirq))
+#define default_EISA_polarity(idx)     default_ISA_polarity(idx)
+
 /* PCI interrupts are always polarity one level triggered,
  * when listed as conforming in the MP table. */
 
 #define default_PCI_trigger(idx)       (1)
 #define default_PCI_polarity(idx)      (1)
 
+/* MCA interrupts are always polarity zero level triggered,
+ * when listed as conforming in the MP table. */
+
+#define default_MCA_trigger(idx)       (1)
+#define default_MCA_polarity(idx)      default_ISA_polarity(idx)
+
 static int MPBIOS_polarity(int idx)
 {
        int bus = mp_irqs[idx].mp_srcbus;
@@ -707,6 +903,36 @@ static int MPBIOS_trigger(int idx)
                                trigger = default_ISA_trigger(idx);
                        else
                                trigger = default_PCI_trigger(idx);
+#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
+                       switch (mp_bus_id_to_type[bus]) {
+                               case MP_BUS_ISA: /* ISA pin */
+                               {
+                                       /* set before the switch */
+                                       break;
+                               }
+                               case MP_BUS_EISA: /* EISA pin */
+                               {
+                                       trigger = default_EISA_trigger(idx);
+                                       break;
+                               }
+                               case MP_BUS_PCI: /* PCI pin */
+                               {
+                                       /* set before the switch */
+                                       break;
+                               }
+                               case MP_BUS_MCA: /* MCA pin */
+                               {
+                                       trigger = default_MCA_trigger(idx);
+                                       break;
+                               }
+                               default:
+                               {
+                                       printk(KERN_WARNING "broken BIOS!!\n");
+                                       trigger = 1;
+                                       break;
+                               }
+                       }
+#endif
                        break;
                case 1: /* edge */
                {
@@ -744,6 +970,7 @@ 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;
@@ -765,8 +992,32 @@ static int pin_2_irq(int idx, int apic, int pin)
                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);
+       }
+
+#ifdef CONFIG_X86_32
+       /*
+        * PCI IRQ command line redirection. Yes, limits are hardcoded.
+        */
+       if ((pin >= 16) && (pin <= 23)) {
+               if (pirq_entries[pin-16] != -1) {
+                       if (!pirq_entries[pin-16]) {
+                               apic_printk(APIC_VERBOSE, KERN_DEBUG
+                                               "disabling PIRQ%d\n", pin-16);
+                       } else {
+                               irq = pirq_entries[pin-16];
+                               apic_printk(APIC_VERBOSE, KERN_DEBUG
+                                               "using PIRQ%d -> IRQ %d\n",
+                                               pin-16, irq);
+                       }
+               }
        }
-       BUG_ON(irq >= NR_IRQS);
+#endif
+
        return irq;
 }
 
@@ -801,8 +1052,7 @@ static int __assign_irq_vector(int irq, cpumask_t mask)
        int cpu;
        struct irq_cfg *cfg;
 
-       BUG_ON((unsigned)irq >= NR_IRQS);
-       cfg = &irq_cfg[irq];
+       cfg = irq_cfg(irq);
 
        /* Only try and allocate irqs on cpus that are present */
        cpus_and(mask, mask, cpu_online_map);
@@ -837,8 +1087,13 @@ next:
                }
                if (unlikely(current_vector == vector))
                        continue;
+#ifdef CONFIG_X86_64
                if (vector == IA32_SYSCALL_VECTOR)
                        goto next;
+#else
+               if (vector == SYSCALL_VECTOR)
+                       goto next;
+#endif
                for_each_cpu_mask_nr(new_cpu, new_mask)
                        if (per_cpu(vector_irq, new_cpu)[vector] != -1)
                                goto next;
@@ -875,8 +1130,7 @@ static void __clear_irq_vector(int irq)
        cpumask_t mask;
        int cpu, vector;
 
-       BUG_ON((unsigned)irq >= NR_IRQS);
-       cfg = &irq_cfg[irq];
+       cfg = irq_cfg(irq);
        BUG_ON(!cfg->vector);
 
        vector = cfg->vector;
@@ -893,12 +1147,13 @@ void __setup_vector_irq(int cpu)
        /* Initialize vector_irq on a new cpu */
        /* This function must be called with vector_lock held */
        int irq, vector;
+       struct irq_cfg *cfg;
 
        /* Mark the inuse vectors */
-       for (irq = 0; irq < NR_IRQS; ++irq) {
-               if (!cpu_isset(cpu, irq_cfg[irq].domain))
+       for_each_irq_cfg(irq, cfg) {
+               if (!cpu_isset(cpu, cfg->domain))
                        continue;
-               vector = irq_cfg[irq].vector;
+               vector = cfg->vector;
                per_cpu(vector_irq, cpu)[vector] = irq;
        }
        /* Mark the free vectors */
@@ -906,7 +1161,9 @@ void __setup_vector_irq(int cpu)
                irq = per_cpu(vector_irq, cpu)[vector];
                if (irq < 0)
                        continue;
-               if (!cpu_isset(cpu, irq_cfg[irq].domain))
+
+               cfg = irq_cfg(irq);
+               if (!cpu_isset(cpu, cfg->domain))
                        per_cpu(vector_irq, cpu)[vector] = -1;
        }
 }
@@ -916,16 +1173,49 @@ static struct irq_chip ioapic_chip;
 static struct irq_chip ir_ioapic_chip;
 #endif
 
+#define IOAPIC_AUTO     -1
+#define IOAPIC_EDGE     0
+#define IOAPIC_LEVEL    1
+
+#ifdef CONFIG_X86_32
+static inline int IO_APIC_irq_trigger(int irq)
+{
+       int apic, idx, pin;
+
+       for (apic = 0; apic < nr_ioapics; apic++) {
+               for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
+                       idx = find_irq_entry(apic, pin, mp_INT);
+                       if ((idx != -1) && (irq == pin_2_irq(idx, apic, pin)))
+                               return irq_trigger(idx);
+               }
+       }
+       /*
+         * nonexistent IRQs are edge default
+         */
+       return 0;
+}
+#else
+static inline int IO_APIC_irq_trigger(int irq)
+{
+       return 1;
+}
+#endif
+
 static void ioapic_register_intr(int irq, unsigned long trigger)
 {
-       if (trigger)
-               irq_desc[irq].status |= IRQ_LEVEL;
+       struct irq_desc *desc;
+
+       desc = irq_to_desc(irq);
+
+       if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
+           trigger == IOAPIC_LEVEL)
+               desc->status |= IRQ_LEVEL;
        else
-               irq_desc[irq].status &= ~IRQ_LEVEL;
+               desc->status &= ~IRQ_LEVEL;
 
 #ifdef CONFIG_INTR_REMAP
        if (irq_remapped(irq)) {
-               irq_desc[irq].status |= IRQ_MOVE_PCNTXT;
+               desc->status |= IRQ_MOVE_PCNTXT;
                if (trigger)
                        set_irq_chip_and_handler_name(irq, &ir_ioapic_chip,
                                                      handle_fasteoi_irq,
@@ -936,7 +1226,8 @@ static void ioapic_register_intr(int irq, unsigned long trigger)
                return;
        }
 #endif
-       if (trigger)
+       if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
+           trigger == IOAPIC_LEVEL)
                set_irq_chip_and_handler_name(irq, &ioapic_chip,
                                              handle_fasteoi_irq,
                                              "fasteoi");
@@ -1009,13 +1300,15 @@ static int setup_ioapic_entry(int apic, int irq,
 static void setup_IO_APIC_irq(int apic, int pin, unsigned int irq,
                              int trigger, int polarity)
 {
-       struct irq_cfg *cfg = irq_cfg + irq;
+       struct irq_cfg *cfg;
        struct IO_APIC_route_entry entry;
        cpumask_t mask;
 
        if (!IO_APIC_IRQ(irq))
                return;
 
+       cfg = irq_cfg(irq);
+
        mask = TARGET_CPUS;
        if (assign_irq_vector(irq, mask))
                return;
@@ -1047,37 +1340,49 @@ static void setup_IO_APIC_irq(int apic, int pin, unsigned int irq,
 
 static void __init setup_IO_APIC_irqs(void)
 {
-       int apic, pin, idx, irq, first_notcon = 1;
+       int apic, pin, idx, irq;
+       int notcon = 0;
 
        apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
 
        for (apic = 0; apic < nr_ioapics; apic++) {
-       for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
-
-               idx = find_irq_entry(apic,pin,mp_INT);
-               if (idx == -1) {
-                       if (first_notcon) {
-                               apic_printk(APIC_VERBOSE, KERN_DEBUG " IO-APIC (apicid-pin) %d-%d", mp_ioapics[apic].mp_apicid, pin);
-                               first_notcon = 0;
-                       } else
-                               apic_printk(APIC_VERBOSE, ", %d-%d", mp_ioapics[apic].mp_apicid, pin);
-                       continue;
-               }
-               if (!first_notcon) {
-                       apic_printk(APIC_VERBOSE, " not connected.\n");
-                       first_notcon = 1;
-               }
+               for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
 
-               irq = pin_2_irq(idx, apic, pin);
-               add_pin_to_irq(irq, apic, pin);
+                       idx = find_irq_entry(apic, pin, mp_INT);
+                       if (idx == -1) {
+                               if (!notcon) {
+                                       notcon = 1;
+                                       apic_printk(APIC_VERBOSE,
+                                               KERN_DEBUG " %d-%d",
+                                               mp_ioapics[apic].mp_apicid,
+                                               pin);
+                               } else
+                                       apic_printk(APIC_VERBOSE, " %d-%d",
+                                               mp_ioapics[apic].mp_apicid,
+                                               pin);
+                               continue;
+                       }
+                       if (notcon) {
+                               apic_printk(APIC_VERBOSE,
+                                       " (apicid-pin) not connected\n");
+                               notcon = 0;
+                       }
 
-               setup_IO_APIC_irq(apic, pin, irq,
-                                 irq_trigger(idx), irq_polarity(idx));
-       }
+                       irq = pin_2_irq(idx, apic, pin);
+#ifdef CONFIG_X86_32
+                       if (multi_timer_check(apic, irq))
+                               continue;
+#endif
+                       add_pin_to_irq(irq, apic, pin);
+
+                       setup_IO_APIC_irq(apic, pin, irq,
+                                       irq_trigger(idx), irq_polarity(idx));
+               }
        }
 
-       if (!first_notcon)
-               apic_printk(APIC_VERBOSE, " not connected.\n");
+       if (notcon)
+               apic_printk(APIC_VERBOSE,
+                       " (apicid-pin) not connected\n");
 }
 
 /*
@@ -1088,8 +1393,10 @@ static void __init setup_timer_IRQ0_pin(unsigned int apic, unsigned int pin,
 {
        struct IO_APIC_route_entry entry;
 
+#ifdef CONFIG_INTR_REMAP
        if (intr_remapping_enabled)
                return;
+#endif
 
        memset(&entry, 0, sizeof(entry));
 
@@ -1124,7 +1431,10 @@ __apicdebuginit(void) print_IO_APIC(void)
        union IO_APIC_reg_00 reg_00;
        union IO_APIC_reg_01 reg_01;
        union IO_APIC_reg_02 reg_02;
+       union IO_APIC_reg_03 reg_03;
        unsigned long flags;
+       struct irq_cfg *cfg;
+       unsigned int irq;
 
        if (apic_verbosity == APIC_QUIET)
                return;
@@ -1147,12 +1457,16 @@ __apicdebuginit(void) print_IO_APIC(void)
        reg_01.raw = io_apic_read(apic, 1);
        if (reg_01.bits.version >= 0x10)
                reg_02.raw = io_apic_read(apic, 2);
+       if (reg_01.bits.version >= 0x20)
+               reg_03.raw = io_apic_read(apic, 3);
        spin_unlock_irqrestore(&ioapic_lock, flags);
 
        printk("\n");
        printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mp_apicid);
        printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw);
        printk(KERN_DEBUG ".......    : physical APIC id: %02X\n", reg_00.bits.ID);
+       printk(KERN_DEBUG ".......    : Delivery Type: %X\n", reg_00.bits.delivery_type);
+       printk(KERN_DEBUG ".......    : LTS          : %X\n", reg_00.bits.LTS);
 
        printk(KERN_DEBUG ".... register #01: %08X\n", *(int *)&reg_01);
        printk(KERN_DEBUG ".......     : max redirection entries: %04X\n", reg_01.bits.entries);
@@ -1160,11 +1474,27 @@ __apicdebuginit(void) print_IO_APIC(void)
        printk(KERN_DEBUG ".......     : PRQ implemented: %X\n", reg_01.bits.PRQ);
        printk(KERN_DEBUG ".......     : IO APIC version: %04X\n", reg_01.bits.version);
 
-       if (reg_01.bits.version >= 0x10) {
+       /*
+        * Some Intel chipsets with IO APIC VERSION of 0x1? don't have reg_02,
+        * but the value of reg_02 is read as the previous read register
+        * value, so ignore it if reg_02 == reg_01.
+        */
+       if (reg_01.bits.version >= 0x10 && reg_02.raw != reg_01.raw) {
                printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw);
                printk(KERN_DEBUG ".......     : arbitration: %02X\n", reg_02.bits.arbitration);
        }
 
+       /*
+        * Some Intel chipsets with IO APIC VERSION of 0x2? don't have reg_02
+        * or reg_03, but the value of reg_0[23] is read as the previous read
+        * register value, so ignore it if reg_03 == reg_0[12].
+        */
+       if (reg_01.bits.version >= 0x20 && reg_03.raw != reg_02.raw &&
+           reg_03.raw != reg_01.raw) {
+               printk(KERN_DEBUG ".... register #03: %08X\n", reg_03.raw);
+               printk(KERN_DEBUG ".......     : Boot DT    : %X\n", reg_03.bits.boot_DT);
+       }
+
        printk(KERN_DEBUG ".... IRQ redirection table:\n");
 
        printk(KERN_DEBUG " NR Dst Mask Trig IRR Pol"
@@ -1193,16 +1523,16 @@ __apicdebuginit(void) print_IO_APIC(void)
        }
        }
        printk(KERN_DEBUG "IRQ to pin mappings:\n");
-       for (i = 0; i < NR_IRQS; i++) {
-               struct irq_pin_list *entry = irq_2_pin + i;
-               if (entry->pin < 0)
+       for_each_irq_cfg(irq, cfg) {
+               struct irq_pin_list *entry = cfg->irq_2_pin;
+               if (!entry)
                        continue;
-               printk(KERN_DEBUG "IRQ%d ", i);
+               printk(KERN_DEBUG "IRQ%d ", irq);
                for (;;) {
                        printk("-> %d:%d", entry->apic, entry->pin);
                        if (!entry->next)
                                break;
-                       entry = irq_2_pin + entry->next;
+                       entry = entry->next;
                }
                printk("\n");
        }
@@ -1236,7 +1566,7 @@ __apicdebuginit(void) print_APIC_bitfield(int base)
 __apicdebuginit(void) print_local_APIC(void *dummy)
 {
        unsigned int v, ver, maxlvt;
-       unsigned long icr;
+       u64 icr;
 
        if (apic_verbosity == APIC_QUIET)
                return;
@@ -1253,20 +1583,31 @@ __apicdebuginit(void) print_local_APIC(void *dummy)
        v = apic_read(APIC_TASKPRI);
        printk(KERN_DEBUG "... APIC TASKPRI: %08x (%02x)\n", v, v & APIC_TPRI_MASK);
 
-       v = apic_read(APIC_ARBPRI);
-       printk(KERN_DEBUG "... APIC ARBPRI: %08x (%02x)\n", v,
-               v & APIC_ARBPRI_MASK);
-       v = apic_read(APIC_PROCPRI);
-       printk(KERN_DEBUG "... APIC PROCPRI: %08x\n", v);
+       if (APIC_INTEGRATED(ver)) {                     /* !82489DX */
+               if (!APIC_XAPIC(ver)) {
+                       v = apic_read(APIC_ARBPRI);
+                       printk(KERN_DEBUG "... APIC ARBPRI: %08x (%02x)\n", v,
+                              v & APIC_ARBPRI_MASK);
+               }
+               v = apic_read(APIC_PROCPRI);
+               printk(KERN_DEBUG "... APIC PROCPRI: %08x\n", v);
+       }
+
+       /*
+        * Remote read supported only in the 82489DX and local APIC for
+        * Pentium processors.
+        */
+       if (!APIC_INTEGRATED(ver) || maxlvt == 3) {
+               v = apic_read(APIC_RRR);
+               printk(KERN_DEBUG "... APIC RRR: %08x\n", v);
+       }
 
-       v = apic_read(APIC_EOI);
-       printk(KERN_DEBUG "... APIC EOI: %08x\n", v);
-       v = apic_read(APIC_RRR);
-       printk(KERN_DEBUG "... APIC RRR: %08x\n", v);
        v = apic_read(APIC_LDR);
        printk(KERN_DEBUG "... APIC LDR: %08x\n", v);
-       v = apic_read(APIC_DFR);
-       printk(KERN_DEBUG "... APIC DFR: %08x\n", v);
+       if (!x2apic_enabled()) {
+               v = apic_read(APIC_DFR);
+               printk(KERN_DEBUG "... APIC DFR: %08x\n", v);
+       }
        v = apic_read(APIC_SPIV);
        printk(KERN_DEBUG "... APIC SPIV: %08x\n", v);
 
@@ -1277,8 +1618,13 @@ __apicdebuginit(void) print_local_APIC(void *dummy)
        printk(KERN_DEBUG "... APIC IRR field:\n");
        print_APIC_bitfield(APIC_IRR);
 
-       v = apic_read(APIC_ESR);
-       printk(KERN_DEBUG "... APIC ESR: %08x\n", v);
+       if (APIC_INTEGRATED(ver)) {             /* !82489DX */
+               if (maxlvt > 3)         /* Due to the Pentium erratum 3AP. */
+                       apic_write(APIC_ESR, 0);
+
+               v = apic_read(APIC_ESR);
+               printk(KERN_DEBUG "... APIC ESR: %08x\n", v);
+       }
 
        icr = apic_icr_read();
        printk(KERN_DEBUG "... APIC ICR: %08x\n", (u32)icr);
@@ -1312,7 +1658,12 @@ __apicdebuginit(void) print_local_APIC(void *dummy)
 
 __apicdebuginit(void) print_all_local_APICs(void)
 {
-       on_each_cpu(print_local_APIC, NULL, 1);
+       int cpu;
+
+       preempt_disable();
+       for_each_online_cpu(cpu)
+               smp_call_function_single(cpu, print_local_APIC, NULL, 1);
+       preempt_enable();
 }
 
 __apicdebuginit(void) print_PIC(void)
@@ -1359,17 +1710,22 @@ __apicdebuginit(int) print_all_ICs(void)
 fs_initcall(print_all_ICs);
 
 
+/* Where if anywhere is the i8259 connect in external int mode */
+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 i, apic;
+       int apic;
        unsigned long flags;
 
-       for (i = 0; i < PIN_MAP_SIZE; i++) {
-               irq_2_pin[i].pin = -1;
-               irq_2_pin[i].next = 0;
-       }
+#ifdef CONFIG_X86_32
+       int i;
+       if (!pirqs_enabled)
+               for (i = 0; i < MAX_PIRQS; i++)
+                       pirq_entries[i] = -1;
+#endif
 
        /*
         * The number of IO-APIC IRQ registers (== #pins):
@@ -1399,6 +1755,10 @@ void __init enable_IO_APIC(void)
        }
  found_i8259:
        /* Look to see what if the MP table has reported the ExtINT */
+       /* If we could not find the appropriate pin by looking at the ioapic
+        * the i8259 probably is not connected the ioapic but give the
+        * mptable a chance anyway.
+        */
        i8259_pin  = find_isa_irq_pin(0, mp_ExtINT);
        i8259_apic = find_isa_irq_apic(0, mp_ExtINT);
        /* Trust the MP table if nothing is setup in the hardware */
@@ -1458,6 +1818,133 @@ void disable_IO_APIC(void)
        disconnect_bsp_APIC(ioapic_i8259.pin != -1);
 }
 
+#ifdef CONFIG_X86_32
+/*
+ * function to set the IO-APIC physical IDs based on the
+ * values stored in the MPC table.
+ *
+ * by Matt Domsch <Matt_Domsch@dell.com>  Tue Dec 21 12:25:05 CST 1999
+ */
+
+static void __init setup_ioapic_ids_from_mpc(void)
+{
+       union IO_APIC_reg_00 reg_00;
+       physid_mask_t phys_id_present_map;
+       int apic;
+       int i;
+       unsigned char old_id;
+       unsigned long flags;
+
+       if (x86_quirks->setup_ioapic_ids && x86_quirks->setup_ioapic_ids())
+               return;
+
+       /*
+        * Don't check I/O APIC IDs for xAPIC systems.  They have
+        * no meaning without the serial APIC bus.
+        */
+       if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
+               || APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
+               return;
+       /*
+        * This is broken; anything with a real cpu count has to
+        * circumvent this idiocy regardless.
+        */
+       phys_id_present_map = ioapic_phys_id_map(phys_cpu_present_map);
+
+       /*
+        * Set the IOAPIC ID to the value stored in the MPC table.
+        */
+       for (apic = 0; apic < nr_ioapics; apic++) {
+
+               /* Read the register 0 value */
+               spin_lock_irqsave(&ioapic_lock, flags);
+               reg_00.raw = io_apic_read(apic, 0);
+               spin_unlock_irqrestore(&ioapic_lock, flags);
+
+               old_id = mp_ioapics[apic].mp_apicid;
+
+               if (mp_ioapics[apic].mp_apicid >= get_physical_broadcast()) {
+                       printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
+                               apic, mp_ioapics[apic].mp_apicid);
+                       printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
+                               reg_00.bits.ID);
+                       mp_ioapics[apic].mp_apicid = reg_00.bits.ID;
+               }
+
+               /*
+                * Sanity check, is the ID really free? Every APIC in a
+                * system must have a unique ID or we get lots of nice
+                * 'stuck on smp_invalidate_needed IPI wait' messages.
+                */
+               if (check_apicid_used(phys_id_present_map,
+                                       mp_ioapics[apic].mp_apicid)) {
+                       printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
+                               apic, mp_ioapics[apic].mp_apicid);
+                       for (i = 0; i < get_physical_broadcast(); i++)
+                               if (!physid_isset(i, phys_id_present_map))
+                                       break;
+                       if (i >= get_physical_broadcast())
+                               panic("Max APIC ID exceeded!\n");
+                       printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
+                               i);
+                       physid_set(i, phys_id_present_map);
+                       mp_ioapics[apic].mp_apicid = i;
+               } else {
+                       physid_mask_t tmp;
+                       tmp = apicid_to_cpu_present(mp_ioapics[apic].mp_apicid);
+                       apic_printk(APIC_VERBOSE, "Setting %d in the "
+                                       "phys_id_present_map\n",
+                                       mp_ioapics[apic].mp_apicid);
+                       physids_or(phys_id_present_map, phys_id_present_map, tmp);
+               }
+
+
+               /*
+                * We need to adjust the IRQ routing table
+                * if the ID changed.
+                */
+               if (old_id != mp_ioapics[apic].mp_apicid)
+                       for (i = 0; i < mp_irq_entries; i++)
+                               if (mp_irqs[i].mp_dstapic == old_id)
+                                       mp_irqs[i].mp_dstapic
+                                               = mp_ioapics[apic].mp_apicid;
+
+               /*
+                * Read the right value from the MPC table and
+                * write it into the ID register.
+                */
+               apic_printk(APIC_VERBOSE, KERN_INFO
+                       "...changing IO-APIC physical APIC ID to %d ...",
+                       mp_ioapics[apic].mp_apicid);
+
+               reg_00.bits.ID = mp_ioapics[apic].mp_apicid;
+               spin_lock_irqsave(&ioapic_lock, flags);
+               io_apic_write(apic, 0, reg_00.raw);
+               spin_unlock_irqrestore(&ioapic_lock, flags);
+
+               /*
+                * Sanity check
+                */
+               spin_lock_irqsave(&ioapic_lock, flags);
+               reg_00.raw = io_apic_read(apic, 0);
+               spin_unlock_irqrestore(&ioapic_lock, flags);
+               if (reg_00.bits.ID != mp_ioapics[apic].mp_apicid)
+                       printk("could not set ID!\n");
+               else
+                       apic_printk(APIC_VERBOSE, " ok.\n");
+       }
+}
+#endif
+
+int no_timer_check __initdata;
+
+static int __init notimercheck(char *s)
+{
+       no_timer_check = 1;
+       return 1;
+}
+__setup("no_timer_check", notimercheck);
+
 /*
  * There is a nasty bug in some older SMP boards, their mptable lies
  * about the timer IRQ. We do the following to work around the situation:
@@ -1471,6 +1958,9 @@ static int __init timer_irq_works(void)
        unsigned long t1 = jiffies;
        unsigned long flags;
 
+       if (no_timer_check)
+               return 1;
+
        local_save_flags(flags);
        local_irq_enable();
        /* Let ten ticks pass... */
@@ -1531,9 +2021,11 @@ static unsigned int startup_ioapic_irq(unsigned int irq)
        return was_pending;
 }
 
+#ifdef CONFIG_X86_64
 static int ioapic_retrigger_irq(unsigned int irq)
 {
-       struct irq_cfg *cfg = &irq_cfg[irq];
+
+       struct irq_cfg *cfg = irq_cfg(irq);
        unsigned long flags;
 
        spin_lock_irqsave(&vector_lock, flags);
@@ -1542,6 +2034,14 @@ static int ioapic_retrigger_irq(unsigned int irq)
 
        return 1;
 }
+#else
+static int ioapic_retrigger_irq(unsigned int irq)
+{
+       send_IPI_self(irq_cfg(irq)->vector);
+
+       return 1;
+}
+#endif
 
 /*
  * Level and edge triggered IO-APIC interrupts need different handling,
@@ -1580,11 +2080,11 @@ static DECLARE_DELAYED_WORK(ir_migration_work, ir_irq_migration);
  */
 static void migrate_ioapic_irq(int irq, cpumask_t mask)
 {
-       struct irq_cfg *cfg = irq_cfg + irq;
-       struct irq_desc *desc = irq_desc + irq;
+       struct irq_cfg *cfg;
+       struct irq_desc *desc;
        cpumask_t tmp, cleanup_mask;
        struct irte irte;
-       int modify_ioapic_rte = desc->status & IRQ_LEVEL;
+       int modify_ioapic_rte;
        unsigned int dest;
        unsigned long flags;
 
@@ -1598,9 +2098,12 @@ static void migrate_ioapic_irq(int irq, cpumask_t mask)
        if (assign_irq_vector(irq, mask))
                return;
 
+       cfg = irq_cfg(irq);
        cpus_and(tmp, cfg->domain, mask);
        dest = cpu_mask_to_apicid(tmp);
 
+       desc = irq_to_desc(irq);
+       modify_ioapic_rte = desc->status & IRQ_LEVEL;
        if (modify_ioapic_rte) {
                spin_lock_irqsave(&ioapic_lock, flags);
                __target_IO_APIC_irq(irq, dest, cfg->vector);
@@ -1622,18 +2125,19 @@ static void migrate_ioapic_irq(int irq, cpumask_t mask)
                cfg->move_in_progress = 0;
        }
 
-       irq_desc[irq].affinity = mask;
+       desc->affinity = mask;
 }
 
 static int migrate_irq_remapped_level(int irq)
 {
        int ret = -1;
+       struct irq_desc *desc = irq_to_desc(irq);
 
        mask_IO_APIC_irq(irq);
 
        if (io_apic_level_ack_pending(irq)) {
                /*
-                * Interrupt in progress. Migrating irq now will change the
+                * Interrupt in progress. Migrating irq now will change the
                 * vector information in the IO-APIC RTE and that will confuse
                 * the EOI broadcast performed by cpu.
                 * So, delay the irq migration to the next instance.
@@ -1643,11 +2147,11 @@ static int migrate_irq_remapped_level(int irq)
        }
 
        /* everthing is clear. we have right of way */
-       migrate_ioapic_irq(irq, irq_desc[irq].pending_mask);
+       migrate_ioapic_irq(irq, desc->pending_mask);
 
        ret = 0;
-       irq_desc[irq].status &= ~IRQ_MOVE_PENDING;
-       cpus_clear(irq_desc[irq].pending_mask);
+       desc->status &= ~IRQ_MOVE_PENDING;
+       cpus_clear(desc->pending_mask);
 
 unmask:
        unmask_IO_APIC_irq(irq);
@@ -1656,10 +2160,10 @@ unmask:
 
 static void ir_irq_migration(struct work_struct *work)
 {
-       int irq;
+       unsigned int irq;
+       struct irq_desc *desc;
 
-       for (irq = 0; irq < NR_IRQS; irq++) {
-               struct irq_desc *desc = irq_desc + irq;
+       for_each_irq_desc(irq, desc) {
                if (desc->status & IRQ_MOVE_PENDING) {
                        unsigned long flags;
 
@@ -1671,8 +2175,7 @@ static void ir_irq_migration(struct work_struct *work)
                                continue;
                        }
 
-                       desc->chip->set_affinity(irq,
-                                                irq_desc[irq].pending_mask);
+                       desc->chip->set_affinity(irq, desc->pending_mask);
                        spin_unlock_irqrestore(&desc->lock, flags);
                }
        }
@@ -1683,9 +2186,11 @@ static void ir_irq_migration(struct work_struct *work)
  */
 static void set_ir_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
 {
-       if (irq_desc[irq].status & IRQ_LEVEL) {
-               irq_desc[irq].status |= IRQ_MOVE_PENDING;
-               irq_desc[irq].pending_mask = mask;
+       struct irq_desc *desc = irq_to_desc(irq);
+
+       if (desc->status & IRQ_LEVEL) {
+               desc->status |= IRQ_MOVE_PENDING;
+               desc->pending_mask = mask;
                migrate_irq_remapped_level(irq);
                return;
        }
@@ -1698,7 +2203,9 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void)
 {
        unsigned vector, me;
        ack_APIC_irq();
+#ifdef CONFIG_X86_64
        exit_idle();
+#endif
        irq_enter();
 
        me = smp_processor_id();
@@ -1707,11 +2214,12 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void)
                struct irq_desc *desc;
                struct irq_cfg *cfg;
                irq = __get_cpu_var(vector_irq)[vector];
-               if (irq >= NR_IRQS)
+
+               desc = irq_to_desc(irq);
+               if (!desc)
                        continue;
 
-               desc = irq_desc + irq;
-               cfg = irq_cfg + irq;
+               cfg = irq_cfg(irq);
                spin_lock(&desc->lock);
                if (!cfg->move_cleanup_count)
                        goto unlock;
@@ -1730,7 +2238,7 @@ unlock:
 
 static void irq_complete_move(unsigned int irq)
 {
-       struct irq_cfg *cfg = irq_cfg + irq;
+       struct irq_cfg *cfg = irq_cfg(irq);
        unsigned vector, me;
 
        if (likely(!cfg->move_in_progress))
@@ -1769,19 +2277,50 @@ static void ack_apic_edge(unsigned int irq)
        ack_APIC_irq();
 }
 
+atomic_t irq_mis_count;
+
 static void ack_apic_level(unsigned int irq)
 {
+#ifdef CONFIG_X86_32
+       unsigned long v;
+       int i;
+#endif
        int do_unmask_irq = 0;
 
        irq_complete_move(irq);
 #ifdef CONFIG_GENERIC_PENDING_IRQ
        /* If we are moving the irq we need to mask it */
-       if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) {
+       if (unlikely(irq_to_desc(irq)->status & IRQ_MOVE_PENDING)) {
                do_unmask_irq = 1;
                mask_IO_APIC_irq(irq);
        }
 #endif
 
+#ifdef CONFIG_X86_32
+       /*
+       * It appears there is an erratum which affects at least version 0x11
+       * of I/O APIC (that's the 82093AA and cores integrated into various
+       * chipsets).  Under certain conditions a level-triggered interrupt is
+       * erroneously delivered as edge-triggered one but the respective IRR
+       * bit gets set nevertheless.  As a result the I/O unit expects an EOI
+       * message but it will never arrive and further interrupts are blocked
+       * from the source.  The exact reason is so far unknown, but the
+       * phenomenon was observed when two consecutive interrupt requests
+       * from a given source get delivered to the same CPU and the source is
+       * temporarily disabled in between.
+       *
+       * A workaround is to simulate an EOI message manually.  We achieve it
+       * by setting the trigger mode to edge and then to level when the edge
+       * trigger mode gets detected in the TMR of a local APIC for a
+       * level-triggered interrupt.  We mask the source for the time of the
+       * operation to prevent an edge-triggered interrupt escaping meanwhile.
+       * The idea is from Manfred Spraul.  --macro
+       */
+       i = irq_cfg(irq)->vector;
+
+       v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1));
+#endif
+
        /*
         * We must acknowledge the irq before we move it or the acknowledge will
         * not propagate properly.
@@ -1820,31 +2359,41 @@ static void ack_apic_level(unsigned int irq)
                        move_masked_irq(irq);
                unmask_IO_APIC_irq(irq);
        }
+
+#ifdef CONFIG_X86_32
+       if (!(v & (1 << (i & 0x1f)))) {
+               atomic_inc(&irq_mis_count);
+               spin_lock(&ioapic_lock);
+               __mask_and_edge_IO_APIC_irq(irq);
+               __unmask_and_level_IO_APIC_irq(irq);
+               spin_unlock(&ioapic_lock);
+       }
+#endif
 }
 
 static struct irq_chip ioapic_chip __read_mostly = {
-       .name           = "IO-APIC",
-       .startup        = startup_ioapic_irq,
-       .mask           = mask_IO_APIC_irq,
-       .unmask         = unmask_IO_APIC_irq,
-       .ack            = ack_apic_edge,
-       .eoi            = ack_apic_level,
+       .name           = "IO-APIC",
+       .startup        = startup_ioapic_irq,
+       .mask           = mask_IO_APIC_irq,
+       .unmask         = unmask_IO_APIC_irq,
+       .ack            = ack_apic_edge,
+       .eoi            = ack_apic_level,
 #ifdef CONFIG_SMP
-       .set_affinity   = set_ioapic_affinity_irq,
+       .set_affinity   = set_ioapic_affinity_irq,
 #endif
        .retrigger      = ioapic_retrigger_irq,
 };
 
 #ifdef CONFIG_INTR_REMAP
 static struct irq_chip ir_ioapic_chip __read_mostly = {
-       .name           = "IR-IO-APIC",
-       .startup        = startup_ioapic_irq,
-       .mask           = mask_IO_APIC_irq,
-       .unmask         = unmask_IO_APIC_irq,
-       .ack            = ack_x2apic_edge,
-       .eoi            = ack_x2apic_level,
+       .name           = "IR-IO-APIC",
+       .startup        = startup_ioapic_irq,
+       .mask           = mask_IO_APIC_irq,
+       .unmask         = unmask_IO_APIC_irq,
+       .ack            = ack_x2apic_edge,
+       .eoi            = ack_x2apic_level,
 #ifdef CONFIG_SMP
-       .set_affinity   = set_ir_ioapic_affinity_irq,
+       .set_affinity   = set_ir_ioapic_affinity_irq,
 #endif
        .retrigger      = ioapic_retrigger_irq,
 };
@@ -1853,6 +2402,8 @@ static struct irq_chip ir_ioapic_chip __read_mostly = {
 static inline void init_IO_APIC_traps(void)
 {
        int irq;
+       struct irq_desc *desc;
+       struct irq_cfg *cfg;
 
        /*
         * NOTE! The local APIC isn't very good at handling
@@ -1865,8 +2416,8 @@ static inline void init_IO_APIC_traps(void)
         * Also, we've got to be careful not to trash gate
         * 0x80, because int 0x80 is hm, kind of importantish. ;)
         */
-       for (irq = 0; irq < NR_IRQS ; irq++) {
-               if (IO_APIC_IRQ(irq) && !irq_cfg[irq].vector) {
+       for_each_irq_cfg(irq, cfg) {
+               if (IO_APIC_IRQ(irq) && !cfg->vector) {
                        /*
                         * Hmm.. We don't have an entry for this,
                         * so default to an old-fashioned 8259
@@ -1874,27 +2425,33 @@ static inline void init_IO_APIC_traps(void)
                         */
                        if (irq < 16)
                                make_8259A_irq(irq);
-                       else
+                       else {
+                               desc = irq_to_desc(irq);
                                /* Strange. Oh, well.. */
-                               irq_desc[irq].chip = &no_irq_chip;
+                               desc->chip = &no_irq_chip;
+                       }
                }
        }
 }
 
-static void unmask_lapic_irq(unsigned int irq)
+/*
+ * The local APIC irq-chip implementation:
+ */
+
+static void mask_lapic_irq(unsigned int irq)
 {
        unsigned long v;
 
        v = apic_read(APIC_LVT0);
-       apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED);
+       apic_write(APIC_LVT0, v APIC_LVT_MASKED);
 }
 
-static void mask_lapic_irq(unsigned int irq)
+static void unmask_lapic_irq(unsigned int irq)
 {
        unsigned long v;
 
        v = apic_read(APIC_LVT0);
-       apic_write(APIC_LVT0, v APIC_LVT_MASKED);
+       apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED);
 }
 
 static void ack_lapic_irq (unsigned int irq)
@@ -1911,7 +2468,10 @@ static struct irq_chip lapic_chip __read_mostly = {
 
 static void lapic_register_intr(int irq)
 {
-       irq_desc[irq].status &= ~IRQ_LEVEL;
+       struct irq_desc *desc;
+
+       desc = irq_to_desc(irq);
+       desc->status &= ~IRQ_LEVEL;
        set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq,
                                      "edge");
 }
@@ -1919,19 +2479,19 @@ static void lapic_register_intr(int irq)
 static void __init setup_nmi(void)
 {
        /*
-        * Dirty trick to enable the NMI watchdog ...
+        * Dirty trick to enable the NMI watchdog ...
         * We put the 8259A master into AEOI mode and
         * unmask on all local APICs LVT0 as NMI.
         *
         * The idea to use the 8259A in AEOI mode ('8259A Virtual Wire')
         * is from Maciej W. Rozycki - so we do not have to EOI from
         * the NMI handler or the timer interrupt.
-        */ 
-       printk(KERN_INFO "activating NMI Watchdog ...");
+        */
+       apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ...");
 
        enable_NMI_through_LVT0();
 
-       printk(" done.\n");
+       apic_printk(APIC_VERBOSE, " done.\n");
 }
 
 /*
@@ -1948,12 +2508,17 @@ static inline void __init unlock_ExtINT_logic(void)
        unsigned char save_control, save_freq_select;
 
        pin  = find_isa_irq_pin(8, mp_INT);
+       if (pin == -1) {
+               WARN_ON_ONCE(1);
+               return;
+       }
        apic = find_isa_irq_apic(8, mp_INT);
-       if (pin == -1)
+       if (apic == -1) {
+               WARN_ON_ONCE(1);
                return;
+       }
 
        entry0 = ioapic_read_entry(apic, pin);
-
        clear_IO_APIC_pin(apic, pin);
 
        memset(&entry1, 0, sizeof(entry1));
@@ -1988,23 +2553,38 @@ static inline void __init unlock_ExtINT_logic(void)
        ioapic_write_entry(apic, pin, entry0);
 }
 
+static int disable_timer_pin_1 __initdata;
+/* Actually the next is obsolete, but keep it for paranoid reasons -AK */
+static int __init disable_timer_pin_setup(char *arg)
+{
+       disable_timer_pin_1 = 1;
+       return 0;
+}
+early_param("disable_timer_pin_1", disable_timer_pin_setup);
+
+int timer_through_8259 __initdata;
+
 /*
  * This code may look a bit paranoid, but it's supposed to cooperate with
  * a wide range of boards and BIOS bugs.  Fortunately only the timer IRQ
  * is so screwy.  Thanks to Brian Perkins for testing/hacking this beast
  * fanatically on his truly buggy board.
  *
- * FIXME: really need to revamp this for modern platforms only.
+ * FIXME: really need to revamp this for all platforms.
  */
 static inline void __init check_timer(void)
 {
-       struct irq_cfg *cfg = irq_cfg + 0;
+       struct irq_cfg *cfg = irq_cfg(0);
        int apic1, pin1, apic2, pin2;
        unsigned long flags;
+       unsigned int ver;
        int no_pin1 = 0;
 
        local_irq_save(flags);
 
+       ver = apic_read(APIC_LVR);
+       ver = GET_APIC_VERSION(ver);
+
        /*
         * get/set the timer IRQ vector:
         */
@@ -2013,10 +2593,18 @@ static inline void __init check_timer(void)
 
        /*
         * As IRQ0 is to be enabled in the 8259A, the virtual
-        * wire has to be disabled in the local APIC.
+        * wire has to be disabled in the local APIC.  Also
+        * timer interrupts need to be acknowledged manually in
+        * the 8259A for the i82489DX when using the NMI
+        * watchdog as that APIC treats NMIs as level-triggered.
+        * The AEOI mode will finish them in the 8259A
+        * automatically.
         */
        apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
        init_8259A(1);
+#ifdef CONFIG_X86_32
+       timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver));
+#endif
 
        pin1  = find_isa_irq_pin(0, mp_INT);
        apic1 = find_isa_irq_apic(0, mp_INT);
@@ -2035,8 +2623,10 @@ static inline void __init check_timer(void)
         * 8259A.
         */
        if (pin1 == -1) {
+#ifdef CONFIG_INTR_REMAP
                if (intr_remapping_enabled)
                        panic("BIOS bug: timer not connected to IO-APIC");
+#endif
                pin1 = pin2;
                apic1 = apic2;
                no_pin1 = 1;
@@ -2054,7 +2644,7 @@ static inline void __init check_timer(void)
                        setup_timer_IRQ0_pin(apic1, pin1, cfg->vector);
                }
                unmask_IO_APIC_irq(0);
-               if (!no_timer_check && timer_irq_works()) {
+               if (timer_irq_works()) {
                        if (nmi_watchdog == NMI_IO_APIC) {
                                setup_nmi();
                                enable_8259A_irq(0);
@@ -2063,8 +2653,10 @@ static inline void __init check_timer(void)
                                clear_IO_APIC_pin(0, pin1);
                        goto out;
                }
+#ifdef CONFIG_INTR_REMAP
                if (intr_remapping_enabled)
                        panic("timer doesn't work through Interrupt-remapped IO-APIC");
+#endif
                clear_IO_APIC_pin(apic1, pin1);
                if (!no_pin1)
                        apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: "
@@ -2104,6 +2696,9 @@ static inline void __init check_timer(void)
                            "through the IO-APIC - disabling NMI Watchdog!\n");
                nmi_watchdog = NMI_NONE;
        }
+#ifdef CONFIG_X86_32
+       timer_ack = 0;
+#endif
 
        apic_printk(APIC_QUIET, KERN_INFO
                    "...trying to set up timer as Virtual Wire IRQ...\n");
@@ -2140,13 +2735,6 @@ out:
        local_irq_restore(flags);
 }
 
-static int __init notimercheck(char *s)
-{
-       no_timer_check = 1;
-       return 1;
-}
-__setup("no_timer_check", notimercheck);
-
 /*
  * Traditionally ISA IRQ2 is the cascade IRQ, and is not available
  * to devices.  However there may be an I/O APIC pin available for
@@ -2164,25 +2752,49 @@ __setup("no_timer_check", notimercheck);
  * the I/O APIC in all cases now.  No actual device should request
  * it anyway.  --macro
  */
-#define PIC_IRQS       (1<<2)
+#define PIC_IRQS       (1 << PIC_CASCADE_IR)
 
 void __init setup_IO_APIC(void)
 {
 
+#ifdef CONFIG_X86_32
+       enable_IO_APIC();
+#else
        /*
         * calling enable_IO_APIC() is moved to setup_local_APIC for BP
         */
+#endif
 
        io_apic_irqs = ~PIC_IRQS;
 
        apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n");
-
+       /*
+         * Set up IO-APIC IRQ routing.
+         */
+#ifdef CONFIG_X86_32
+       if (!acpi_ioapic)
+               setup_ioapic_ids_from_mpc();
+#endif
        sync_Arb_IDs();
        setup_IO_APIC_irqs();
        init_IO_APIC_traps();
        check_timer();
 }
 
+/*
+ *      Called after all the initialization is done. If we didnt find any
+ *      APIC bugs then we can allow the modify fast path
+ */
+
+static int __init io_apic_bug_finalize(void)
+{
+       if (sis_apic_bug == -1)
+               sis_apic_bug = 0;
+       return 0;
+}
+
+late_initcall(io_apic_bug_finalize);
+
 struct sysfs_ioapic_data {
        struct sys_device dev;
        struct IO_APIC_route_entry entry[0];
@@ -2270,32 +2882,51 @@ device_initcall(ioapic_init_sysfs);
 /*
  * Dynamic irq allocate and deallocation
  */
-int create_irq(void)
+unsigned int create_irq_nr(unsigned int irq_want)
 {
        /* Allocate an unused irq */
-       int irq;
-       int new;
+       unsigned int irq;
+       unsigned int new;
        unsigned long flags;
+       struct irq_cfg *cfg_new;
+
+       irq_want = nr_irqs - 1;
 
-       irq = -ENOSPC;
+       irq = 0;
        spin_lock_irqsave(&vector_lock, flags);
-       for (new = (NR_IRQS - 1); new >= 0; new--) {
+       for (new = irq_want; new > 0; new--) {
                if (platform_legacy_irq(new))
                        continue;
-               if (irq_cfg[new].vector != 0)
+               cfg_new = irq_cfg(new);
+               if (cfg_new && cfg_new->vector != 0)
                        continue;
+               /* check if need to create one */
+               if (!cfg_new)
+                       cfg_new = irq_cfg_alloc(new);
                if (__assign_irq_vector(new, TARGET_CPUS) == 0)
                        irq = new;
                break;
        }
        spin_unlock_irqrestore(&vector_lock, flags);
 
-       if (irq >= 0) {
+       if (irq > 0) {
                dynamic_irq_init(irq);
        }
        return irq;
 }
 
+int create_irq(void)
+{
+       int irq;
+
+       irq = create_irq_nr(nr_irqs - 1);
+
+       if (irq == 0)
+               irq = -1;
+
+       return irq;
+}
+
 void destroy_irq(unsigned int irq)
 {
        unsigned long flags;
@@ -2316,7 +2947,7 @@ void destroy_irq(unsigned int irq)
 #ifdef CONFIG_PCI_MSI
 static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
 {
-       struct irq_cfg *cfg = irq_cfg + irq;
+       struct irq_cfg *cfg;
        int err;
        unsigned dest;
        cpumask_t tmp;
@@ -2326,6 +2957,7 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms
        if (err)
                return err;
 
+       cfg = irq_cfg(irq);
        cpus_and(tmp, cfg->domain, tmp);
        dest = cpu_mask_to_apicid(tmp);
 
@@ -2383,10 +3015,11 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms
 #ifdef CONFIG_SMP
 static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
 {
-       struct irq_cfg *cfg = irq_cfg + irq;
+       struct irq_cfg *cfg;
        struct msi_msg msg;
        unsigned int dest;
        cpumask_t tmp;
+       struct irq_desc *desc;
 
        cpus_and(tmp, mask, cpu_online_map);
        if (cpus_empty(tmp))
@@ -2395,6 +3028,7 @@ static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
        if (assign_irq_vector(irq, mask))
                return;
 
+       cfg = irq_cfg(irq);
        cpus_and(tmp, cfg->domain, mask);
        dest = cpu_mask_to_apicid(tmp);
 
@@ -2406,7 +3040,8 @@ static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
        msg.address_lo |= MSI_ADDR_DEST_ID(dest);
 
        write_msi_msg(irq, &msg);
-       irq_desc[irq].affinity = mask;
+       desc = irq_to_desc(irq);
+       desc->affinity = mask;
 }
 
 #ifdef CONFIG_INTR_REMAP
@@ -2416,10 +3051,11 @@ static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
  */
 static void ir_set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
 {
-       struct irq_cfg *cfg = irq_cfg + irq;
+       struct irq_cfg *cfg;
        unsigned int dest;
        cpumask_t tmp, cleanup_mask;
        struct irte irte;
+       struct irq_desc *desc;
 
        cpus_and(tmp, mask, cpu_online_map);
        if (cpus_empty(tmp))
@@ -2431,6 +3067,7 @@ static void ir_set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
        if (assign_irq_vector(irq, mask))
                return;
 
+       cfg = irq_cfg(irq);
        cpus_and(tmp, cfg->domain, mask);
        dest = cpu_mask_to_apicid(tmp);
 
@@ -2454,7 +3091,8 @@ static void ir_set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
                cfg->move_in_progress = 0;
        }
 
-       irq_desc[irq].affinity = mask;
+       desc = irq_to_desc(irq);
+       desc->affinity = mask;
 }
 #endif
 #endif /* CONFIG_SMP */
@@ -2507,7 +3145,7 @@ static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec)
        if (index < 0) {
                printk(KERN_ERR
                       "Unable to allocate %d IRTE for PCI %s\n", nvec,
-                       pci_name(dev));
+                      pci_name(dev));
                return -ENOSPC;
        }
        return index;
@@ -2528,7 +3166,7 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc, int irq)
 
 #ifdef CONFIG_INTR_REMAP
        if (irq_remapped(irq)) {
-               struct irq_desc *desc = irq_desc + irq;
+               struct irq_desc *desc = irq_to_desc(irq);
                /*
                 * irq migration in process context
                 */
@@ -2538,16 +3176,34 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc, int irq)
 #endif
                set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge");
 
+       dev_printk(KERN_DEBUG, &dev->dev, "irq %d for MSI/MSI-X\n", irq);
+
        return 0;
 }
 
+static unsigned int build_irq_for_pci_dev(struct pci_dev *dev)
+{
+       unsigned int irq;
+
+       irq = dev->bus->number;
+       irq <<= 8;
+       irq |= dev->devfn;
+       irq <<= 12;
+
+       return irq;
+}
+
 int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
 {
-       int irq, ret;
+       unsigned int irq;
+       int ret;
+       unsigned int irq_want;
 
-       irq = create_irq();
-       if (irq < 0)
-               return irq;
+       irq_want = build_irq_for_pci_dev(dev) + 0x100;
+
+       irq = create_irq_nr(irq_want);
+       if (irq == 0)
+               return -1;
 
 #ifdef CONFIG_INTR_REMAP
        if (!intr_remapping_enabled)
@@ -2574,18 +3230,22 @@ error:
 
 int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 {
-       int irq, ret, sub_handle;
+       unsigned int irq;
+       int ret, sub_handle;
        struct msi_desc *desc;
+       unsigned int irq_want;
+
 #ifdef CONFIG_INTR_REMAP
        struct intel_iommu *iommu = 0;
        int index = 0;
 #endif
 
+       irq_want = build_irq_for_pci_dev(dev) + 0x100;
        sub_handle = 0;
        list_for_each_entry(desc, &dev->msi_list, list) {
-               irq = create_irq();
-               if (irq < 0)
-                       return irq;
+               irq = create_irq_nr(irq_want--);
+               if (irq == 0)
+                       return -1;
 #ifdef CONFIG_INTR_REMAP
                if (!intr_remapping_enabled)
                        goto no_ir;
@@ -2636,10 +3296,11 @@ void arch_teardown_msi_irq(unsigned int irq)
 #ifdef CONFIG_SMP
 static void dmar_msi_set_affinity(unsigned int irq, cpumask_t mask)
 {
-       struct irq_cfg *cfg = irq_cfg + irq;
+       struct irq_cfg *cfg;
        struct msi_msg msg;
        unsigned int dest;
        cpumask_t tmp;
+       struct irq_desc *desc;
 
        cpus_and(tmp, mask, cpu_online_map);
        if (cpus_empty(tmp))
@@ -2648,6 +3309,7 @@ static void dmar_msi_set_affinity(unsigned int irq, cpumask_t mask)
        if (assign_irq_vector(irq, mask))
                return;
 
+       cfg = irq_cfg(irq);
        cpus_and(tmp, cfg->domain, mask);
        dest = cpu_mask_to_apicid(tmp);
 
@@ -2659,7 +3321,8 @@ static void dmar_msi_set_affinity(unsigned int irq, cpumask_t mask)
        msg.address_lo |= MSI_ADDR_DEST_ID(dest);
 
        dmar_msi_write(irq, &msg);
-       irq_desc[irq].affinity = mask;
+       desc = irq_to_desc(irq);
+       desc->affinity = mask;
 }
 #endif /* CONFIG_SMP */
 
@@ -2689,6 +3352,69 @@ int arch_setup_dmar_msi(unsigned int irq)
 }
 #endif
 
+#ifdef CONFIG_HPET_TIMER
+
+#ifdef CONFIG_SMP
+static void hpet_msi_set_affinity(unsigned int irq, cpumask_t mask)
+{
+       struct irq_cfg *cfg;
+       struct irq_desc *desc;
+       struct msi_msg msg;
+       unsigned int dest;
+       cpumask_t tmp;
+
+       cpus_and(tmp, mask, cpu_online_map);
+       if (cpus_empty(tmp))
+               return;
+
+       if (assign_irq_vector(irq, mask))
+               return;
+
+       cfg = irq_cfg(irq);
+       cpus_and(tmp, cfg->domain, mask);
+       dest = cpu_mask_to_apicid(tmp);
+
+       hpet_msi_read(irq, &msg);
+
+       msg.data &= ~MSI_DATA_VECTOR_MASK;
+       msg.data |= MSI_DATA_VECTOR(cfg->vector);
+       msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
+       msg.address_lo |= MSI_ADDR_DEST_ID(dest);
+
+       hpet_msi_write(irq, &msg);
+       desc = irq_to_desc(irq);
+       desc->affinity = mask;
+}
+#endif /* CONFIG_SMP */
+
+struct irq_chip hpet_msi_type = {
+       .name = "HPET_MSI",
+       .unmask = hpet_msi_unmask,
+       .mask = hpet_msi_mask,
+       .ack = ack_apic_edge,
+#ifdef CONFIG_SMP
+       .set_affinity = hpet_msi_set_affinity,
+#endif
+       .retrigger = ioapic_retrigger_irq,
+};
+
+int arch_setup_hpet_msi(unsigned int irq)
+{
+       int ret;
+       struct msi_msg msg;
+
+       ret = msi_compose_msg(NULL, irq, &msg);
+       if (ret < 0)
+               return ret;
+
+       hpet_msi_write(irq, &msg);
+       set_irq_chip_and_handler_name(irq, &hpet_msi_type, handle_edge_irq,
+               "edge");
+
+       return 0;
+}
+#endif
+
 #endif /* CONFIG_PCI_MSI */
 /*
  * Hypertransport interrupt support
@@ -2713,9 +3439,10 @@ static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector)
 
 static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
 {
-       struct irq_cfg *cfg = irq_cfg + irq;
+       struct irq_cfg *cfg;
        unsigned int dest;
        cpumask_t tmp;
+       struct irq_desc *desc;
 
        cpus_and(tmp, mask, cpu_online_map);
        if (cpus_empty(tmp))
@@ -2724,11 +3451,13 @@ static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
        if (assign_irq_vector(irq, mask))
                return;
 
+       cfg = irq_cfg(irq);
        cpus_and(tmp, cfg->domain, mask);
        dest = cpu_mask_to_apicid(tmp);
 
        target_ht_irq(irq, dest, cfg->vector);
-       irq_desc[irq].affinity = mask;
+       desc = irq_to_desc(irq);
+       desc->affinity = mask;
 }
 #endif
 
@@ -2745,7 +3474,7 @@ static struct irq_chip ht_irq_chip = {
 
 int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
 {
-       struct irq_cfg *cfg = irq_cfg + irq;
+       struct irq_cfg *cfg;
        int err;
        cpumask_t tmp;
 
@@ -2755,6 +3484,7 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
                struct ht_irq_msg msg;
                unsigned dest;
 
+               cfg = irq_cfg(irq);
                cpus_and(tmp, cfg->domain, tmp);
                dest = cpu_mask_to_apicid(tmp);
 
@@ -2777,20 +3507,196 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
 
                set_irq_chip_and_handler_name(irq, &ht_irq_chip,
                                              handle_edge_irq, "edge");
+
+               dev_printk(KERN_DEBUG, &dev->dev, "irq %d for HT\n", irq);
        }
        return err;
 }
 #endif /* CONFIG_HT_IRQ */
 
+#ifdef CONFIG_X86_64
+/*
+ * Re-target the irq to the specified CPU and enable the specified MMR located
+ * on the specified blade to allow the sending of MSIs to the specified CPU.
+ */
+int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
+                      unsigned long mmr_offset)
+{
+       const cpumask_t *eligible_cpu = get_cpu_mask(cpu);
+       struct irq_cfg *cfg;
+       int mmr_pnode;
+       unsigned long mmr_value;
+       struct uv_IO_APIC_route_entry *entry;
+       unsigned long flags;
+       int err;
+
+       err = assign_irq_vector(irq, *eligible_cpu);
+       if (err != 0)
+               return err;
+
+       spin_lock_irqsave(&vector_lock, flags);
+       set_irq_chip_and_handler_name(irq, &uv_irq_chip, handle_percpu_irq,
+                                     irq_name);
+       spin_unlock_irqrestore(&vector_lock, flags);
+
+       cfg = irq_cfg(irq);
+
+       mmr_value = 0;
+       entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
+       BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
+
+       entry->vector = cfg->vector;
+       entry->delivery_mode = INT_DELIVERY_MODE;
+       entry->dest_mode = INT_DEST_MODE;
+       entry->polarity = 0;
+       entry->trigger = 0;
+       entry->mask = 0;
+       entry->dest = cpu_mask_to_apicid(*eligible_cpu);
+
+       mmr_pnode = uv_blade_to_pnode(mmr_blade);
+       uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
+
+       return irq;
+}
+
+/*
+ * Disable the specified MMR located on the specified blade so that MSIs are
+ * longer allowed to be sent.
+ */
+void arch_disable_uv_irq(int mmr_blade, unsigned long mmr_offset)
+{
+       unsigned long mmr_value;
+       struct uv_IO_APIC_route_entry *entry;
+       int mmr_pnode;
+
+       mmr_value = 0;
+       entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
+       BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
+
+       entry->mask = 1;
+
+       mmr_pnode = uv_blade_to_pnode(mmr_blade);
+       uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
+}
+#endif /* CONFIG_X86_64 */
+
+int __init io_apic_get_redir_entries (int ioapic)
+{
+       union IO_APIC_reg_01    reg_01;
+       unsigned long flags;
+
+       spin_lock_irqsave(&ioapic_lock, flags);
+       reg_01.raw = io_apic_read(ioapic, 1);
+       spin_unlock_irqrestore(&ioapic_lock, flags);
+
+       return reg_01.bits.entries;
+}
+
+int __init probe_nr_irqs(void)
+{
+       int idx;
+       int nr = 0;
+#ifndef CONFIG_XEN
+       int nr_min = 32;
+#else
+       int nr_min = NR_IRQS;
+#endif
+
+       for (idx = 0; idx < nr_ioapics; idx++)
+               nr += io_apic_get_redir_entries(idx) + 1;
+
+       /* double it for hotplug and msi and nmi */
+       nr <<= 1;
+
+       /* something wrong ? */
+       if (nr < nr_min)
+               nr = nr_min;
+
+       return nr;
+}
+
 /* --------------------------------------------------------------------------
                           ACPI-based IOAPIC Configuration
    -------------------------------------------------------------------------- */
 
 #ifdef CONFIG_ACPI
 
-#define IO_APIC_MAX_ID         0xFE
+#ifdef CONFIG_X86_32
+int __init io_apic_get_unique_id(int ioapic, int apic_id)
+{
+       union IO_APIC_reg_00 reg_00;
+       static physid_mask_t apic_id_map = PHYSID_MASK_NONE;
+       physid_mask_t tmp;
+       unsigned long flags;
+       int i = 0;
+
+       /*
+        * The P4 platform supports up to 256 APIC IDs on two separate APIC
+        * buses (one for LAPICs, one for IOAPICs), where predecessors only
+        * supports up to 16 on one shared APIC bus.
+        *
+        * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full
+        *      advantage of new APIC bus architecture.
+        */
+
+       if (physids_empty(apic_id_map))
+               apic_id_map = ioapic_phys_id_map(phys_cpu_present_map);
 
-int __init io_apic_get_redir_entries (int ioapic)
+       spin_lock_irqsave(&ioapic_lock, flags);
+       reg_00.raw = io_apic_read(ioapic, 0);
+       spin_unlock_irqrestore(&ioapic_lock, flags);
+
+       if (apic_id >= get_physical_broadcast()) {
+               printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying "
+                       "%d\n", ioapic, apic_id, reg_00.bits.ID);
+               apic_id = reg_00.bits.ID;
+       }
+
+       /*
+        * Every APIC in a system must have a unique ID or we get lots of nice
+        * 'stuck on smp_invalidate_needed IPI wait' messages.
+        */
+       if (check_apicid_used(apic_id_map, apic_id)) {
+
+               for (i = 0; i < get_physical_broadcast(); i++) {
+                       if (!check_apicid_used(apic_id_map, i))
+                               break;
+               }
+
+               if (i == get_physical_broadcast())
+                       panic("Max apic_id exceeded!\n");
+
+               printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, "
+                       "trying %d\n", ioapic, apic_id, i);
+
+               apic_id = i;
+       }
+
+       tmp = apicid_to_cpu_present(apic_id);
+       physids_or(apic_id_map, apic_id_map, tmp);
+
+       if (reg_00.bits.ID != apic_id) {
+               reg_00.bits.ID = apic_id;
+
+               spin_lock_irqsave(&ioapic_lock, flags);
+               io_apic_write(ioapic, 0, reg_00.raw);
+               reg_00.raw = io_apic_read(ioapic, 0);
+               spin_unlock_irqrestore(&ioapic_lock, flags);
+
+               /* Sanity check */
+               if (reg_00.bits.ID != apic_id) {
+                       printk("IOAPIC[%d]: Unable to change apic_id!\n", ioapic);
+                       return -1;
+               }
+       }
+
+       apic_printk(APIC_VERBOSE, KERN_INFO
+                       "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id);
+
+       return apic_id;
+}
+
+int __init io_apic_get_version(int ioapic)
 {
        union IO_APIC_reg_01    reg_01;
        unsigned long flags;
@@ -2799,9 +3705,9 @@ int __init io_apic_get_redir_entries (int ioapic)
        reg_01.raw = io_apic_read(ioapic, 1);
        spin_unlock_irqrestore(&ioapic_lock, flags);
 
-       return reg_01.bits.entries;
+       return reg_01.bits.version;
 }
-
+#endif
 
 int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int polarity)
 {
@@ -2853,6 +3759,7 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
 void __init setup_ioapic_dest(void)
 {
        int pin, ioapic, irq, irq_entry;
+       struct irq_cfg *cfg;
 
        if (skip_ioapic_setup == 1)
                return;
@@ -2868,7 +3775,8 @@ void __init setup_ioapic_dest(void)
                         * when you have too many devices, because at that time only boot
                         * cpu is online.
                         */
-                       if (!irq_cfg[irq].vector)
+                       cfg = irq_cfg(irq);
+                       if (!cfg->vector)
                                setup_IO_APIC_irq(ioapic, pin, irq,
                                                  irq_trigger(irq_entry),
                                                  irq_polarity(irq_entry));
@@ -2926,18 +3834,33 @@ void __init ioapic_init_mappings(void)
        struct resource *ioapic_res;
        int i;
 
+       irq_2_pin_init();
        ioapic_res = ioapic_setup_resources();
        for (i = 0; i < nr_ioapics; i++) {
                if (smp_found_config) {
                        ioapic_phys = mp_ioapics[i].mp_apicaddr;
+#ifdef CONFIG_X86_32
+                       if (!ioapic_phys) {
+                               printk(KERN_ERR
+                                      "WARNING: bogus zero IO-APIC "
+                                      "address found in MPTABLE, "
+                                      "disabling IO/APIC support!\n");
+                               smp_found_config = 0;
+                               skip_ioapic_setup = 1;
+                               goto fake_ioapic_page;
+                       }
+#endif
                } else {
+#ifdef CONFIG_X86_32
+fake_ioapic_page:
+#endif
                        ioapic_phys = (unsigned long)
                                alloc_bootmem_pages(PAGE_SIZE);
                        ioapic_phys = __pa(ioapic_phys);
                }
                set_fixmap_nocache(idx, ioapic_phys);
                apic_printk(APIC_VERBOSE,
-                           "mapped IOAPIC to %016lx (%016lx)\n",
+                           "mapped IOAPIC to %08lx (%08lx)\n",
                            __fix_to_virt(idx), ioapic_phys);
                idx++;
 
@@ -2971,4 +3894,3 @@ static int __init ioapic_insert_resources(void)
 /* Insert the IO APIC resources after PCI initialization has occured to handle
  * IO APICS that are mapped in on a BAR in PCI space. */
 late_initcall(ioapic_insert_resources);
-
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c
deleted file mode 100644 (file)
index e710289..0000000
+++ /dev/null
@@ -1,2908 +0,0 @@
-/*
- *     Intel IO-APIC support for multi-Pentium hosts.
- *
- *     Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar, Hajnalka Szabo
- *
- *     Many thanks to Stig Venaas for trying out countless experimental
- *     patches and reporting/debugging problems patiently!
- *
- *     (c) 1999, Multiple IO-APIC support, developed by
- *     Ken-ichi Yaku <yaku@css1.kbnes.nec.co.jp> and
- *      Hidemi Kishimoto <kisimoto@css1.kbnes.nec.co.jp>,
- *     further tested and cleaned up by Zach Brown <zab@redhat.com>
- *     and Ingo Molnar <mingo@redhat.com>
- *
- *     Fixes
- *     Maciej W. Rozycki       :       Bits for genuine 82489DX APICs;
- *                                     thanks to Eric Gilmore
- *                                     and Rolf G. Tews
- *                                     for testing these extensively
- *     Paul Diefenbaugh        :       Added full ACPI support
- */
-
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/bootmem.h>
-#include <linux/mc146818rtc.h>
-#include <linux/compiler.h>
-#include <linux/acpi.h>
-#include <linux/module.h>
-#include <linux/sysdev.h>
-#include <linux/pci.h>
-#include <linux/msi.h>
-#include <linux/htirq.h>
-#include <linux/freezer.h>
-#include <linux/kthread.h>
-#include <linux/jiffies.h>     /* time_after() */
-
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/desc.h>
-#include <asm/timer.h>
-#include <asm/i8259.h>
-#include <asm/nmi.h>
-#include <asm/msidef.h>
-#include <asm/hypertransport.h>
-#include <asm/setup.h>
-
-#include <mach_apic.h>
-#include <mach_apicdef.h>
-
-#define __apicdebuginit(type) static type __init
-
-int (*ioapic_renumber_irq)(int ioapic, int irq);
-atomic_t irq_mis_count;
-
-/* Where if anywhere is the i8259 connect in external int mode */
-static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
-
-static DEFINE_SPINLOCK(ioapic_lock);
-DEFINE_SPINLOCK(vector_lock);
-
-int timer_through_8259 __initdata;
-
-/*
- *     Is the SiS APIC rmw bug present ?
- *     -1 = don't know, 0 = no, 1 = yes
- */
-int sis_apic_bug = -1;
-
-/*
- * # of IRQ routing registers
- */
-int nr_ioapic_registers[MAX_IO_APICS];
-
-/* I/O APIC entries */
-struct mp_config_ioapic mp_ioapics[MAX_IO_APICS];
-int nr_ioapics;
-
-/* MP IRQ source entries */
-struct mp_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
-
-/* # of MP IRQ source entries */
-int mp_irq_entries;
-
-#if defined (CONFIG_MCA) || defined (CONFIG_EISA)
-int mp_bus_id_to_type[MAX_MP_BUSSES];
-#endif
-
-DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
-
-static int disable_timer_pin_1 __initdata;
-
-/*
- * Rough estimation of how many shared IRQs there are, can
- * be changed anytime.
- */
-#define MAX_PLUS_SHARED_IRQS NR_IRQS
-#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + NR_IRQS)
-
-/*
- * This is performance-critical, we want to do it O(1)
- *
- * the indexing order of this array favors 1:1 mappings
- * between pins and IRQs.
- */
-
-static struct irq_pin_list {
-       int apic, pin, next;
-} irq_2_pin[PIN_MAP_SIZE];
-
-struct io_apic {
-       unsigned int index;
-       unsigned int unused[3];
-       unsigned int data;
-};
-
-static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx)
-{
-       return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx)
-               + (mp_ioapics[idx].mp_apicaddr & ~PAGE_MASK);
-}
-
-static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
-{
-       struct io_apic __iomem *io_apic = io_apic_base(apic);
-       writel(reg, &io_apic->index);
-       return readl(&io_apic->data);
-}
-
-static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
-{
-       struct io_apic __iomem *io_apic = io_apic_base(apic);
-       writel(reg, &io_apic->index);
-       writel(value, &io_apic->data);
-}
-
-/*
- * Re-write a value: to be used for read-modify-write
- * cycles where the read already set up the index register.
- *
- * Older SiS APIC requires we rewrite the index register
- */
-static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value)
-{
-       volatile struct io_apic __iomem *io_apic = io_apic_base(apic);
-       if (sis_apic_bug)
-               writel(reg, &io_apic->index);
-       writel(value, &io_apic->data);
-}
-
-union entry_union {
-       struct { u32 w1, w2; };
-       struct IO_APIC_route_entry entry;
-};
-
-static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin)
-{
-       union entry_union eu;
-       unsigned long flags;
-       spin_lock_irqsave(&ioapic_lock, flags);
-       eu.w1 = io_apic_read(apic, 0x10 + 2 * pin);
-       eu.w2 = io_apic_read(apic, 0x11 + 2 * pin);
-       spin_unlock_irqrestore(&ioapic_lock, flags);
-       return eu.entry;
-}
-
-/*
- * When we write a new IO APIC routing entry, we need to write the high
- * word first! If the mask bit in the low word is clear, we will enable
- * the interrupt, and we need to make sure the entry is fully populated
- * before that happens.
- */
-static void
-__ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
-{
-       union entry_union eu;
-       eu.entry = e;
-       io_apic_write(apic, 0x11 + 2*pin, eu.w2);
-       io_apic_write(apic, 0x10 + 2*pin, eu.w1);
-}
-
-static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&ioapic_lock, flags);
-       __ioapic_write_entry(apic, pin, e);
-       spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
-/*
- * When we mask an IO APIC routing entry, we need to write the low
- * word first, in order to set the mask bit before we change the
- * high bits!
- */
-static void ioapic_mask_entry(int apic, int pin)
-{
-       unsigned long flags;
-       union entry_union eu = { .entry.mask = 1 };
-
-       spin_lock_irqsave(&ioapic_lock, flags);
-       io_apic_write(apic, 0x10 + 2*pin, eu.w1);
-       io_apic_write(apic, 0x11 + 2*pin, eu.w2);
-       spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
-/*
- * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
- * shared ISA-space IRQs, so we have to support them. We are super
- * fast in the common case, and fast for shared ISA-space IRQs.
- */
-static void add_pin_to_irq(unsigned int irq, int apic, int pin)
-{
-       static int first_free_entry = NR_IRQS;
-       struct irq_pin_list *entry = irq_2_pin + irq;
-
-       while (entry->next)
-               entry = irq_2_pin + entry->next;
-
-       if (entry->pin != -1) {
-               entry->next = first_free_entry;
-               entry = irq_2_pin + entry->next;
-               if (++first_free_entry >= PIN_MAP_SIZE)
-                       panic("io_apic.c: whoops");
-       }
-       entry->apic = apic;
-       entry->pin = pin;
-}
-
-/*
- * Reroute an IRQ to a different pin.
- */
-static void __init replace_pin_at_irq(unsigned int irq,
-                                     int oldapic, int oldpin,
-                                     int newapic, int newpin)
-{
-       struct irq_pin_list *entry = irq_2_pin + irq;
-
-       while (1) {
-               if (entry->apic == oldapic && entry->pin == oldpin) {
-                       entry->apic = newapic;
-                       entry->pin = newpin;
-               }
-               if (!entry->next)
-                       break;
-               entry = irq_2_pin + entry->next;
-       }
-}
-
-static void __modify_IO_APIC_irq(unsigned int irq, unsigned long enable, unsigned long disable)
-{
-       struct irq_pin_list *entry = irq_2_pin + irq;
-       unsigned int pin, reg;
-
-       for (;;) {
-               pin = entry->pin;
-               if (pin == -1)
-                       break;
-               reg = io_apic_read(entry->apic, 0x10 + pin*2);
-               reg &= ~disable;
-               reg |= enable;
-               io_apic_modify(entry->apic, 0x10 + pin*2, reg);
-               if (!entry->next)
-                       break;
-               entry = irq_2_pin + entry->next;
-       }
-}
-
-/* mask = 1 */
-static void __mask_IO_APIC_irq(unsigned int irq)
-{
-       __modify_IO_APIC_irq(irq, IO_APIC_REDIR_MASKED, 0);
-}
-
-/* mask = 0 */
-static void __unmask_IO_APIC_irq(unsigned int irq)
-{
-       __modify_IO_APIC_irq(irq, 0, IO_APIC_REDIR_MASKED);
-}
-
-/* mask = 1, trigger = 0 */
-static void __mask_and_edge_IO_APIC_irq(unsigned int irq)
-{
-       __modify_IO_APIC_irq(irq, IO_APIC_REDIR_MASKED,
-                               IO_APIC_REDIR_LEVEL_TRIGGER);
-}
-
-/* mask = 0, trigger = 1 */
-static void __unmask_and_level_IO_APIC_irq(unsigned int irq)
-{
-       __modify_IO_APIC_irq(irq, IO_APIC_REDIR_LEVEL_TRIGGER,
-                               IO_APIC_REDIR_MASKED);
-}
-
-static void mask_IO_APIC_irq(unsigned int irq)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&ioapic_lock, flags);
-       __mask_IO_APIC_irq(irq);
-       spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
-static void unmask_IO_APIC_irq(unsigned int irq)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&ioapic_lock, flags);
-       __unmask_IO_APIC_irq(irq);
-       spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
-static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
-{
-       struct IO_APIC_route_entry entry;
-
-       /* Check delivery_mode to be sure we're not clearing an SMI pin */
-       entry = ioapic_read_entry(apic, pin);
-       if (entry.delivery_mode == dest_SMI)
-               return;
-
-       /*
-        * Disable it in the IO-APIC irq-routing table:
-        */
-       ioapic_mask_entry(apic, pin);
-}
-
-static void clear_IO_APIC(void)
-{
-       int apic, pin;
-
-       for (apic = 0; apic < nr_ioapics; apic++)
-               for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
-                       clear_IO_APIC_pin(apic, pin);
-}
-
-#ifdef CONFIG_SMP
-static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask)
-{
-       unsigned long flags;
-       int pin;
-       struct irq_pin_list *entry = irq_2_pin + irq;
-       unsigned int apicid_value;
-       cpumask_t tmp;
-
-       cpus_and(tmp, cpumask, cpu_online_map);
-       if (cpus_empty(tmp))
-               tmp = TARGET_CPUS;
-
-       cpus_and(cpumask, tmp, CPU_MASK_ALL);
-
-       apicid_value = cpu_mask_to_apicid(cpumask);
-       /* Prepare to do the io_apic_write */
-       apicid_value = apicid_value << 24;
-       spin_lock_irqsave(&ioapic_lock, flags);
-       for (;;) {
-               pin = entry->pin;
-               if (pin == -1)
-                       break;
-               io_apic_write(entry->apic, 0x10 + 1 + pin*2, apicid_value);
-               if (!entry->next)
-                       break;
-               entry = irq_2_pin + entry->next;
-       }
-       irq_desc[irq].affinity = cpumask;
-       spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
-#if defined(CONFIG_IRQBALANCE)
-# include <asm/processor.h>    /* kernel_thread() */
-# include <linux/kernel_stat.h>        /* kstat */
-# include <linux/slab.h>               /* kmalloc() */
-# include <linux/timer.h>
-
-#define IRQBALANCE_CHECK_ARCH -999
-#define MAX_BALANCED_IRQ_INTERVAL      (5*HZ)
-#define MIN_BALANCED_IRQ_INTERVAL      (HZ/2)
-#define BALANCED_IRQ_MORE_DELTA                (HZ/10)
-#define BALANCED_IRQ_LESS_DELTA                (HZ)
-
-static int irqbalance_disabled __read_mostly = IRQBALANCE_CHECK_ARCH;
-static int physical_balance __read_mostly;
-static long balanced_irq_interval __read_mostly = MAX_BALANCED_IRQ_INTERVAL;
-
-static struct irq_cpu_info {
-       unsigned long *last_irq;
-       unsigned long *irq_delta;
-       unsigned long irq;
-} irq_cpu_data[NR_CPUS];
-
-#define CPU_IRQ(cpu)           (irq_cpu_data[cpu].irq)
-#define LAST_CPU_IRQ(cpu, irq)   (irq_cpu_data[cpu].last_irq[irq])
-#define IRQ_DELTA(cpu, irq)    (irq_cpu_data[cpu].irq_delta[irq])
-
-#define IDLE_ENOUGH(cpu,now) \
-       (idle_cpu(cpu) && ((now) - per_cpu(irq_stat, (cpu)).idle_timestamp > 1))
-
-#define IRQ_ALLOWED(cpu, allowed_mask) cpu_isset(cpu, allowed_mask)
-
-#define CPU_TO_PACKAGEINDEX(i) (first_cpu(per_cpu(cpu_sibling_map, i)))
-
-static cpumask_t balance_irq_affinity[NR_IRQS] = {
-       [0 ... NR_IRQS-1] = CPU_MASK_ALL
-};
-
-void set_balance_irq_affinity(unsigned int irq, cpumask_t mask)
-{
-       balance_irq_affinity[irq] = mask;
-}
-
-static unsigned long move(int curr_cpu, cpumask_t allowed_mask,
-                       unsigned long now, int direction)
-{
-       int search_idle = 1;
-       int cpu = curr_cpu;
-
-       goto inside;
-
-       do {
-               if (unlikely(cpu == curr_cpu))
-                       search_idle = 0;
-inside:
-               if (direction == 1) {
-                       cpu++;
-                       if (cpu >= NR_CPUS)
-                               cpu = 0;
-               } else {
-                       cpu--;
-                       if (cpu == -1)
-                               cpu = NR_CPUS-1;
-               }
-       } while (!cpu_online(cpu) || !IRQ_ALLOWED(cpu, allowed_mask) ||
-                       (search_idle && !IDLE_ENOUGH(cpu, now)));
-
-       return cpu;
-}
-
-static inline void balance_irq(int cpu, int irq)
-{
-       unsigned long now = jiffies;
-       cpumask_t allowed_mask;
-       unsigned int new_cpu;
-
-       if (irqbalance_disabled)
-               return;
-
-       cpus_and(allowed_mask, cpu_online_map, balance_irq_affinity[irq]);
-       new_cpu = move(cpu, allowed_mask, now, 1);
-       if (cpu != new_cpu)
-               set_pending_irq(irq, cpumask_of_cpu(new_cpu));
-}
-
-static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold)
-{
-       int i, j;
-
-       for_each_online_cpu(i) {
-               for (j = 0; j < NR_IRQS; j++) {
-                       if (!irq_desc[j].action)
-                               continue;
-                       /* Is it a significant load ?  */
-                       if (IRQ_DELTA(CPU_TO_PACKAGEINDEX(i), j) <
-                                               useful_load_threshold)
-                               continue;
-                       balance_irq(i, j);
-               }
-       }
-       balanced_irq_interval = max((long)MIN_BALANCED_IRQ_INTERVAL,
-               balanced_irq_interval - BALANCED_IRQ_LESS_DELTA);
-       return;
-}
-
-static void do_irq_balance(void)
-{
-       int i, j;
-       unsigned long max_cpu_irq = 0, min_cpu_irq = (~0);
-       unsigned long move_this_load = 0;
-       int max_loaded = 0, min_loaded = 0;
-       int load;
-       unsigned long useful_load_threshold = balanced_irq_interval + 10;
-       int selected_irq;
-       int tmp_loaded, first_attempt = 1;
-       unsigned long tmp_cpu_irq;
-       unsigned long imbalance = 0;
-       cpumask_t allowed_mask, target_cpu_mask, tmp;
-
-       for_each_possible_cpu(i) {
-               int package_index;
-               CPU_IRQ(i) = 0;
-               if (!cpu_online(i))
-                       continue;
-               package_index = CPU_TO_PACKAGEINDEX(i);
-               for (j = 0; j < NR_IRQS; j++) {
-                       unsigned long value_now, delta;
-                       /* Is this an active IRQ or balancing disabled ? */
-                       if (!irq_desc[j].action || irq_balancing_disabled(j))
-                               continue;
-                       if (package_index == i)
-                               IRQ_DELTA(package_index, j) = 0;
-                       /* Determine the total count per processor per IRQ */
-                       value_now = (unsigned long) kstat_cpu(i).irqs[j];
-
-                       /* Determine the activity per processor per IRQ */
-                       delta = value_now - LAST_CPU_IRQ(i, j);
-
-                       /* Update last_cpu_irq[][] for the next time */
-                       LAST_CPU_IRQ(i, j) = value_now;
-
-                       /* Ignore IRQs whose rate is less than the clock */
-                       if (delta < useful_load_threshold)
-                               continue;
-                       /* update the load for the processor or package total */
-                       IRQ_DELTA(package_index, j) += delta;
-
-                       /* Keep track of the higher numbered sibling as well */
-                       if (i != package_index)
-                               CPU_IRQ(i) += delta;
-                       /*
-                        * We have sibling A and sibling B in the package
-                        *
-                        * cpu_irq[A] = load for cpu A + load for cpu B
-                        * cpu_irq[B] = load for cpu B
-                        */
-                       CPU_IRQ(package_index) += delta;
-               }
-       }
-       /* Find the least loaded processor package */
-       for_each_online_cpu(i) {
-               if (i != CPU_TO_PACKAGEINDEX(i))
-                       continue;
-               if (min_cpu_irq > CPU_IRQ(i)) {
-                       min_cpu_irq = CPU_IRQ(i);
-                       min_loaded = i;
-               }
-       }
-       max_cpu_irq = ULONG_MAX;
-
-tryanothercpu:
-       /*
-        * Look for heaviest loaded processor.
-        * We may come back to get the next heaviest loaded processor.
-        * Skip processors with trivial loads.
-        */
-       tmp_cpu_irq = 0;
-       tmp_loaded = -1;
-       for_each_online_cpu(i) {
-               if (i != CPU_TO_PACKAGEINDEX(i))
-                       continue;
-               if (max_cpu_irq <= CPU_IRQ(i))
-                       continue;
-               if (tmp_cpu_irq < CPU_IRQ(i)) {
-                       tmp_cpu_irq = CPU_IRQ(i);
-                       tmp_loaded = i;
-               }
-       }
-
-       if (tmp_loaded == -1) {
-        /*
-         * In the case of small number of heavy interrupt sources,
-         * loading some of the cpus too much. We use Ingo's original
-         * approach to rotate them around.
-         */
-               if (!first_attempt && imbalance >= useful_load_threshold) {
-                       rotate_irqs_among_cpus(useful_load_threshold);
-                       return;
-               }
-               goto not_worth_the_effort;
-       }
-
-       first_attempt = 0;              /* heaviest search */
-       max_cpu_irq = tmp_cpu_irq;      /* load */
-       max_loaded = tmp_loaded;        /* processor */
-       imbalance = (max_cpu_irq - min_cpu_irq) / 2;
-
-       /*
-        * if imbalance is less than approx 10% of max load, then
-        * observe diminishing returns action. - quit
-        */
-       if (imbalance < (max_cpu_irq >> 3))
-               goto not_worth_the_effort;
-
-tryanotherirq:
-       /* if we select an IRQ to move that can't go where we want, then
-        * see if there is another one to try.
-        */
-       move_this_load = 0;
-       selected_irq = -1;
-       for (j = 0; j < NR_IRQS; j++) {
-               /* Is this an active IRQ? */
-               if (!irq_desc[j].action)
-                       continue;
-               if (imbalance <= IRQ_DELTA(max_loaded, j))
-                       continue;
-               /* Try to find the IRQ that is closest to the imbalance
-                * without going over.
-                */
-               if (move_this_load < IRQ_DELTA(max_loaded, j)) {
-                       move_this_load = IRQ_DELTA(max_loaded, j);
-                       selected_irq = j;
-               }
-       }
-       if (selected_irq == -1)
-               goto tryanothercpu;
-
-       imbalance = move_this_load;
-
-       /* For physical_balance case, we accumulated both load
-        * values in the one of the siblings cpu_irq[],
-        * to use the same code for physical and logical processors
-        * as much as possible.
-        *
-        * NOTE: the cpu_irq[] array holds the sum of the load for
-        * sibling A and sibling B in the slot for the lowest numbered
-        * sibling (A), _AND_ the load for sibling B in the slot for
-        * the higher numbered sibling.
-        *
-        * We seek the least loaded sibling by making the comparison
-        * (A+B)/2 vs B
-        */
-       load = CPU_IRQ(min_loaded) >> 1;
-       for_each_cpu_mask(j, per_cpu(cpu_sibling_map, min_loaded)) {
-               if (load > CPU_IRQ(j)) {
-                       /* This won't change cpu_sibling_map[min_loaded] */
-                       load = CPU_IRQ(j);
-                       min_loaded = j;
-               }
-       }
-
-       cpus_and(allowed_mask,
-               cpu_online_map,
-               balance_irq_affinity[selected_irq]);
-       target_cpu_mask = cpumask_of_cpu(min_loaded);
-       cpus_and(tmp, target_cpu_mask, allowed_mask);
-
-       if (!cpus_empty(tmp)) {
-               /* mark for change destination */
-               set_pending_irq(selected_irq, cpumask_of_cpu(min_loaded));
-
-               /* Since we made a change, come back sooner to
-                * check for more variation.
-                */
-               balanced_irq_interval = max((long)MIN_BALANCED_IRQ_INTERVAL,
-                       balanced_irq_interval - BALANCED_IRQ_LESS_DELTA);
-               return;
-       }
-       goto tryanotherirq;
-
-not_worth_the_effort:
-       /*
-        * if we did not find an IRQ to move, then adjust the time interval
-        * upward
-        */
-       balanced_irq_interval = min((long)MAX_BALANCED_IRQ_INTERVAL,
-               balanced_irq_interval + BALANCED_IRQ_MORE_DELTA);
-       return;
-}
-
-static int balanced_irq(void *unused)
-{
-       int i;
-       unsigned long prev_balance_time = jiffies;
-       long time_remaining = balanced_irq_interval;
-
-       /* push everything to CPU 0 to give us a starting point.  */
-       for (i = 0 ; i < NR_IRQS ; i++) {
-               irq_desc[i].pending_mask = cpumask_of_cpu(0);
-               set_pending_irq(i, cpumask_of_cpu(0));
-       }
-
-       set_freezable();
-       for ( ; ; ) {
-               time_remaining = schedule_timeout_interruptible(time_remaining);
-               try_to_freeze();
-               if (time_after(jiffies,
-                               prev_balance_time+balanced_irq_interval)) {
-                       preempt_disable();
-                       do_irq_balance();
-                       prev_balance_time = jiffies;
-                       time_remaining = balanced_irq_interval;
-                       preempt_enable();
-               }
-       }
-       return 0;
-}
-
-static int __init balanced_irq_init(void)
-{
-       int i;
-       struct cpuinfo_x86 *c;
-       cpumask_t tmp;
-
-       cpus_shift_right(tmp, cpu_online_map, 2);
-       c = &boot_cpu_data;
-       /* When not overwritten by the command line ask subarchitecture. */
-       if (irqbalance_disabled == IRQBALANCE_CHECK_ARCH)
-               irqbalance_disabled = NO_BALANCE_IRQ;
-       if (irqbalance_disabled)
-               return 0;
-
-        /* disable irqbalance completely if there is only one processor online */
-       if (num_online_cpus() < 2) {
-               irqbalance_disabled = 1;
-               return 0;
-       }
-       /*
-        * Enable physical balance only if more than 1 physical processor
-        * is present
-        */
-       if (smp_num_siblings > 1 && !cpus_empty(tmp))
-               physical_balance = 1;
-
-       for_each_online_cpu(i) {
-               irq_cpu_data[i].irq_delta = kzalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL);
-               irq_cpu_data[i].last_irq = kzalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL);
-               if (irq_cpu_data[i].irq_delta == NULL || irq_cpu_data[i].last_irq == NULL) {
-                       printk(KERN_ERR "balanced_irq_init: out of memory");
-                       goto failed;
-               }
-       }
-
-       printk(KERN_INFO "Starting balanced_irq\n");
-       if (!IS_ERR(kthread_run(balanced_irq, NULL, "kirqd")))
-               return 0;
-       printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq");
-failed:
-       for_each_possible_cpu(i) {
-               kfree(irq_cpu_data[i].irq_delta);
-               irq_cpu_data[i].irq_delta = NULL;
-               kfree(irq_cpu_data[i].last_irq);
-               irq_cpu_data[i].last_irq = NULL;
-       }
-       return 0;
-}
-
-int __devinit irqbalance_disable(char *str)
-{
-       irqbalance_disabled = 1;
-       return 1;
-}
-
-__setup("noirqbalance", irqbalance_disable);
-
-late_initcall(balanced_irq_init);
-#endif /* CONFIG_IRQBALANCE */
-#endif /* CONFIG_SMP */
-
-#ifndef CONFIG_SMP
-void send_IPI_self(int vector)
-{
-       unsigned int cfg;
-
-       /*
-        * Wait for idle.
-        */
-       apic_wait_icr_idle();
-       cfg = APIC_DM_FIXED | APIC_DEST_SELF | vector | APIC_DEST_LOGICAL;
-       /*
-        * Send the IPI. The write to APIC_ICR fires this off.
-        */
-       apic_write(APIC_ICR, cfg);
-}
-#endif /* !CONFIG_SMP */
-
-
-/*
- * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to
- * specific CPU-side IRQs.
- */
-
-#define MAX_PIRQS 8
-static int pirq_entries [MAX_PIRQS];
-static int pirqs_enabled;
-int skip_ioapic_setup;
-
-static int __init ioapic_pirq_setup(char *str)
-{
-       int i, max;
-       int ints[MAX_PIRQS+1];
-
-       get_options(str, ARRAY_SIZE(ints), ints);
-
-       for (i = 0; i < MAX_PIRQS; i++)
-               pirq_entries[i] = -1;
-
-       pirqs_enabled = 1;
-       apic_printk(APIC_VERBOSE, KERN_INFO
-                       "PIRQ redirection, working around broken MP-BIOS.\n");
-       max = MAX_PIRQS;
-       if (ints[0] < MAX_PIRQS)
-               max = ints[0];
-
-       for (i = 0; i < max; i++) {
-               apic_printk(APIC_VERBOSE, KERN_DEBUG
-                               "... PIRQ%d -> IRQ %d\n", i, ints[i+1]);
-               /*
-                * PIRQs are mapped upside down, usually.
-                */
-               pirq_entries[MAX_PIRQS-i-1] = ints[i+1];
-       }
-       return 1;
-}
-
-__setup("pirq=", ioapic_pirq_setup);
-
-/*
- * Find the IRQ entry number of a certain pin.
- */
-static int find_irq_entry(int apic, int pin, int type)
-{
-       int i;
-
-       for (i = 0; i < mp_irq_entries; i++)
-               if (mp_irqs[i].mp_irqtype == type &&
-                   (mp_irqs[i].mp_dstapic == mp_ioapics[apic].mp_apicid ||
-                    mp_irqs[i].mp_dstapic == MP_APIC_ALL) &&
-                   mp_irqs[i].mp_dstirq == pin)
-                       return i;
-
-       return -1;
-}
-
-/*
- * Find the pin to which IRQ[irq] (ISA) is connected
- */
-static int __init find_isa_irq_pin(int irq, int type)
-{
-       int i;
-
-       for (i = 0; i < mp_irq_entries; i++) {
-               int lbus = mp_irqs[i].mp_srcbus;
-
-               if (test_bit(lbus, mp_bus_not_pci) &&
-                   (mp_irqs[i].mp_irqtype == type) &&
-                   (mp_irqs[i].mp_srcbusirq == irq))
-
-                       return mp_irqs[i].mp_dstirq;
-       }
-       return -1;
-}
-
-static int __init find_isa_irq_apic(int irq, int type)
-{
-       int i;
-
-       for (i = 0; i < mp_irq_entries; i++) {
-               int lbus = mp_irqs[i].mp_srcbus;
-
-               if (test_bit(lbus, mp_bus_not_pci) &&
-                   (mp_irqs[i].mp_irqtype == type) &&
-                   (mp_irqs[i].mp_srcbusirq == irq))
-                       break;
-       }
-       if (i < mp_irq_entries) {
-               int apic;
-               for (apic = 0; apic < nr_ioapics; apic++) {
-                       if (mp_ioapics[apic].mp_apicid == mp_irqs[i].mp_dstapic)
-                               return apic;
-               }
-       }
-
-       return -1;
-}
-
-/*
- * Find a specific PCI IRQ entry.
- * Not an __init, possibly needed by modules
- */
-static int pin_2_irq(int idx, int apic, int pin);
-
-int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
-{
-       int apic, i, best_guess = -1;
-
-       apic_printk(APIC_DEBUG, "querying PCI -> IRQ mapping bus:%d, "
-               "slot:%d, pin:%d.\n", bus, slot, pin);
-       if (test_bit(bus, mp_bus_not_pci)) {
-               printk(KERN_WARNING "PCI BIOS passed nonexistent PCI bus %d!\n", bus);
-               return -1;
-       }
-       for (i = 0; i < mp_irq_entries; i++) {
-               int lbus = mp_irqs[i].mp_srcbus;
-
-               for (apic = 0; apic < nr_ioapics; apic++)
-                       if (mp_ioapics[apic].mp_apicid == mp_irqs[i].mp_dstapic ||
-                           mp_irqs[i].mp_dstapic == MP_APIC_ALL)
-                               break;
-
-               if (!test_bit(lbus, mp_bus_not_pci) &&
-                   !mp_irqs[i].mp_irqtype &&
-                   (bus == lbus) &&
-                   (slot == ((mp_irqs[i].mp_srcbusirq >> 2) & 0x1f))) {
-                       int irq = pin_2_irq(i, apic, mp_irqs[i].mp_dstirq);
-
-                       if (!(apic || IO_APIC_IRQ(irq)))
-                               continue;
-
-                       if (pin == (mp_irqs[i].mp_srcbusirq & 3))
-                               return irq;
-                       /*
-                        * Use the first all-but-pin matching entry as a
-                        * best-guess fuzzy result for broken mptables.
-                        */
-                       if (best_guess < 0)
-                               best_guess = irq;
-               }
-       }
-       return best_guess;
-}
-EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
-
-/*
- * This function currently is only a helper for the i386 smp boot process where
- * we need to reprogram the ioredtbls to cater for the cpus which have come online
- * so mask in all cases should simply be TARGET_CPUS
- */
-#ifdef CONFIG_SMP
-void __init setup_ioapic_dest(void)
-{
-       int pin, ioapic, irq, irq_entry;
-
-       if (skip_ioapic_setup == 1)
-               return;
-
-       for (ioapic = 0; ioapic < nr_ioapics; ioapic++) {
-               for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
-                       irq_entry = find_irq_entry(ioapic, pin, mp_INT);
-                       if (irq_entry == -1)
-                               continue;
-                       irq = pin_2_irq(irq_entry, ioapic, pin);
-                       set_ioapic_affinity_irq(irq, TARGET_CPUS);
-               }
-
-       }
-}
-#endif
-
-#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
-/*
- * EISA Edge/Level control register, ELCR
- */
-static int EISA_ELCR(unsigned int irq)
-{
-       if (irq < 16) {
-               unsigned int port = 0x4d0 + (irq >> 3);
-               return (inb(port) >> (irq & 7)) & 1;
-       }
-       apic_printk(APIC_VERBOSE, KERN_INFO
-                       "Broken MPtable reports ISA irq %d\n", irq);
-       return 0;
-}
-#endif
-
-/* ISA interrupts are always polarity zero edge triggered,
- * when listed as conforming in the MP table. */
-
-#define default_ISA_trigger(idx)       (0)
-#define default_ISA_polarity(idx)      (0)
-
-/* EISA interrupts are always polarity zero and can be edge or level
- * trigger depending on the ELCR value.  If an interrupt is listed as
- * EISA conforming in the MP table, that means its trigger type must
- * be read in from the ELCR */
-
-#define default_EISA_trigger(idx)      (EISA_ELCR(mp_irqs[idx].mp_srcbusirq))
-#define default_EISA_polarity(idx)     default_ISA_polarity(idx)
-
-/* PCI interrupts are always polarity one level triggered,
- * when listed as conforming in the MP table. */
-
-#define default_PCI_trigger(idx)       (1)
-#define default_PCI_polarity(idx)      (1)
-
-/* MCA interrupts are always polarity zero level triggered,
- * when listed as conforming in the MP table. */
-
-#define default_MCA_trigger(idx)       (1)
-#define default_MCA_polarity(idx)      default_ISA_polarity(idx)
-
-static int MPBIOS_polarity(int idx)
-{
-       int bus = mp_irqs[idx].mp_srcbus;
-       int polarity;
-
-       /*
-        * Determine IRQ line polarity (high active or low active):
-        */
-       switch (mp_irqs[idx].mp_irqflag & 3) {
-       case 0: /* conforms, ie. bus-type dependent polarity */
-       {
-               polarity = test_bit(bus, mp_bus_not_pci)?
-                       default_ISA_polarity(idx):
-                       default_PCI_polarity(idx);
-               break;
-       }
-       case 1: /* high active */
-       {
-               polarity = 0;
-               break;
-       }
-       case 2: /* reserved */
-       {
-               printk(KERN_WARNING "broken BIOS!!\n");
-               polarity = 1;
-               break;
-       }
-       case 3: /* low active */
-       {
-               polarity = 1;
-               break;
-       }
-       default: /* invalid */
-       {
-               printk(KERN_WARNING "broken BIOS!!\n");
-               polarity = 1;
-               break;
-       }
-       }
-       return polarity;
-}
-
-static int MPBIOS_trigger(int idx)
-{
-       int bus = mp_irqs[idx].mp_srcbus;
-       int trigger;
-
-       /*
-        * Determine IRQ trigger mode (edge or level sensitive):
-        */
-       switch ((mp_irqs[idx].mp_irqflag>>2) & 3) {
-       case 0: /* conforms, ie. bus-type dependent */
-       {
-               trigger = test_bit(bus, mp_bus_not_pci)?
-                               default_ISA_trigger(idx):
-                               default_PCI_trigger(idx);
-#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
-               switch (mp_bus_id_to_type[bus]) {
-               case MP_BUS_ISA: /* ISA pin */
-               {
-                       /* set before the switch */
-                       break;
-               }
-               case MP_BUS_EISA: /* EISA pin */
-               {
-                       trigger = default_EISA_trigger(idx);
-                       break;
-               }
-               case MP_BUS_PCI: /* PCI pin */
-               {
-                       /* set before the switch */
-                       break;
-               }
-               case MP_BUS_MCA: /* MCA pin */
-               {
-                       trigger = default_MCA_trigger(idx);
-                       break;
-               }
-               default:
-               {
-                       printk(KERN_WARNING "broken BIOS!!\n");
-                       trigger = 1;
-                       break;
-               }
-       }
-#endif
-               break;
-       }
-       case 1: /* edge */
-       {
-               trigger = 0;
-               break;
-       }
-       case 2: /* reserved */
-       {
-               printk(KERN_WARNING "broken BIOS!!\n");
-               trigger = 1;
-               break;
-       }
-       case 3: /* level */
-       {
-               trigger = 1;
-               break;
-       }
-       default: /* invalid */
-       {
-               printk(KERN_WARNING "broken BIOS!!\n");
-               trigger = 0;
-               break;
-       }
-       }
-       return trigger;
-}
-
-static inline int irq_polarity(int idx)
-{
-       return MPBIOS_polarity(idx);
-}
-
-static inline int irq_trigger(int idx)
-{
-       return MPBIOS_trigger(idx);
-}
-
-static int pin_2_irq(int idx, int apic, int pin)
-{
-       int irq, i;
-       int bus = mp_irqs[idx].mp_srcbus;
-
-       /*
-        * Debugging check, we are in big trouble if this message pops up!
-        */
-       if (mp_irqs[idx].mp_dstirq != pin)
-               printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n");
-
-       if (test_bit(bus, mp_bus_not_pci))
-               irq = mp_irqs[idx].mp_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);
-       }
-
-       /*
-        * PCI IRQ command line redirection. Yes, limits are hardcoded.
-        */
-       if ((pin >= 16) && (pin <= 23)) {
-               if (pirq_entries[pin-16] != -1) {
-                       if (!pirq_entries[pin-16]) {
-                               apic_printk(APIC_VERBOSE, KERN_DEBUG
-                                               "disabling PIRQ%d\n", pin-16);
-                       } else {
-                               irq = pirq_entries[pin-16];
-                               apic_printk(APIC_VERBOSE, KERN_DEBUG
-                                               "using PIRQ%d -> IRQ %d\n",
-                                               pin-16, irq);
-                       }
-               }
-       }
-       return irq;
-}
-
-static inline int IO_APIC_irq_trigger(int irq)
-{
-       int apic, idx, pin;
-
-       for (apic = 0; apic < nr_ioapics; apic++) {
-               for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
-                       idx = find_irq_entry(apic, pin, mp_INT);
-                       if ((idx != -1) && (irq == pin_2_irq(idx, apic, pin)))
-                               return irq_trigger(idx);
-               }
-       }
-       /*
-        * nonexistent IRQs are edge default
-        */
-       return 0;
-}
-
-/* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
-static u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 };
-
-static int __assign_irq_vector(int irq)
-{
-       static int current_vector = FIRST_DEVICE_VECTOR, current_offset;
-       int vector, offset;
-
-       BUG_ON((unsigned)irq >= NR_IRQ_VECTORS);
-
-       if (irq_vector[irq] > 0)
-               return irq_vector[irq];
-
-       vector = current_vector;
-       offset = current_offset;
-next:
-       vector += 8;
-       if (vector >= first_system_vector) {
-               offset = (offset + 1) % 8;
-               vector = FIRST_DEVICE_VECTOR + offset;
-       }
-       if (vector == current_vector)
-               return -ENOSPC;
-       if (test_and_set_bit(vector, used_vectors))
-               goto next;
-
-       current_vector = vector;
-       current_offset = offset;
-       irq_vector[irq] = vector;
-
-       return vector;
-}
-
-static int assign_irq_vector(int irq)
-{
-       unsigned long flags;
-       int vector;
-
-       spin_lock_irqsave(&vector_lock, flags);
-       vector = __assign_irq_vector(irq);
-       spin_unlock_irqrestore(&vector_lock, flags);
-
-       return vector;
-}
-
-static struct irq_chip ioapic_chip;
-
-#define IOAPIC_AUTO    -1
-#define IOAPIC_EDGE    0
-#define IOAPIC_LEVEL   1
-
-static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
-{
-       if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
-           trigger == IOAPIC_LEVEL) {
-               irq_desc[irq].status |= IRQ_LEVEL;
-               set_irq_chip_and_handler_name(irq, &ioapic_chip,
-                                        handle_fasteoi_irq, "fasteoi");
-       } else {
-               irq_desc[irq].status &= ~IRQ_LEVEL;
-               set_irq_chip_and_handler_name(irq, &ioapic_chip,
-                                        handle_edge_irq, "edge");
-       }
-       set_intr_gate(vector, interrupt[irq]);
-}
-
-static void __init setup_IO_APIC_irqs(void)
-{
-       struct IO_APIC_route_entry entry;
-       int apic, pin, idx, irq, first_notcon = 1, vector;
-
-       apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
-
-       for (apic = 0; apic < nr_ioapics; apic++) {
-       for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
-
-               /*
-                * add it to the IO-APIC irq-routing table:
-                */
-               memset(&entry, 0, sizeof(entry));
-
-               entry.delivery_mode = INT_DELIVERY_MODE;
-               entry.dest_mode = INT_DEST_MODE;
-               entry.mask = 0;                         /* enable IRQ */
-               entry.dest.logical.logical_dest =
-                                       cpu_mask_to_apicid(TARGET_CPUS);
-
-               idx = find_irq_entry(apic, pin, mp_INT);
-               if (idx == -1) {
-                       if (first_notcon) {
-                               apic_printk(APIC_VERBOSE, KERN_DEBUG
-                                               " IO-APIC (apicid-pin) %d-%d",
-                                               mp_ioapics[apic].mp_apicid,
-                                               pin);
-                               first_notcon = 0;
-                       } else
-                               apic_printk(APIC_VERBOSE, ", %d-%d",
-                                       mp_ioapics[apic].mp_apicid, pin);
-                       continue;
-               }
-
-               if (!first_notcon) {
-                       apic_printk(APIC_VERBOSE, " not connected.\n");
-                       first_notcon = 1;
-               }
-
-               entry.trigger = irq_trigger(idx);
-               entry.polarity = irq_polarity(idx);
-
-               if (irq_trigger(idx)) {
-                       entry.trigger = 1;
-                       entry.mask = 1;
-               }
-
-               irq = pin_2_irq(idx, apic, pin);
-               /*
-                * skip adding the timer int on secondary nodes, which causes
-                * a small but painful rift in the time-space continuum
-                */
-               if (multi_timer_check(apic, irq))
-                       continue;
-               else
-                       add_pin_to_irq(irq, apic, pin);
-
-               if (!apic && !IO_APIC_IRQ(irq))
-                       continue;
-
-               if (IO_APIC_IRQ(irq)) {
-                       vector = assign_irq_vector(irq);
-                       entry.vector = vector;
-                       ioapic_register_intr(irq, vector, IOAPIC_AUTO);
-
-                       if (!apic && (irq < 16))
-                               disable_8259A_irq(irq);
-               }
-               ioapic_write_entry(apic, pin, entry);
-       }
-       }
-
-       if (!first_notcon)
-               apic_printk(APIC_VERBOSE, " not connected.\n");
-}
-
-/*
- * Set up the timer pin, possibly with the 8259A-master behind.
- */
-static void __init setup_timer_IRQ0_pin(unsigned int apic, unsigned int pin,
-                                       int vector)
-{
-       struct IO_APIC_route_entry entry;
-
-       memset(&entry, 0, sizeof(entry));
-
-       /*
-        * We use logical delivery to get the timer IRQ
-        * to the first CPU.
-        */
-       entry.dest_mode = INT_DEST_MODE;
-       entry.mask = 1;                                 /* mask IRQ now */
-       entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
-       entry.delivery_mode = INT_DELIVERY_MODE;
-       entry.polarity = 0;
-       entry.trigger = 0;
-       entry.vector = vector;
-
-       /*
-        * The timer IRQ doesn't have to know that behind the
-        * scene we may have a 8259A-master in AEOI mode ...
-        */
-       ioapic_register_intr(0, vector, IOAPIC_EDGE);
-
-       /*
-        * Add it to the IO-APIC irq-routing table:
-        */
-       ioapic_write_entry(apic, pin, entry);
-}
-
-
-__apicdebuginit(void) print_IO_APIC(void)
-{
-       int apic, i;
-       union IO_APIC_reg_00 reg_00;
-       union IO_APIC_reg_01 reg_01;
-       union IO_APIC_reg_02 reg_02;
-       union IO_APIC_reg_03 reg_03;
-       unsigned long flags;
-
-       if (apic_verbosity == APIC_QUIET)
-               return;
-
-       printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
-       for (i = 0; i < nr_ioapics; i++)
-               printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n",
-                      mp_ioapics[i].mp_apicid, nr_ioapic_registers[i]);
-
-       /*
-        * We are a bit conservative about what we expect.  We have to
-        * know about every hardware change ASAP.
-        */
-       printk(KERN_INFO "testing the IO APIC.......................\n");
-
-       for (apic = 0; apic < nr_ioapics; apic++) {
-
-       spin_lock_irqsave(&ioapic_lock, flags);
-       reg_00.raw = io_apic_read(apic, 0);
-       reg_01.raw = io_apic_read(apic, 1);
-       if (reg_01.bits.version >= 0x10)
-               reg_02.raw = io_apic_read(apic, 2);
-       if (reg_01.bits.version >= 0x20)
-               reg_03.raw = io_apic_read(apic, 3);
-       spin_unlock_irqrestore(&ioapic_lock, flags);
-
-       printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mp_apicid);
-       printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw);
-       printk(KERN_DEBUG ".......    : physical APIC id: %02X\n", reg_00.bits.ID);
-       printk(KERN_DEBUG ".......    : Delivery Type: %X\n", reg_00.bits.delivery_type);
-       printk(KERN_DEBUG ".......    : LTS          : %X\n", reg_00.bits.LTS);
-
-       printk(KERN_DEBUG ".... register #01: %08X\n", reg_01.raw);
-       printk(KERN_DEBUG ".......     : max redirection entries: %04X\n", reg_01.bits.entries);
-
-       printk(KERN_DEBUG ".......     : PRQ implemented: %X\n", reg_01.bits.PRQ);
-       printk(KERN_DEBUG ".......     : IO APIC version: %04X\n", reg_01.bits.version);
-
-       /*
-        * Some Intel chipsets with IO APIC VERSION of 0x1? don't have reg_02,
-        * but the value of reg_02 is read as the previous read register
-        * value, so ignore it if reg_02 == reg_01.
-        */
-       if (reg_01.bits.version >= 0x10 && reg_02.raw != reg_01.raw) {
-               printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw);
-               printk(KERN_DEBUG ".......     : arbitration: %02X\n", reg_02.bits.arbitration);
-       }
-
-       /*
-        * Some Intel chipsets with IO APIC VERSION of 0x2? don't have reg_02
-        * or reg_03, but the value of reg_0[23] is read as the previous read
-        * register value, so ignore it if reg_03 == reg_0[12].
-        */
-       if (reg_01.bits.version >= 0x20 && reg_03.raw != reg_02.raw &&
-           reg_03.raw != reg_01.raw) {
-               printk(KERN_DEBUG ".... register #03: %08X\n", reg_03.raw);
-               printk(KERN_DEBUG ".......     : Boot DT    : %X\n", reg_03.bits.boot_DT);
-       }
-
-       printk(KERN_DEBUG ".... IRQ redirection table:\n");
-
-       printk(KERN_DEBUG " NR Log Phy Mask Trig IRR Pol"
-                         " Stat Dest Deli Vect:   \n");
-
-       for (i = 0; i <= reg_01.bits.entries; i++) {
-               struct IO_APIC_route_entry entry;
-
-               entry = ioapic_read_entry(apic, i);
-
-               printk(KERN_DEBUG " %02x %03X %02X  ",
-                       i,
-                       entry.dest.logical.logical_dest,
-                       entry.dest.physical.physical_dest
-               );
-
-               printk("%1d    %1d    %1d   %1d   %1d    %1d    %1d    %02X\n",
-                       entry.mask,
-                       entry.trigger,
-                       entry.irr,
-                       entry.polarity,
-                       entry.delivery_status,
-                       entry.dest_mode,
-                       entry.delivery_mode,
-                       entry.vector
-               );
-       }
-       }
-       printk(KERN_DEBUG "IRQ to pin mappings:\n");
-       for (i = 0; i < NR_IRQS; i++) {
-               struct irq_pin_list *entry = irq_2_pin + i;
-               if (entry->pin < 0)
-                       continue;
-               printk(KERN_DEBUG "IRQ%d ", i);
-               for (;;) {
-                       printk("-> %d:%d", entry->apic, entry->pin);
-                       if (!entry->next)
-                               break;
-                       entry = irq_2_pin + entry->next;
-               }
-               printk("\n");
-       }
-
-       printk(KERN_INFO ".................................... done.\n");
-
-       return;
-}
-
-__apicdebuginit(void) print_APIC_bitfield(int base)
-{
-       unsigned int v;
-       int i, j;
-
-       if (apic_verbosity == APIC_QUIET)
-               return;
-
-       printk(KERN_DEBUG "0123456789abcdef0123456789abcdef\n" KERN_DEBUG);
-       for (i = 0; i < 8; i++) {
-               v = apic_read(base + i*0x10);
-               for (j = 0; j < 32; j++) {
-                       if (v & (1<<j))
-                               printk("1");
-                       else
-                               printk("0");
-               }
-               printk("\n");
-       }
-}
-
-__apicdebuginit(void) print_local_APIC(void *dummy)
-{
-       unsigned int v, ver, maxlvt;
-       u64 icr;
-
-       if (apic_verbosity == APIC_QUIET)
-               return;
-
-       printk("\n" KERN_DEBUG "printing local APIC contents on CPU#%d/%d:\n",
-               smp_processor_id(), hard_smp_processor_id());
-       v = apic_read(APIC_ID);
-       printk(KERN_INFO "... APIC ID:      %08x (%01x)\n", v,
-                       GET_APIC_ID(v));
-       v = apic_read(APIC_LVR);
-       printk(KERN_INFO "... APIC VERSION: %08x\n", v);
-       ver = GET_APIC_VERSION(v);
-       maxlvt = lapic_get_maxlvt();
-
-       v = apic_read(APIC_TASKPRI);
-       printk(KERN_DEBUG "... APIC TASKPRI: %08x (%02x)\n", v, v & APIC_TPRI_MASK);
-
-       if (APIC_INTEGRATED(ver)) {                     /* !82489DX */
-               v = apic_read(APIC_ARBPRI);
-               printk(KERN_DEBUG "... APIC ARBPRI: %08x (%02x)\n", v,
-                       v & APIC_ARBPRI_MASK);
-               v = apic_read(APIC_PROCPRI);
-               printk(KERN_DEBUG "... APIC PROCPRI: %08x\n", v);
-       }
-
-       v = apic_read(APIC_EOI);
-       printk(KERN_DEBUG "... APIC EOI: %08x\n", v);
-       v = apic_read(APIC_RRR);
-       printk(KERN_DEBUG "... APIC RRR: %08x\n", v);
-       v = apic_read(APIC_LDR);
-       printk(KERN_DEBUG "... APIC LDR: %08x\n", v);
-       v = apic_read(APIC_DFR);
-       printk(KERN_DEBUG "... APIC DFR: %08x\n", v);
-       v = apic_read(APIC_SPIV);
-       printk(KERN_DEBUG "... APIC SPIV: %08x\n", v);
-
-       printk(KERN_DEBUG "... APIC ISR field:\n");
-       print_APIC_bitfield(APIC_ISR);
-       printk(KERN_DEBUG "... APIC TMR field:\n");
-       print_APIC_bitfield(APIC_TMR);
-       printk(KERN_DEBUG "... APIC IRR field:\n");
-       print_APIC_bitfield(APIC_IRR);
-
-       if (APIC_INTEGRATED(ver)) {             /* !82489DX */
-               if (maxlvt > 3)         /* Due to the Pentium erratum 3AP. */
-                       apic_write(APIC_ESR, 0);
-               v = apic_read(APIC_ESR);
-               printk(KERN_DEBUG "... APIC ESR: %08x\n", v);
-       }
-
-       icr = apic_icr_read();
-       printk(KERN_DEBUG "... APIC ICR: %08x\n", icr);
-       printk(KERN_DEBUG "... APIC ICR2: %08x\n", icr >> 32);
-
-       v = apic_read(APIC_LVTT);
-       printk(KERN_DEBUG "... APIC LVTT: %08x\n", v);
-
-       if (maxlvt > 3) {                       /* PC is LVT#4. */
-               v = apic_read(APIC_LVTPC);
-               printk(KERN_DEBUG "... APIC LVTPC: %08x\n", v);
-       }
-       v = apic_read(APIC_LVT0);
-       printk(KERN_DEBUG "... APIC LVT0: %08x\n", v);
-       v = apic_read(APIC_LVT1);
-       printk(KERN_DEBUG "... APIC LVT1: %08x\n", v);
-
-       if (maxlvt > 2) {                       /* ERR is LVT#3. */
-               v = apic_read(APIC_LVTERR);
-               printk(KERN_DEBUG "... APIC LVTERR: %08x\n", v);
-       }
-
-       v = apic_read(APIC_TMICT);
-       printk(KERN_DEBUG "... APIC TMICT: %08x\n", v);
-       v = apic_read(APIC_TMCCT);
-       printk(KERN_DEBUG "... APIC TMCCT: %08x\n", v);
-       v = apic_read(APIC_TDCR);
-       printk(KERN_DEBUG "... APIC TDCR: %08x\n", v);
-       printk("\n");
-}
-
-__apicdebuginit(void) print_all_local_APICs(void)
-{
-       on_each_cpu(print_local_APIC, NULL, 1);
-}
-
-__apicdebuginit(void) print_PIC(void)
-{
-       unsigned int v;
-       unsigned long flags;
-
-       if (apic_verbosity == APIC_QUIET)
-               return;
-
-       printk(KERN_DEBUG "\nprinting PIC contents\n");
-
-       spin_lock_irqsave(&i8259A_lock, flags);
-
-       v = inb(0xa1) << 8 | inb(0x21);
-       printk(KERN_DEBUG "... PIC  IMR: %04x\n", v);
-
-       v = inb(0xa0) << 8 | inb(0x20);
-       printk(KERN_DEBUG "... PIC  IRR: %04x\n", v);
-
-       outb(0x0b, 0xa0);
-       outb(0x0b, 0x20);
-       v = inb(0xa0) << 8 | inb(0x20);
-       outb(0x0a, 0xa0);
-       outb(0x0a, 0x20);
-
-       spin_unlock_irqrestore(&i8259A_lock, flags);
-
-       printk(KERN_DEBUG "... PIC  ISR: %04x\n", v);
-
-       v = inb(0x4d1) << 8 | inb(0x4d0);
-       printk(KERN_DEBUG "... PIC ELCR: %04x\n", v);
-}
-
-__apicdebuginit(int) print_all_ICs(void)
-{
-       print_PIC();
-       print_all_local_APICs();
-       print_IO_APIC();
-
-       return 0;
-}
-
-fs_initcall(print_all_ICs);
-
-
-static void __init enable_IO_APIC(void)
-{
-       union IO_APIC_reg_01 reg_01;
-       int i8259_apic, i8259_pin;
-       int i, apic;
-       unsigned long flags;
-
-       for (i = 0; i < PIN_MAP_SIZE; i++) {
-               irq_2_pin[i].pin = -1;
-               irq_2_pin[i].next = 0;
-       }
-       if (!pirqs_enabled)
-               for (i = 0; i < MAX_PIRQS; i++)
-                       pirq_entries[i] = -1;
-
-       /*
-        * The number of IO-APIC IRQ registers (== #pins):
-        */
-       for (apic = 0; apic < nr_ioapics; apic++) {
-               spin_lock_irqsave(&ioapic_lock, flags);
-               reg_01.raw = io_apic_read(apic, 1);
-               spin_unlock_irqrestore(&ioapic_lock, flags);
-               nr_ioapic_registers[apic] = reg_01.bits.entries+1;
-       }
-       for (apic = 0; apic < nr_ioapics; apic++) {
-               int pin;
-               /* See if any of the pins is in ExtINT mode */
-               for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
-                       struct IO_APIC_route_entry entry;
-                       entry = ioapic_read_entry(apic, pin);
-
-
-                       /* If the interrupt line is enabled and in ExtInt mode
-                        * I have found the pin where the i8259 is connected.
-                        */
-                       if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) {
-                               ioapic_i8259.apic = apic;
-                               ioapic_i8259.pin  = pin;
-                               goto found_i8259;
-                       }
-               }
-       }
- found_i8259:
-       /* Look to see what if the MP table has reported the ExtINT */
-       /* If we could not find the appropriate pin by looking at the ioapic
-        * the i8259 probably is not connected the ioapic but give the
-        * mptable a chance anyway.
-        */
-       i8259_pin  = find_isa_irq_pin(0, mp_ExtINT);
-       i8259_apic = find_isa_irq_apic(0, mp_ExtINT);
-       /* Trust the MP table if nothing is setup in the hardware */
-       if ((ioapic_i8259.pin == -1) && (i8259_pin >= 0)) {
-               printk(KERN_WARNING "ExtINT not setup in hardware but reported by MP table\n");
-               ioapic_i8259.pin  = i8259_pin;
-               ioapic_i8259.apic = i8259_apic;
-       }
-       /* Complain if the MP table and the hardware disagree */
-       if (((ioapic_i8259.apic != i8259_apic) || (ioapic_i8259.pin != i8259_pin)) &&
-               (i8259_pin >= 0) && (ioapic_i8259.pin >= 0))
-       {
-               printk(KERN_WARNING "ExtINT in hardware and MP table differ\n");
-       }
-
-       /*
-        * Do not trust the IO-APIC being empty at bootup
-        */
-       clear_IO_APIC();
-}
-
-/*
- * Not an __init, needed by the reboot code
- */
-void disable_IO_APIC(void)
-{
-       /*
-        * Clear the IO-APIC before rebooting:
-        */
-       clear_IO_APIC();
-
-       /*
-        * If the i8259 is routed through an IOAPIC
-        * Put that IOAPIC in virtual wire mode
-        * so legacy interrupts can be delivered.
-        */
-       if (ioapic_i8259.pin != -1) {
-               struct IO_APIC_route_entry entry;
-
-               memset(&entry, 0, sizeof(entry));
-               entry.mask            = 0; /* Enabled */
-               entry.trigger         = 0; /* Edge */
-               entry.irr             = 0;
-               entry.polarity        = 0; /* High */
-               entry.delivery_status = 0;
-               entry.dest_mode       = 0; /* Physical */
-               entry.delivery_mode   = dest_ExtINT; /* ExtInt */
-               entry.vector          = 0;
-               entry.dest.physical.physical_dest = read_apic_id();
-
-               /*
-                * Add it to the IO-APIC irq-routing table:
-                */
-               ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry);
-       }
-       disconnect_bsp_APIC(ioapic_i8259.pin != -1);
-}
-
-/*
- * function to set the IO-APIC physical IDs based on the
- * values stored in the MPC table.
- *
- * by Matt Domsch <Matt_Domsch@dell.com>  Tue Dec 21 12:25:05 CST 1999
- */
-
-static void __init setup_ioapic_ids_from_mpc(void)
-{
-       union IO_APIC_reg_00 reg_00;
-       physid_mask_t phys_id_present_map;
-       int apic;
-       int i;
-       unsigned char old_id;
-       unsigned long flags;
-
-       if (x86_quirks->setup_ioapic_ids && x86_quirks->setup_ioapic_ids())
-               return;
-
-       /*
-        * Don't check I/O APIC IDs for xAPIC systems.  They have
-        * no meaning without the serial APIC bus.
-        */
-       if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
-               || APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
-               return;
-       /*
-        * This is broken; anything with a real cpu count has to
-        * circumvent this idiocy regardless.
-        */
-       phys_id_present_map = ioapic_phys_id_map(phys_cpu_present_map);
-
-       /*
-        * Set the IOAPIC ID to the value stored in the MPC table.
-        */
-       for (apic = 0; apic < nr_ioapics; apic++) {
-
-               /* Read the register 0 value */
-               spin_lock_irqsave(&ioapic_lock, flags);
-               reg_00.raw = io_apic_read(apic, 0);
-               spin_unlock_irqrestore(&ioapic_lock, flags);
-
-               old_id = mp_ioapics[apic].mp_apicid;
-
-               if (mp_ioapics[apic].mp_apicid >= get_physical_broadcast()) {
-                       printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
-                               apic, mp_ioapics[apic].mp_apicid);
-                       printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
-                               reg_00.bits.ID);
-                       mp_ioapics[apic].mp_apicid = reg_00.bits.ID;
-               }
-
-               /*
-                * Sanity check, is the ID really free? Every APIC in a
-                * system must have a unique ID or we get lots of nice
-                * 'stuck on smp_invalidate_needed IPI wait' messages.
-                */
-               if (check_apicid_used(phys_id_present_map,
-                                       mp_ioapics[apic].mp_apicid)) {
-                       printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
-                               apic, mp_ioapics[apic].mp_apicid);
-                       for (i = 0; i < get_physical_broadcast(); i++)
-                               if (!physid_isset(i, phys_id_present_map))
-                                       break;
-                       if (i >= get_physical_broadcast())
-                               panic("Max APIC ID exceeded!\n");
-                       printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
-                               i);
-                       physid_set(i, phys_id_present_map);
-                       mp_ioapics[apic].mp_apicid = i;
-               } else {
-                       physid_mask_t tmp;
-                       tmp = apicid_to_cpu_present(mp_ioapics[apic].mp_apicid);
-                       apic_printk(APIC_VERBOSE, "Setting %d in the "
-                                       "phys_id_present_map\n",
-                                       mp_ioapics[apic].mp_apicid);
-                       physids_or(phys_id_present_map, phys_id_present_map, tmp);
-               }
-
-
-               /*
-                * We need to adjust the IRQ routing table
-                * if the ID changed.
-                */
-               if (old_id != mp_ioapics[apic].mp_apicid)
-                       for (i = 0; i < mp_irq_entries; i++)
-                               if (mp_irqs[i].mp_dstapic == old_id)
-                                       mp_irqs[i].mp_dstapic
-                                               = mp_ioapics[apic].mp_apicid;
-
-               /*
-                * Read the right value from the MPC table and
-                * write it into the ID register.
-                */
-               apic_printk(APIC_VERBOSE, KERN_INFO
-                       "...changing IO-APIC physical APIC ID to %d ...",
-                       mp_ioapics[apic].mp_apicid);
-
-               reg_00.bits.ID = mp_ioapics[apic].mp_apicid;
-               spin_lock_irqsave(&ioapic_lock, flags);
-               io_apic_write(apic, 0, reg_00.raw);
-               spin_unlock_irqrestore(&ioapic_lock, flags);
-
-               /*
-                * Sanity check
-                */
-               spin_lock_irqsave(&ioapic_lock, flags);
-               reg_00.raw = io_apic_read(apic, 0);
-               spin_unlock_irqrestore(&ioapic_lock, flags);
-               if (reg_00.bits.ID != mp_ioapics[apic].mp_apicid)
-                       printk("could not set ID!\n");
-               else
-                       apic_printk(APIC_VERBOSE, " ok.\n");
-       }
-}
-
-int no_timer_check __initdata;
-
-static int __init notimercheck(char *s)
-{
-       no_timer_check = 1;
-       return 1;
-}
-__setup("no_timer_check", notimercheck);
-
-/*
- * There is a nasty bug in some older SMP boards, their mptable lies
- * about the timer IRQ. We do the following to work around the situation:
- *
- *     - timer IRQ defaults to IO-APIC IRQ
- *     - if this function detects that timer IRQs are defunct, then we fall
- *       back to ISA timer IRQs
- */
-static int __init timer_irq_works(void)
-{
-       unsigned long t1 = jiffies;
-       unsigned long flags;
-
-       if (no_timer_check)
-               return 1;
-
-       local_save_flags(flags);
-       local_irq_enable();
-       /* Let ten ticks pass... */
-       mdelay((10 * 1000) / HZ);
-       local_irq_restore(flags);
-
-       /*
-        * Expect a few ticks at least, to be sure some possible
-        * glue logic does not lock up after one or two first
-        * ticks in a non-ExtINT mode.  Also the local APIC
-        * might have cached one ExtINT interrupt.  Finally, at
-        * least one tick may be lost due to delays.
-        */
-       if (time_after(jiffies, t1 + 4))
-               return 1;
-
-       return 0;
-}
-
-/*
- * In the SMP+IOAPIC case it might happen that there are an unspecified
- * number of pending IRQ events unhandled. These cases are very rare,
- * so we 'resend' these IRQs via IPIs, to the same CPU. It's much
- * better to do it this way as thus we do not have to be aware of
- * 'pending' interrupts in the IRQ path, except at this point.
- */
-/*
- * Edge triggered needs to resend any interrupt
- * that was delayed but this is now handled in the device
- * independent code.
- */
-
-/*
- * Startup quirk:
- *
- * Starting up a edge-triggered IO-APIC interrupt is
- * nasty - we need to make sure that we get the edge.
- * If it is already asserted for some reason, we need
- * return 1 to indicate that is was pending.
- *
- * This is not complete - we should be able to fake
- * an edge even if it isn't on the 8259A...
- *
- * (We do this for level-triggered IRQs too - it cannot hurt.)
- */
-static unsigned int startup_ioapic_irq(unsigned int irq)
-{
-       int was_pending = 0;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ioapic_lock, flags);
-       if (irq < 16) {
-               disable_8259A_irq(irq);
-               if (i8259A_irq_pending(irq))
-                       was_pending = 1;
-       }
-       __unmask_IO_APIC_irq(irq);
-       spin_unlock_irqrestore(&ioapic_lock, flags);
-
-       return was_pending;
-}
-
-static void ack_ioapic_irq(unsigned int irq)
-{
-       move_native_irq(irq);
-       ack_APIC_irq();
-}
-
-static void ack_ioapic_quirk_irq(unsigned int irq)
-{
-       unsigned long v;
-       int i;
-
-       move_native_irq(irq);
-/*
- * It appears there is an erratum which affects at least version 0x11
- * of I/O APIC (that's the 82093AA and cores integrated into various
- * chipsets).  Under certain conditions a level-triggered interrupt is
- * erroneously delivered as edge-triggered one but the respective IRR
- * bit gets set nevertheless.  As a result the I/O unit expects an EOI
- * message but it will never arrive and further interrupts are blocked
- * from the source.  The exact reason is so far unknown, but the
- * phenomenon was observed when two consecutive interrupt requests
- * from a given source get delivered to the same CPU and the source is
- * temporarily disabled in between.
- *
- * A workaround is to simulate an EOI message manually.  We achieve it
- * by setting the trigger mode to edge and then to level when the edge
- * trigger mode gets detected in the TMR of a local APIC for a
- * level-triggered interrupt.  We mask the source for the time of the
- * operation to prevent an edge-triggered interrupt escaping meanwhile.
- * The idea is from Manfred Spraul.  --macro
- */
-       i = irq_vector[irq];
-
-       v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1));
-
-       ack_APIC_irq();
-
-       if (!(v & (1 << (i & 0x1f)))) {
-               atomic_inc(&irq_mis_count);
-               spin_lock(&ioapic_lock);
-               __mask_and_edge_IO_APIC_irq(irq);
-               __unmask_and_level_IO_APIC_irq(irq);
-               spin_unlock(&ioapic_lock);
-       }
-}
-
-static int ioapic_retrigger_irq(unsigned int irq)
-{
-       send_IPI_self(irq_vector[irq]);
-
-       return 1;
-}
-
-static struct irq_chip ioapic_chip __read_mostly = {
-       .name           = "IO-APIC",
-       .startup        = startup_ioapic_irq,
-       .mask           = mask_IO_APIC_irq,
-       .unmask         = unmask_IO_APIC_irq,
-       .ack            = ack_ioapic_irq,
-       .eoi            = ack_ioapic_quirk_irq,
-#ifdef CONFIG_SMP
-       .set_affinity   = set_ioapic_affinity_irq,
-#endif
-       .retrigger      = ioapic_retrigger_irq,
-};
-
-
-static inline void init_IO_APIC_traps(void)
-{
-       int irq;
-
-       /*
-        * NOTE! The local APIC isn't very good at handling
-        * multiple interrupts at the same interrupt level.
-        * As the interrupt level is determined by taking the
-        * vector number and shifting that right by 4, we
-        * want to spread these out a bit so that they don't
-        * all fall in the same interrupt level.
-        *
-        * Also, we've got to be careful not to trash gate
-        * 0x80, because int 0x80 is hm, kind of importantish. ;)
-        */
-       for (irq = 0; irq < NR_IRQS ; irq++) {
-               if (IO_APIC_IRQ(irq) && !irq_vector[irq]) {
-                       /*
-                        * Hmm.. We don't have an entry for this,
-                        * so default to an old-fashioned 8259
-                        * interrupt if we can..
-                        */
-                       if (irq < 16)
-                               make_8259A_irq(irq);
-                       else
-                               /* Strange. Oh, well.. */
-                               irq_desc[irq].chip = &no_irq_chip;
-               }
-       }
-}
-
-/*
- * The local APIC irq-chip implementation:
- */
-
-static void ack_lapic_irq(unsigned int irq)
-{
-       ack_APIC_irq();
-}
-
-static void mask_lapic_irq(unsigned int irq)
-{
-       unsigned long v;
-
-       v = apic_read(APIC_LVT0);
-       apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
-}
-
-static void unmask_lapic_irq(unsigned int irq)
-{
-       unsigned long v;
-
-       v = apic_read(APIC_LVT0);
-       apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED);
-}
-
-static struct irq_chip lapic_chip __read_mostly = {
-       .name           = "local-APIC",
-       .mask           = mask_lapic_irq,
-       .unmask         = unmask_lapic_irq,
-       .ack            = ack_lapic_irq,
-};
-
-static void lapic_register_intr(int irq, int vector)
-{
-       irq_desc[irq].status &= ~IRQ_LEVEL;
-       set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq,
-                                     "edge");
-       set_intr_gate(vector, interrupt[irq]);
-}
-
-static void __init setup_nmi(void)
-{
-       /*
-        * Dirty trick to enable the NMI watchdog ...
-        * We put the 8259A master into AEOI mode and
-        * unmask on all local APICs LVT0 as NMI.
-        *
-        * The idea to use the 8259A in AEOI mode ('8259A Virtual Wire')
-        * is from Maciej W. Rozycki - so we do not have to EOI from
-        * the NMI handler or the timer interrupt.
-        */
-       apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ...");
-
-       enable_NMI_through_LVT0();
-
-       apic_printk(APIC_VERBOSE, " done.\n");
-}
-
-/*
- * This looks a bit hackish but it's about the only one way of sending
- * a few INTA cycles to 8259As and any associated glue logic.  ICR does
- * not support the ExtINT mode, unfortunately.  We need to send these
- * cycles as some i82489DX-based boards have glue logic that keeps the
- * 8259A interrupt line asserted until INTA.  --macro
- */
-static inline void __init unlock_ExtINT_logic(void)
-{
-       int apic, pin, i;
-       struct IO_APIC_route_entry entry0, entry1;
-       unsigned char save_control, save_freq_select;
-
-       pin  = find_isa_irq_pin(8, mp_INT);
-       if (pin == -1) {
-               WARN_ON_ONCE(1);
-               return;
-       }
-       apic = find_isa_irq_apic(8, mp_INT);
-       if (apic == -1) {
-               WARN_ON_ONCE(1);
-               return;
-       }
-
-       entry0 = ioapic_read_entry(apic, pin);
-       clear_IO_APIC_pin(apic, pin);
-
-       memset(&entry1, 0, sizeof(entry1));
-
-       entry1.dest_mode = 0;                   /* physical delivery */
-       entry1.mask = 0;                        /* unmask IRQ now */
-       entry1.dest.physical.physical_dest = hard_smp_processor_id();
-       entry1.delivery_mode = dest_ExtINT;
-       entry1.polarity = entry0.polarity;
-       entry1.trigger = 0;
-       entry1.vector = 0;
-
-       ioapic_write_entry(apic, pin, entry1);
-
-       save_control = CMOS_READ(RTC_CONTROL);
-       save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
-       CMOS_WRITE((save_freq_select & ~RTC_RATE_SELECT) | 0x6,
-                  RTC_FREQ_SELECT);
-       CMOS_WRITE(save_control | RTC_PIE, RTC_CONTROL);
-
-       i = 100;
-       while (i-- > 0) {
-               mdelay(10);
-               if ((CMOS_READ(RTC_INTR_FLAGS) & RTC_PF) == RTC_PF)
-                       i -= 10;
-       }
-
-       CMOS_WRITE(save_control, RTC_CONTROL);
-       CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
-       clear_IO_APIC_pin(apic, pin);
-
-       ioapic_write_entry(apic, pin, entry0);
-}
-
-/*
- * This code may look a bit paranoid, but it's supposed to cooperate with
- * a wide range of boards and BIOS bugs.  Fortunately only the timer IRQ
- * is so screwy.  Thanks to Brian Perkins for testing/hacking this beast
- * fanatically on his truly buggy board.
- */
-static inline void __init check_timer(void)
-{
-       int apic1, pin1, apic2, pin2;
-       int no_pin1 = 0;
-       int vector;
-       unsigned int ver;
-       unsigned long flags;
-
-       local_irq_save(flags);
-
-       ver = apic_read(APIC_LVR);
-       ver = GET_APIC_VERSION(ver);
-
-       /*
-        * get/set the timer IRQ vector:
-        */
-       disable_8259A_irq(0);
-       vector = assign_irq_vector(0);
-       set_intr_gate(vector, interrupt[0]);
-
-       /*
-        * As IRQ0 is to be enabled in the 8259A, the virtual
-        * wire has to be disabled in the local APIC.  Also
-        * timer interrupts need to be acknowledged manually in
-        * the 8259A for the i82489DX when using the NMI
-        * watchdog as that APIC treats NMIs as level-triggered.
-        * The AEOI mode will finish them in the 8259A
-        * automatically.
-        */
-       apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
-       init_8259A(1);
-       timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver));
-
-       pin1  = find_isa_irq_pin(0, mp_INT);
-       apic1 = find_isa_irq_apic(0, mp_INT);
-       pin2  = ioapic_i8259.pin;
-       apic2 = ioapic_i8259.apic;
-
-       apic_printk(APIC_QUIET, KERN_INFO "..TIMER: vector=0x%02X "
-                   "apic1=%d pin1=%d apic2=%d pin2=%d\n",
-                   vector, apic1, pin1, apic2, pin2);
-
-       /*
-        * Some BIOS writers are clueless and report the ExtINTA
-        * I/O APIC input from the cascaded 8259A as the timer
-        * interrupt input.  So just in case, if only one pin
-        * was found above, try it both directly and through the
-        * 8259A.
-        */
-       if (pin1 == -1) {
-               pin1 = pin2;
-               apic1 = apic2;
-               no_pin1 = 1;
-       } else if (pin2 == -1) {
-               pin2 = pin1;
-               apic2 = apic1;
-       }
-
-       if (pin1 != -1) {
-               /*
-                * Ok, does IRQ0 through the IOAPIC work?
-                */
-               if (no_pin1) {
-                       add_pin_to_irq(0, apic1, pin1);
-                       setup_timer_IRQ0_pin(apic1, pin1, vector);
-               }
-               unmask_IO_APIC_irq(0);
-               if (timer_irq_works()) {
-                       if (nmi_watchdog == NMI_IO_APIC) {
-                               setup_nmi();
-                               enable_8259A_irq(0);
-                       }
-                       if (disable_timer_pin_1 > 0)
-                               clear_IO_APIC_pin(0, pin1);
-                       goto out;
-               }
-               clear_IO_APIC_pin(apic1, pin1);
-               if (!no_pin1)
-                       apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: "
-                                   "8254 timer not connected to IO-APIC\n");
-
-               apic_printk(APIC_QUIET, KERN_INFO "...trying to set up timer "
-                           "(IRQ0) through the 8259A ...\n");
-               apic_printk(APIC_QUIET, KERN_INFO
-                           "..... (found apic %d pin %d) ...\n", apic2, pin2);
-               /*
-                * legacy devices should be connected to IO APIC #0
-                */
-               replace_pin_at_irq(0, apic1, pin1, apic2, pin2);
-               setup_timer_IRQ0_pin(apic2, pin2, vector);
-               unmask_IO_APIC_irq(0);
-               enable_8259A_irq(0);
-               if (timer_irq_works()) {
-                       apic_printk(APIC_QUIET, KERN_INFO "....... works.\n");
-                       timer_through_8259 = 1;
-                       if (nmi_watchdog == NMI_IO_APIC) {
-                               disable_8259A_irq(0);
-                               setup_nmi();
-                               enable_8259A_irq(0);
-                       }
-                       goto out;
-               }
-               /*
-                * Cleanup, just in case ...
-                */
-               disable_8259A_irq(0);
-               clear_IO_APIC_pin(apic2, pin2);
-               apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
-       }
-
-       if (nmi_watchdog == NMI_IO_APIC) {
-               apic_printk(APIC_QUIET, KERN_WARNING "timer doesn't work "
-                           "through the IO-APIC - disabling NMI Watchdog!\n");
-               nmi_watchdog = NMI_NONE;
-       }
-       timer_ack = 0;
-
-       apic_printk(APIC_QUIET, KERN_INFO
-                   "...trying to set up timer as Virtual Wire IRQ...\n");
-
-       lapic_register_intr(0, vector);
-       apic_write(APIC_LVT0, APIC_DM_FIXED | vector);  /* Fixed mode */
-       enable_8259A_irq(0);
-
-       if (timer_irq_works()) {
-               apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
-               goto out;
-       }
-       disable_8259A_irq(0);
-       apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector);
-       apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
-
-       apic_printk(APIC_QUIET, KERN_INFO
-                   "...trying to set up timer as ExtINT IRQ...\n");
-
-       init_8259A(0);
-       make_8259A_irq(0);
-       apic_write(APIC_LVT0, APIC_DM_EXTINT);
-
-       unlock_ExtINT_logic();
-
-       if (timer_irq_works()) {
-               apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
-               goto out;
-       }
-       apic_printk(APIC_QUIET, KERN_INFO "..... failed :(.\n");
-       panic("IO-APIC + timer doesn't work!  Boot with apic=debug and send a "
-               "report.  Then try booting with the 'noapic' option.\n");
-out:
-       local_irq_restore(flags);
-}
-
-/*
- * Traditionally ISA IRQ2 is the cascade IRQ, and is not available
- * to devices.  However there may be an I/O APIC pin available for
- * this interrupt regardless.  The pin may be left unconnected, but
- * typically it will be reused as an ExtINT cascade interrupt for
- * the master 8259A.  In the MPS case such a pin will normally be
- * reported as an ExtINT interrupt in the MP table.  With ACPI
- * there is no provision for ExtINT interrupts, and in the absence
- * of an override it would be treated as an ordinary ISA I/O APIC
- * interrupt, that is edge-triggered and unmasked by default.  We
- * used to do this, but it caused problems on some systems because
- * of the NMI watchdog and sometimes IRQ0 of the 8254 timer using
- * the same ExtINT cascade interrupt to drive the local APIC of the
- * bootstrap processor.  Therefore we refrain from routing IRQ2 to
- * the I/O APIC in all cases now.  No actual device should request
- * it anyway.  --macro
- */
-#define PIC_IRQS       (1 << PIC_CASCADE_IR)
-
-void __init setup_IO_APIC(void)
-{
-       int i;
-
-       /* Reserve all the system vectors. */
-       for (i = first_system_vector; i < NR_VECTORS; i++)
-               set_bit(i, used_vectors);
-
-       enable_IO_APIC();
-
-       io_apic_irqs = ~PIC_IRQS;
-
-       printk("ENABLING IO-APIC IRQs\n");
-
-       /*
-        * Set up IO-APIC IRQ routing.
-        */
-       if (!acpi_ioapic)
-               setup_ioapic_ids_from_mpc();
-       sync_Arb_IDs();
-       setup_IO_APIC_irqs();
-       init_IO_APIC_traps();
-       check_timer();
-}
-
-/*
- *     Called after all the initialization is done. If we didnt find any
- *     APIC bugs then we can allow the modify fast path
- */
-
-static int __init io_apic_bug_finalize(void)
-{
-       if (sis_apic_bug == -1)
-               sis_apic_bug = 0;
-       return 0;
-}
-
-late_initcall(io_apic_bug_finalize);
-
-struct sysfs_ioapic_data {
-       struct sys_device dev;
-       struct IO_APIC_route_entry entry[0];
-};
-static struct sysfs_ioapic_data *mp_ioapic_data[MAX_IO_APICS];
-
-static int ioapic_suspend(struct sys_device *dev, pm_message_t state)
-{
-       struct IO_APIC_route_entry *entry;
-       struct sysfs_ioapic_data *data;
-       int i;
-
-       data = container_of(dev, struct sysfs_ioapic_data, dev);
-       entry = data->entry;
-       for (i = 0; i < nr_ioapic_registers[dev->id]; i++)
-               entry[i] = ioapic_read_entry(dev->id, i);
-
-       return 0;
-}
-
-static int ioapic_resume(struct sys_device *dev)
-{
-       struct IO_APIC_route_entry *entry;
-       struct sysfs_ioapic_data *data;
-       unsigned long flags;
-       union IO_APIC_reg_00 reg_00;
-       int i;
-
-       data = container_of(dev, struct sysfs_ioapic_data, dev);
-       entry = data->entry;
-
-       spin_lock_irqsave(&ioapic_lock, flags);
-       reg_00.raw = io_apic_read(dev->id, 0);
-       if (reg_00.bits.ID != mp_ioapics[dev->id].mp_apicid) {
-               reg_00.bits.ID = mp_ioapics[dev->id].mp_apicid;
-               io_apic_write(dev->id, 0, reg_00.raw);
-       }
-       spin_unlock_irqrestore(&ioapic_lock, flags);
-       for (i = 0; i < nr_ioapic_registers[dev->id]; i++)
-               ioapic_write_entry(dev->id, i, entry[i]);
-
-       return 0;
-}
-
-static struct sysdev_class ioapic_sysdev_class = {
-       .name = "ioapic",
-       .suspend = ioapic_suspend,
-       .resume = ioapic_resume,
-};
-
-static int __init ioapic_init_sysfs(void)
-{
-       struct sys_device *dev;
-       int i, size, error = 0;
-
-       error = sysdev_class_register(&ioapic_sysdev_class);
-       if (error)
-               return error;
-
-       for (i = 0; i < nr_ioapics; i++) {
-               size = sizeof(struct sys_device) + nr_ioapic_registers[i]
-                       * sizeof(struct IO_APIC_route_entry);
-               mp_ioapic_data[i] = kzalloc(size, GFP_KERNEL);
-               if (!mp_ioapic_data[i]) {
-                       printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
-                       continue;
-               }
-               dev = &mp_ioapic_data[i]->dev;
-               dev->id = i;
-               dev->cls = &ioapic_sysdev_class;
-               error = sysdev_register(dev);
-               if (error) {
-                       kfree(mp_ioapic_data[i]);
-                       mp_ioapic_data[i] = NULL;
-                       printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
-                       continue;
-               }
-       }
-
-       return 0;
-}
-
-device_initcall(ioapic_init_sysfs);
-
-/*
- * Dynamic irq allocate and deallocation
- */
-int create_irq(void)
-{
-       /* Allocate an unused irq */
-       int irq, new, vector = 0;
-       unsigned long flags;
-
-       irq = -ENOSPC;
-       spin_lock_irqsave(&vector_lock, flags);
-       for (new = (NR_IRQS - 1); new >= 0; new--) {
-               if (platform_legacy_irq(new))
-                       continue;
-               if (irq_vector[new] != 0)
-                       continue;
-               vector = __assign_irq_vector(new);
-               if (likely(vector > 0))
-                       irq = new;
-               break;
-       }
-       spin_unlock_irqrestore(&vector_lock, flags);
-
-       if (irq >= 0) {
-               set_intr_gate(vector, interrupt[irq]);
-               dynamic_irq_init(irq);
-       }
-       return irq;
-}
-
-void destroy_irq(unsigned int irq)
-{
-       unsigned long flags;
-
-       dynamic_irq_cleanup(irq);
-
-       spin_lock_irqsave(&vector_lock, flags);
-       clear_bit(irq_vector[irq], used_vectors);
-       irq_vector[irq] = 0;
-       spin_unlock_irqrestore(&vector_lock, flags);
-}
-
-/*
- * MSI message composition
- */
-#ifdef CONFIG_PCI_MSI
-static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
-{
-       int vector;
-       unsigned dest;
-
-       vector = assign_irq_vector(irq);
-       if (vector >= 0) {
-               dest = cpu_mask_to_apicid(TARGET_CPUS);
-
-               msg->address_hi = MSI_ADDR_BASE_HI;
-               msg->address_lo =
-                       MSI_ADDR_BASE_LO |
-                       ((INT_DEST_MODE == 0) ?
-MSI_ADDR_DEST_MODE_PHYSICAL:
-                               MSI_ADDR_DEST_MODE_LOGICAL) |
-                       ((INT_DELIVERY_MODE != dest_LowestPrio) ?
-                               MSI_ADDR_REDIRECTION_CPU:
-                               MSI_ADDR_REDIRECTION_LOWPRI) |
-                       MSI_ADDR_DEST_ID(dest);
-
-               msg->data =
-                       MSI_DATA_TRIGGER_EDGE |
-                       MSI_DATA_LEVEL_ASSERT |
-                       ((INT_DELIVERY_MODE != dest_LowestPrio) ?
-MSI_DATA_DELIVERY_FIXED:
-                               MSI_DATA_DELIVERY_LOWPRI) |
-                       MSI_DATA_VECTOR(vector);
-       }
-       return vector;
-}
-
-#ifdef CONFIG_SMP
-static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
-{
-       struct msi_msg msg;
-       unsigned int dest;
-       cpumask_t tmp;
-       int vector;
-
-       cpus_and(tmp, mask, cpu_online_map);
-       if (cpus_empty(tmp))
-               tmp = TARGET_CPUS;
-
-       vector = assign_irq_vector(irq);
-       if (vector < 0)
-               return;
-
-       dest = cpu_mask_to_apicid(mask);
-
-       read_msi_msg(irq, &msg);
-
-       msg.data &= ~MSI_DATA_VECTOR_MASK;
-       msg.data |= MSI_DATA_VECTOR(vector);
-       msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
-       msg.address_lo |= MSI_ADDR_DEST_ID(dest);
-
-       write_msi_msg(irq, &msg);
-       irq_desc[irq].affinity = mask;
-}
-#endif /* CONFIG_SMP */
-
-/*
- * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
- * which implement the MSI or MSI-X Capability Structure.
- */
-static struct irq_chip msi_chip = {
-       .name           = "PCI-MSI",
-       .unmask         = unmask_msi_irq,
-       .mask           = mask_msi_irq,
-       .ack            = ack_ioapic_irq,
-#ifdef CONFIG_SMP
-       .set_affinity   = set_msi_irq_affinity,
-#endif
-       .retrigger      = ioapic_retrigger_irq,
-};
-
-int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
-{
-       struct msi_msg msg;
-       int irq, ret;
-       irq = create_irq();
-       if (irq < 0)
-               return irq;
-
-       ret = msi_compose_msg(dev, irq, &msg);
-       if (ret < 0) {
-               destroy_irq(irq);
-               return ret;
-       }
-
-       set_irq_msi(irq, desc);
-       write_msi_msg(irq, &msg);
-
-       set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq,
-                                     "edge");
-
-       return 0;
-}
-
-void arch_teardown_msi_irq(unsigned int irq)
-{
-       destroy_irq(irq);
-}
-
-#endif /* CONFIG_PCI_MSI */
-
-/*
- * Hypertransport interrupt support
- */
-#ifdef CONFIG_HT_IRQ
-
-#ifdef CONFIG_SMP
-
-static void target_ht_irq(unsigned int irq, unsigned int dest)
-{
-       struct ht_irq_msg msg;
-       fetch_ht_irq_msg(irq, &msg);
-
-       msg.address_lo &= ~(HT_IRQ_LOW_DEST_ID_MASK);
-       msg.address_hi &= ~(HT_IRQ_HIGH_DEST_ID_MASK);
-
-       msg.address_lo |= HT_IRQ_LOW_DEST_ID(dest);
-       msg.address_hi |= HT_IRQ_HIGH_DEST_ID(dest);
-
-       write_ht_irq_msg(irq, &msg);
-}
-
-static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
-{
-       unsigned int dest;
-       cpumask_t tmp;
-
-       cpus_and(tmp, mask, cpu_online_map);
-       if (cpus_empty(tmp))
-               tmp = TARGET_CPUS;
-
-       cpus_and(mask, tmp, CPU_MASK_ALL);
-
-       dest = cpu_mask_to_apicid(mask);
-
-       target_ht_irq(irq, dest);
-       irq_desc[irq].affinity = mask;
-}
-#endif
-
-static struct irq_chip ht_irq_chip = {
-       .name           = "PCI-HT",
-       .mask           = mask_ht_irq,
-       .unmask         = unmask_ht_irq,
-       .ack            = ack_ioapic_irq,
-#ifdef CONFIG_SMP
-       .set_affinity   = set_ht_irq_affinity,
-#endif
-       .retrigger      = ioapic_retrigger_irq,
-};
-
-int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
-{
-       int vector;
-
-       vector = assign_irq_vector(irq);
-       if (vector >= 0) {
-               struct ht_irq_msg msg;
-               unsigned dest;
-               cpumask_t tmp;
-
-               cpus_clear(tmp);
-               cpu_set(vector >> 8, tmp);
-               dest = cpu_mask_to_apicid(tmp);
-
-               msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest);
-
-               msg.address_lo =
-                       HT_IRQ_LOW_BASE |
-                       HT_IRQ_LOW_DEST_ID(dest) |
-                       HT_IRQ_LOW_VECTOR(vector) |
-                       ((INT_DEST_MODE == 0) ?
-                               HT_IRQ_LOW_DM_PHYSICAL :
-                               HT_IRQ_LOW_DM_LOGICAL) |
-                       HT_IRQ_LOW_RQEOI_EDGE |
-                       ((INT_DELIVERY_MODE != dest_LowestPrio) ?
-                               HT_IRQ_LOW_MT_FIXED :
-                               HT_IRQ_LOW_MT_ARBITRATED) |
-                       HT_IRQ_LOW_IRQ_MASKED;
-
-               write_ht_irq_msg(irq, &msg);
-
-               set_irq_chip_and_handler_name(irq, &ht_irq_chip,
-                                             handle_edge_irq, "edge");
-       }
-       return vector;
-}
-#endif /* CONFIG_HT_IRQ */
-
-/* --------------------------------------------------------------------------
-                       ACPI-based IOAPIC Configuration
-   -------------------------------------------------------------------------- */
-
-#ifdef CONFIG_ACPI
-
-int __init io_apic_get_unique_id(int ioapic, int apic_id)
-{
-       union IO_APIC_reg_00 reg_00;
-       static physid_mask_t apic_id_map = PHYSID_MASK_NONE;
-       physid_mask_t tmp;
-       unsigned long flags;
-       int i = 0;
-
-       /*
-        * The P4 platform supports up to 256 APIC IDs on two separate APIC
-        * buses (one for LAPICs, one for IOAPICs), where predecessors only
-        * supports up to 16 on one shared APIC bus.
-        *
-        * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full
-        *      advantage of new APIC bus architecture.
-        */
-
-       if (physids_empty(apic_id_map))
-               apic_id_map = ioapic_phys_id_map(phys_cpu_present_map);
-
-       spin_lock_irqsave(&ioapic_lock, flags);
-       reg_00.raw = io_apic_read(ioapic, 0);
-       spin_unlock_irqrestore(&ioapic_lock, flags);
-
-       if (apic_id >= get_physical_broadcast()) {
-               printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying "
-                       "%d\n", ioapic, apic_id, reg_00.bits.ID);
-               apic_id = reg_00.bits.ID;
-       }
-
-       /*
-        * Every APIC in a system must have a unique ID or we get lots of nice
-        * 'stuck on smp_invalidate_needed IPI wait' messages.
-        */
-       if (check_apicid_used(apic_id_map, apic_id)) {
-
-               for (i = 0; i < get_physical_broadcast(); i++) {
-                       if (!check_apicid_used(apic_id_map, i))
-                               break;
-               }
-
-               if (i == get_physical_broadcast())
-                       panic("Max apic_id exceeded!\n");
-
-               printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, "
-                       "trying %d\n", ioapic, apic_id, i);
-
-               apic_id = i;
-       }
-
-       tmp = apicid_to_cpu_present(apic_id);
-       physids_or(apic_id_map, apic_id_map, tmp);
-
-       if (reg_00.bits.ID != apic_id) {
-               reg_00.bits.ID = apic_id;
-
-               spin_lock_irqsave(&ioapic_lock, flags);
-               io_apic_write(ioapic, 0, reg_00.raw);
-               reg_00.raw = io_apic_read(ioapic, 0);
-               spin_unlock_irqrestore(&ioapic_lock, flags);
-
-               /* Sanity check */
-               if (reg_00.bits.ID != apic_id) {
-                       printk("IOAPIC[%d]: Unable to change apic_id!\n", ioapic);
-                       return -1;
-               }
-       }
-
-       apic_printk(APIC_VERBOSE, KERN_INFO
-                       "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id);
-
-       return apic_id;
-}
-
-
-int __init io_apic_get_version(int ioapic)
-{
-       union IO_APIC_reg_01    reg_01;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ioapic_lock, flags);
-       reg_01.raw = io_apic_read(ioapic, 1);
-       spin_unlock_irqrestore(&ioapic_lock, flags);
-
-       return reg_01.bits.version;
-}
-
-
-int __init io_apic_get_redir_entries(int ioapic)
-{
-       union IO_APIC_reg_01    reg_01;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ioapic_lock, flags);
-       reg_01.raw = io_apic_read(ioapic, 1);
-       spin_unlock_irqrestore(&ioapic_lock, flags);
-
-       return reg_01.bits.entries;
-}
-
-
-int io_apic_set_pci_routing(int ioapic, int pin, int irq, int edge_level, int active_high_low)
-{
-       struct IO_APIC_route_entry entry;
-
-       if (!IO_APIC_IRQ(irq)) {
-               printk(KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n",
-                       ioapic);
-               return -EINVAL;
-       }
-
-       /*
-        * Generate a PCI IRQ routing entry and program the IOAPIC accordingly.
-        * Note that we mask (disable) IRQs now -- these get enabled when the
-        * corresponding device driver registers for this IRQ.
-        */
-
-       memset(&entry, 0, sizeof(entry));
-
-       entry.delivery_mode = INT_DELIVERY_MODE;
-       entry.dest_mode = INT_DEST_MODE;
-       entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
-       entry.trigger = edge_level;
-       entry.polarity = active_high_low;
-       entry.mask  = 1;
-
-       /*
-        * IRQs < 16 are already in the irq_2_pin[] map
-        */
-       if (irq >= 16)
-               add_pin_to_irq(irq, ioapic, pin);
-
-       entry.vector = assign_irq_vector(irq);
-
-       apic_printk(APIC_DEBUG, KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry "
-               "(%d-%d -> 0x%x -> IRQ %d Mode:%i Active:%i)\n", ioapic,
-               mp_ioapics[ioapic].mp_apicid, pin, entry.vector, irq,
-               edge_level, active_high_low);
-
-       ioapic_register_intr(irq, entry.vector, edge_level);
-
-       if (!ioapic && (irq < 16))
-               disable_8259A_irq(irq);
-
-       ioapic_write_entry(ioapic, pin, entry);
-
-       return 0;
-}
-
-int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
-{
-       int i;
-
-       if (skip_ioapic_setup)
-               return -1;
-
-       for (i = 0; i < mp_irq_entries; i++)
-               if (mp_irqs[i].mp_irqtype == mp_INT &&
-                   mp_irqs[i].mp_srcbusirq == bus_irq)
-                       break;
-       if (i >= mp_irq_entries)
-               return -1;
-
-       *trigger = irq_trigger(i);
-       *polarity = irq_polarity(i);
-       return 0;
-}
-
-#endif /* CONFIG_ACPI */
-
-static int __init parse_disable_timer_pin_1(char *arg)
-{
-       disable_timer_pin_1 = 1;
-       return 0;
-}
-early_param("disable_timer_pin_1", parse_disable_timer_pin_1);
-
-static int __init parse_enable_timer_pin_1(char *arg)
-{
-       disable_timer_pin_1 = -1;
-       return 0;
-}
-early_param("enable_timer_pin_1", parse_enable_timer_pin_1);
-
-static int __init parse_noapic(char *arg)
-{
-       /* disable IO-APIC */
-       disable_ioapic_setup();
-       return 0;
-}
-early_param("noapic", parse_noapic);
-
-void __init ioapic_init_mappings(void)
-{
-       unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
-       int i;
-
-       for (i = 0; i < nr_ioapics; i++) {
-               if (smp_found_config) {
-                       ioapic_phys = mp_ioapics[i].mp_apicaddr;
-                       if (!ioapic_phys) {
-                               printk(KERN_ERR
-                                      "WARNING: bogus zero IO-APIC "
-                                      "address found in MPTABLE, "
-                                      "disabling IO/APIC support!\n");
-                               smp_found_config = 0;
-                               skip_ioapic_setup = 1;
-                               goto fake_ioapic_page;
-                       }
-               } else {
-fake_ioapic_page:
-                       ioapic_phys = (unsigned long)
-                                     alloc_bootmem_pages(PAGE_SIZE);
-                       ioapic_phys = __pa(ioapic_phys);
-               }
-               set_fixmap_nocache(idx, ioapic_phys);
-               printk(KERN_DEBUG "mapped IOAPIC to %08lx (%08lx)\n",
-                      __fix_to_virt(idx), ioapic_phys);
-               idx++;
-       }
-}
-
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
new file mode 100644 (file)
index 0000000..d1d4dc5
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * Common interrupt code for 32 and 64 bit
+ */
+#include <linux/cpu.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/seq_file.h>
+
+#include <asm/apic.h>
+#include <asm/io_apic.h>
+#include <asm/smp.h>
+
+atomic_t irq_err_count;
+
+/*
+ * 'what should we do if we get a hw irq event on an illegal vector'.
+ * each architecture has to answer this themselves.
+ */
+void ack_bad_irq(unsigned int irq)
+{
+       printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq);
+
+#ifdef CONFIG_X86_LOCAL_APIC
+       /*
+        * Currently unexpected vectors happen only on SMP and APIC.
+        * We _must_ ack these because every local APIC has only N
+        * irq slots per priority level, and a 'hanging, unacked' IRQ
+        * holds up an irq slot - in excessive cases (when multiple
+        * unexpected vectors occur) that might lock up the APIC
+        * completely.
+        * But only ack when the APIC is enabled -AK
+        */
+       if (cpu_has_apic)
+               ack_APIC_irq();
+#endif
+}
+
+#ifdef CONFIG_X86_32
+# define irq_stats(x)          (&per_cpu(irq_stat, x))
+#else
+# define irq_stats(x)          cpu_pda(x)
+#endif
+/*
+ * /proc/interrupts printing:
+ */
+static int show_other_interrupts(struct seq_file *p)
+{
+       int j;
+
+       seq_printf(p, "NMI: ");
+       for_each_online_cpu(j)
+               seq_printf(p, "%10u ", irq_stats(j)->__nmi_count);
+       seq_printf(p, "  Non-maskable interrupts\n");
+#ifdef CONFIG_X86_LOCAL_APIC
+       seq_printf(p, "LOC: ");
+       for_each_online_cpu(j)
+               seq_printf(p, "%10u ", irq_stats(j)->apic_timer_irqs);
+       seq_printf(p, "  Local timer interrupts\n");
+#endif
+#ifdef CONFIG_SMP
+       seq_printf(p, "RES: ");
+       for_each_online_cpu(j)
+               seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count);
+       seq_printf(p, "  Rescheduling interrupts\n");
+       seq_printf(p, "CAL: ");
+       for_each_online_cpu(j)
+               seq_printf(p, "%10u ", irq_stats(j)->irq_call_count);
+       seq_printf(p, "  Function call interrupts\n");
+       seq_printf(p, "TLB: ");
+       for_each_online_cpu(j)
+               seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count);
+       seq_printf(p, "  TLB shootdowns\n");
+#endif
+#ifdef CONFIG_X86_MCE
+       seq_printf(p, "TRM: ");
+       for_each_online_cpu(j)
+               seq_printf(p, "%10u ", irq_stats(j)->irq_thermal_count);
+       seq_printf(p, "  Thermal event interrupts\n");
+# ifdef CONFIG_X86_64
+       seq_printf(p, "THR: ");
+       for_each_online_cpu(j)
+               seq_printf(p, "%10u ", irq_stats(j)->irq_threshold_count);
+       seq_printf(p, "  Threshold APIC interrupts\n");
+# endif
+#endif
+#ifdef CONFIG_X86_LOCAL_APIC
+       seq_printf(p, "SPU: ");
+       for_each_online_cpu(j)
+               seq_printf(p, "%10u ", irq_stats(j)->irq_spurious_count);
+       seq_printf(p, "  Spurious interrupts\n");
+#endif
+       seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
+#if defined(CONFIG_X86_IO_APIC)
+       seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
+#endif
+       return 0;
+}
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+       unsigned long flags, any_count = 0;
+       int i = *(loff_t *) v, j;
+       struct irqaction *action;
+       struct irq_desc *desc;
+
+       if (i > nr_irqs)
+               return 0;
+
+       if (i == nr_irqs)
+               return show_other_interrupts(p);
+
+       /* print header */
+       if (i == 0) {
+               seq_printf(p, "           ");
+               for_each_online_cpu(j)
+                       seq_printf(p, "CPU%-8d", j);
+               seq_putc(p, '\n');
+       }
+
+       desc = irq_to_desc(i);
+       spin_lock_irqsave(&desc->lock, flags);
+#ifndef CONFIG_SMP
+       any_count = kstat_irqs(i);
+#else
+       for_each_online_cpu(j)
+               any_count |= kstat_irqs_cpu(i, j);
+#endif
+       action = desc->action;
+       if (!action && !any_count)
+               goto out;
+
+       seq_printf(p, "%3d: ", i);
+#ifndef CONFIG_SMP
+       seq_printf(p, "%10u ", kstat_irqs(i));
+#else
+       for_each_online_cpu(j)
+               seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
+#endif
+       seq_printf(p, " %8s", desc->chip->name);
+       seq_printf(p, "-%-8s", desc->name);
+
+       if (action) {
+               seq_printf(p, "  %s", action->name);
+               while ((action = action->next) != NULL)
+                       seq_printf(p, ", %s", action->name);
+       }
+
+       seq_putc(p, '\n');
+out:
+       spin_unlock_irqrestore(&desc->lock, flags);
+       return 0;
+}
+
+/*
+ * /proc/stat helpers
+ */
+u64 arch_irq_stat_cpu(unsigned int cpu)
+{
+       u64 sum = irq_stats(cpu)->__nmi_count;
+
+#ifdef CONFIG_X86_LOCAL_APIC
+       sum += irq_stats(cpu)->apic_timer_irqs;
+#endif
+#ifdef CONFIG_SMP
+       sum += irq_stats(cpu)->irq_resched_count;
+       sum += irq_stats(cpu)->irq_call_count;
+       sum += irq_stats(cpu)->irq_tlb_count;
+#endif
+#ifdef CONFIG_X86_MCE
+       sum += irq_stats(cpu)->irq_thermal_count;
+# ifdef CONFIG_X86_64
+       sum += irq_stats(cpu)->irq_threshold_count;
+#endif
+#endif
+#ifdef CONFIG_X86_LOCAL_APIC
+       sum += irq_stats(cpu)->irq_spurious_count;
+#endif
+       return sum;
+}
+
+u64 arch_irq_stat(void)
+{
+       u64 sum = atomic_read(&irq_err_count);
+
+#ifdef CONFIG_X86_IO_APIC
+       sum += atomic_read(&irq_mis_count);
+#endif
+       return sum;
+}
index b71e02d42f4fd288a21a51f256c422b6d4d74d83..a51382672de0c5e5fb291bd6ff6bce13396a8f73 100644 (file)
@@ -25,29 +25,6 @@ EXPORT_PER_CPU_SYMBOL(irq_stat);
 DEFINE_PER_CPU(struct pt_regs *, irq_regs);
 EXPORT_PER_CPU_SYMBOL(irq_regs);
 
-/*
- * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themselves.
- */
-void ack_bad_irq(unsigned int irq)
-{
-       printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq);
-
-#ifdef CONFIG_X86_LOCAL_APIC
-       /*
-        * Currently unexpected vectors happen only on SMP and APIC.
-        * We _must_ ack these because every local APIC has only N
-        * irq slots per priority level, and a 'hanging, unacked' IRQ
-        * holds up an irq slot - in excessive cases (when multiple
-        * unexpected vectors occur) that might lock up the APIC
-        * completely.
-        * But only ack when the APIC is enabled -AK
-        */
-       if (cpu_has_apic)
-               ack_APIC_irq();
-#endif
-}
-
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
 /* Debugging check for stack overflow: is there less than 1KB free? */
 static int check_stack_overflow(void)
@@ -223,20 +200,25 @@ unsigned int do_IRQ(struct pt_regs *regs)
 {
        struct pt_regs *old_regs;
        /* high bit used in ret_from_ code */
-       int overflow, irq = ~regs->orig_ax;
-       struct irq_desc *desc = irq_desc + irq;
+       int overflow;
+       unsigned vector = ~regs->orig_ax;
+       struct irq_desc *desc;
+       unsigned irq;
 
-       if (unlikely((unsigned)irq >= NR_IRQS)) {
-               printk(KERN_EMERG "%s: cannot handle IRQ %d\n",
-                                       __func__, irq);
-               BUG();
-       }
 
        old_regs = set_irq_regs(regs);
        irq_enter();
+       irq = __get_cpu_var(vector_irq)[vector];
 
        overflow = check_stack_overflow();
 
+       desc = irq_to_desc(irq);
+       if (unlikely(!desc)) {
+               printk(KERN_EMERG "%s: cannot handle IRQ %d vector %#x cpu %d\n",
+                                       __func__, irq, vector, smp_processor_id());
+               BUG();
+       }
+
        if (!execute_on_irq_stack(overflow, desc, irq)) {
                if (unlikely(overflow))
                        print_stack_overflow();
@@ -248,146 +230,6 @@ unsigned int do_IRQ(struct pt_regs *regs)
        return 1;
 }
 
-/*
- * Interrupt statistics:
- */
-
-atomic_t irq_err_count;
-
-/*
- * /proc/interrupts printing:
- */
-
-int show_interrupts(struct seq_file *p, void *v)
-{
-       int i = *(loff_t *) v, j;
-       struct irqaction * action;
-       unsigned long flags;
-
-       if (i == 0) {
-               seq_printf(p, "           ");
-               for_each_online_cpu(j)
-                       seq_printf(p, "CPU%-8d",j);
-               seq_putc(p, '\n');
-       }
-
-       if (i < NR_IRQS) {
-               unsigned any_count = 0;
-
-               spin_lock_irqsave(&irq_desc[i].lock, flags);
-#ifndef CONFIG_SMP
-               any_count = kstat_irqs(i);
-#else
-               for_each_online_cpu(j)
-                       any_count |= kstat_cpu(j).irqs[i];
-#endif
-               action = irq_desc[i].action;
-               if (!action && !any_count)
-                       goto skip;
-               seq_printf(p, "%3d: ",i);
-#ifndef CONFIG_SMP
-               seq_printf(p, "%10u ", kstat_irqs(i));
-#else
-               for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
-#endif
-               seq_printf(p, " %8s", irq_desc[i].chip->name);
-               seq_printf(p, "-%-8s", irq_desc[i].name);
-
-               if (action) {
-                       seq_printf(p, "  %s", action->name);
-                       while ((action = action->next) != NULL)
-                               seq_printf(p, ", %s", action->name);
-               }
-
-               seq_putc(p, '\n');
-skip:
-               spin_unlock_irqrestore(&irq_desc[i].lock, flags);
-       } else if (i == NR_IRQS) {
-               seq_printf(p, "NMI: ");
-               for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", nmi_count(j));
-               seq_printf(p, "  Non-maskable interrupts\n");
-#ifdef CONFIG_X86_LOCAL_APIC
-               seq_printf(p, "LOC: ");
-               for_each_online_cpu(j)
-                       seq_printf(p, "%10u ",
-                               per_cpu(irq_stat,j).apic_timer_irqs);
-               seq_printf(p, "  Local timer interrupts\n");
-#endif
-#ifdef CONFIG_SMP
-               seq_printf(p, "RES: ");
-               for_each_online_cpu(j)
-                       seq_printf(p, "%10u ",
-                               per_cpu(irq_stat,j).irq_resched_count);
-               seq_printf(p, "  Rescheduling interrupts\n");
-               seq_printf(p, "CAL: ");
-               for_each_online_cpu(j)
-                       seq_printf(p, "%10u ",
-                               per_cpu(irq_stat,j).irq_call_count);
-               seq_printf(p, "  Function call interrupts\n");
-               seq_printf(p, "TLB: ");
-               for_each_online_cpu(j)
-                       seq_printf(p, "%10u ",
-                               per_cpu(irq_stat,j).irq_tlb_count);
-               seq_printf(p, "  TLB shootdowns\n");
-#endif
-#ifdef CONFIG_X86_MCE
-               seq_printf(p, "TRM: ");
-               for_each_online_cpu(j)
-                       seq_printf(p, "%10u ",
-                               per_cpu(irq_stat,j).irq_thermal_count);
-               seq_printf(p, "  Thermal event interrupts\n");
-#endif
-#ifdef CONFIG_X86_LOCAL_APIC
-               seq_printf(p, "SPU: ");
-               for_each_online_cpu(j)
-                       seq_printf(p, "%10u ",
-                               per_cpu(irq_stat,j).irq_spurious_count);
-               seq_printf(p, "  Spurious interrupts\n");
-#endif
-               seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
-#if defined(CONFIG_X86_IO_APIC)
-               seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
-#endif
-       }
-       return 0;
-}
-
-/*
- * /proc/stat helpers
- */
-u64 arch_irq_stat_cpu(unsigned int cpu)
-{
-       u64 sum = nmi_count(cpu);
-
-#ifdef CONFIG_X86_LOCAL_APIC
-       sum += per_cpu(irq_stat, cpu).apic_timer_irqs;
-#endif
-#ifdef CONFIG_SMP
-       sum += per_cpu(irq_stat, cpu).irq_resched_count;
-       sum += per_cpu(irq_stat, cpu).irq_call_count;
-       sum += per_cpu(irq_stat, cpu).irq_tlb_count;
-#endif
-#ifdef CONFIG_X86_MCE
-       sum += per_cpu(irq_stat, cpu).irq_thermal_count;
-#endif
-#ifdef CONFIG_X86_LOCAL_APIC
-       sum += per_cpu(irq_stat, cpu).irq_spurious_count;
-#endif
-       return sum;
-}
-
-u64 arch_irq_stat(void)
-{
-       u64 sum = atomic_read(&irq_err_count);
-
-#ifdef CONFIG_X86_IO_APIC
-       sum += atomic_read(&irq_mis_count);
-#endif
-       return sum;
-}
-
 #ifdef CONFIG_HOTPLUG_CPU
 #include <mach_apic.h>
 
@@ -395,20 +237,22 @@ void fixup_irqs(cpumask_t map)
 {
        unsigned int irq;
        static int warned;
+       struct irq_desc *desc;
 
-       for (irq = 0; irq < NR_IRQS; irq++) {
+       for_each_irq_desc(irq, desc) {
                cpumask_t mask;
+
                if (irq == 2)
                        continue;
 
-               cpus_and(mask, irq_desc[irq].affinity, map);
+               cpus_and(mask, desc->affinity, map);
                if (any_online_cpu(mask) == NR_CPUS) {
                        printk("Breaking affinity for irq %i\n", irq);
                        mask = map;
                }
-               if (irq_desc[irq].chip->set_affinity)
-                       irq_desc[irq].chip->set_affinity(irq, mask);
-               else if (irq_desc[irq].action && !(warned++))
+               if (desc->chip->set_affinity)
+                       desc->chip->set_affinity(irq, mask);
+               else if (desc->action && !(warned++))
                        printk("Cannot set affinity for irq %i\n", irq);
        }
 
index f065fe9071b9f65dcaf1d519c0063065c43cce62..60eb84eb77a0a34232be8aafbe8a7d1e040f454f 100644 (file)
 #include <asm/idle.h>
 #include <asm/smp.h>
 
-atomic_t irq_err_count;
-
-/*
- * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themselves.
- */
-void ack_bad_irq(unsigned int irq)
-{
-       printk(KERN_WARNING "unexpected IRQ trap at vector %02x\n", irq);
-       /*
-        * Currently unexpected vectors happen only on SMP and APIC.
-        * We _must_ ack these because every local APIC has only N
-        * irq slots per priority level, and a 'hanging, unacked' IRQ
-        * holds up an irq slot - in excessive cases (when multiple
-        * unexpected vectors occur) that might lock up the APIC
-        * completely.
-        * But don't ack when the APIC is disabled. -AK
-        */
-       if (!disable_apic)
-               ack_APIC_irq();
-}
-
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
 /*
  * Probabilistic stack overflow check:
@@ -64,122 +42,6 @@ static inline void stack_overflow_check(struct pt_regs *regs)
 }
 #endif
 
-/*
- * Generic, controller-independent functions:
- */
-
-int show_interrupts(struct seq_file *p, void *v)
-{
-       int i = *(loff_t *) v, j;
-       struct irqaction * action;
-       unsigned long flags;
-
-       if (i == 0) {
-               seq_printf(p, "           ");
-               for_each_online_cpu(j)
-                       seq_printf(p, "CPU%-8d",j);
-               seq_putc(p, '\n');
-       }
-
-       if (i < NR_IRQS) {
-               unsigned any_count = 0;
-
-               spin_lock_irqsave(&irq_desc[i].lock, flags);
-#ifndef CONFIG_SMP
-               any_count = kstat_irqs(i);
-#else
-               for_each_online_cpu(j)
-                       any_count |= kstat_cpu(j).irqs[i];
-#endif
-               action = irq_desc[i].action;
-               if (!action && !any_count)
-                       goto skip;
-               seq_printf(p, "%3d: ",i);
-#ifndef CONFIG_SMP
-               seq_printf(p, "%10u ", kstat_irqs(i));
-#else
-               for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
-#endif
-               seq_printf(p, " %8s", irq_desc[i].chip->name);
-               seq_printf(p, "-%-8s", irq_desc[i].name);
-
-               if (action) {
-                       seq_printf(p, "  %s", action->name);
-                       while ((action = action->next) != NULL)
-                               seq_printf(p, ", %s", action->name);
-               }
-               seq_putc(p, '\n');
-skip:
-               spin_unlock_irqrestore(&irq_desc[i].lock, flags);
-       } else if (i == NR_IRQS) {
-               seq_printf(p, "NMI: ");
-               for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", cpu_pda(j)->__nmi_count);
-               seq_printf(p, "  Non-maskable interrupts\n");
-               seq_printf(p, "LOC: ");
-               for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", cpu_pda(j)->apic_timer_irqs);
-               seq_printf(p, "  Local timer interrupts\n");
-#ifdef CONFIG_SMP
-               seq_printf(p, "RES: ");
-               for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", cpu_pda(j)->irq_resched_count);
-               seq_printf(p, "  Rescheduling interrupts\n");
-               seq_printf(p, "CAL: ");
-               for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", cpu_pda(j)->irq_call_count);
-               seq_printf(p, "  Function call interrupts\n");
-               seq_printf(p, "TLB: ");
-               for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", cpu_pda(j)->irq_tlb_count);
-               seq_printf(p, "  TLB shootdowns\n");
-#endif
-#ifdef CONFIG_X86_MCE
-               seq_printf(p, "TRM: ");
-               for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", cpu_pda(j)->irq_thermal_count);
-               seq_printf(p, "  Thermal event interrupts\n");
-               seq_printf(p, "THR: ");
-               for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", cpu_pda(j)->irq_threshold_count);
-               seq_printf(p, "  Threshold APIC interrupts\n");
-#endif
-               seq_printf(p, "SPU: ");
-               for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", cpu_pda(j)->irq_spurious_count);
-               seq_printf(p, "  Spurious interrupts\n");
-               seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
-       }
-       return 0;
-}
-
-/*
- * /proc/stat helpers
- */
-u64 arch_irq_stat_cpu(unsigned int cpu)
-{
-       u64 sum = cpu_pda(cpu)->__nmi_count;
-
-       sum += cpu_pda(cpu)->apic_timer_irqs;
-#ifdef CONFIG_SMP
-       sum += cpu_pda(cpu)->irq_resched_count;
-       sum += cpu_pda(cpu)->irq_call_count;
-       sum += cpu_pda(cpu)->irq_tlb_count;
-#endif
-#ifdef CONFIG_X86_MCE
-       sum += cpu_pda(cpu)->irq_thermal_count;
-       sum += cpu_pda(cpu)->irq_threshold_count;
-#endif
-       sum += cpu_pda(cpu)->irq_spurious_count;
-       return sum;
-}
-
-u64 arch_irq_stat(void)
-{
-       return atomic_read(&irq_err_count);
-}
-
 /*
  * do_IRQ handles all normal device IRQ's (the special
  * SMP cross-CPU interrupts have their own specific
@@ -188,6 +50,7 @@ u64 arch_irq_stat(void)
 asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
 {
        struct pt_regs *old_regs = set_irq_regs(regs);
+       struct irq_desc *desc;
 
        /* high bit used in ret_from_ code  */
        unsigned vector = ~regs->orig_ax;
@@ -201,8 +64,9 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
        stack_overflow_check(regs);
 #endif
 
-       if (likely(irq < NR_IRQS))
-               generic_handle_irq(irq);
+       desc = irq_to_desc(irq);
+       if (likely(desc))
+               generic_handle_irq_desc(irq, desc);
        else {
                if (!disable_apic)
                        ack_APIC_irq();
@@ -223,8 +87,9 @@ void fixup_irqs(cpumask_t map)
 {
        unsigned int irq;
        static int warned;
+       struct irq_desc *desc;
 
-       for (irq = 0; irq < NR_IRQS; irq++) {
+       for_each_irq_desc(irq, desc) {
                cpumask_t mask;
                int break_affinity = 0;
                int set_affinity = 1;
@@ -233,32 +98,32 @@ void fixup_irqs(cpumask_t map)
                        continue;
 
                /* interrupt's are disabled at this point */
-               spin_lock(&irq_desc[irq].lock);
+               spin_lock(&desc->lock);
 
                if (!irq_has_action(irq) ||
-                   cpus_equal(irq_desc[irq].affinity, map)) {
-                       spin_unlock(&irq_desc[irq].lock);
+                   cpus_equal(desc->affinity, map)) {
+                       spin_unlock(&desc->lock);
                        continue;
                }
 
-               cpus_and(mask, irq_desc[irq].affinity, map);
+               cpus_and(mask, desc->affinity, map);
                if (cpus_empty(mask)) {
                        break_affinity = 1;
                        mask = map;
                }
 
-               if (irq_desc[irq].chip->mask)
-                       irq_desc[irq].chip->mask(irq);
+               if (desc->chip->mask)
+                       desc->chip->mask(irq);
 
-               if (irq_desc[irq].chip->set_affinity)
-                       irq_desc[irq].chip->set_affinity(irq, mask);
+               if (desc->chip->set_affinity)
+                       desc->chip->set_affinity(irq, mask);
                else if (!(warned++))
                        set_affinity = 0;
 
-               if (irq_desc[irq].chip->unmask)
-                       irq_desc[irq].chip->unmask(irq);
+               if (desc->chip->unmask)
+                       desc->chip->unmask(irq);
 
-               spin_unlock(&irq_desc[irq].lock);
+               spin_unlock(&desc->lock);
 
                if (break_affinity && set_affinity)
                        printk("Broke affinity for irq %i\n", irq);
index 9200a1e2752dd04846cff1205d4731a8965d4b78..845aa9803e804edd7cdc6ef5bb61e2db72f1a911 100644 (file)
@@ -69,6 +69,13 @@ void __init init_ISA_irqs (void)
         * 16 old-style INTA-cycle interrupts:
         */
        for (i = 0; i < 16; i++) {
+               /* first time call this irq_desc */
+               struct irq_desc *desc = irq_to_desc(i);
+
+               desc->status = IRQ_DISABLED;
+               desc->action = NULL;
+               desc->depth = 1;
+
                set_irq_chip_and_handler_name(i, &i8259A_chip,
                                              handle_level_irq, "XT");
        }
@@ -83,6 +90,27 @@ static struct irqaction irq2 = {
        .name = "cascade",
 };
 
+DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
+       [0 ... IRQ0_VECTOR - 1] = -1,
+       [IRQ0_VECTOR] = 0,
+       [IRQ1_VECTOR] = 1,
+       [IRQ2_VECTOR] = 2,
+       [IRQ3_VECTOR] = 3,
+       [IRQ4_VECTOR] = 4,
+       [IRQ5_VECTOR] = 5,
+       [IRQ6_VECTOR] = 6,
+       [IRQ7_VECTOR] = 7,
+       [IRQ8_VECTOR] = 8,
+       [IRQ9_VECTOR] = 9,
+       [IRQ10_VECTOR] = 10,
+       [IRQ11_VECTOR] = 11,
+       [IRQ12_VECTOR] = 12,
+       [IRQ13_VECTOR] = 13,
+       [IRQ14_VECTOR] = 14,
+       [IRQ15_VECTOR] = 15,
+       [IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1
+};
+
 /* Overridden in paravirt.c */
 void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));
 
@@ -98,22 +126,14 @@ void __init native_init_IRQ(void)
         * us. (some of these will be overridden and become
         * 'special' SMP interrupts)
         */
-       for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) {
-               int vector = FIRST_EXTERNAL_VECTOR + i;
-               if (i >= NR_IRQS)
-                       break;
+       for (i =  FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) {
                /* SYSCALL_VECTOR was reserved in trap_init. */
-               if (!test_bit(vector, used_vectors))
-                       set_intr_gate(vector, interrupt[i]);
+               if (i != SYSCALL_VECTOR)
+                       set_intr_gate(i, interrupt[i]);
        }
 
-#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_SMP)
-       /*
-        * IRQ0 must be given a fixed assignment and initialized,
-        * because it's used before the IO-APIC is set up.
-        */
-       set_intr_gate(FIRST_DEVICE_VECTOR, interrupt[0]);
 
+#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_SMP)
        /*
         * The reschedule interrupt is a CPU-to-CPU reschedule-helper
         * IPI, driven by wakeup.
@@ -128,6 +148,9 @@ void __init native_init_IRQ(void)
 
        /* IPI for single call function */
        set_intr_gate(CALL_FUNCTION_SINGLE_VECTOR, call_function_single_interrupt);
+
+       /* Low priority IPI to cleanup after moving an irq */
+       set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt);
 #endif
 
 #ifdef CONFIG_X86_LOCAL_APIC
index 5b5be9d43c2a865fdcbe1ac0f689e750f5e6f5de..ff0235391285a6dc388e1d175f04a6425972d90f 100644 (file)
@@ -142,23 +142,19 @@ void __init init_ISA_irqs(void)
        init_bsp_APIC();
        init_8259A(0);
 
-       for (i = 0; i < NR_IRQS; i++) {
-               irq_desc[i].status = IRQ_DISABLED;
-               irq_desc[i].action = NULL;
-               irq_desc[i].depth = 1;
-
-               if (i < 16) {
-                       /*
-                        * 16 old-style INTA-cycle interrupts:
-                        */
-                       set_irq_chip_and_handler_name(i, &i8259A_chip,
+       for (i = 0; i < 16; i++) {
+               /* first time call this irq_desc */
+               struct irq_desc *desc = irq_to_desc(i);
+
+               desc->status = IRQ_DISABLED;
+               desc->action = NULL;
+               desc->depth = 1;
+
+               /*
+                * 16 old-style INTA-cycle interrupts:
+                */
+               set_irq_chip_and_handler_name(i, &i8259A_chip,
                                                      handle_level_irq, "XT");
-               } else {
-                       /*
-                        * 'high' PCI IRQs filled in on demand
-                        */
-                       irq_desc[i].chip = &no_irq_chip;
-               }
        }
 }
 
index 192624820217f9eeeb64ee39ada5ad57a76a0df5..1972266e8ba59fb845bec4df4e59c5d04707ec5d 100644 (file)
@@ -9,8 +9,6 @@
 #include <asm/calgary.h>
 #include <asm/amd_iommu.h>
 
-static int forbid_dac __read_mostly;
-
 struct dma_mapping_ops *dma_ops;
 EXPORT_SYMBOL(dma_ops);
 
@@ -293,17 +291,3 @@ void pci_iommu_shutdown(void)
 }
 /* Must execute after PCI subsystem */
 fs_initcall(pci_iommu_init);
-
-#ifdef CONFIG_PCI
-/* Many VIA bridges seem to corrupt data for DAC. Disable it here */
-
-static __devinit void via_no_dac(struct pci_dev *dev)
-{
-       if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) {
-               printk(KERN_INFO "PCI: VIA PCI bridge detected."
-                                "Disabling DAC.\n");
-               forbid_dac = 1;
-       }
-}
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, via_no_dac);
-#endif
index cd8c0ed02b7e2c017905a403f10fc3cd25413f4a..c958120fb1b6f549f853a79a26864abeb38ceb24 100644 (file)
@@ -63,6 +63,13 @@ void idle_notifier_register(struct notifier_block *n)
 {
        atomic_notifier_chain_register(&idle_notifier, n);
 }
+EXPORT_SYMBOL_GPL(idle_notifier_register);
+
+void idle_notifier_unregister(struct notifier_block *n)
+{
+       atomic_notifier_chain_unregister(&idle_notifier, n);
+}
+EXPORT_SYMBOL_GPL(idle_notifier_unregister);
 
 void enter_idle(void)
 {
index f6a11b9b1f9887f8979e67c982c5c5a39b3e1915..67465ed8931088b52d9b521cb3a116511cef9e42 100644 (file)
@@ -35,9 +35,6 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
        if (!(word & (1 << 13))) {
                dev_info(&dev->dev, "Intel E7520/7320/7525 detected; "
                        "disabling irq balancing and affinity\n");
-#ifdef CONFIG_IRQBALANCE
-               irqbalance_disable("");
-#endif
                noirqdebug_setup("");
 #ifdef CONFIG_PROC_FS
                no_irq_affinity = 1;
index b2c97874ec0f95f7cfbea51b7b7695a2939c1b01..0fa6790c1dd37d76e257de661ba3ed9312de89e0 100644 (file)
@@ -1073,6 +1073,7 @@ void __init setup_arch(char **cmdline_p)
 #endif
 
        prefill_possible_map();
+
 #ifdef CONFIG_X86_64
        init_cpu_to_node();
 #endif
@@ -1080,6 +1081,9 @@ void __init setup_arch(char **cmdline_p)
        init_apic_mappings();
        ioapic_init_mappings();
 
+       /* need to wait for io_apic is mapped */
+       nr_irqs = probe_nr_irqs();
+
        kvm_guest_init();
 
        e820_reserve_resources();
index 0e67f72d931683413160a007d554c44a438c2c28..ae0c0d3bb7704605440467d26ec48eaf84faad83 100644 (file)
@@ -140,25 +140,30 @@ static void __init setup_cpu_pda_map(void)
  */
 void __init setup_per_cpu_areas(void)
 {
-       ssize_t size = PERCPU_ENOUGH_ROOM;
+       ssize_t size, old_size;
        char *ptr;
        int cpu;
+       unsigned long align = 1;
 
        /* Setup cpu_pda map */
        setup_cpu_pda_map();
 
        /* Copy section for each CPU (we discard the original) */
-       size = PERCPU_ENOUGH_ROOM;
+       old_size = PERCPU_ENOUGH_ROOM;
+       align = max_t(unsigned long, PAGE_SIZE, align);
+       size = roundup(old_size, align);
        printk(KERN_INFO "PERCPU: Allocating %zd bytes of per cpu data\n",
                          size);
 
        for_each_possible_cpu(cpu) {
 #ifndef CONFIG_NEED_MULTIPLE_NODES
-               ptr = alloc_bootmem_pages(size);
+               ptr = __alloc_bootmem(size, align,
+                                __pa(MAX_DMA_ADDRESS));
 #else
                int node = early_cpu_to_node(cpu);
                if (!node_online(node) || !NODE_DATA(node)) {
-                       ptr = alloc_bootmem_pages(size);
+                       ptr = __alloc_bootmem(size, align,
+                                        __pa(MAX_DMA_ADDRESS));
                        printk(KERN_INFO
                               "cpu %d has no node %d or node-local memory\n",
                                cpu, node);
@@ -167,7 +172,8 @@ void __init setup_per_cpu_areas(void)
                                         cpu, __pa(ptr));
                }
                else {
-                       ptr = alloc_bootmem_pages_node(NODE_DATA(node), size);
+                       ptr = __alloc_bootmem_node(NODE_DATA(node), size, align,
+                                                       __pa(MAX_DMA_ADDRESS));
                        if (ptr)
                                printk(KERN_DEBUG "per cpu data for cpu%d on node%d at %016lx\n",
                                         cpu, node, __pa(ptr));
@@ -175,7 +181,6 @@ void __init setup_per_cpu_areas(void)
 #endif
                per_cpu_offset(cpu) = ptr - __per_cpu_start;
                memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
-
        }
 
        printk(KERN_DEBUG "NR_CPUS: %d, nr_cpu_ids: %d, nr_node_ids %d\n",
@@ -213,7 +218,7 @@ static void __init setup_node_to_cpumask_map(void)
        /* allocate the map */
        map = alloc_bootmem_low(nr_node_ids * sizeof(cpumask_t));
 
-       pr_debug(KERN_DEBUG "Node to cpumask map at %p for %d nodes\n",
+       pr_debug("Node to cpumask map at %p for %d nodes\n",
                 map, nr_node_ids);
 
        /* node_to_cpumask() will now work */
index 7ed9e070a6e930d97e2d55c8750a50f57a9baef1..7b1093397319766b2e4848a5a883b0dc35f49804 100644 (file)
@@ -543,10 +543,10 @@ static inline void __inquire_remote_apic(int apicid)
        int timeout;
        u32 status;
 
-       printk(KERN_INFO "Inquiring remote APIC #%d...\n", apicid);
+       printk(KERN_INFO "Inquiring remote APIC 0x%x...\n", apicid);
 
        for (i = 0; i < ARRAY_SIZE(regs); i++) {
-               printk(KERN_INFO "... APIC #%d %s: ", apicid, names[i]);
+               printk(KERN_INFO "... APIC 0x%x %s: ", apicid, names[i]);
 
                /*
                 * Wait for idle.
@@ -874,7 +874,7 @@ do_rest:
        start_ip = setup_trampoline();
 
        /* So we see what's up   */
-       printk(KERN_INFO "Booting processor %d/%d ip %lx\n",
+       printk(KERN_INFO "Booting processor %d APIC 0x%x ip 0x%lx\n",
                          cpu, apicid, start_ip);
 
        /*
@@ -893,9 +893,11 @@ do_rest:
                smpboot_setup_warm_reset_vector(start_ip);
                /*
                 * Be paranoid about clearing APIC errors.
-               */
-               apic_write(APIC_ESR, 0);
-               apic_read(APIC_ESR);
+               */
+               if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
+                       apic_write(APIC_ESR, 0);
+                       apic_read(APIC_ESR);
+               }
        }
 
        /*
index 3d1be4f0fac563f56247204e8d62967872092268..de87d6008295c5459aa1cbc9f41037829e1c82c8 100644 (file)
@@ -8,12 +8,12 @@
 #define __NO_STUBS
 
 #define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ;
-#undef ASM_X86__UNISTD_64_H
+#undef _ASM_X86_UNISTD_64_H
 #include <asm/unistd_64.h>
 
 #undef __SYSCALL
 #define __SYSCALL(nr, sym) [nr] = sym,
-#undef ASM_X86__UNISTD_64_H
+#undef _ASM_X86_UNISTD_64_H
 
 typedef void (*sys_call_ptr_t)(void);
 
index 8b8c0d6640fa9ba9ca7da73fac2cb4ee52e7be26..04431f34fd16f24946bb66b4eedf69ed7e51cf6f 100644 (file)
@@ -6,7 +6,7 @@
  *     This code is released under the GNU General Public License version 2 or
  *     later.
  */
-#include <linux/mc146818rtc.h>
+#include <linux/seq_file.h>
 #include <linux/proc_fs.h>
 #include <linux/kernel.h>
 
index e062974cce34265bc9f20857e3e4996c62c153c9..04d242ab0161967985bcb7f9e24f9fe54fb9f33f 100644 (file)
@@ -931,14 +931,6 @@ do_device_not_available(struct pt_regs *regs, long error)
 }
 
 #ifdef CONFIG_X86_32
-#ifdef CONFIG_X86_MCE
-dotraplinkage void __kprobes do_machine_check(struct pt_regs *regs, long error)
-{
-       conditional_sti(regs);
-       machine_check_vector(regs, error);
-}
-#endif
-
 dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code)
 {
        siginfo_t info;
diff --git a/arch/x86/kernel/uv_irq.c b/arch/x86/kernel/uv_irq.c
new file mode 100644 (file)
index 0000000..aeef529
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ *
+ * SGI UV IRQ functions
+ *
+ * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/irq.h>
+
+#include <asm/apic.h>
+#include <asm/uv/uv_irq.h>
+
+static void uv_noop(unsigned int irq)
+{
+}
+
+static unsigned int uv_noop_ret(unsigned int irq)
+{
+       return 0;
+}
+
+static void uv_ack_apic(unsigned int irq)
+{
+       ack_APIC_irq();
+}
+
+struct irq_chip uv_irq_chip = {
+       .name           = "UV-CORE",
+       .startup        = uv_noop_ret,
+       .shutdown       = uv_noop,
+       .enable         = uv_noop,
+       .disable        = uv_noop,
+       .ack            = uv_noop,
+       .mask           = uv_noop,
+       .unmask         = uv_noop,
+       .eoi            = uv_ack_apic,
+       .end            = uv_noop,
+};
+
+/*
+ * Set up a mapping of an available irq and vector, and enable the specified
+ * MMR that defines the MSI that is to be sent to the specified CPU when an
+ * interrupt is raised.
+ */
+int uv_setup_irq(char *irq_name, int cpu, int mmr_blade,
+                unsigned long mmr_offset)
+{
+       int irq;
+       int ret;
+
+       irq = create_irq();
+       if (irq <= 0)
+               return -EBUSY;
+
+       ret = arch_enable_uv_irq(irq_name, irq, cpu, mmr_blade, mmr_offset);
+       if (ret != irq)
+               destroy_irq(irq);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(uv_setup_irq);
+
+/*
+ * Tear down a mapping of an irq and vector, and disable the specified MMR that
+ * defined the MSI that was to be sent to the specified CPU when an interrupt
+ * was raised.
+ *
+ * Set mmr_blade and mmr_offset to what was passed in on uv_setup_irq().
+ */
+void uv_teardown_irq(unsigned int irq, int mmr_blade, unsigned long mmr_offset)
+{
+       arch_disable_uv_irq(mmr_blade, mmr_offset);
+       destroy_irq(irq);
+}
+EXPORT_SYMBOL_GPL(uv_teardown_irq);
diff --git a/arch/x86/kernel/uv_sysfs.c b/arch/x86/kernel/uv_sysfs.c
new file mode 100644 (file)
index 0000000..67f9b9d
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * This file supports the /sys/firmware/sgi_uv interfaces for SGI UV.
+ *
+ *  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) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ *  Copyright (c) Russ Anderson
+ */
+
+#include <linux/sysdev.h>
+#include <asm/uv/bios.h>
+
+struct kobject *sgi_uv_kobj;
+
+static ssize_t partition_id_show(struct kobject *kobj,
+                       struct kobj_attribute *attr, char *buf)
+{
+       return snprintf(buf, PAGE_SIZE, "%ld\n", sn_partition_id);
+}
+
+static ssize_t coherence_id_show(struct kobject *kobj,
+                       struct kobj_attribute *attr, char *buf)
+{
+       return snprintf(buf, PAGE_SIZE, "%ld\n", partition_coherence_id());
+}
+
+static struct kobj_attribute partition_id_attr =
+       __ATTR(partition_id, S_IRUGO, partition_id_show, NULL);
+
+static struct kobj_attribute coherence_id_attr =
+       __ATTR(coherence_id, S_IRUGO, coherence_id_show, NULL);
+
+
+static int __init sgi_uv_sysfs_init(void)
+{
+       unsigned long ret;
+
+       if (!sgi_uv_kobj)
+               sgi_uv_kobj = kobject_create_and_add("sgi_uv", firmware_kobj);
+       if (!sgi_uv_kobj) {
+               printk(KERN_WARNING "kobject_create_and_add sgi_uv failed \n");
+               return -EINVAL;
+       }
+
+       ret = sysfs_create_file(sgi_uv_kobj, &partition_id_attr.attr);
+       if (ret) {
+               printk(KERN_WARNING "sysfs_create_file partition_id failed \n");
+               return ret;
+       }
+
+       ret = sysfs_create_file(sgi_uv_kobj, &coherence_id_attr.attr);
+       if (ret) {
+               printk(KERN_WARNING "sysfs_create_file coherence_id failed \n");
+               return ret;
+       }
+
+       return 0;
+}
+
+device_initcall(sgi_uv_sysfs_init);
index 61a97e616f7034e252fe1e23e8e1fc847fd476f3..0c9667f0752ad7c8b98a1b762d7c6e10dcd07b11 100644 (file)
@@ -484,10 +484,11 @@ static void disable_cobalt_irq(unsigned int irq)
 static unsigned int startup_cobalt_irq(unsigned int irq)
 {
        unsigned long flags;
+       struct irq_desc *desc = irq_to_desc(irq);
 
        spin_lock_irqsave(&cobalt_lock, flags);
-       if ((irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING)))
-               irq_desc[irq].status &= ~(IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING);
+       if ((desc->status & (IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING)))
+               desc->status &= ~(IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING);
        enable_cobalt_irq(irq);
        spin_unlock_irqrestore(&cobalt_lock, flags);
        return 0;
@@ -506,9 +507,10 @@ static void ack_cobalt_irq(unsigned int irq)
 static void end_cobalt_irq(unsigned int irq)
 {
        unsigned long flags;
+       struct irq_desc *desc = irq_to_desc(irq);
 
        spin_lock_irqsave(&cobalt_lock, flags);
-       if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+       if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)))
                enable_cobalt_irq(irq);
        spin_unlock_irqrestore(&cobalt_lock, flags);
 }
@@ -626,12 +628,12 @@ static irqreturn_t piix4_master_intr(int irq, void *dev_id)
 
        spin_unlock_irqrestore(&i8259A_lock, flags);
 
-       desc = irq_desc + realirq;
+       desc = irq_to_desc(realirq);
 
        /*
         * handle this 'virtual interrupt' as a Cobalt one now.
         */
-       kstat_cpu(smp_processor_id()).irqs[realirq]++;
+       kstat_incr_irqs_this_cpu(realirq, desc);
 
        if (likely(desc->action != NULL))
                handle_IRQ_event(realirq, desc->action);
@@ -662,27 +664,29 @@ void init_VISWS_APIC_irqs(void)
        int i;
 
        for (i = 0; i < CO_IRQ_APIC0 + CO_APIC_LAST + 1; i++) {
-               irq_desc[i].status = IRQ_DISABLED;
-               irq_desc[i].action = 0;
-               irq_desc[i].depth = 1;
+               struct irq_desc *desc = irq_to_desc(i);
+
+               desc->status = IRQ_DISABLED;
+               desc->action = 0;
+               desc->depth = 1;
 
                if (i == 0) {
-                       irq_desc[i].chip = &cobalt_irq_type;
+                       desc->chip = &cobalt_irq_type;
                }
                else if (i == CO_IRQ_IDE0) {
-                       irq_desc[i].chip = &cobalt_irq_type;
+                       desc->chip = &cobalt_irq_type;
                }
                else if (i == CO_IRQ_IDE1) {
-                       irq_desc[i].chip = &cobalt_irq_type;
+                       desc->chip = &cobalt_irq_type;
                }
                else if (i == CO_IRQ_8259) {
-                       irq_desc[i].chip = &piix4_master_irq_type;
+                       desc->chip = &piix4_master_irq_type;
                }
                else if (i < CO_IRQ_APIC0) {
-                       irq_desc[i].chip = &piix4_virtual_irq_type;
+                       desc->chip = &piix4_virtual_irq_type;
                }
                else if (IS_CO_APIC(i)) {
-                       irq_desc[i].chip = &cobalt_irq_type;
+                       desc->chip = &cobalt_irq_type;
                }
        }
 
index 6953859fe28965bc77a7db5955a0b3a0d143127e..254ee07f8635007262591bbdf595f819caa1358d 100644 (file)
@@ -235,11 +235,14 @@ static void __devinit vmi_time_init_clockevent(void)
 
 void __init vmi_time_init(void)
 {
+       unsigned int cpu;
        /* Disable PIT: BIOSes start PIT CH0 with 18.2hz peridic. */
        outb_pit(0x3a, PIT_MODE); /* binary, mode 5, LSB/MSB, ch 0 */
 
        vmi_time_init_clockevent();
        setup_irq(0, &vmi_clock_action);
+       for_each_possible_cpu(cpu)
+               per_cpu(vector_irq, cpu)[vmi_get_timer_vector()] = 0;
 }
 
 #ifdef CONFIG_X86_LOCAL_APIC
index 9abac8a9d823656b720e81023aed96147b82d6f8..b13acb75e822e337aec4f8e8d6a094c24e30feb0 100644 (file)
@@ -248,7 +248,7 @@ clear:
  * This will be saved when ever the FP and extended state context is
  * saved on the user stack during the signal handler delivery to the user.
  */
-void prepare_fx_sw_frame(void)
+static void prepare_fx_sw_frame(void)
 {
        int size_extended = (xstate_size - sizeof(struct i387_fxsave_struct)) +
                             FP_XSTATE_MAGIC2_SIZE;
index 634132a9a512391d324def8826390a709d257c80..11c6725fb798b6967d60f07ea920fc594d292994 100644 (file)
@@ -204,10 +204,10 @@ static int __pit_timer_fn(struct kvm_kpit_state *ps)
        if (vcpu0 && waitqueue_active(&vcpu0->wq))
                wake_up_interruptible(&vcpu0->wq);
 
-       pt->timer.expires = ktime_add_ns(pt->timer.expires, pt->period);
-       pt->scheduled = ktime_to_ns(pt->timer.expires);
+       hrtimer_add_expires_ns(&pt->timer, pt->period);
+       pt->scheduled = hrtimer_get_expires_ns(&pt->timer);
        if (pt->period)
-               ps->channels[0].count_load_time = pt->timer.expires;
+               ps->channels[0].count_load_time = hrtimer_get_expires(&pt->timer);
 
        return (pt->period == 0 ? 0 : 1);
 }
@@ -257,7 +257,7 @@ void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu)
 
        timer = &pit->pit_state.pit_timer.timer;
        if (hrtimer_cancel(timer))
-               hrtimer_start(timer, timer->expires, HRTIMER_MODE_ABS);
+               hrtimer_start_expires(timer, HRTIMER_MODE_ABS);
 }
 
 static void destroy_pit_timer(struct kvm_kpit_timer *pt)
index 6571926bfd339b498c2ca06835b71d8ead494787..0fc3cab48943da8a3c513c7c753a4792c6743198 100644 (file)
@@ -946,9 +946,7 @@ static int __apic_timer_fn(struct kvm_lapic *apic)
 
        if (apic_lvtt_period(apic)) {
                result = 1;
-               apic->timer.dev.expires = ktime_add_ns(
-                                       apic->timer.dev.expires,
-                                       apic->timer.period);
+               hrtimer_add_expires_ns(&apic->timer.dev, apic->timer.period);
        }
        return result;
 }
@@ -1117,7 +1115,7 @@ void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu)
 
        timer = &apic->timer.dev;
        if (hrtimer_cancel(timer))
-               hrtimer_start(timer, timer->expires, HRTIMER_MODE_ABS);
+               hrtimer_start_expires(timer, HRTIMER_MODE_ABS);
 }
 
 void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu)
index 65f0b8a47bed0dd2ccdd31e507cdfd70846c4d48..48ee4f9435f418c45439ab02a1926a1c054cb071 100644 (file)
@@ -582,7 +582,7 @@ static void __init lguest_init_IRQ(void)
        for (i = 0; i < LGUEST_IRQS; i++) {
                int vector = FIRST_EXTERNAL_VECTOR + i;
                if (vector != SYSCALL_VECTOR) {
-                       set_intr_gate(vector, interrupt[i]);
+                       set_intr_gate(vector, interrupt[vector]);
                        set_irq_chip_and_handler_name(i, &lguest_irq_controller,
                                                      handle_level_irq,
                                                      "level");
index df37fc9d6a2612d0ddf1105b8510a320b3445923..3c3b471ea496225e5a53029b92cfd5eeee658e43 100644 (file)
@@ -41,6 +41,10 @@ static const struct dmi_system_id bigsmp_dmi_table[] = {
         { }
 };
 
+static cpumask_t vector_allocation_domain(int cpu)
+{
+        return cpumask_of_cpu(cpu);
+}
 
 static int probe_bigsmp(void)
 {
index 6513d41ea21eb54d84aa3c7720afaf7671f27d8e..28459cab3ddb5fdae0d560e5f766b141412e00bb 100644 (file)
@@ -75,4 +75,18 @@ static int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 }
 #endif
 
+static cpumask_t vector_allocation_domain(int cpu)
+{
+       /* Careful. Some cpus do not strictly honor the set of cpus
+        * specified in the interrupt destination when using lowest
+        * priority interrupt delivery mode.
+        *
+        * In particular there was a hyperthreading cpu observed to
+        * deliver interrupts to the wrong hyperthread when only one
+        * hyperthread was specified in the interrupt desitination.
+        */
+       cpumask_t domain = { { [0] = APIC_ALL_CPUS, } };
+       return domain;
+}
+
 struct genapic __initdata_refok apic_es7000 = APIC_INIT("es7000", probe_es7000);
index 8cf58394975e199ac7aaa0f70c2bc0de6547ccf2..71a309b122e672ef948fbe125f3637588ecf1149 100644 (file)
@@ -38,4 +38,18 @@ static int acpi_madt_oem_check(char *oem_id, char *oem_table_id)
        return 0;
 }
 
+static cpumask_t vector_allocation_domain(int cpu)
+{
+       /* Careful. Some cpus do not strictly honor the set of cpus
+        * specified in the interrupt destination when using lowest
+        * priority interrupt delivery mode.
+        *
+        * In particular there was a hyperthreading cpu observed to
+        * deliver interrupts to the wrong hyperthread when only one
+        * hyperthread was specified in the interrupt desitination.
+        */
+       cpumask_t domain = { { [0] = APIC_ALL_CPUS, } };
+       return domain;
+}
+
 struct genapic apic_numaq = APIC_INIT("NUMAQ", probe_numaq);
index 6ad6b67a723de01768c0373cac3023a43cd289b3..6272b5e69da62b28f660105d9a8788e4944432b3 100644 (file)
@@ -23,4 +23,18 @@ static int probe_summit(void)
        return 0;
 }
 
+static cpumask_t vector_allocation_domain(int cpu)
+{
+       /* Careful. Some cpus do not strictly honor the set of cpus
+        * specified in the interrupt destination when using lowest
+        * priority interrupt delivery mode.
+        *
+        * In particular there was a hyperthreading cpu observed to
+        * deliver interrupts to the wrong hyperthread when only one
+        * hyperthread was specified in the interrupt desitination.
+        */
+       cpumask_t domain = { { [0] = APIC_ALL_CPUS, } };
+       return domain;
+}
+
 struct genapic apic_summit = APIC_INIT("summit", probe_summit);
index 199a5f4a873c76b33728fbfaaf186a0fb6404530..0f6e8a6523ae1dfb6aed3031bbce9ae1341b6adc 100644 (file)
@@ -1483,7 +1483,7 @@ static void disable_local_vic_irq(unsigned int irq)
  * the interrupt off to another CPU */
 static void before_handle_vic_irq(unsigned int irq)
 {
-       irq_desc_t *desc = irq_desc + irq;
+       irq_desc_t *desc = irq_to_desc(irq);
        __u8 cpu = smp_processor_id();
 
        _raw_spin_lock(&vic_irq_lock);
@@ -1518,7 +1518,7 @@ static void before_handle_vic_irq(unsigned int irq)
 /* Finish the VIC interrupt: basically mask */
 static void after_handle_vic_irq(unsigned int irq)
 {
-       irq_desc_t *desc = irq_desc + irq;
+       irq_desc_t *desc = irq_to_desc(irq);
 
        _raw_spin_lock(&vic_irq_lock);
        {
index 672e17f8262a28d3fa9a1b3c9c6a734db84693fe..9cab18b0b857e2d199d54d402c4a9dd110a58d5c 100644 (file)
@@ -61,9 +61,9 @@ static void __init memtest(unsigned long start_phys, unsigned long size,
                                last_bad += incr;
                        } else {
                                if (start_bad) {
-                                       printk(KERN_CONT "\n  %010lx bad mem addr %010lx - %010lx reserved",
+                                       printk(KERN_CONT "\n  %016lx bad mem addr %010lx - %010lx reserved",
                                                val, start_bad, last_bad + incr);
-                                       reserve_early(start_bad, last_bad - start_bad, "BAD RAM");
+                                       reserve_early(start_bad, last_bad + incr, "BAD RAM");
                                }
                                start_bad = last_bad = start_phys_aligned;
                        }
@@ -72,9 +72,8 @@ static void __init memtest(unsigned long start_phys, unsigned long size,
        if (start_bad) {
                printk(KERN_CONT "\n  %016lx bad mem addr %010lx - %010lx reserved",
                        val, start_bad, last_bad + incr);
-               reserve_early(start_bad, last_bad - start_bad, "BAD RAM");
+               reserve_early(start_bad, last_bad + incr, "BAD RAM");
        }
-
 }
 
 /* default is disabled */
index 635b50e85581de29bc4a9d32ffbd82da6612838c..2c4baa88f2cb7a377e456a147e3c139dbe2f3dff 100644 (file)
@@ -56,13 +56,6 @@ struct remap_trace {
 static DEFINE_PER_CPU(struct trap_reason, pf_reason);
 static DEFINE_PER_CPU(struct mmiotrace_rw, cpu_trace);
 
-#if 0 /* XXX: no way gather this info anymore */
-/* Access to this is not per-cpu. */
-static DEFINE_PER_CPU(atomic_t, dropped);
-#endif
-
-static struct dentry *marker_file;
-
 static DEFINE_MUTEX(mmiotrace_mutex);
 static DEFINE_SPINLOCK(trace_lock);
 static atomic_t mmiotrace_enabled;
@@ -75,7 +68,7 @@ static LIST_HEAD(trace_list);         /* struct remap_trace */
  *   and trace_lock.
  * - Routines depending on is_enabled() must take trace_lock.
  * - trace_list users must hold trace_lock.
- * - is_enabled() guarantees that mmio_trace_record is allowed.
+ * - is_enabled() guarantees that mmio_trace_{rw,mapping} are allowed.
  * - pre/post callbacks assume the effect of is_enabled() being true.
  */
 
@@ -97,44 +90,6 @@ static bool is_enabled(void)
        return atomic_read(&mmiotrace_enabled);
 }
 
-#if 0 /* XXX: needs rewrite */
-/*
- * Write callback for the debugfs entry:
- * Read a marker and write it to the mmio trace log
- */
-static ssize_t write_marker(struct file *file, const char __user *buffer,
-                                               size_t count, loff_t *ppos)
-{
-       char *event = NULL;
-       struct mm_io_header *headp;
-       ssize_t len = (count > 65535) ? 65535 : count;
-
-       event = kzalloc(sizeof(*headp) + len, GFP_KERNEL);
-       if (!event)
-               return -ENOMEM;
-
-       headp = (struct mm_io_header *)event;
-       headp->type = MMIO_MAGIC | (MMIO_MARKER << MMIO_OPCODE_SHIFT);
-       headp->data_len = len;
-
-       if (copy_from_user(event + sizeof(*headp), buffer, len)) {
-               kfree(event);
-               return -EFAULT;
-       }
-
-       spin_lock_irq(&trace_lock);
-#if 0 /* XXX: convert this to use tracing */
-       if (is_enabled())
-               relay_write(chan, event, sizeof(*headp) + len);
-       else
-#endif
-               len = -EINVAL;
-       spin_unlock_irq(&trace_lock);
-       kfree(event);
-       return len;
-}
-#endif
-
 static void print_pte(unsigned long address)
 {
        unsigned int level;
@@ -307,8 +262,10 @@ static void ioremap_trace_core(resource_size_t offset, unsigned long size,
        map.map_id = trace->id;
 
        spin_lock_irq(&trace_lock);
-       if (!is_enabled())
+       if (!is_enabled()) {
+               kfree(trace);
                goto not_enabled;
+       }
 
        mmio_trace_mapping(&map);
        list_add_tail(&trace->list, &trace_list);
@@ -377,6 +334,23 @@ void mmiotrace_iounmap(volatile void __iomem *addr)
                iounmap_trace_core(addr);
 }
 
+int mmiotrace_printk(const char *fmt, ...)
+{
+       int ret = 0;
+       va_list args;
+       unsigned long flags;
+       va_start(args, fmt);
+
+       spin_lock_irqsave(&trace_lock, flags);
+       if (is_enabled())
+               ret = mmio_trace_printk(fmt, args);
+       spin_unlock_irqrestore(&trace_lock, flags);
+
+       va_end(args);
+       return ret;
+}
+EXPORT_SYMBOL(mmiotrace_printk);
+
 static void clear_trace_list(void)
 {
        struct remap_trace *trace;
@@ -462,26 +436,12 @@ static void leave_uniprocessor(void)
 }
 #endif
 
-#if 0 /* XXX: out of order */
-static struct file_operations fops_marker = {
-       .owner =        THIS_MODULE,
-       .write =        write_marker
-};
-#endif
-
 void enable_mmiotrace(void)
 {
        mutex_lock(&mmiotrace_mutex);
        if (is_enabled())
                goto out;
 
-#if 0 /* XXX: tracing does not support text entries */
-       marker_file = debugfs_create_file("marker", 0660, dir, NULL,
-                                                               &fops_marker);
-       if (!marker_file)
-               pr_err(NAME "marker file creation failed.\n");
-#endif
-
        if (nommiotrace)
                pr_info(NAME "MMIO tracing disabled.\n");
        enter_uniprocessor();
@@ -506,11 +466,6 @@ void disable_mmiotrace(void)
 
        clear_trace_list(); /* guarantees: no more kmmio callbacks */
        leave_uniprocessor();
-       if (marker_file) {
-               debugfs_remove(marker_file);
-               marker_file = NULL;
-       }
-
        pr_info(NAME "disabled.\n");
 out:
        mutex_unlock(&mmiotrace_mutex);
index 407d8784f669603fd48667c8d2ee22bb8e870f35..f1dc1b75d166696628a02ea473a5bdbc0dcaabe5 100644 (file)
@@ -65,23 +65,22 @@ static void split_page_count(int level)
        direct_pages_count[level - 1] += PTRS_PER_PTE;
 }
 
-int arch_report_meminfo(char *page)
+void arch_report_meminfo(struct seq_file *m)
 {
-       int n = sprintf(page, "DirectMap4k:  %8lu kB\n",
+       seq_printf(m, "DirectMap4k:  %8lu kB\n",
                        direct_pages_count[PG_LEVEL_4K] << 2);
 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
-       n += sprintf(page + n, "DirectMap2M:  %8lu kB\n",
+       seq_printf(m, "DirectMap2M:  %8lu kB\n",
                        direct_pages_count[PG_LEVEL_2M] << 11);
 #else
-       n += sprintf(page + n, "DirectMap4M:  %8lu kB\n",
+       seq_printf(m, "DirectMap4M:  %8lu kB\n",
                        direct_pages_count[PG_LEVEL_2M] << 12);
 #endif
 #ifdef CONFIG_X86_64
        if (direct_gbpages)
-               n += sprintf(page + n, "DirectMap1G:  %8lu kB\n",
+               seq_printf(m, "DirectMap1G:  %8lu kB\n",
                        direct_pages_count[PG_LEVEL_1G] << 20);
 #endif
-       return n;
 }
 #else
 static inline void split_page_count(int level) { }
index efa1911e20cad5e708d14cad403617de50d643c7..df3d5c861cdad6e36680613b4db8df5776e6c094 100644 (file)
@@ -79,25 +79,34 @@ static unsigned int mw32[] = { 0xC7 };
 static unsigned int mw64[] = { 0x89, 0x8B };
 #endif /* not __i386__ */
 
-static int skip_prefix(unsigned char *addr, int *shorted, int *enlarged,
-                                                               int *rexr)
+struct prefix_bits {
+       unsigned shorted:1;
+       unsigned enlarged:1;
+       unsigned rexr:1;
+       unsigned rex:1;
+};
+
+static int skip_prefix(unsigned char *addr, struct prefix_bits *prf)
 {
        int i;
        unsigned char *p = addr;
-       *shorted = 0;
-       *enlarged = 0;
-       *rexr = 0;
+       prf->shorted = 0;
+       prf->enlarged = 0;
+       prf->rexr = 0;
+       prf->rex = 0;
 
 restart:
        for (i = 0; i < ARRAY_SIZE(prefix_codes); i++) {
                if (*p == prefix_codes[i]) {
                        if (*p == 0x66)
-                               *shorted = 1;
+                               prf->shorted = 1;
 #ifdef __amd64__
                        if ((*p & 0xf8) == 0x48)
-                               *enlarged = 1;
+                               prf->enlarged = 1;
                        if ((*p & 0xf4) == 0x44)
-                               *rexr = 1;
+                               prf->rexr = 1;
+                       if ((*p & 0xf0) == 0x40)
+                               prf->rex = 1;
 #endif
                        p++;
                        goto restart;
@@ -135,12 +144,12 @@ enum reason_type get_ins_type(unsigned long ins_addr)
 {
        unsigned int opcode;
        unsigned char *p;
-       int shorted, enlarged, rexr;
+       struct prefix_bits prf;
        int i;
        enum reason_type rv = OTHERS;
 
        p = (unsigned char *)ins_addr;
-       p += skip_prefix(p, &shorted, &enlarged, &rexr);
+       p += skip_prefix(p, &prf);
        p += get_opcode(p, &opcode);
 
        CHECK_OP_TYPE(opcode, reg_rop, REG_READ);
@@ -156,10 +165,11 @@ static unsigned int get_ins_reg_width(unsigned long ins_addr)
 {
        unsigned int opcode;
        unsigned char *p;
-       int i, shorted, enlarged, rexr;
+       struct prefix_bits prf;
+       int i;
 
        p = (unsigned char *)ins_addr;
-       p += skip_prefix(p, &shorted, &enlarged, &rexr);
+       p += skip_prefix(p, &prf);
        p += get_opcode(p, &opcode);
 
        for (i = 0; i < ARRAY_SIZE(rw8); i++)
@@ -168,7 +178,7 @@ static unsigned int get_ins_reg_width(unsigned long ins_addr)
 
        for (i = 0; i < ARRAY_SIZE(rw32); i++)
                if (rw32[i] == opcode)
-                       return (shorted ? 2 : (enlarged ? 8 : 4));
+                       return prf.shorted ? 2 : (prf.enlarged ? 8 : 4);
 
        printk(KERN_ERR "mmiotrace: Unknown opcode 0x%02x\n", opcode);
        return 0;
@@ -178,10 +188,11 @@ unsigned int get_ins_mem_width(unsigned long ins_addr)
 {
        unsigned int opcode;
        unsigned char *p;
-       int i, shorted, enlarged, rexr;
+       struct prefix_bits prf;
+       int i;
 
        p = (unsigned char *)ins_addr;
-       p += skip_prefix(p, &shorted, &enlarged, &rexr);
+       p += skip_prefix(p, &prf);
        p += get_opcode(p, &opcode);
 
        for (i = 0; i < ARRAY_SIZE(mw8); i++)
@@ -194,11 +205,11 @@ unsigned int get_ins_mem_width(unsigned long ins_addr)
 
        for (i = 0; i < ARRAY_SIZE(mw32); i++)
                if (mw32[i] == opcode)
-                       return shorted ? 2 : 4;
+                       return prf.shorted ? 2 : 4;
 
        for (i = 0; i < ARRAY_SIZE(mw64); i++)
                if (mw64[i] == opcode)
-                       return shorted ? 2 : (enlarged ? 8 : 4);
+                       return prf.shorted ? 2 : (prf.enlarged ? 8 : 4);
 
        printk(KERN_ERR "mmiotrace: Unknown opcode 0x%02x\n", opcode);
        return 0;
@@ -238,7 +249,7 @@ enum {
 #endif
 };
 
-static unsigned char *get_reg_w8(int no, struct pt_regs *regs)
+static unsigned char *get_reg_w8(int no, int rex, struct pt_regs *regs)
 {
        unsigned char *rv = NULL;
 
@@ -255,18 +266,6 @@ static unsigned char *get_reg_w8(int no, struct pt_regs *regs)
        case arg_DL:
                rv = (unsigned char *)&regs->dx;
                break;
-       case arg_AH:
-               rv = 1 + (unsigned char *)&regs->ax;
-               break;
-       case arg_BH:
-               rv = 1 + (unsigned char *)&regs->bx;
-               break;
-       case arg_CH:
-               rv = 1 + (unsigned char *)&regs->cx;
-               break;
-       case arg_DH:
-               rv = 1 + (unsigned char *)&regs->dx;
-               break;
 #ifdef __amd64__
        case arg_R8:
                rv = (unsigned char *)&regs->r8;
@@ -294,9 +293,55 @@ static unsigned char *get_reg_w8(int no, struct pt_regs *regs)
                break;
 #endif
        default:
-               printk(KERN_ERR "mmiotrace: Error reg no# %d\n", no);
                break;
        }
+
+       if (rv)
+               return rv;
+
+       if (rex) {
+               /*
+                * If REX prefix exists, access low bytes of SI etc.
+                * instead of AH etc.
+                */
+               switch (no) {
+               case arg_SI:
+                       rv = (unsigned char *)&regs->si;
+                       break;
+               case arg_DI:
+                       rv = (unsigned char *)&regs->di;
+                       break;
+               case arg_BP:
+                       rv = (unsigned char *)&regs->bp;
+                       break;
+               case arg_SP:
+                       rv = (unsigned char *)&regs->sp;
+                       break;
+               default:
+                       break;
+               }
+       } else {
+               switch (no) {
+               case arg_AH:
+                       rv = 1 + (unsigned char *)&regs->ax;
+                       break;
+               case arg_BH:
+                       rv = 1 + (unsigned char *)&regs->bx;
+                       break;
+               case arg_CH:
+                       rv = 1 + (unsigned char *)&regs->cx;
+                       break;
+               case arg_DH:
+                       rv = 1 + (unsigned char *)&regs->dx;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       if (!rv)
+               printk(KERN_ERR "mmiotrace: Error reg no# %d\n", no);
+
        return rv;
 }
 
@@ -368,11 +413,12 @@ unsigned long get_ins_reg_val(unsigned long ins_addr, struct pt_regs *regs)
        unsigned char mod_rm;
        int reg;
        unsigned char *p;
-       int i, shorted, enlarged, rexr;
+       struct prefix_bits prf;
+       int i;
        unsigned long rv;
 
        p = (unsigned char *)ins_addr;
-       p += skip_prefix(p, &shorted, &enlarged, &rexr);
+       p += skip_prefix(p, &prf);
        p += get_opcode(p, &opcode);
        for (i = 0; i < ARRAY_SIZE(reg_rop); i++)
                if (reg_rop[i] == opcode) {
@@ -392,10 +438,10 @@ unsigned long get_ins_reg_val(unsigned long ins_addr, struct pt_regs *regs)
 
 do_work:
        mod_rm = *p;
-       reg = ((mod_rm >> 3) & 0x7) | (rexr << 3);
+       reg = ((mod_rm >> 3) & 0x7) | (prf.rexr << 3);
        switch (get_ins_reg_width(ins_addr)) {
        case 1:
-               return *get_reg_w8(reg, regs);
+               return *get_reg_w8(reg, prf.rex, regs);
 
        case 2:
                return *(unsigned short *)get_reg_w32(reg, regs);
@@ -422,11 +468,12 @@ unsigned long get_ins_imm_val(unsigned long ins_addr)
        unsigned char mod_rm;
        unsigned char mod;
        unsigned char *p;
-       int i, shorted, enlarged, rexr;
+       struct prefix_bits prf;
+       int i;
        unsigned long rv;
 
        p = (unsigned char *)ins_addr;
-       p += skip_prefix(p, &shorted, &enlarged, &rexr);
+       p += skip_prefix(p, &prf);
        p += get_opcode(p, &opcode);
        for (i = 0; i < ARRAY_SIZE(imm_wop); i++)
                if (imm_wop[i] == opcode) {
index d877c5b423efbacd13c018ab4f4555f0f2c7cfb2..ab50a8d7402c8c7f4320f0fd803a22a2d9abf84a 100644 (file)
@@ -3,6 +3,7 @@
  */
 #include <linux/module.h>
 #include <linux/io.h>
+#include <linux/mmiotrace.h>
 
 #define MODULE_NAME "testmmiotrace"
 
@@ -13,6 +14,7 @@ MODULE_PARM_DESC(mmio_address, "Start address of the mapping of 16 kB.");
 static void do_write_test(void __iomem *p)
 {
        unsigned int i;
+       mmiotrace_printk("Write test.\n");
        for (i = 0; i < 256; i++)
                iowrite8(i, p + i);
        for (i = 1024; i < (5 * 1024); i += 2)
@@ -24,6 +26,7 @@ static void do_write_test(void __iomem *p)
 static void do_read_test(void __iomem *p)
 {
        unsigned int i;
+       mmiotrace_printk("Read test.\n");
        for (i = 0; i < 256; i++)
                ioread8(p + i);
        for (i = 1024; i < (5 * 1024); i += 2)
@@ -39,6 +42,7 @@ static void do_test(void)
                pr_err(MODULE_NAME ": could not ioremap, aborting.\n");
                return;
        }
+       mmiotrace_printk("ioremap returned %p.\n", p);
        do_write_test(p);
        do_read_test(p);
        iounmap(p);
index e2095cba409f200b5b25e9b5bcdbce0ed6288492..04df67f8a7ba8f2f8c397832eec1b6fb0180ef8d 100644 (file)
@@ -52,8 +52,7 @@ struct frame_head {
        unsigned long ret;
 } __attribute__((packed));
 
-static struct frame_head *
-dump_user_backtrace(struct frame_head * head)
+static struct frame_head *dump_user_backtrace(struct frame_head *head)
 {
        struct frame_head bufhead[2];
 
index 57f6c90880816b113074cf306f678f8781c04d50..022cd41ea9b4106e5884277096e80e9088a7c7a9 100644 (file)
@@ -28,85 +28,9 @@ static struct op_x86_model_spec const *model;
 static DEFINE_PER_CPU(struct op_msrs, cpu_msrs);
 static DEFINE_PER_CPU(unsigned long, saved_lvtpc);
 
-static int nmi_start(void);
-static void nmi_stop(void);
-static void nmi_cpu_start(void *dummy);
-static void nmi_cpu_stop(void *dummy);
-
 /* 0 == registered but off, 1 == registered and on */
 static int nmi_enabled = 0;
 
-#ifdef CONFIG_SMP
-static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action,
-                                void *data)
-{
-       int cpu = (unsigned long)data;
-       switch (action) {
-       case CPU_DOWN_FAILED:
-       case CPU_ONLINE:
-               smp_call_function_single(cpu, nmi_cpu_start, NULL, 0);
-               break;
-       case CPU_DOWN_PREPARE:
-               smp_call_function_single(cpu, nmi_cpu_stop, NULL, 1);
-               break;
-       }
-       return NOTIFY_DONE;
-}
-
-static struct notifier_block oprofile_cpu_nb = {
-       .notifier_call = oprofile_cpu_notifier
-};
-#endif
-
-#ifdef CONFIG_PM
-
-static int nmi_suspend(struct sys_device *dev, pm_message_t state)
-{
-       /* Only one CPU left, just stop that one */
-       if (nmi_enabled == 1)
-               nmi_cpu_stop(NULL);
-       return 0;
-}
-
-static int nmi_resume(struct sys_device *dev)
-{
-       if (nmi_enabled == 1)
-               nmi_cpu_start(NULL);
-       return 0;
-}
-
-static struct sysdev_class oprofile_sysclass = {
-       .name           = "oprofile",
-       .resume         = nmi_resume,
-       .suspend        = nmi_suspend,
-};
-
-static struct sys_device device_oprofile = {
-       .id     = 0,
-       .cls    = &oprofile_sysclass,
-};
-
-static int __init init_sysfs(void)
-{
-       int error;
-
-       error = sysdev_class_register(&oprofile_sysclass);
-       if (!error)
-               error = sysdev_register(&device_oprofile);
-       return error;
-}
-
-static void exit_sysfs(void)
-{
-       sysdev_unregister(&device_oprofile);
-       sysdev_class_unregister(&oprofile_sysclass);
-}
-
-#else
-#define init_sysfs() do { } while (0)
-#define exit_sysfs() do { } while (0)
-#endif /* CONFIG_PM */
-
 static int profile_exceptions_notify(struct notifier_block *self,
                                     unsigned long val, void *data)
 {
@@ -361,6 +285,77 @@ 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)
+{
+       int cpu = (unsigned long)data;
+       switch (action) {
+       case CPU_DOWN_FAILED:
+       case CPU_ONLINE:
+               smp_call_function_single(cpu, nmi_cpu_start, NULL, 0);
+               break;
+       case CPU_DOWN_PREPARE:
+               smp_call_function_single(cpu, nmi_cpu_stop, NULL, 1);
+               break;
+       }
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block oprofile_cpu_nb = {
+       .notifier_call = oprofile_cpu_notifier
+};
+#endif
+
+#ifdef CONFIG_PM
+
+static int nmi_suspend(struct sys_device *dev, pm_message_t state)
+{
+       /* Only one CPU left, just stop that one */
+       if (nmi_enabled == 1)
+               nmi_cpu_stop(NULL);
+       return 0;
+}
+
+static int nmi_resume(struct sys_device *dev)
+{
+       if (nmi_enabled == 1)
+               nmi_cpu_start(NULL);
+       return 0;
+}
+
+static struct sysdev_class oprofile_sysclass = {
+       .name           = "oprofile",
+       .resume         = nmi_resume,
+       .suspend        = nmi_suspend,
+};
+
+static struct sys_device device_oprofile = {
+       .id     = 0,
+       .cls    = &oprofile_sysclass,
+};
+
+static int __init init_sysfs(void)
+{
+       int error;
+
+       error = sysdev_class_register(&oprofile_sysclass);
+       if (!error)
+               error = sysdev_register(&device_oprofile);
+       return error;
+}
+
+static void exit_sysfs(void)
+{
+       sysdev_unregister(&device_oprofile);
+       sysdev_class_unregister(&oprofile_sysclass);
+}
+
+#else
+#define init_sysfs() do { } while (0)
+#define exit_sysfs() do { } while (0)
+#endif /* CONFIG_PM */
+
 static int p4force;
 module_param(p4force, int, 0);
 
@@ -420,9 +415,6 @@ static int __init ppro_init(char **cpu_type)
        case 15: case 23:
                *cpu_type = "i386/core_2";
                break;
-       case 26:
-               *cpu_type = "i386/core_2";
-               break;
        default:
                /* Unknown */
                return 0;
@@ -432,6 +424,16 @@ static int __init ppro_init(char **cpu_type)
        return 1;
 }
 
+static int __init arch_perfmon_init(char **cpu_type)
+{
+       if (!cpu_has_arch_perfmon)
+               return 0;
+       *cpu_type = "i386/arch_perfmon";
+       model = &op_arch_perfmon_spec;
+       arch_perfmon_setup_counters();
+       return 1;
+}
+
 /* in order to get sysfs right */
 static int using_nmi;
 
@@ -439,7 +441,7 @@ int __init op_nmi_init(struct oprofile_operations *ops)
 {
        __u8 vendor = boot_cpu_data.x86_vendor;
        __u8 family = boot_cpu_data.x86;
-       char *cpu_type;
+       char *cpu_type = NULL;
        int ret = 0;
 
        if (!cpu_has_apic)
@@ -477,19 +479,20 @@ int __init op_nmi_init(struct oprofile_operations *ops)
                switch (family) {
                        /* Pentium IV */
                case 0xf:
-                       if (!p4_init(&cpu_type))
-                               return -ENODEV;
+                       p4_init(&cpu_type);
                        break;
 
                        /* A P6-class processor */
                case 6:
-                       if (!ppro_init(&cpu_type))
-                               return -ENODEV;
+                       ppro_init(&cpu_type);
                        break;
 
                default:
-                       return -ENODEV;
+                       break;
                }
+
+               if (!cpu_type && !arch_perfmon_init(&cpu_type))
+                       return -ENODEV;
                break;
 
        default:
index 2880b15c46752e0d14e35a825ebe30d7a6c2f7d3..91b6a116165e2e80deb3822286907acfe825b2f9 100644 (file)
@@ -6,22 +6,22 @@
  *
  * @author John Levon
  */
+
 #ifndef OP_COUNTER_H
 #define OP_COUNTER_H
+
 #define OP_MAX_COUNTER 8
+
 /* Per-perfctr configuration as set via
  * oprofilefs.
  */
 struct op_counter_config {
-        unsigned long count;
-        unsigned long enabled;
-        unsigned long event;
-        unsigned long kernel;
-        unsigned long user;
-        unsigned long unit_mask;
+       unsigned long count;
+       unsigned long enabled;
+       unsigned long event;
+       unsigned long kernel;
+       unsigned long user;
+       unsigned long unit_mask;
 };
 
 extern struct op_counter_config counter_config[];
index d9faf607b3a6816ad8b89d625446b74eb5e1214b..509513760a6e45c6ccade4b0054cf93f508add84 100644 (file)
@@ -67,8 +67,9 @@ static unsigned long reset_value[NUM_COUNTERS];
 
 /* The function interface needs to be fixed, something like add
    data. Should then be added to linux/oprofile.h. */
-extern void oprofile_add_ibs_sample(struct pt_regs *const regs,
-                                   unsigned int * const ibs_sample, u8 code);
+extern void
+oprofile_add_ibs_sample(struct pt_regs *const regs,
+                       unsigned int *const ibs_sample, int ibs_code);
 
 struct ibs_fetch_sample {
        /* MSRC001_1031 IBS Fetch Linear Address Register */
@@ -309,12 +310,15 @@ static void op_amd_start(struct op_msrs const * const msrs)
 #ifdef CONFIG_OPROFILE_IBS
        if (ibs_allowed && ibs_config.fetch_enabled) {
                low = (ibs_config.max_cnt_fetch >> 4) & 0xFFFF;
-               high = IBS_FETCH_HIGH_ENABLE;
+               high = ((ibs_config.rand_en & 0x1) << 25) /* bit 57 */
+                       + IBS_FETCH_HIGH_ENABLE;
                wrmsr(MSR_AMD64_IBSFETCHCTL, low, high);
        }
 
        if (ibs_allowed && ibs_config.op_enabled) {
-               low = ((ibs_config.max_cnt_op >> 4) & 0xFFFF) + IBS_OP_LOW_ENABLE;
+               low = ((ibs_config.max_cnt_op >> 4) & 0xFFFF)
+                       + ((ibs_config.dispatched_ops & 0x1) << 19) /* bit 19 */
+                       + IBS_OP_LOW_ENABLE;
                high = 0;
                wrmsr(MSR_AMD64_IBSOPCTL, low, high);
        }
@@ -468,11 +472,10 @@ static void clear_ibs_nmi(void)
                on_each_cpu(apic_clear_ibs_nmi_per_cpu, NULL, 1);
 }
 
-static int (*create_arch_files)(struct super_block * sb, struct dentry * root);
+static int (*create_arch_files)(struct super_block *sb, struct dentry *root);
 
-static int setup_ibs_files(struct super_block * sb, struct dentry * root)
+static int setup_ibs_files(struct super_block *sb, struct dentry *root)
 {
-       char buf[12];
        struct dentry *dir;
        int ret = 0;
 
@@ -494,22 +497,22 @@ static int setup_ibs_files(struct super_block * sb, struct dentry * root)
        ibs_config.max_cnt_op = 250000;
        ibs_config.op_enabled = 0;
        ibs_config.dispatched_ops = 1;
-       snprintf(buf,  sizeof(buf), "ibs_fetch");
-       dir = oprofilefs_mkdir(sb, root, buf);
-       oprofilefs_create_ulong(sb, dir, "rand_enable",
-                               &ibs_config.rand_en);
+
+       dir = oprofilefs_mkdir(sb, root, "ibs_fetch");
        oprofilefs_create_ulong(sb, dir, "enable",
-               &ibs_config.fetch_enabled);
+                               &ibs_config.fetch_enabled);
        oprofilefs_create_ulong(sb, dir, "max_count",
-               &ibs_config.max_cnt_fetch);
-       snprintf(buf,  sizeof(buf), "ibs_uops");
-       dir = oprofilefs_mkdir(sb, root, buf);
+                               &ibs_config.max_cnt_fetch);
+       oprofilefs_create_ulong(sb, dir, "rand_enable",
+                               &ibs_config.rand_en);
+
+       dir = oprofilefs_mkdir(sb, root, "ibs_op");
        oprofilefs_create_ulong(sb, dir, "enable",
-               &ibs_config.op_enabled);
+                               &ibs_config.op_enabled);
        oprofilefs_create_ulong(sb, dir, "max_count",
-               &ibs_config.max_cnt_op);
+                               &ibs_config.max_cnt_op);
        oprofilefs_create_ulong(sb, dir, "dispatched_ops",
-               &ibs_config.dispatched_ops);
+                               &ibs_config.dispatched_ops);
 
        return 0;
 }
@@ -530,14 +533,14 @@ static void op_amd_exit(void)
 #endif
 
 struct op_x86_model_spec const op_amd_spec = {
-       .init = op_amd_init,
-       .exit = op_amd_exit,
-       .num_counters = NUM_COUNTERS,
-       .num_controls = NUM_CONTROLS,
-       .fill_in_addresses = &op_amd_fill_in_addresses,
-       .setup_ctrs = &op_amd_setup_ctrs,
-       .check_ctrs = &op_amd_check_ctrs,
-       .start = &op_amd_start,
-       .stop = &op_amd_stop,
-       .shutdown = &op_amd_shutdown
+       .init                   = op_amd_init,
+       .exit                   = op_amd_exit,
+       .num_counters           = NUM_COUNTERS,
+       .num_controls           = NUM_CONTROLS,
+       .fill_in_addresses      = &op_amd_fill_in_addresses,
+       .setup_ctrs             = &op_amd_setup_ctrs,
+       .check_ctrs             = &op_amd_check_ctrs,
+       .start                  = &op_amd_start,
+       .stop                   = &op_amd_stop,
+       .shutdown               = &op_amd_shutdown
 };
index 43ac5af338d8c910c2295a7484453ab6b8a01b2a..4c4a51c90bc26f31cfc192adf2fb341ba7fcc754 100644 (file)
@@ -698,24 +698,24 @@ static void p4_shutdown(struct op_msrs const * const msrs)
 
 #ifdef CONFIG_SMP
 struct op_x86_model_spec const op_p4_ht2_spec = {
-       .num_counters = NUM_COUNTERS_HT2,
-       .num_controls = NUM_CONTROLS_HT2,
-       .fill_in_addresses = &p4_fill_in_addresses,
-       .setup_ctrs = &p4_setup_ctrs,
-       .check_ctrs = &p4_check_ctrs,
-       .start = &p4_start,
-       .stop = &p4_stop,
-       .shutdown = &p4_shutdown
+       .num_counters           = NUM_COUNTERS_HT2,
+       .num_controls           = NUM_CONTROLS_HT2,
+       .fill_in_addresses      = &p4_fill_in_addresses,
+       .setup_ctrs             = &p4_setup_ctrs,
+       .check_ctrs             = &p4_check_ctrs,
+       .start                  = &p4_start,
+       .stop                   = &p4_stop,
+       .shutdown               = &p4_shutdown
 };
 #endif
 
 struct op_x86_model_spec const op_p4_spec = {
-       .num_counters = NUM_COUNTERS_NON_HT,
-       .num_controls = NUM_CONTROLS_NON_HT,
-       .fill_in_addresses = &p4_fill_in_addresses,
-       .setup_ctrs = &p4_setup_ctrs,
-       .check_ctrs = &p4_check_ctrs,
-       .start = &p4_start,
-       .stop = &p4_stop,
-       .shutdown = &p4_shutdown
+       .num_counters           = NUM_COUNTERS_NON_HT,
+       .num_controls           = NUM_CONTROLS_NON_HT,
+       .fill_in_addresses      = &p4_fill_in_addresses,
+       .setup_ctrs             = &p4_setup_ctrs,
+       .check_ctrs             = &p4_check_ctrs,
+       .start                  = &p4_start,
+       .stop                   = &p4_stop,
+       .shutdown               = &p4_shutdown
 };
index eff431f6c57b179465d1cb2b3f671f62ac6568d7..0620d6d45f7d08f99e8974396260fb071f02948c 100644 (file)
@@ -1,32 +1,34 @@
 /*
  * @file op_model_ppro.h
- * pentium pro / P6 model-specific MSR operations
+ * Family 6 perfmon and architectural perfmon MSR operations
  *
  * @remark Copyright 2002 OProfile authors
+ * @remark Copyright 2008 Intel Corporation
  * @remark Read the file COPYING
  *
  * @author John Levon
  * @author Philippe Elie
  * @author Graydon Hoare
+ * @author Andi Kleen
  */
 
 #include <linux/oprofile.h>
+#include <linux/slab.h>
 #include <asm/ptrace.h>
 #include <asm/msr.h>
 #include <asm/apic.h>
 #include <asm/nmi.h>
+#include <asm/intel_arch_perfmon.h>
 
 #include "op_x86_model.h"
 #include "op_counter.h"
 
-#define NUM_COUNTERS 2
-#define NUM_CONTROLS 2
+static int num_counters = 2;
+static int counter_width = 32;
 
 #define CTR_IS_RESERVED(msrs, c) (msrs->counters[(c)].addr ? 1 : 0)
 #define CTR_READ(l, h, msrs, c) do {rdmsr(msrs->counters[(c)].addr, (l), (h)); } while (0)
-#define CTR_32BIT_WRITE(l, msrs, c)    \
-       do {wrmsr(msrs->counters[(c)].addr, -(u32)(l), 0); } while (0)
-#define CTR_OVERFLOWED(n) (!((n) & (1U<<31)))
+#define CTR_OVERFLOWED(n) (!((n) & (1U<<(counter_width-1))))
 
 #define CTRL_IS_RESERVED(msrs, c) (msrs->controls[(c)].addr ? 1 : 0)
 #define CTRL_READ(l, h, msrs, c) do {rdmsr((msrs->controls[(c)].addr), (l), (h)); } while (0)
 #define CTRL_SET_UM(val, m) (val |= (m << 8))
 #define CTRL_SET_EVENT(val, e) (val |= e)
 
-static unsigned long reset_value[NUM_COUNTERS];
+static u64 *reset_value;
 
 static void ppro_fill_in_addresses(struct op_msrs * const msrs)
 {
        int i;
 
-       for (i = 0; i < NUM_COUNTERS; i++) {
+       for (i = 0; i < num_counters; i++) {
                if (reserve_perfctr_nmi(MSR_P6_PERFCTR0 + i))
                        msrs->counters[i].addr = MSR_P6_PERFCTR0 + i;
                else
                        msrs->counters[i].addr = 0;
        }
 
-       for (i = 0; i < NUM_CONTROLS; i++) {
+       for (i = 0; i < num_counters; i++) {
                if (reserve_evntsel_nmi(MSR_P6_EVNTSEL0 + i))
                        msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i;
                else
@@ -67,8 +69,22 @@ static void ppro_setup_ctrs(struct op_msrs const * const msrs)
        unsigned int low, high;
        int i;
 
+       if (!reset_value) {
+               reset_value = kmalloc(sizeof(unsigned) * num_counters,
+                                       GFP_ATOMIC);
+               if (!reset_value)
+                       return;
+       }
+
+       if (cpu_has_arch_perfmon) {
+               union cpuid10_eax eax;
+               eax.full = cpuid_eax(0xa);
+               if (counter_width < eax.split.bit_width)
+                       counter_width = eax.split.bit_width;
+       }
+
        /* clear all counters */
-       for (i = 0 ; i < NUM_CONTROLS; ++i) {
+       for (i = 0 ; i < num_counters; ++i) {
                if (unlikely(!CTRL_IS_RESERVED(msrs, i)))
                        continue;
                CTRL_READ(low, high, msrs, i);
@@ -77,18 +93,18 @@ static void ppro_setup_ctrs(struct op_msrs const * const msrs)
        }
 
        /* avoid a false detection of ctr overflows in NMI handler */
-       for (i = 0; i < NUM_COUNTERS; ++i) {
+       for (i = 0; i < num_counters; ++i) {
                if (unlikely(!CTR_IS_RESERVED(msrs, i)))
                        continue;
-               CTR_32BIT_WRITE(1, msrs, i);
+               wrmsrl(msrs->counters[i].addr, -1LL);
        }
 
        /* enable active counters */
-       for (i = 0; i < NUM_COUNTERS; ++i) {
+       for (i = 0; i < num_counters; ++i) {
                if ((counter_config[i].enabled) && (CTR_IS_RESERVED(msrs, i))) {
                        reset_value[i] = counter_config[i].count;
 
-                       CTR_32BIT_WRITE(counter_config[i].count, msrs, i);
+                       wrmsrl(msrs->counters[i].addr, -reset_value[i]);
 
                        CTRL_READ(low, high, msrs, i);
                        CTRL_CLEAR(low);
@@ -111,13 +127,13 @@ static int ppro_check_ctrs(struct pt_regs * const regs,
        unsigned int low, high;
        int i;
 
-       for (i = 0 ; i < NUM_COUNTERS; ++i) {
+       for (i = 0 ; i < num_counters; ++i) {
                if (!reset_value[i])
                        continue;
                CTR_READ(low, high, msrs, i);
                if (CTR_OVERFLOWED(low)) {
                        oprofile_add_sample(regs, i);
-                       CTR_32BIT_WRITE(reset_value[i], msrs, i);
+                       wrmsrl(msrs->counters[i].addr, -reset_value[i]);
                }
        }
 
@@ -141,7 +157,7 @@ static void ppro_start(struct op_msrs const * const msrs)
        unsigned int low, high;
        int i;
 
-       for (i = 0; i < NUM_COUNTERS; ++i) {
+       for (i = 0; i < num_counters; ++i) {
                if (reset_value[i]) {
                        CTRL_READ(low, high, msrs, i);
                        CTRL_SET_ACTIVE(low);
@@ -156,7 +172,7 @@ static void ppro_stop(struct op_msrs const * const msrs)
        unsigned int low, high;
        int i;
 
-       for (i = 0; i < NUM_COUNTERS; ++i) {
+       for (i = 0; i < num_counters; ++i) {
                if (!reset_value[i])
                        continue;
                CTRL_READ(low, high, msrs, i);
@@ -169,24 +185,70 @@ static void ppro_shutdown(struct op_msrs const * const msrs)
 {
        int i;
 
-       for (i = 0 ; i < NUM_COUNTERS ; ++i) {
+       for (i = 0 ; i < num_counters ; ++i) {
                if (CTR_IS_RESERVED(msrs, i))
                        release_perfctr_nmi(MSR_P6_PERFCTR0 + i);
        }
-       for (i = 0 ; i < NUM_CONTROLS ; ++i) {
+       for (i = 0 ; i < num_counters ; ++i) {
                if (CTRL_IS_RESERVED(msrs, i))
                        release_evntsel_nmi(MSR_P6_EVNTSEL0 + i);
        }
+       if (reset_value) {
+               kfree(reset_value);
+               reset_value = NULL;
+       }
 }
 
 
-struct op_x86_model_spec const op_ppro_spec = {
-       .num_counters = NUM_COUNTERS,
-       .num_controls = NUM_CONTROLS,
-       .fill_in_addresses = &ppro_fill_in_addresses,
-       .setup_ctrs = &ppro_setup_ctrs,
-       .check_ctrs = &ppro_check_ctrs,
-       .start = &ppro_start,
-       .stop = &ppro_stop,
-       .shutdown = &ppro_shutdown
+struct op_x86_model_spec op_ppro_spec = {
+       .num_counters           = 2,    /* can be overriden */
+       .num_controls           = 2,    /* dito */
+       .fill_in_addresses      = &ppro_fill_in_addresses,
+       .setup_ctrs             = &ppro_setup_ctrs,
+       .check_ctrs             = &ppro_check_ctrs,
+       .start                  = &ppro_start,
+       .stop                   = &ppro_stop,
+       .shutdown               = &ppro_shutdown
+};
+
+/*
+ * Architectural performance monitoring.
+ *
+ * Newer Intel CPUs (Core1+) have support for architectural
+ * events described in CPUID 0xA. See the IA32 SDM Vol3b.18 for details.
+ * The advantage of this is that it can be done without knowing about
+ * the specific CPU.
+ */
+
+void arch_perfmon_setup_counters(void)
+{
+       union cpuid10_eax eax;
+
+       eax.full = cpuid_eax(0xa);
+
+       /* Workaround for BIOS bugs in 6/15. Taken from perfmon2 */
+       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_counters = 2;
+               eax.split.bit_width = 40;
+       }
+
+       num_counters = eax.split.num_counters;
+
+       op_arch_perfmon_spec.num_counters = num_counters;
+       op_arch_perfmon_spec.num_controls = num_counters;
+       op_ppro_spec.num_counters = num_counters;
+       op_ppro_spec.num_controls = num_counters;
+}
+
+struct op_x86_model_spec op_arch_perfmon_spec = {
+       /* num_counters/num_controls filled in at runtime */
+       .fill_in_addresses      = &ppro_fill_in_addresses,
+       /* user space does the cpuid check for available events */
+       .setup_ctrs             = &ppro_setup_ctrs,
+       .check_ctrs             = &ppro_check_ctrs,
+       .start                  = &ppro_start,
+       .stop                   = &ppro_stop,
+       .shutdown               = &ppro_shutdown
 };
index 05a0261ba0c38208f4481d467ffc9efc70e57479..825e79064d64ebd87c71f74954a861e69d5abaae 100644 (file)
@@ -22,8 +22,8 @@ struct op_msr {
 };
 
 struct op_msrs {
-       struct op_msr * counters;
-       struct op_msr * controls;
+       struct op_msr *counters;
+       struct op_msr *controls;
 };
 
 struct pt_regs;
@@ -34,8 +34,8 @@ struct pt_regs;
 struct op_x86_model_spec {
        int (*init)(struct oprofile_operations *ops);
        void (*exit)(void);
-       unsigned int const num_counters;
-       unsigned int const num_controls;
+       unsigned int num_counters;
+       unsigned int num_controls;
        void (*fill_in_addresses)(struct op_msrs * const msrs);
        void (*setup_ctrs)(struct op_msrs const * const msrs);
        int (*check_ctrs)(struct pt_regs * const regs,
@@ -45,9 +45,12 @@ struct op_x86_model_spec {
        void (*shutdown)(struct op_msrs const * const msrs);
 };
 
-extern struct op_x86_model_spec const op_ppro_spec;
+extern struct op_x86_model_spec op_ppro_spec;
 extern struct op_x86_model_spec const op_p4_spec;
 extern struct op_x86_model_spec const op_p4_ht2_spec;
 extern struct op_x86_model_spec const op_amd_spec;
+extern struct op_x86_model_spec op_arch_perfmon_spec;
+
+extern void arch_perfmon_setup_counters(void);
 
 #endif /* OP_X86_MODEL_H */
index 006599db0dc7024a9bc9cde36bab97b2dc114b0f..bf69dbe08bff66b19b8e9a7558d152fd4fce62f7 100644 (file)
@@ -493,7 +493,7 @@ static int pirq_amd756_get(struct pci_dev *router, struct pci_dev *dev, int pirq
        if (pirq <= 4)
                irq = read_config_nybble(router, 0x56, pirq - 1);
        dev_info(&dev->dev,
-                "AMD756: dev [%04x/%04x], router PIRQ %d get IRQ %d\n",
+                "AMD756: dev [%04x:%04x], router PIRQ %d get IRQ %d\n",
                 dev->vendor, dev->device, pirq, irq);
        return irq;
 }
@@ -501,7 +501,7 @@ static int pirq_amd756_get(struct pci_dev *router, struct pci_dev *dev, int pirq
 static int pirq_amd756_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
 {
        dev_info(&dev->dev,
-                "AMD756: dev [%04x/%04x], router PIRQ %d set IRQ %d\n",
+                "AMD756: dev [%04x:%04x], router PIRQ %d set IRQ %d\n",
                 dev->vendor, dev->device, pirq, irq);
        if (pirq <= 4)
                write_config_nybble(router, 0x56, pirq - 1, irq);
@@ -590,13 +590,20 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route
        case PCI_DEVICE_ID_INTEL_ICH10_1:
        case PCI_DEVICE_ID_INTEL_ICH10_2:
        case PCI_DEVICE_ID_INTEL_ICH10_3:
-       case PCI_DEVICE_ID_INTEL_PCH_0:
-       case PCI_DEVICE_ID_INTEL_PCH_1:
                r->name = "PIIX/ICH";
                r->get = pirq_piix_get;
                r->set = pirq_piix_set;
                return 1;
        }
+
+       if ((device >= PCI_DEVICE_ID_INTEL_PCH_LPC_MIN) && 
+               (device <= PCI_DEVICE_ID_INTEL_PCH_LPC_MAX)) {
+               r->name = "PIIX/ICH";
+               r->get = pirq_piix_get;
+               r->set = pirq_piix_set;
+               return 1;
+       }
+
        return 0;
 }
 
@@ -823,7 +830,7 @@ static void __init pirq_find_router(struct irq_router *r)
        r->get = NULL;
        r->set = NULL;
 
-       DBG(KERN_DEBUG "PCI: Attempting to find IRQ router for %04x:%04x\n",
+       DBG(KERN_DEBUG "PCI: Attempting to find IRQ router for [%04x:%04x]\n",
            rt->rtr_vendor, rt->rtr_device);
 
        pirq_router_dev = pci_get_bus_and_slot(rt->rtr_bus, rt->rtr_devfn);
@@ -843,7 +850,7 @@ static void __init pirq_find_router(struct irq_router *r)
                        h->probe(r, pirq_router_dev, pirq_router_dev->device))
                        break;
        }
-       dev_info(&pirq_router_dev->dev, "%s IRQ router [%04x/%04x]\n",
+       dev_info(&pirq_router_dev->dev, "%s IRQ router [%04x:%04x]\n",
                 pirq_router.name,
                 pirq_router_dev->vendor, pirq_router_dev->device);
 
index 28b85ab8422eb17d883ed031da6021f70259ae9d..bb042608c6023fd8214139d64befd8217797ba43 100644 (file)
@@ -21,7 +21,6 @@ void xen_force_evtchn_callback(void)
 
 static void __init __xen_init_IRQ(void)
 {
-#ifdef CONFIG_X86_64
        int i;
 
        /* Create identity vector->irq map */
@@ -31,7 +30,6 @@ static void __init __xen_init_IRQ(void)
                for_each_possible_cpu(cpu)
                        per_cpu(vector_irq, cpu)[i] = i;
        }
-#endif /* CONFIG_X86_64 */
 
        xen_init_IRQ();
 }
index dd71e3a021cd9ba5b5e5433f2031bad45d0ce7a5..5601506f2dd96d49031873216d7e8aa12c689a91 100644 (file)
@@ -241,7 +241,7 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl
                ADD_STATS(taken_slow_spurious, !xen_test_irq_pending(irq));
        } while (!xen_test_irq_pending(irq)); /* check for spurious wakeups */
 
-       kstat_this_cpu.irqs[irq]++;
+       kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
 
 out:
        raw_local_irq_restore(flags);
index a213260b51e5b4d8d3d64d7aebc85d2b2f21eb74..6c873dceb177c8d79a76bb35ae09a78e7bdb8d6b 100644 (file)
@@ -64,7 +64,12 @@ choice
        default XTENSA_VARIANT_FSF
 
 config XTENSA_VARIANT_FSF
-       bool "fsf"
+       bool "fsf - default (not generic) configuration"
+
+config XTENSA_VARIANT_DC232B
+       bool "dc232b - Diamond 232L Standard Core Rev.B (LE)"
+       help
+       This variant refers to Tensilica's Diamond 232L Standard core Rev.B (LE).
 endchoice
 
 config MMU
index 4bd1e14c6b908cca0fcf04d96a766ab10f372387..015b6b2a26b96676eadbae477d68ea4e82ebf340 100644 (file)
@@ -14,6 +14,7 @@
 # (Use VAR=<xtensa_config> to use another default compiler.)
 
 variant-$(CONFIG_XTENSA_VARIANT_FSF)           := fsf
+variant-$(CONFIG_XTENSA_VARIANT_DC232B)                := dc232b
 variant-$(CONFIG_XTENSA_VARIANT_LINUX_CUSTOM)  := custom
 
 VARIANT = $(variant-y)
index c9ea73b7031b837561f225168cc71c0af420a672..5fbcde59a92d919507505e0605a7faf08f02a2d1 100644 (file)
@@ -48,7 +48,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
 
        if (irq >= NR_IRQS) {
                printk(KERN_EMERG "%s: cannot handle IRQ %d\n",
-                               __FUNCTION__, irq);
+                               __func__, irq);
        }
 
        irq_enter();
index a2e252217428f0500ea965c47bf18822d32e4a2b..11a20adc140999b96b5b76f844c9e8fedd00c9f0 100644 (file)
@@ -640,7 +640,7 @@ static int iss_net_configure(int index, char *init)
        *lp = ((struct iss_net_private) {
                .device_list            = LIST_HEAD_INIT(lp->device_list),
                .opened_list            = LIST_HEAD_INIT(lp->opened_list),
-               .lock                   = SPIN_LOCK_UNLOCKED,
+               .lock                   = __SPIN_LOCK_UNLOCKED(lp.lock),
                .dev                    = dev,
                .index                  = index,
                //.fd                   = -1,
index 034112bfe1f32a3876449533530edc0ed875e677..e8bd2475682ab4c2d29f8f205e57b62427b7cfe2 100644 (file)
@@ -173,7 +173,7 @@ unlock:
 
 static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
                                struct sg_io_v4 *hdr, struct bsg_device *bd,
-                               int has_write_perm)
+                               fmode_t has_write_perm)
 {
        if (hdr->request_len > BLK_MAX_CDB) {
                rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL);
@@ -242,7 +242,7 @@ bsg_validate_sgv4_hdr(struct request_queue *q, struct sg_io_v4 *hdr, int *rw)
  * map sg_io_v4 to a request.
  */
 static struct request *
-bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, int has_write_perm)
+bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm)
 {
        struct request_queue *q = bd->queue;
        struct request *rq, *next_rq = NULL;
@@ -601,7 +601,8 @@ bsg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 }
 
 static int __bsg_write(struct bsg_device *bd, const char __user *buf,
-                      size_t count, ssize_t *bytes_written, int has_write_perm)
+                      size_t count, ssize_t *bytes_written,
+                      fmode_t has_write_perm)
 {
        struct bsg_command *bc;
        struct request *rq;
@@ -913,7 +914,7 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        case SG_EMULATED_HOST:
        case SCSI_IOCTL_SEND_COMMAND: {
                void __user *uarg = (void __user *) arg;
-               return scsi_cmd_ioctl(file, bd->queue, NULL, cmd, uarg);
+               return scsi_cmd_ioctl(bd->queue, NULL, file->f_mode, cmd, uarg);
        }
        case SG_IO: {
                struct request *rq;
index e669aed4c6bcd8896434b7625766d8f2772f2ad3..504b275e1b905a5ffe6d42695acbefe6fd0fff55 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/cdrom.h>
 
 int blk_verify_command(struct blk_cmd_filter *filter,
-                      unsigned char *cmd, int has_write_perm)
+                      unsigned char *cmd, fmode_t has_write_perm)
 {
        /* root can do any command. */
        if (capable(CAP_SYS_RAWIO))
index 1e559fba7bdfc58859605b0d9fdc879346f86b07..3d3e7a46f38c43319a2fcbed71e99a5da9af8e68 100644 (file)
@@ -71,8 +71,8 @@ static int compat_hdio_getgeo(struct gendisk *disk, struct block_device *bdev,
        return ret;
 }
 
-static int compat_hdio_ioctl(struct inode *inode, struct file *file,
-               struct gendisk *disk, unsigned int cmd, unsigned long arg)
+static int compat_hdio_ioctl(struct block_device *bdev, fmode_t mode,
+               unsigned int cmd, unsigned long arg)
 {
        mm_segment_t old_fs = get_fs();
        unsigned long kval;
@@ -80,7 +80,7 @@ static int compat_hdio_ioctl(struct inode *inode, struct file *file,
        int error;
 
        set_fs(KERNEL_DS);
-       error = blkdev_driver_ioctl(inode, file, disk,
+       error = __blkdev_driver_ioctl(bdev, mode,
                                cmd, (unsigned long)(&kval));
        set_fs(old_fs);
 
@@ -111,8 +111,8 @@ struct compat_cdrom_generic_command {
        compat_caddr_t  reserved[1];
 };
 
-static int compat_cdrom_read_audio(struct inode *inode, struct file *file,
-               struct gendisk *disk, unsigned int cmd, unsigned long arg)
+static int compat_cdrom_read_audio(struct block_device *bdev, fmode_t mode,
+               unsigned int cmd, unsigned long arg)
 {
        struct cdrom_read_audio __user *cdread_audio;
        struct compat_cdrom_read_audio __user *cdread_audio32;
@@ -134,12 +134,12 @@ static int compat_cdrom_read_audio(struct inode *inode, struct file *file,
        if (put_user(datap, &cdread_audio->buf))
                return -EFAULT;
 
-       return blkdev_driver_ioctl(inode, file, disk, cmd,
+       return __blkdev_driver_ioctl(bdev, mode, cmd,
                        (unsigned long)cdread_audio);
 }
 
-static int compat_cdrom_generic_command(struct inode *inode, struct file *file,
-               struct gendisk *disk, unsigned int cmd, unsigned long arg)
+static int compat_cdrom_generic_command(struct block_device *bdev, fmode_t mode,
+               unsigned int cmd, unsigned long arg)
 {
        struct cdrom_generic_command __user *cgc;
        struct compat_cdrom_generic_command __user *cgc32;
@@ -167,7 +167,7 @@ static int compat_cdrom_generic_command(struct inode *inode, struct file *file,
            put_user(compat_ptr(data), &cgc->reserved[0]))
                return -EFAULT;
 
-       return blkdev_driver_ioctl(inode, file, disk, cmd, (unsigned long)cgc);
+       return __blkdev_driver_ioctl(bdev, mode, cmd, (unsigned long)cgc);
 }
 
 struct compat_blkpg_ioctl_arg {
@@ -177,7 +177,7 @@ struct compat_blkpg_ioctl_arg {
        compat_caddr_t data;
 };
 
-static int compat_blkpg_ioctl(struct inode *inode, struct file *file,
+static int compat_blkpg_ioctl(struct block_device *bdev, fmode_t mode,
                unsigned int cmd, struct compat_blkpg_ioctl_arg __user *ua32)
 {
        struct blkpg_ioctl_arg __user *a = compat_alloc_user_space(sizeof(*a));
@@ -196,7 +196,7 @@ static int compat_blkpg_ioctl(struct inode *inode, struct file *file,
        if (err)
                return err;
 
-       return blkdev_ioctl(inode, file, cmd, (unsigned long)a);
+       return blkdev_ioctl(bdev, mode, cmd, (unsigned long)a);
 }
 
 #define BLKBSZGET_32           _IOR(0x12, 112, int)
@@ -308,8 +308,8 @@ static struct {
 
 #define NR_FD_IOCTL_TRANS ARRAY_SIZE(fd_ioctl_trans_table)
 
-static int compat_fd_ioctl(struct inode *inode, struct file *file,
-               struct gendisk *disk, unsigned int cmd, unsigned long arg)
+static int compat_fd_ioctl(struct block_device *bdev, fmode_t mode,
+               unsigned int cmd, unsigned long arg)
 {
        mm_segment_t old_fs = get_fs();
        void *karg = NULL;
@@ -413,7 +413,7 @@ static int compat_fd_ioctl(struct inode *inode, struct file *file,
                return -EINVAL;
        }
        set_fs(KERNEL_DS);
-       err = blkdev_driver_ioctl(inode, file, disk, kcmd, (unsigned long)karg);
+       err = __blkdev_driver_ioctl(bdev, mode, kcmd, (unsigned long)karg);
        set_fs(old_fs);
        if (err)
                goto out;
@@ -579,11 +579,9 @@ static int compat_blk_trace_setup(struct block_device *bdev, char __user *arg)
        return 0;
 }
 
-static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file,
-                       struct gendisk *disk, unsigned cmd, unsigned long arg)
+static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
+                       unsigned cmd, unsigned long arg)
 {
-       int ret;
-
        switch (cmd) {
        case HDIO_GET_UNMASKINTR:
        case HDIO_GET_MULTCOUNT:
@@ -596,7 +594,7 @@ static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file,
        case HDIO_GET_ACOUSTIC:
        case HDIO_GET_ADDRESS:
        case HDIO_GET_BUSSTATE:
-               return compat_hdio_ioctl(inode, file, disk, cmd, arg);
+               return compat_hdio_ioctl(bdev, mode, cmd, arg);
        case FDSETPRM32:
        case FDDEFPRM32:
        case FDGETPRM32:
@@ -606,11 +604,11 @@ static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file,
        case FDPOLLDRVSTAT32:
        case FDGETFDCSTAT32:
        case FDWERRORGET32:
-               return compat_fd_ioctl(inode, file, disk, cmd, arg);
+               return compat_fd_ioctl(bdev, mode, cmd, arg);
        case CDROMREADAUDIO:
-               return compat_cdrom_read_audio(inode, file, disk, cmd, arg);
+               return compat_cdrom_read_audio(bdev, mode, cmd, arg);
        case CDROM_SEND_PACKET:
-               return compat_cdrom_generic_command(inode, file, disk, cmd, arg);
+               return compat_cdrom_generic_command(bdev, mode, cmd, arg);
 
        /*
         * No handler required for the ones below, we just need to
@@ -679,55 +677,49 @@ static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file,
        case DVD_WRITE_STRUCT:
        case DVD_AUTH:
                arg = (unsigned long)compat_ptr(arg);
-       /* These intepret arg as an unsigned long, not as a pointer,
-        * so we must not do compat_ptr() conversion. */
-       case HDIO_SET_MULTCOUNT:
-       case HDIO_SET_UNMASKINTR:
-       case HDIO_SET_KEEPSETTINGS:
-       case HDIO_SET_32BIT:
-       case HDIO_SET_NOWERR:
-       case HDIO_SET_DMA:
-       case HDIO_SET_PIO_MODE:
-       case HDIO_SET_NICE:
-       case HDIO_SET_WCACHE:
-       case HDIO_SET_ACOUSTIC:
-       case HDIO_SET_BUSSTATE:
-       case HDIO_SET_ADDRESS:
-       case CDROMEJECT_SW:
-       case CDROM_SET_OPTIONS:
-       case CDROM_CLEAR_OPTIONS:
-       case CDROM_SELECT_SPEED:
-       case CDROM_SELECT_DISC:
-       case CDROM_MEDIA_CHANGED:
-       case CDROM_DRIVE_STATUS:
-       case CDROM_LOCKDOOR:
-       case CDROM_DEBUG:
                break;
        default:
                /* unknown ioctl number */
                return -ENOIOCTLCMD;
        }
 
-       if (disk->fops->unlocked_ioctl)
-               return disk->fops->unlocked_ioctl(file, cmd, arg);
-
-       if (disk->fops->ioctl) {
-               lock_kernel();
-               ret = disk->fops->ioctl(inode, file, cmd, arg);
-               unlock_kernel();
-               return ret;
-       }
-
-       return -ENOTTY;
+       return __blkdev_driver_ioctl(bdev, mode, cmd, arg);
 }
 
-static int compat_blkdev_locked_ioctl(struct inode *inode, struct file *file,
-                               struct block_device *bdev,
-                               unsigned cmd, unsigned long arg)
+/* Most of the generic ioctls are handled in the normal fallback path.
+   This assumes the blkdev's low level compat_ioctl always returns
+   ENOIOCTLCMD for unknown ioctls. */
+long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
 {
+       int ret = -ENOIOCTLCMD;
+       struct inode *inode = file->f_mapping->host;
+       struct block_device *bdev = inode->i_bdev;
+       struct gendisk *disk = bdev->bd_disk;
+       fmode_t mode = file->f_mode;
        struct backing_dev_info *bdi;
+       loff_t size;
+
+       if (file->f_flags & O_NDELAY)
+               mode |= FMODE_NDELAY_NOW;
 
        switch (cmd) {
+       case HDIO_GETGEO:
+               return compat_hdio_getgeo(disk, bdev, compat_ptr(arg));
+       case BLKFLSBUF:
+       case BLKROSET:
+       case BLKDISCARD:
+       /*
+        * the ones below are implemented in blkdev_locked_ioctl,
+        * but we call blkdev_ioctl, which gets the lock for us
+        */
+       case BLKRRPART:
+               return blkdev_ioctl(bdev, mode, cmd,
+                               (unsigned long)compat_ptr(arg));
+       case BLKBSZSET_32:
+               return blkdev_ioctl(bdev, mode, BLKBSZSET,
+                               (unsigned long)compat_ptr(arg));
+       case BLKPG:
+               return compat_blkpg_ioctl(bdev, mode, cmd, compat_ptr(arg));
        case BLKRAGET:
        case BLKFRAGET:
                if (!arg)
@@ -753,65 +745,36 @@ static int compat_blkdev_locked_ioctl(struct inode *inode, struct file *file,
                bdi = blk_get_backing_dev_info(bdev);
                if (bdi == NULL)
                        return -ENOTTY;
+               lock_kernel();
                bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE;
+               unlock_kernel();
                return 0;
        case BLKGETSIZE:
-               if ((bdev->bd_inode->i_size >> 9) > ~0UL)
+               size = bdev->bd_inode->i_size;
+               if ((size >> 9) > ~0UL)
                        return -EFBIG;
-               return compat_put_ulong(arg, bdev->bd_inode->i_size >> 9);
+               return compat_put_ulong(arg, size >> 9);
 
        case BLKGETSIZE64_32:
                return compat_put_u64(arg, bdev->bd_inode->i_size);
 
        case BLKTRACESETUP32:
-               return compat_blk_trace_setup(bdev, compat_ptr(arg));
+               lock_kernel();
+               ret = compat_blk_trace_setup(bdev, compat_ptr(arg));
+               unlock_kernel();
+               return ret;
        case BLKTRACESTART: /* compatible */
        case BLKTRACESTOP:  /* compatible */
        case BLKTRACETEARDOWN: /* compatible */
-               return blk_trace_ioctl(bdev, cmd, compat_ptr(arg));
-       }
-       return -ENOIOCTLCMD;
-}
-
-/* Most of the generic ioctls are handled in the normal fallback path.
-   This assumes the blkdev's low level compat_ioctl always returns
-   ENOIOCTLCMD for unknown ioctls. */
-long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
-{
-       int ret = -ENOIOCTLCMD;
-       struct inode *inode = file->f_mapping->host;
-       struct block_device *bdev = inode->i_bdev;
-       struct gendisk *disk = bdev->bd_disk;
-
-       switch (cmd) {
-       case HDIO_GETGEO:
-               return compat_hdio_getgeo(disk, bdev, compat_ptr(arg));
-       case BLKFLSBUF:
-       case BLKROSET:
-       case BLKDISCARD:
-       /*
-        * the ones below are implemented in blkdev_locked_ioctl,
-        * but we call blkdev_ioctl, which gets the lock for us
-        */
-       case BLKRRPART:
-               return blkdev_ioctl(inode, file, cmd,
-                               (unsigned long)compat_ptr(arg));
-       case BLKBSZSET_32:
-               return blkdev_ioctl(inode, file, BLKBSZSET,
-                               (unsigned long)compat_ptr(arg));
-       case BLKPG:
-               return compat_blkpg_ioctl(inode, file, cmd, compat_ptr(arg));
-       }
-
-       lock_kernel();
-       ret = compat_blkdev_locked_ioctl(inode, file, bdev, cmd, arg);
-       /* FIXME: why do we assume -> compat_ioctl needs the BKL? */
-       if (ret == -ENOIOCTLCMD && disk->fops->compat_ioctl)
-               ret = disk->fops->compat_ioctl(file, cmd, arg);
-       unlock_kernel();
-
-       if (ret != -ENOIOCTLCMD)
+               lock_kernel();
+               ret = blk_trace_ioctl(bdev, cmd, compat_ptr(arg));
+               unlock_kernel();
                return ret;
-
-       return compat_blkdev_driver_ioctl(inode, file, disk, cmd, arg);
+       default:
+               if (disk->fops->compat_ioctl)
+                       ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg);
+               if (ret == -ENOIOCTLCMD)
+                       ret = compat_blkdev_driver_ioctl(bdev, mode, cmd, arg);
+               return ret;
+       }
 }
index 646e1d2507c70d2ba88824c3dd84d91874ecb192..4e5e7493f6764e8f3a03b62e40bd40b724d15880 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/blkdev.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
+#include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/kmod.h>
@@ -727,12 +728,24 @@ static int show_partition(struct seq_file *seqf, void *v)
        return 0;
 }
 
-const struct seq_operations partitions_op = {
+static const struct seq_operations partitions_op = {
        .start  = show_partition_start,
        .next   = disk_seqf_next,
        .stop   = disk_seqf_stop,
        .show   = show_partition
 };
+
+static int partitions_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &partitions_op);
+}
+
+static const struct file_operations proc_partitions_operations = {
+       .open           = partitions_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 #endif
 
 
@@ -992,12 +1005,32 @@ static int diskstats_show(struct seq_file *seqf, void *v)
        return 0;
 }
 
-const struct seq_operations diskstats_op = {
+static const struct seq_operations diskstats_op = {
        .start  = disk_seqf_start,
        .next   = disk_seqf_next,
        .stop   = disk_seqf_stop,
        .show   = diskstats_show
 };
+
+static int diskstats_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &diskstats_op);
+}
+
+static const struct file_operations proc_diskstats_operations = {
+       .open           = diskstats_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+static int __init proc_genhd_init(void)
+{
+       proc_create("diskstats", 0, NULL, &proc_diskstats_operations);
+       proc_create("partitions", 0, NULL, &proc_partitions_operations);
+       return 0;
+}
+module_init(proc_genhd_init);
 #endif /* CONFIG_PROC_FS */
 
 static void media_change_notify_thread(struct work_struct *work)
index 38bee321e1fa07c7dd41940c6fae8094a822068c..c832d639b6e254eb375d9c69504172182ab14c4d 100644 (file)
@@ -201,97 +201,41 @@ static int put_u64(unsigned long arg, u64 val)
        return put_user(val, (u64 __user *)arg);
 }
 
-static int blkdev_locked_ioctl(struct file *file, struct block_device *bdev,
-                               unsigned cmd, unsigned long arg)
-{
-       struct backing_dev_info *bdi;
-       int ret, n;
-
-       switch (cmd) {
-       case BLKRAGET:
-       case BLKFRAGET:
-               if (!arg)
-                       return -EINVAL;
-               bdi = blk_get_backing_dev_info(bdev);
-               if (bdi == NULL)
-                       return -ENOTTY;
-               return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512);
-       case BLKROGET:
-               return put_int(arg, bdev_read_only(bdev) != 0);
-       case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */
-               return put_int(arg, block_size(bdev));
-       case BLKSSZGET: /* get block device hardware sector size */
-               return put_int(arg, bdev_hardsect_size(bdev));
-       case BLKSECTGET:
-               return put_ushort(arg, bdev_get_queue(bdev)->max_sectors);
-       case BLKRASET:
-       case BLKFRASET:
-               if(!capable(CAP_SYS_ADMIN))
-                       return -EACCES;
-               bdi = blk_get_backing_dev_info(bdev);
-               if (bdi == NULL)
-                       return -ENOTTY;
-               bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE;
-               return 0;
-       case BLKBSZSET:
-               /* set the logical block size */
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EACCES;
-               if (!arg)
-                       return -EINVAL;
-               if (get_user(n, (int __user *) arg))
-                       return -EFAULT;
-               if (bd_claim(bdev, file) < 0)
-                       return -EBUSY;
-               ret = set_blocksize(bdev, n);
-               bd_release(bdev);
-               return ret;
-       case BLKPG:
-               return blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg);
-       case BLKRRPART:
-               return blkdev_reread_part(bdev);
-       case BLKGETSIZE:
-               if ((bdev->bd_inode->i_size >> 9) > ~0UL)
-                       return -EFBIG;
-               return put_ulong(arg, bdev->bd_inode->i_size >> 9);
-       case BLKGETSIZE64:
-               return put_u64(arg, bdev->bd_inode->i_size);
-       case BLKTRACESTART:
-       case BLKTRACESTOP:
-       case BLKTRACESETUP:
-       case BLKTRACETEARDOWN:
-               return blk_trace_ioctl(bdev, cmd, (char __user *) arg);
-       }
-       return -ENOIOCTLCMD;
-}
-
-int blkdev_driver_ioctl(struct inode *inode, struct file *file,
-                       struct gendisk *disk, unsigned cmd, unsigned long arg)
+int __blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
+                       unsigned cmd, unsigned long arg)
 {
+       struct gendisk *disk = bdev->bd_disk;
        int ret;
-       if (disk->fops->unlocked_ioctl)
-               return disk->fops->unlocked_ioctl(file, cmd, arg);
 
-       if (disk->fops->ioctl) {
+       if (disk->fops->ioctl)
+               return disk->fops->ioctl(bdev, mode, cmd, arg);
+
+       if (disk->fops->locked_ioctl) {
                lock_kernel();
-               ret = disk->fops->ioctl(inode, file, cmd, arg);
+               ret = disk->fops->locked_ioctl(bdev, mode, cmd, arg);
                unlock_kernel();
                return ret;
        }
 
        return -ENOTTY;
 }
-EXPORT_SYMBOL_GPL(blkdev_driver_ioctl);
+/*
+ * For the record: _GPL here is only because somebody decided to slap it
+ * on the previous export.  Sheer idiocy, since it wasn't copyrightable
+ * at all and could be open-coded without any exports by anybody who cares.
+ */
+EXPORT_SYMBOL_GPL(__blkdev_driver_ioctl);
 
 /*
  * always keep this in sync with compat_blkdev_ioctl() and
  * compat_blkdev_locked_ioctl()
  */
-int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
+int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
                        unsigned long arg)
 {
-       struct block_device *bdev = inode->i_bdev;
        struct gendisk *disk = bdev->bd_disk;
+       struct backing_dev_info *bdi;
+       loff_t size;
        int ret, n;
 
        switch(cmd) {
@@ -299,7 +243,7 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
                if (!capable(CAP_SYS_ADMIN))
                        return -EACCES;
 
-               ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg);
+               ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
                /* -EINVAL to handle old uncorrected drivers */
                if (ret != -EINVAL && ret != -ENOTTY)
                        return ret;
@@ -311,7 +255,7 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
                return 0;
 
        case BLKROSET:
-               ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg);
+               ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
                /* -EINVAL to handle old uncorrected drivers */
                if (ret != -EINVAL && ret != -ENOTTY)
                        return ret;
@@ -327,7 +271,7 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
        case BLKDISCARD: {
                uint64_t range[2];
 
-               if (!(file->f_mode & FMODE_WRITE))
+               if (!(mode & FMODE_WRITE))
                        return -EBADF;
 
                if (copy_from_user(range, (void __user *)arg, sizeof(range)))
@@ -357,14 +301,75 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
                        return -EFAULT;
                return 0;
        }
-       }
-
-       lock_kernel();
-       ret = blkdev_locked_ioctl(file, bdev, cmd, arg);
-       unlock_kernel();
-       if (ret != -ENOIOCTLCMD)
+       case BLKRAGET:
+       case BLKFRAGET:
+               if (!arg)
+                       return -EINVAL;
+               bdi = blk_get_backing_dev_info(bdev);
+               if (bdi == NULL)
+                       return -ENOTTY;
+               return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512);
+       case BLKROGET:
+               return put_int(arg, bdev_read_only(bdev) != 0);
+       case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */
+               return put_int(arg, block_size(bdev));
+       case BLKSSZGET: /* get block device hardware sector size */
+               return put_int(arg, bdev_hardsect_size(bdev));
+       case BLKSECTGET:
+               return put_ushort(arg, bdev_get_queue(bdev)->max_sectors);
+       case BLKRASET:
+       case BLKFRASET:
+               if(!capable(CAP_SYS_ADMIN))
+                       return -EACCES;
+               bdi = blk_get_backing_dev_info(bdev);
+               if (bdi == NULL)
+                       return -ENOTTY;
+               lock_kernel();
+               bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE;
+               unlock_kernel();
+               return 0;
+       case BLKBSZSET:
+               /* set the logical block size */
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EACCES;
+               if (!arg)
+                       return -EINVAL;
+               if (get_user(n, (int __user *) arg))
+                       return -EFAULT;
+               if (!(mode & FMODE_EXCL) && bd_claim(bdev, &bdev) < 0)
+                       return -EBUSY;
+               ret = set_blocksize(bdev, n);
+               if (!(mode & FMODE_EXCL))
+                       bd_release(bdev);
                return ret;
-
-       return blkdev_driver_ioctl(inode, file, disk, cmd, arg);
+       case BLKPG:
+               lock_kernel();
+               ret = blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg);
+               unlock_kernel();
+               break;
+       case BLKRRPART:
+               lock_kernel();
+               ret = blkdev_reread_part(bdev);
+               unlock_kernel();
+               break;
+       case BLKGETSIZE:
+               size = bdev->bd_inode->i_size;
+               if ((size >> 9) > ~0UL)
+                       return -EFBIG;
+               return put_ulong(arg, size >> 9);
+       case BLKGETSIZE64:
+               return put_u64(arg, bdev->bd_inode->i_size);
+       case BLKTRACESTART:
+       case BLKTRACESTOP:
+       case BLKTRACESETUP:
+       case BLKTRACETEARDOWN:
+               lock_kernel();
+               ret = blk_trace_ioctl(bdev, cmd, (char __user *) arg);
+               unlock_kernel();
+               break;
+       default:
+               ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
+       }
+       return ret;
 }
 EXPORT_SYMBOL_GPL(blkdev_ioctl);
index c34272a348fe07fd22aec5c8d8ccc55c37cddf64..5963cf91a3a0c4f67dc709f9a6b98fdd87235f53 100644 (file)
@@ -190,12 +190,11 @@ void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter)
 EXPORT_SYMBOL_GPL(blk_set_cmd_filter_defaults);
 
 static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,
-                            struct sg_io_hdr *hdr, struct file *file)
+                            struct sg_io_hdr *hdr, fmode_t mode)
 {
        if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len))
                return -EFAULT;
-       if (blk_verify_command(&q->cmd_filter, rq->cmd,
-                              file->f_mode & FMODE_WRITE))
+       if (blk_verify_command(&q->cmd_filter, rq->cmd, mode & FMODE_WRITE))
                return -EPERM;
 
        /*
@@ -260,8 +259,8 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
        return r;
 }
 
-static int sg_io(struct file *file, struct request_queue *q,
-               struct gendisk *bd_disk, struct sg_io_hdr *hdr)
+static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
+               struct sg_io_hdr *hdr, fmode_t mode)
 {
        unsigned long start_time;
        int writing = 0, ret = 0;
@@ -293,7 +292,7 @@ static int sg_io(struct file *file, struct request_queue *q,
        if (!rq)
                return -ENOMEM;
 
-       if (blk_fill_sghdr_rq(q, rq, hdr, file)) {
+       if (blk_fill_sghdr_rq(q, rq, hdr, mode)) {
                blk_put_request(rq);
                return -EFAULT;
        }
@@ -380,11 +379,11 @@ out:
  *      bytes in one int) where the lowest byte is the SCSI status.
  */
 #define OMAX_SB_LEN 16          /* For backward compatibility */
-int sg_scsi_ioctl(struct file *file, struct request_queue *q,
-                 struct gendisk *disk, struct scsi_ioctl_command __user *sic)
+int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
+               struct scsi_ioctl_command __user *sic)
 {
        struct request *rq;
-       int err, write_perm = 0;
+       int err;
        unsigned int in_len, out_len, bytes, opcode, cmdlen;
        char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE];
 
@@ -426,11 +425,7 @@ int sg_scsi_ioctl(struct file *file, struct request_queue *q,
        if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))
                goto error;
 
-       /* scsi_ioctl passes NULL */
-       if (file && (file->f_mode & FMODE_WRITE))
-               write_perm = 1;
-
-       err = blk_verify_command(&q->cmd_filter, rq->cmd, write_perm);
+       err = blk_verify_command(&q->cmd_filter, rq->cmd, mode & FMODE_WRITE);
        if (err)
                goto error;
 
@@ -522,8 +517,8 @@ static inline int blk_send_start_stop(struct request_queue *q,
        return __blk_send_generic(q, bd_disk, GPCMD_START_STOP_UNIT, data);
 }
 
-int scsi_cmd_ioctl(struct file *file, struct request_queue *q,
-                  struct gendisk *bd_disk, unsigned int cmd, void __user *arg)
+int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mode,
+                  unsigned int cmd, void __user *arg)
 {
        int err;
 
@@ -564,7 +559,7 @@ int scsi_cmd_ioctl(struct file *file, struct request_queue *q,
                        err = -EFAULT;
                        if (copy_from_user(&hdr, arg, sizeof(hdr)))
                                break;
-                       err = sg_io(file, q, bd_disk, &hdr);
+                       err = sg_io(q, bd_disk, &hdr, mode);
                        if (err == -EFAULT)
                                break;
 
@@ -612,7 +607,7 @@ int scsi_cmd_ioctl(struct file *file, struct request_queue *q,
                        hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd;
                        hdr.cmd_len = sizeof(cgc.cmd);
 
-                       err = sg_io(file, q, bd_disk, &hdr);
+                       err = sg_io(q, bd_disk, &hdr, mode);
                        if (err == -EFAULT)
                                break;
 
@@ -636,7 +631,7 @@ int scsi_cmd_ioctl(struct file *file, struct request_queue *q,
                        if (!arg)
                                break;
 
-                       err = sg_scsi_ioctl(file, q, bd_disk, arg);
+                       err = sg_scsi_ioctl(q, bd_disk, mode, arg);
                        break;
                case CDROMCLOSETRAY:
                        err = blk_send_start_stop(q, bd_disk, 0x03);
index e8362c1efa309f8e0242a255235650d953aeca51..dcbf1be149f3486e26f38428499d2a07d0ff604e 100644 (file)
@@ -115,34 +115,32 @@ EXPORT_SYMBOL_GPL(dma_wait_for_async_tx);
  *     (start) dependent operations on their target channel
  * @tx: transaction with dependencies
  */
-void
-async_tx_run_dependencies(struct dma_async_tx_descriptor *tx)
+void async_tx_run_dependencies(struct dma_async_tx_descriptor *tx)
 {
-       struct dma_async_tx_descriptor *next = tx->next;
+       struct dma_async_tx_descriptor *dep = tx->next;
+       struct dma_async_tx_descriptor *dep_next;
        struct dma_chan *chan;
 
-       if (!next)
+       if (!dep)
                return;
 
-       tx->next = NULL;
-       chan = next->chan;
+       chan = dep->chan;
 
        /* keep submitting up until a channel switch is detected
         * in that case we will be called again as a result of
         * processing the interrupt from async_tx_channel_switch
         */
-       while (next && next->chan == chan) {
-               struct dma_async_tx_descriptor *_next;
-
-               spin_lock_bh(&next->lock);
-               next->parent = NULL;
-               _next = next->next;
-               if (_next && _next->chan == chan)
-                       next->next = NULL;
-               spin_unlock_bh(&next->lock);
-
-               next->tx_submit(next);
-               next = _next;
+       for (; dep; dep = dep_next) {
+               spin_lock_bh(&dep->lock);
+               dep->parent = NULL;
+               dep_next = dep->next;
+               if (dep_next && dep_next->chan == chan)
+                       dep->next = NULL; /* ->next will be submitted */
+               else
+                       dep_next = NULL; /* submit current dep and terminate */
+               spin_unlock_bh(&dep->lock);
+
+               dep->tx_submit(dep);
        }
 
        chan->device->device_issue_pending(chan);
index d19b6f5a1106b5202d88ecbe0dccad43a129c369..d38f43f593d400e64ab7796c1f90760c66966caf 100644 (file)
@@ -78,6 +78,8 @@ source "drivers/hid/Kconfig"
 
 source "drivers/usb/Kconfig"
 
+source "drivers/uwb/Kconfig"
+
 source "drivers/mmc/Kconfig"
 
 source "drivers/memstick/Kconfig"
index 46c8681a07f48cd89766e97155d2adb9f3b91454..2503f7b99b2fdc70edf3648d365c7a2c35e85eaa 100644 (file)
@@ -82,6 +82,7 @@ obj-$(CONFIG_EISA)            += eisa/
 obj-y                          += lguest/
 obj-$(CONFIG_CPU_FREQ)         += cpufreq/
 obj-$(CONFIG_CPU_IDLE)         += cpuidle/
+obj-y                          += idle/
 obj-$(CONFIG_MMC)              += mmc/
 obj-$(CONFIG_MEMSTICK)         += memstick/
 obj-$(CONFIG_NEW_LEDS)         += leds/
@@ -100,3 +101,4 @@ obj-$(CONFIG_SSB)           += ssb/
 obj-$(CONFIG_VIRTIO)           += virtio/
 obj-$(CONFIG_REGULATOR)                += regulator/
 obj-$(CONFIG_STAGING)          += staging/
+obj-$(CONFIG_UWB)              += uwb/
index da49b006bcc58cb4819787cdb3156c82138180af..f4f6329175094383e61749a6dbf893a3ecda92d9 100644 (file)
@@ -42,7 +42,7 @@ if ACPI
 
 config ACPI_SLEEP
        bool
-       depends on PM_SLEEP
+       depends on SUSPEND || HIBERNATION
        default y
 
 config ACPI_PROCFS
@@ -157,18 +157,11 @@ config ACPI_FAN
          applications to perform basic fan control (on, off, status).
 
 config ACPI_DOCK
-       tristate "Dock"
+       bool "Dock"
        depends on EXPERIMENTAL
        help
-         This driver adds support for ACPI controlled docking stations
-
-config ACPI_BAY
-       tristate "Removable Drive Bay (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
-       depends on ACPI_DOCK
-       help
-         This driver adds support for ACPI controlled removable drive
-         bays such as the IBM ultrabay or the Dell Module Bay.
+         This driver adds support for ACPI controlled docking stations and removable
+         drive bays such as the IBM ultrabay or the Dell Module Bay.
 
 config ACPI_PROCESSOR
        tristate "Processor"
index 52a4cd4b81d0735e916f4ab6ce037265106c27d5..d91c027ece8f6409cc50a83023ac7821a4f9b1a4 100644 (file)
@@ -45,14 +45,13 @@ obj-$(CONFIG_ACPI_BATTERY)  += battery.o
 obj-$(CONFIG_ACPI_BUTTON)      += button.o
 obj-$(CONFIG_ACPI_FAN)         += fan.o
 obj-$(CONFIG_ACPI_DOCK)                += dock.o
-obj-$(CONFIG_ACPI_BAY)         += bay.o
 obj-$(CONFIG_ACPI_VIDEO)       += video.o
 obj-y                          += pci_root.o pci_link.o pci_irq.o pci_bind.o
 obj-$(CONFIG_ACPI_PCI_SLOT)    += pci_slot.o
-obj-$(CONFIG_ACPI_POWER)       += power.o
 obj-$(CONFIG_ACPI_PROCESSOR)   += processor.o
 obj-$(CONFIG_ACPI_CONTAINER)   += container.o
 obj-$(CONFIG_ACPI_THERMAL)     += thermal.o
+obj-$(CONFIG_ACPI_POWER)       += power.o
 obj-$(CONFIG_ACPI_SYSTEM)      += system.o event.o
 obj-$(CONFIG_ACPI_DEBUG)       += debug.o
 obj-$(CONFIG_ACPI_NUMA)                += numa.o
index 831883b7d6c9c5f456bb8db766ebc978b00bd907..d72a1b6c8a943bde5aff998e09b2fbaf1ea9d222 100644 (file)
@@ -85,7 +85,7 @@ struct acpi_ac {
        struct power_supply charger;
 #endif
        struct acpi_device * device;
-       unsigned long state;
+       unsigned long long state;
 };
 
 #define to_acpi_ac(x) container_of(x, struct acpi_ac, charger);
@@ -269,7 +269,7 @@ static int acpi_ac_add(struct acpi_device *device)
        ac->device = device;
        strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_AC_CLASS);
-       acpi_driver_data(device) = ac;
+       device->driver_data = ac;
 
        result = acpi_ac_get_state(ac);
        if (result)
index 5f1127ad5a9538fde4cdaa8e4a6658f2880928a7..71d21c51c45f573c6591d224e835843357df5981 100644 (file)
@@ -194,8 +194,7 @@ acpi_memory_get_device(acpi_handle handle,
 
 static int acpi_memory_check_device(struct acpi_memory_device *mem_device)
 {
-       unsigned long current_status;
-
+       unsigned long long current_status;
 
        /* Get device present/absent information from the _STA */
        if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->device->handle, "_STA",
@@ -264,7 +263,7 @@ static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device)
        acpi_status status;
        struct acpi_object_list arg_list;
        union acpi_object arg;
-       unsigned long current_status;
+       unsigned long long current_status;
 
 
        /* Issue the _EJ0 command */
@@ -403,7 +402,7 @@ static int acpi_memory_device_add(struct acpi_device *device)
        mem_device->device = device;
        sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME);
        sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS);
-       acpi_driver_data(device) = mem_device;
+       device->driver_data = mem_device;
 
        /* Get the range from the _CRS */
        result = acpi_memory_get_device_resources(mem_device);
@@ -454,8 +453,8 @@ static int acpi_memory_device_start (struct acpi_device *device)
                /* call add_memory func */
                result = acpi_memory_enable_device(mem_device);
                if (result)
-                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                               "Error in acpi_memory_enable_device\n"));
+                       printk(KERN_ERR PREFIX
+                               "Error in acpi_memory_enable_device\n");
        }
        return result;
 }
index d3d0886d637f4f6e33e7a0f0ed54fe00560d2615..1e74988c7b2d2859871ca335d16af235a3ca7e6f 100644 (file)
@@ -42,7 +42,7 @@
 
 #define ASUS_ACPI_VERSION "0.30"
 
-#define PROC_ASUS       "asus" //the directory
+#define PROC_ASUS       "asus" /* The directory */
 #define PROC_MLED       "mled"
 #define PROC_WLED       "wled"
 #define PROC_TLED       "tled"
 /*
  * Flags for hotk status
  */
-#define MLED_ON     0x01       //mail LED
-#define WLED_ON     0x02       //wireless LED
-#define TLED_ON     0x04       //touchpad LED
-#define BT_ON       0x08       //internal Bluetooth
+#define MLED_ON     0x01       /* Mail LED */
+#define WLED_ON     0x02       /* Wireless LED */
+#define TLED_ON     0x04       /* Touchpad LED */
+#define BT_ON       0x08       /* Internal Bluetooth */
 
 MODULE_AUTHOR("Julien Lerouge, Karol Kozimor");
 MODULE_DESCRIPTION(ACPI_HOTK_NAME);
@@ -82,28 +82,28 @@ MODULE_PARM_DESC(asus_uid, "UID for entries in /proc/acpi/asus");
 module_param(asus_gid, uint, 0);
 MODULE_PARM_DESC(asus_gid, "GID for entries in /proc/acpi/asus");
 
-/* For each model, all features implemented, 
+/* For each model, all features implemented,
  * those marked with R are relative to HOTK, A for absolute */
 struct model_data {
-       char *name;             //name of the laptop________________A
-       char *mt_mled;          //method to handle mled_____________R
-       char *mled_status;      //node to handle mled reading_______A
-       char *mt_wled;          //method to handle wled_____________R
-       char *wled_status;      //node to handle wled reading_______A
-       char *mt_tled;          //method to handle tled_____________R
-       char *tled_status;      //node to handle tled reading_______A
-       char *mt_ledd;          //method to handle LED display______R
-       char *mt_bt_switch;     //method to switch Bluetooth on/off_R
-       char *bt_status;        //no model currently supports this__?
-       char *mt_lcd_switch;    //method to turn LCD on/off_________A
-       char *lcd_status;       //node to read LCD panel state______A
-       char *brightness_up;    //method to set brightness up_______A
-       char *brightness_down;  //guess what ?______________________A
-       char *brightness_set;   //method to set absolute brightness_R
-       char *brightness_get;   //method to get absolute brightness_R
-       char *brightness_status;        //node to get brightness____________A
-       char *display_set;      //method to set video output________R
-       char *display_get;      //method to get video output________R
+       char *name;             /* name of the laptop________________A */
+       char *mt_mled;          /* method to handle mled_____________R */
+       char *mled_status;      /* node to handle mled reading_______A */
+       char *mt_wled;          /* method to handle wled_____________R */
+       char *wled_status;      /* node to handle wled reading_______A */
+       char *mt_tled;          /* method to handle tled_____________R */
+       char *tled_status;      /* node to handle tled reading_______A */
+       char *mt_ledd;          /* method to handle LED display______R */
+       char *mt_bt_switch;     /* method to switch Bluetooth on/off_R */
+       char *bt_status;        /* no model currently supports this__? */
+       char *mt_lcd_switch;    /* method to turn LCD on/off_________A */
+       char *lcd_status;       /* node to read LCD panel state______A */
+       char *brightness_up;    /* method to set brightness up_______A */
+       char *brightness_down;  /* method to set brightness down ____A */
+       char *brightness_set;   /* method to set absolute brightness_R */
+       char *brightness_get;   /* method to get absolute brightness_R */
+       char *brightness_status;/* node to get brightness____________A */
+       char *display_set;      /* method to set video output________R */
+       char *display_get;      /* method to get video output________R */
 };
 
 /*
@@ -111,41 +111,41 @@ struct model_data {
  * about the hotk device
  */
 struct asus_hotk {
-       struct acpi_device *device;     //the device we are in
-       acpi_handle handle;     //the handle of the hotk device
-       char status;            //status of the hotk, for LEDs, ...
-       u32 ledd_status;        //status of the LED display
-       struct model_data *methods;     //methods available on the laptop
-       u8 brightness;          //brightness level
+       struct acpi_device *device;     /* the device we are in */
+       acpi_handle handle;             /* the handle of the hotk device */
+       char status;                    /* status of the hotk, for LEDs */
+       u32 ledd_status;                /* status of the LED display */
+       struct model_data *methods;     /* methods available on the laptop */
+       u8 brightness;                  /* brightness level */
        enum {
-               A1x = 0,        //A1340D, A1300F
-               A2x,            //A2500H
-               A4G,            //A4700G
-               D1x,            //D1
-               L2D,            //L2000D
-               L3C,            //L3800C
-               L3D,            //L3400D
-               L3H,            //L3H, L2000E, L5D
-               L4R,            //L4500R
-               L5x,            //L5800C 
-               L8L,            //L8400L
-               M1A,            //M1300A
-               M2E,            //M2400E, L4400L
-               M6N,            //M6800N, W3400N
-               M6R,            //M6700R, A3000G
-               P30,            //Samsung P30
-               S1x,            //S1300A, but also L1400B and M2400A (L84F)
-               S2x,            //S200 (J1 reported), Victor MP-XP7210
-               W1N,            //W1000N
-               W5A,            //W5A
-               W3V,            //W3030V
-               xxN,            //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N
-               A4S,            //Z81sp
-               //(Centrino)
-               F3Sa,
+               A1x = 0,        /* A1340D, A1300F */
+               A2x,            /* A2500H */
+               A4G,            /* A4700G */
+               D1x,            /* D1 */
+               L2D,            /* L2000D */
+               L3C,            /* L3800C */
+               L3D,            /* L3400D */
+               L3H,            /* L3H, L2000E, L5D */
+               L4R,            /* L4500R */
+               L5x,            /* L5800C */
+               L8L,            /* L8400L */
+               M1A,            /* M1300A */
+               M2E,            /* M2400E, L4400L */
+               M6N,            /* M6800N, W3400N */
+               M6R,            /* M6700R, A3000G */
+               P30,            /* Samsung P30 */
+               S1x,            /* S1300A, but also L1400B and M2400A (L84F) */
+               S2x,            /* S200 (J1 reported), Victor MP-XP7210 */
+               W1N,            /* W1000N */
+               W5A,            /* W5A */
+               W3V,            /* W3030V */
+               xxN,            /* M2400N, M3700N, M5200N, M6800N,
+                                                        S1300N, S5200N*/
+               A4S,            /* Z81sp */
+               F3Sa,           /* (Centrino) */
                END_MODEL
-       } model;                //Models currently supported
-       u16 event_count[128];   //count for each event TODO make this better
+       } model;                /* Models currently supported */
+       u16 event_count[128];   /* Count for each event TODO make this better */
 };
 
 /* Here we go */
@@ -459,18 +459,18 @@ static struct acpi_driver asus_hotk_driver = {
                },
 };
 
-/* 
+/*
  * This function evaluates an ACPI method, given an int as parameter, the
  * method is searched within the scope of the handle, can be NULL. The output
  * of the method is written is output, which can also be NULL
  *
- * returns 1 if write is successful, 0 else. 
+ * returns 1 if write is successful, 0 else.
  */
 static int write_acpi_int(acpi_handle handle, const char *method, int val,
                          struct acpi_buffer *output)
 {
-       struct acpi_object_list params; //list of input parameters (an int here)
-       union acpi_object in_obj;       //the only param we use
+       struct acpi_object_list params; /* list of input parameters (int) */
+       union acpi_object in_obj;       /* the only param we use */
        acpi_status status;
 
        params.count = 1;
@@ -507,18 +507,18 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof,
 {
        int len = 0;
        int temp;
-       char buf[16];           //enough for all info
+       char buf[16];           /* enough for all info */
        /*
-        * We use the easy way, we don't care of off and count, so we don't set eof
-        * to 1
+        * We use the easy way, we don't care of off and count,
+        * so we don't set eof to 1
         */
 
        len += sprintf(page, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n");
        len += sprintf(page + len, "Model reference    : %s\n",
                       hotk->methods->name);
-       /* 
-        * The SFUN method probably allows the original driver to get the list 
-        * of features supported by a given model. For now, 0x0100 or 0x0800 
+       /*
+        * The SFUN method probably allows the original driver to get the list
+        * of features supported by a given model. For now, 0x0100 or 0x0800
         * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card.
         * The significance of others is yet to be found.
         */
@@ -528,7 +528,7 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof,
        /*
         * Another value for userspace: the ASYM method returns 0x02 for
         * battery low and 0x04 for battery critical, its readings tend to be
-        * more accurate than those provided by _BST. 
+        * more accurate than those provided by _BST.
         * Note: since not all the laptops provide this method, errors are
         * silently ignored.
         */
@@ -579,7 +579,7 @@ static int read_led(const char *ledname, int ledmask)
        return (hotk->status & ledmask) ? 1 : 0;
 }
 
-static int parse_arg(const char __user * buf, unsigned long count, int *val)
+static int parse_arg(const char __user *buf, unsigned long count, int *val)
 {
        char s[32];
        if (!count)
@@ -596,7 +596,7 @@ static int parse_arg(const char __user * buf, unsigned long count, int *val)
 
 /* FIXME: kill extraneous args so it can be called independently */
 static int
-write_led(const char __user * buffer, unsigned long count,
+write_led(const char __user *buffer, unsigned long count,
          char *ledname, int ledmask, int invert)
 {
        int rv, value;
@@ -631,7 +631,7 @@ proc_read_mled(char *page, char **start, off_t off, int count, int *eof,
 }
 
 static int
-proc_write_mled(struct file *file, const char __user * buffer,
+proc_write_mled(struct file *file, const char __user *buffer,
                unsigned long count, void *data)
 {
        return write_led(buffer, count, hotk->methods->mt_mled, MLED_ON, 1);
@@ -648,7 +648,7 @@ proc_read_ledd(char *page, char **start, off_t off, int count, int *eof,
 }
 
 static int
-proc_write_ledd(struct file *file, const char __user * buffer,
+proc_write_ledd(struct file *file, const char __user *buffer,
                unsigned long count, void *data)
 {
        int rv, value;
@@ -677,7 +677,7 @@ proc_read_wled(char *page, char **start, off_t off, int count, int *eof,
 }
 
 static int
-proc_write_wled(struct file *file, const char __user * buffer,
+proc_write_wled(struct file *file, const char __user *buffer,
                unsigned long count, void *data)
 {
        return write_led(buffer, count, hotk->methods->mt_wled, WLED_ON, 0);
@@ -694,10 +694,10 @@ proc_read_bluetooth(char *page, char **start, off_t off, int count, int *eof,
 }
 
 static int
-proc_write_bluetooth(struct file *file, const char __user * buffer,
+proc_write_bluetooth(struct file *file, const char __user *buffer,
                     unsigned long count, void *data)
 {
-       /* Note: mt_bt_switch controls both internal Bluetooth adapter's 
+       /* Note: mt_bt_switch controls both internal Bluetooth adapter's
           presence and its LED */
        return write_led(buffer, count, hotk->methods->mt_bt_switch, BT_ON, 0);
 }
@@ -714,7 +714,7 @@ proc_read_tled(char *page, char **start, off_t off, int count, int *eof,
 }
 
 static int
-proc_write_tled(struct file *file, const char __user * buffer,
+proc_write_tled(struct file *file, const char __user *buffer,
                unsigned long count, void *data)
 {
        return write_led(buffer, count, hotk->methods->mt_tled, TLED_ON, 0);
@@ -734,7 +734,7 @@ static int get_lcd_state(void)
 
                input.count = 2;
                input.pointer = mt_params;
-               /* Note: the following values are partly guessed up, but 
+               /* Note: the following values are partly guessed up, but
                   otherwise they seem to work */
                mt_params[0].type = ACPI_TYPE_INTEGER;
                mt_params[0].integer.value = 0x02;
@@ -753,7 +753,7 @@ static int get_lcd_state(void)
                        /* That's what the AML code does */
                        lcd = out_obj.integer.value >> 8;
        } else if (hotk->model == F3Sa) {
-               unsigned long tmp;
+               unsigned long long tmp;
                union acpi_object param;
                struct acpi_object_list input;
                acpi_status status;
@@ -796,12 +796,13 @@ static int set_lcd_state(int value)
                            acpi_evaluate_object(NULL,
                                                 hotk->methods->mt_lcd_switch,
                                                 NULL, NULL);
-               } else {        /* L3H and the like have to be handled differently */
+               } else {
+                       /* L3H and the like must be handled differently */
                        if (!write_acpi_int
                            (hotk->handle, hotk->methods->mt_lcd_switch, 0x07,
                             NULL))
                                status = AE_ERROR;
-                       /* L3H's AML executes EHK (0x07) upon Fn+F7 keypress, 
+                       /* L3H's AML executes EHK (0x07) upon Fn+F7 keypress,
                           the exact behaviour is simulated here */
                }
                if (ACPI_FAILURE(status))
@@ -819,7 +820,7 @@ proc_read_lcd(char *page, char **start, off_t off, int count, int *eof,
 }
 
 static int
-proc_write_lcd(struct file *file, const char __user * buffer,
+proc_write_lcd(struct file *file, const char __user *buffer,
               unsigned long count, void *data)
 {
        int rv, value;
@@ -897,7 +898,7 @@ proc_read_brn(char *page, char **start, off_t off, int count, int *eof,
 }
 
 static int
-proc_write_brn(struct file *file, const char __user * buffer,
+proc_write_brn(struct file *file, const char __user *buffer,
               unsigned long count, void *data)
 {
        int rv, value;
@@ -921,7 +922,7 @@ static void set_display(int value)
 }
 
 /*
- * Now, *this* one could be more user-friendly, but so far, no-one has 
+ * Now, *this* one could be more user-friendly, but so far, no-one has
  * complained. The significance of bits is the same as in proc_write_disp()
  */
 static int
@@ -933,18 +934,18 @@ proc_read_disp(char *page, char **start, off_t off, int count, int *eof,
        if (!read_acpi_int(hotk->handle, hotk->methods->display_get, &value))
                printk(KERN_WARNING
                       "Asus ACPI: Error reading display status\n");
-       value &= 0x07;          /* needed for some models, shouldn't hurt others */
+       value &= 0x07;  /* needed for some models, shouldn't hurt others */
        return sprintf(page, "%d\n", value);
 }
 
 /*
- * Experimental support for display switching. As of now: 1 should activate 
- * the LCD output, 2 should do for CRT, and 4 for TV-Out. Any combination 
- * (bitwise) of these will suffice. I never actually tested 3 displays hooked up 
- * simultaneously, so be warned. See the acpi4asus README for more info.
+ * Experimental support for display switching. As of now: 1 should activate
+ * the LCD output, 2 should do for CRT, and 4 for TV-Out. Any combination
+ * (bitwise) of these will suffice. I never actually tested 3 displays hooked
+ * up simultaneously, so be warned. See the acpi4asus README for more info.
  */
 static int
-proc_write_disp(struct file *file, const char __user * buffer,
+proc_write_disp(struct file *file, const char __user *buffer,
                unsigned long count, void *data)
 {
        int rv, value;
@@ -957,12 +958,12 @@ proc_write_disp(struct file *file, const char __user * buffer,
 
 typedef int (proc_readfunc) (char *page, char **start, off_t off, int count,
                             int *eof, void *data);
-typedef int (proc_writefunc) (struct file * file, const char __user * buffer,
+typedef int (proc_writefunc) (struct file *file, const char __user *buffer,
                              unsigned long count, void *data);
 
 static int
-asus_proc_add(char *name, proc_writefunc * writefunc,
-                    proc_readfunc * readfunc, mode_t mode,
+asus_proc_add(char *name, proc_writefunc *writefunc,
+                    proc_readfunc *readfunc, mode_t mode,
                     struct acpi_device *device)
 {
        struct proc_dir_entry *proc =
@@ -1040,9 +1041,9 @@ static int asus_hotk_add_fs(struct acpi_device *device)
                              &proc_read_bluetooth, mode, device);
        }
 
-       /* 
-        * We need both read node and write method as LCD switch is also accessible
-        * from keyboard 
+       /*
+        * We need both read node and write method as LCD switch is also
+        * accessible from the keyboard
         */
        if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) {
                asus_proc_add(PROC_LCD, &proc_write_lcd, &proc_read_lcd, mode,
@@ -1096,11 +1097,10 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
        if (!hotk)
                return;
 
-       if ((event & ~((u32) BR_UP)) < 16) {
+       if ((event & ~((u32) BR_UP)) < 16)
                hotk->brightness = (event & ~((u32) BR_UP));
-       } else if ((event & ~((u32) BR_DOWN)) < 16) {
+       else if ((event & ~((u32) BR_DOWN)) < 16)
                hotk->brightness = (event & ~((u32) BR_DOWN));
-       }
 
        acpi_bus_generate_proc_event(hotk->device, event,
                                hotk->event_count[event % 128]++);
@@ -1186,8 +1186,8 @@ static int asus_hotk_get_info(void)
        acpi_status status;
 
        /*
-        * Get DSDT headers early enough to allow for differentiating between 
-        * models, but late enough to allow acpi_bus_register_driver() to fail 
+        * Get DSDT headers early enough to allow for differentiating between
+        * models, but late enough to allow acpi_bus_register_driver() to fail
         * before doing anything ACPI-specific. Should we encounter a machine,
         * which needs special handling (i.e. its hotkey device has a different
         * HID), this bit will be moved. A global variable asus_info contains
@@ -1212,8 +1212,8 @@ static int asus_hotk_get_info(void)
 
        /*
         * Try to match the object returned by INIT to the specific model.
-        * Handle every possible object (or the lack of thereof) the DSDT 
-        * writers might throw at us. When in trouble, we pass NULL to 
+        * Handle every possible object (or the lack of thereof) the DSDT
+        * writers might throw at us. When in trouble, we pass NULL to
         * asus_model_match() and try something completely different.
         */
        if (buffer.pointer) {
@@ -1244,6 +1244,8 @@ static int asus_hotk_get_info(void)
                               "default values\n", string);
                        printk(KERN_NOTICE
                               "  send /proc/acpi/dsdt to the developers\n");
+                       kfree(model);
+                       return -ENODEV;
                }
                hotk->methods = &model_conf[hotk->model];
                return AE_OK;
@@ -1254,7 +1256,7 @@ static int asus_hotk_get_info(void)
        /* Sort of per-model blacklist */
        if (strncmp(string, "L2B", 3) == 0)
                hotk->methods->lcd_status = NULL;
-       /* L2B is similar enough to L3C to use its settings, with this only 
+       /* L2B is similar enough to L3C to use its settings, with this only
           exception */
        else if (strncmp(string, "A3G", 3) == 0)
                hotk->methods->lcd_status = "\\BLFG";
@@ -1321,7 +1323,7 @@ static int asus_hotk_add(struct acpi_device *device)
        hotk->handle = device->handle;
        strcpy(acpi_device_name(device), ACPI_HOTK_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_HOTK_CLASS);
-       acpi_driver_data(device) = hotk;
+       device->driver_data = hotk;
        hotk->device = device;
 
        result = asus_hotk_check();
@@ -1366,10 +1368,9 @@ static int asus_hotk_add(struct acpi_device *device)
        /* LED display is off by default */
        hotk->ledd_status = 0xFFF;
 
-      end:
-       if (result) {
+end:
+       if (result)
                kfree(hotk);
-       }
 
        return result;
 }
@@ -1394,8 +1395,8 @@ static int asus_hotk_remove(struct acpi_device *device, int type)
 }
 
 static struct backlight_ops asus_backlight_data = {
-        .get_brightness = read_brightness,
-        .update_status  = set_brightness_status,
+       .get_brightness = read_brightness,
+       .update_status  = set_brightness_status,
 };
 
 static void asus_acpi_exit(void)
@@ -1442,15 +1443,15 @@ static int __init asus_acpi_init(void)
                return -ENODEV;
        }
 
-       asus_backlight_device = backlight_device_register("asus",NULL,NULL,
+       asus_backlight_device = backlight_device_register("asus", NULL, NULL,
                                                          &asus_backlight_data);
-        if (IS_ERR(asus_backlight_device)) {
+       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;
+       asus_backlight_device->props.max_brightness = 15;
 
        return 0;
 }
index 70f7f60929ca552f87dfa819dd93296abd3cea60..b2133e89ad9a6debafa3dbad49cf998daad80ec7 100644 (file)
@@ -804,7 +804,7 @@ static int acpi_battery_add(struct acpi_device *device)
        battery->device = device;
        strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
-       acpi_driver_data(device) = battery;
+       device->driver_data = battery;
        mutex_init(&battery->lock);
        acpi_battery_update(battery);
 #ifdef CONFIG_ACPI_PROCFS_POWER
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c
deleted file mode 100644 (file)
index 61b6c5b..0000000
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
- *  bay.c - ACPI removable drive bay driver
- *
- *  Copyright (C) 2006 Kristen Carlson Accardi <kristen.c.accardi@intel.com>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or (at
- *  your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/notifier.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
-#include <linux/seq_file.h>
-#include <asm/uaccess.h>
-#include <linux/platform_device.h>
-
-ACPI_MODULE_NAME("bay");
-MODULE_AUTHOR("Kristen Carlson Accardi");
-MODULE_DESCRIPTION("ACPI Removable Drive Bay Driver");
-MODULE_LICENSE("GPL");
-#define ACPI_BAY_CLASS "bay"
-#define ACPI_BAY_COMPONENT     0x10000000
-#define _COMPONENT ACPI_BAY_COMPONENT
-#define bay_dprintk(h,s) {\
-       char prefix[80] = {'\0'};\
-       struct acpi_buffer buffer = {sizeof(prefix), prefix};\
-       acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);\
-       printk(KERN_DEBUG PREFIX "%s: %s\n", prefix, s); }
-static void bay_notify(acpi_handle handle, u32 event, void *data);
-
-static const struct acpi_device_id bay_device_ids[] = {
-       {"LNXIOBAY", 0},
-       {"", 0},
-};
-MODULE_DEVICE_TABLE(acpi, bay_device_ids);
-
-struct bay {
-       acpi_handle handle;
-       char *name;
-       struct list_head list;
-       struct platform_device *pdev;
-};
-
-static LIST_HEAD(drive_bays);
-
-
-/*****************************************************************************
- *                         Drive Bay functions                               *
- *****************************************************************************/
-/**
- * is_ejectable - see if a device is ejectable
- * @handle: acpi handle of the device
- *
- * If an acpi object has a _EJ0 method, then it is ejectable
- */
-static int is_ejectable(acpi_handle handle)
-{
-       acpi_status status;
-       acpi_handle tmp;
-
-       status = acpi_get_handle(handle, "_EJ0", &tmp);
-       if (ACPI_FAILURE(status))
-               return 0;
-       return 1;
-}
-
-/**
- * bay_present - see if the bay device is present
- * @bay: the drive bay
- *
- * execute the _STA method.
- */
-static int bay_present(struct bay *bay)
-{
-       unsigned long sta;
-       acpi_status status;
-
-       if (bay) {
-               status = acpi_evaluate_integer(bay->handle, "_STA", NULL, &sta);
-               if (ACPI_SUCCESS(status) && sta)
-                       return 1;
-       }
-       return 0;
-}
-
-/**
- * eject_device - respond to an eject request
- * @handle - the device to eject
- *
- * Call this devices _EJ0 method.
- */
-static void eject_device(acpi_handle handle)
-{
-       struct acpi_object_list arg_list;
-       union acpi_object arg;
-
-       bay_dprintk(handle, "Ejecting device");
-
-       arg_list.count = 1;
-       arg_list.pointer = &arg;
-       arg.type = ACPI_TYPE_INTEGER;
-       arg.integer.value = 1;
-
-       if (ACPI_FAILURE(acpi_evaluate_object(handle, "_EJ0",
-                                             &arg_list, NULL)))
-               pr_debug("Failed to evaluate _EJ0!\n");
-}
-
-/*
- * show_present - read method for "present" file in sysfs
- */
-static ssize_t show_present(struct device *dev,
-                          struct device_attribute *attr, char *buf)
-{
-       struct bay *bay = dev_get_drvdata(dev);
-       return snprintf(buf, PAGE_SIZE, "%d\n", bay_present(bay));
-
-}
-static DEVICE_ATTR(present, S_IRUGO, show_present, NULL);
-
-/*
- * write_eject - write method for "eject" file in sysfs
- */
-static ssize_t write_eject(struct device *dev, struct device_attribute *attr,
-                          const char *buf, size_t count)
-{
-       struct bay *bay = dev_get_drvdata(dev);
-
-       if (!count)
-               return -EINVAL;
-
-       eject_device(bay->handle);
-       return count;
-}
-static DEVICE_ATTR(eject, S_IWUSR, NULL, write_eject);
-
-/**
- * is_ata - see if a device is an ata device
- * @handle: acpi handle of the device
- *
- * If an acpi object has one of 4 ATA ACPI methods defined,
- * then it is an ATA device
- */
-static int is_ata(acpi_handle handle)
-{
-       acpi_handle tmp;
-
-       if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) ||
-          (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) ||
-          (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) ||
-          (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp))))
-               return 1;
-
-       return 0;
-}
-
-/**
- * parent_is_ata(acpi_handle handle)
- *
- */
-static int parent_is_ata(acpi_handle handle)
-{
-       acpi_handle phandle;
-
-       if (acpi_get_parent(handle, &phandle))
-               return 0;
-
-       return is_ata(phandle);
-}
-
-/**
- * is_ejectable_bay - see if a device is an ejectable drive bay
- * @handle: acpi handle of the device
- *
- * If an acpi object is ejectable and has one of the ACPI ATA
- * methods defined, then we can safely call it an ejectable
- * drive bay
- */
-static int is_ejectable_bay(acpi_handle handle)
-{
-       if ((is_ata(handle) || parent_is_ata(handle)) && is_ejectable(handle))
-               return 1;
-       return 0;
-}
-
-#if 0
-/**
- * eject_removable_drive - try to eject this drive
- * @dev : the device structure of the drive
- *
- * If a device is a removable drive that requires an _EJ0 method
- * to be executed in order to safely remove from the system, do
- * it.  ATM - always returns success
- */
-int eject_removable_drive(struct device *dev)
-{
-       acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
-
-       if (handle) {
-               bay_dprintk(handle, "Got device handle");
-               if (is_ejectable_bay(handle))
-                       eject_device(handle);
-       } else {
-               printk("No acpi handle for device\n");
-       }
-
-       /* should I return an error code? */
-       return 0;
-}
-EXPORT_SYMBOL_GPL(eject_removable_drive);
-#endif  /*  0  */
-
-static int acpi_bay_add_fs(struct bay *bay)
-{
-       int ret;
-       struct device *dev = &bay->pdev->dev;
-
-       ret = device_create_file(dev, &dev_attr_present);
-       if (ret)
-               goto add_fs_err;
-       ret = device_create_file(dev, &dev_attr_eject);
-       if (ret) {
-               device_remove_file(dev, &dev_attr_present);
-               goto add_fs_err;
-       }
-       return 0;
-
- add_fs_err:
-       bay_dprintk(bay->handle, "Error adding sysfs files\n");
-       return ret;
-}
-
-static void acpi_bay_remove_fs(struct bay *bay)
-{
-       struct device *dev = &bay->pdev->dev;
-
-       /* cleanup sysfs */
-       device_remove_file(dev, &dev_attr_present);
-       device_remove_file(dev, &dev_attr_eject);
-}
-
-static int bay_is_dock_device(acpi_handle handle)
-{
-       acpi_handle parent;
-
-       acpi_get_parent(handle, &parent);
-
-       /* if the device or it's parent is dependent on the
-        * dock, then we are a dock device
-        */
-       return (is_dock_device(handle) || is_dock_device(parent));
-}
-
-static int bay_add(acpi_handle handle, int id)
-{
-       acpi_status status;
-       struct bay *new_bay;
-       struct platform_device *pdev;
-       struct acpi_buffer nbuffer = {ACPI_ALLOCATE_BUFFER, NULL};
-       acpi_get_name(handle, ACPI_FULL_PATHNAME, &nbuffer);
-
-       bay_dprintk(handle, "Adding notify handler");
-
-       /*
-        * Initialize bay device structure
-        */
-       new_bay = kzalloc(sizeof(*new_bay), GFP_ATOMIC);
-       INIT_LIST_HEAD(&new_bay->list);
-       new_bay->handle = handle;
-       new_bay->name = (char *)nbuffer.pointer;
-
-       /* initialize platform device stuff */
-       pdev = platform_device_register_simple(ACPI_BAY_CLASS, id, NULL, 0);
-       if (IS_ERR(pdev)) {
-               printk(KERN_ERR PREFIX "Error registering bay device\n");
-               goto bay_add_err;
-       }
-       new_bay->pdev = pdev;
-       platform_set_drvdata(pdev, new_bay);
-
-       /*
-        * we want the bay driver to be able to send uevents
-        */
-       pdev->dev.uevent_suppress = 0;
-
-       /* register for events on this device */
-       status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
-                       bay_notify, new_bay);
-       if (ACPI_FAILURE(status)) {
-               printk(KERN_INFO PREFIX "Error installing bay notify handler\n");
-               platform_device_unregister(new_bay->pdev);
-               goto bay_add_err;
-       }
-
-       if (acpi_bay_add_fs(new_bay)) {
-               acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
-                                          bay_notify);
-               platform_device_unregister(new_bay->pdev);
-               goto bay_add_err;
-       }
-
-       /* if we are on a dock station, we should register for dock
-        * notifications.
-        */
-       if (bay_is_dock_device(handle)) {
-               bay_dprintk(handle, "Is dependent on dock\n");
-               register_hotplug_dock_device(handle, bay_notify, new_bay);
-       }
-       list_add(&new_bay->list, &drive_bays);
-       printk(KERN_INFO PREFIX "Bay [%s] Added\n", new_bay->name);
-       return 0;
-
-bay_add_err:
-       kfree(new_bay->name);
-       kfree(new_bay);
-       return -ENODEV;
-}
-
-/**
- * bay_notify - act upon an acpi bay notification
- * @handle: the bay handle
- * @event: the acpi event
- * @data: our driver data struct
- *
- */
-static void bay_notify(acpi_handle handle, u32 event, void *data)
-{
-       struct bay *bay_dev = (struct bay *)data;
-       struct device *dev = &bay_dev->pdev->dev;
-       char event_string[12];
-       char *envp[] = { event_string, NULL };
-
-       bay_dprintk(handle, "Bay event");
-       sprintf(event_string, "BAY_EVENT=%d", event);
-       kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
-}
-
-static acpi_status
-find_bay(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-       int *count = (int *)context;
-
-       /*
-        * there could be more than one ejectable bay.
-        * so, just return AE_OK always so that every object
-        * will be checked.
-        */
-       if (is_ejectable_bay(handle)) {
-               bay_dprintk(handle, "found ejectable bay");
-               if (!bay_add(handle, *count))
-                       (*count)++;
-       }
-       return AE_OK;
-}
-
-static int __init bay_init(void)
-{
-       int bays = 0;
-
-       INIT_LIST_HEAD(&drive_bays);
-
-       if (acpi_disabled)
-               return -ENODEV;
-
-       /* look for dockable drive bays */
-       acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-               ACPI_UINT32_MAX, find_bay, &bays, NULL);
-
-       if (!bays)
-               return -ENODEV;
-
-       return 0;
-}
-
-static void __exit bay_exit(void)
-{
-       struct bay *bay, *tmp;
-
-       list_for_each_entry_safe(bay, tmp, &drive_bays, list) {
-               if (is_dock_device(bay->handle))
-                       unregister_hotplug_dock_device(bay->handle);
-               acpi_bay_remove_fs(bay);
-               acpi_remove_notify_handler(bay->handle, ACPI_SYSTEM_NOTIFY,
-                       bay_notify);
-               platform_device_unregister(bay->pdev);
-               kfree(bay->name);
-               kfree(bay);
-       }
-}
-
-postcore_initcall(bay_init);
-module_exit(bay_exit);
-
index ccae305ee55dcb554c441d908c20b43d509b3709..c797c6473f31588cbc6ddf03c25a0770f26ccbe7 100644 (file)
@@ -48,6 +48,23 @@ EXPORT_SYMBOL(acpi_root_dir);
 
 #define STRUCT_TO_INT(s)       (*((int*)&s))
 
+static int set_power_nocheck(const struct dmi_system_id *id)
+{
+       printk(KERN_NOTICE PREFIX "%s detected - "
+               "disable power check in power transistion\n", id->ident);
+       acpi_power_nocheck = 1;
+       return 0;
+}
+static struct dmi_system_id __cpuinitdata power_nocheck_dmi_table[] = {
+       {
+       set_power_nocheck, "HP Pavilion 05", {
+       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+       DMI_MATCH(DMI_SYS_VENDOR, "HP Pavilion 05"),
+       DMI_MATCH(DMI_PRODUCT_VERSION, "2001211RE101GLEND") }, NULL},
+       {},
+};
+
+
 /* --------------------------------------------------------------------------
                                 Device Management
    -------------------------------------------------------------------------- */
@@ -77,7 +94,7 @@ EXPORT_SYMBOL(acpi_bus_get_device);
 int acpi_bus_get_status(struct acpi_device *device)
 {
        acpi_status status = AE_OK;
-       unsigned long sta = 0;
+       unsigned long long sta = 0;
 
 
        if (!device)
@@ -95,21 +112,21 @@ int acpi_bus_get_status(struct acpi_device *device)
        }
 
        /*
-        * Otherwise we assume the status of our parent (unless we don't
-        * have one, in which case status is implied).
+        * According to ACPI spec some device can be present and functional
+        * even if the parent is not present but functional.
+        * In such conditions the child device should not inherit the status
+        * from the parent.
         */
-       else if (device->parent)
-               device->status = device->parent->status;
        else
                STRUCT_TO_INT(device->status) =
                    ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
                    ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING;
 
        if (device->status.functional && !device->status.present) {
-               printk(KERN_WARNING PREFIX "Device [%s] status [%08x]: "
-                      "functional but not present; setting present\n",
-                      device->pnp.bus_id, (u32) STRUCT_TO_INT(device->status));
-               device->status.present = 1;
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: "
+                      "functional but not present;\n",
+                       device->pnp.bus_id,
+                       (u32) STRUCT_TO_INT(device->status)));
        }
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n",
@@ -155,7 +172,7 @@ int acpi_bus_get_power(acpi_handle handle, int *state)
        int result = 0;
        acpi_status status = 0;
        struct acpi_device *device = NULL;
-       unsigned long psc = 0;
+       unsigned long long psc = 0;
 
 
        result = acpi_bus_get_device(handle, &device);
@@ -223,7 +240,19 @@ int acpi_bus_set_power(acpi_handle handle, int state)
        /*
         * Get device's current power state
         */
-       acpi_bus_get_power(device->handle, &device->power.state);
+       if (!acpi_power_nocheck) {
+               /*
+                * Maybe the incorrect power state is returned on the bogus
+                * bios, which is different with the real power state.
+                * For example: the bios returns D0 state and the real power
+                * state is D3. OS expects to set the device to D0 state. In
+                * such case if OS uses the power state returned by the BIOS,
+                * the device can't be transisted to the correct power state.
+                * So if the acpi_power_nocheck is set, it is unnecessary to
+                * get the power state by calling acpi_bus_get_power.
+                */
+               acpi_bus_get_power(device->handle, &device->power.state);
+       }
        if ((state == device->power.state) && !device->flags.force_power_state) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
                                  state));
@@ -496,6 +525,19 @@ static int acpi_bus_check_scope(struct acpi_device *device)
        return 0;
 }
 
+static BLOCKING_NOTIFIER_HEAD(acpi_bus_notify_list);
+int register_acpi_bus_notifier(struct notifier_block *nb)
+{
+       return blocking_notifier_chain_register(&acpi_bus_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(register_acpi_bus_notifier);
+
+void unregister_acpi_bus_notifier(struct notifier_block *nb)
+{
+       blocking_notifier_chain_unregister(&acpi_bus_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_acpi_bus_notifier);
+
 /**
  * acpi_bus_notify
  * ---------------
@@ -506,6 +548,8 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
        int result = 0;
        struct acpi_device *device = NULL;
 
+       blocking_notifier_call_chain(&acpi_bus_notify_list,
+               type, (void *)handle);
 
        if (acpi_bus_get_device(handle, &device))
                return;
@@ -749,6 +793,12 @@ static int __init acpi_bus_init(void)
                goto error1;
        }
 
+       /*
+        * Maybe EC region is required at bus_scan/acpi_get_devices. So it
+        * is necessary to enable it as early as possible.
+        */
+       acpi_boot_ec_enable();
+
        printk(KERN_INFO PREFIX "Interpreter enabled\n");
 
        /* Initialize sleep structures */
@@ -818,7 +868,11 @@ static int __init acpi_init(void)
                }
        } else
                disable_acpi();
-
+       /*
+        * If the laptop falls into the DMI check table, the power state check
+        * will be disabled in the course of device power transistion.
+        */
+       dmi_check_system(power_nocheck_dmi_table);
        return result;
 }
 
index 1dfec413588ca6e07ba06f51b69b7ea431906a2b..9d568d417eaa48e2e76624a0a2e505499c3aedcb 100644 (file)
@@ -145,7 +145,7 @@ static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
 {
        struct acpi_button *button = seq->private;
        acpi_status status;
-       unsigned long state;
+       unsigned long long state;
 
        if (!button || !button->device)
                return 0;
@@ -253,7 +253,7 @@ static int acpi_button_remove_fs(struct acpi_device *device)
    -------------------------------------------------------------------------- */
 static int acpi_lid_send_state(struct acpi_button *button)
 {
-       unsigned long state;
+       unsigned long long state;
        acpi_status status;
 
        status = acpi_evaluate_integer(button->device->handle, "_LID", NULL,
@@ -384,7 +384,7 @@ static int acpi_button_add(struct acpi_device *device)
                return -ENOMEM;
 
        button->device = device;
-       acpi_driver_data(device) = button;
+       device->driver_data = button;
 
        button->input = input = input_allocate_device();
        if (!input) {
index f9db4f444bd0f814fe4ffbec8252e4227df981dc..4441e84b28a9a2e652d00445d2dbf1b722ac8e90 100644 (file)
@@ -52,8 +52,8 @@ struct proc_dir_entry *acpi_lock_ac_dir(void)
        if (acpi_ac_dir) {
                lock_ac_dir_cnt++;
        } else {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                                 "Cannot create %s\n", ACPI_AC_CLASS));
+               printk(KERN_ERR PREFIX
+                                 "Cannot create %s\n", ACPI_AC_CLASS);
        }
        mutex_unlock(&cm_sbs_mutex);
        return acpi_ac_dir;
@@ -83,8 +83,8 @@ struct proc_dir_entry *acpi_lock_battery_dir(void)
        if (acpi_battery_dir) {
                lock_battery_dir_cnt++;
        } else {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                                 "Cannot create %s\n", ACPI_BATTERY_CLASS));
+               printk(KERN_ERR PREFIX
+                                 "Cannot create %s\n", ACPI_BATTERY_CLASS);
        }
        mutex_unlock(&cm_sbs_mutex);
        return acpi_battery_dir;
index 3c25ec7a187142dc224c748dcb481601df626501..134818b265a9fae8ff5aec7af3e443d4cc6d7c59 100644 (file)
@@ -76,7 +76,7 @@ static int is_device_present(acpi_handle handle)
 {
        acpi_handle temp;
        acpi_status status;
-       unsigned long sta;
+       unsigned long long sta;
 
 
        status = acpi_get_handle(handle, "_STA", &temp);
@@ -108,7 +108,7 @@ static int acpi_container_add(struct acpi_device *device)
        container->handle = device->handle;
        strcpy(acpi_device_name(device), ACPI_CONTAINER_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_CONTAINER_CLASS);
-       acpi_driver_data(device) = container;
+       device->driver_data = container;
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device <%s> bid <%s>\n",
                          acpi_device_name(device), acpi_device_bid(device)));
index 6df564f4ca6ed4bf48c1284f3c7d2807986b1f77..abf36b4b1d1d828ba7024ef3ddf49df5c9d1310f 100644 (file)
@@ -47,8 +47,6 @@ static const struct acpi_dlayer acpi_debug_layers[] = {
 };
 
 static const struct acpi_dlevel acpi_debug_levels[] = {
-       ACPI_DEBUG_INIT(ACPI_LV_ERROR),
-       ACPI_DEBUG_INIT(ACPI_LV_WARN),
        ACPI_DEBUG_INIT(ACPI_LV_INIT),
        ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT),
        ACPI_DEBUG_INIT(ACPI_LV_INFO),
index 4613b9ca57929f5c4ba867c6f8aa496a887d3dbe..279a5a60a0dd492a2b27f144b12b353b9de78a2a 100644 (file)
@@ -103,6 +103,9 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state)
                                                    NULL);
                acpi_ex_enter_interpreter();
        }
+
+       acpi_ds_clear_implicit_return(walk_state);
+
 #ifdef ACPI_DISASSEMBLER
        if (ACPI_FAILURE(status)) {
 
index 13c43eac35dba9570b0dc2ad8bf9a0c866a2d312..d03f81bd1bcb01f02cd6704732c37d54a2ae6822 100644 (file)
@@ -43,7 +43,6 @@
 
 #include <acpi/acpi.h>
 #include <acpi/acdispat.h>
-#include <acpi/amlcode.h>
 #include <acpi/acnamesp.h>
 #include <acpi/acinterp.h>
 
@@ -52,11 +51,11 @@ ACPI_MODULE_NAME("dsmthdat")
 
 /* Local prototypes */
 static void
-acpi_ds_method_data_delete_value(u16 opcode,
+acpi_ds_method_data_delete_value(u8 type,
                                 u32 index, struct acpi_walk_state *walk_state);
 
 static acpi_status
-acpi_ds_method_data_set_value(u16 opcode,
+acpi_ds_method_data_set_value(u8 type,
                              u32 index,
                              union acpi_operand_object *object,
                              struct acpi_walk_state *walk_state);
@@ -216,7 +215,7 @@ acpi_ds_method_data_init_args(union acpi_operand_object **params,
                 * Store the argument in the method/walk descriptor.
                 * Do not copy the arg in order to implement call by reference
                 */
-               status = acpi_ds_method_data_set_value(AML_ARG_OP, index,
+               status = acpi_ds_method_data_set_value(ACPI_REFCLASS_ARG, index,
                                                       params[index],
                                                       walk_state);
                if (ACPI_FAILURE(status)) {
@@ -234,7 +233,8 @@ acpi_ds_method_data_init_args(union acpi_operand_object **params,
  *
  * FUNCTION:    acpi_ds_method_data_get_node
  *
- * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
+ * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
+ *                                    ACPI_REFCLASS_ARG
  *              Index               - Which Local or Arg whose type to get
  *              walk_state          - Current walk state object
  *              Node                - Where the node is returned.
@@ -246,7 +246,7 @@ acpi_ds_method_data_init_args(union acpi_operand_object **params,
  ******************************************************************************/
 
 acpi_status
-acpi_ds_method_data_get_node(u16 opcode,
+acpi_ds_method_data_get_node(u8 type,
                             u32 index,
                             struct acpi_walk_state *walk_state,
                             struct acpi_namespace_node **node)
@@ -256,8 +256,8 @@ acpi_ds_method_data_get_node(u16 opcode,
        /*
         * Method Locals and Arguments are supported
         */
-       switch (opcode) {
-       case AML_LOCAL_OP:
+       switch (type) {
+       case ACPI_REFCLASS_LOCAL:
 
                if (index > ACPI_METHOD_MAX_LOCAL) {
                        ACPI_ERROR((AE_INFO,
@@ -271,7 +271,7 @@ acpi_ds_method_data_get_node(u16 opcode,
                *node = &walk_state->local_variables[index];
                break;
 
-       case AML_ARG_OP:
+       case ACPI_REFCLASS_ARG:
 
                if (index > ACPI_METHOD_MAX_ARG) {
                        ACPI_ERROR((AE_INFO,
@@ -286,8 +286,8 @@ acpi_ds_method_data_get_node(u16 opcode,
                break;
 
        default:
-               ACPI_ERROR((AE_INFO, "Opcode %d is invalid", opcode));
-               return_ACPI_STATUS(AE_AML_BAD_OPCODE);
+               ACPI_ERROR((AE_INFO, "Type %d is invalid", type));
+               return_ACPI_STATUS(AE_TYPE);
        }
 
        return_ACPI_STATUS(AE_OK);
@@ -297,7 +297,8 @@ acpi_ds_method_data_get_node(u16 opcode,
  *
  * FUNCTION:    acpi_ds_method_data_set_value
  *
- * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
+ * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
+ *                                    ACPI_REFCLASS_ARG
  *              Index               - Which Local or Arg to get
  *              Object              - Object to be inserted into the stack entry
  *              walk_state          - Current walk state object
@@ -310,7 +311,7 @@ acpi_ds_method_data_get_node(u16 opcode,
  ******************************************************************************/
 
 static acpi_status
-acpi_ds_method_data_set_value(u16 opcode,
+acpi_ds_method_data_set_value(u8 type,
                              u32 index,
                              union acpi_operand_object *object,
                              struct acpi_walk_state *walk_state)
@@ -321,13 +322,13 @@ acpi_ds_method_data_set_value(u16 opcode,
        ACPI_FUNCTION_TRACE(ds_method_data_set_value);
 
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                         "NewObj %p Opcode %X, Refs=%d [%s]\n", object,
-                         opcode, object->common.reference_count,
+                         "NewObj %p Type %2.2X, Refs=%d [%s]\n", object,
+                         type, object->common.reference_count,
                          acpi_ut_get_type_name(object->common.type)));
 
        /* Get the namespace node for the arg/local */
 
-       status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node);
+       status = acpi_ds_method_data_get_node(type, index, walk_state, &node);
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
        }
@@ -350,7 +351,8 @@ acpi_ds_method_data_set_value(u16 opcode,
  *
  * FUNCTION:    acpi_ds_method_data_get_value
  *
- * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
+ * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
+ *                                    ACPI_REFCLASS_ARG
  *              Index               - Which local_var or argument to get
  *              walk_state          - Current walk state object
  *              dest_desc           - Where Arg or Local value is returned
@@ -363,7 +365,7 @@ acpi_ds_method_data_set_value(u16 opcode,
  ******************************************************************************/
 
 acpi_status
-acpi_ds_method_data_get_value(u16 opcode,
+acpi_ds_method_data_get_value(u8 type,
                              u32 index,
                              struct acpi_walk_state *walk_state,
                              union acpi_operand_object **dest_desc)
@@ -383,7 +385,7 @@ acpi_ds_method_data_get_value(u16 opcode,
 
        /* Get the namespace node for the arg/local */
 
-       status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node);
+       status = acpi_ds_method_data_get_node(type, index, walk_state, &node);
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
        }
@@ -419,8 +421,8 @@ acpi_ds_method_data_get_value(u16 opcode,
                /* Otherwise, return the error */
 
                else
-                       switch (opcode) {
-                       case AML_ARG_OP:
+                       switch (type) {
+                       case ACPI_REFCLASS_ARG:
 
                                ACPI_ERROR((AE_INFO,
                                            "Uninitialized Arg[%d] at node %p",
@@ -428,7 +430,7 @@ acpi_ds_method_data_get_value(u16 opcode,
 
                                return_ACPI_STATUS(AE_AML_UNINITIALIZED_ARG);
 
-                       case AML_LOCAL_OP:
+                       case ACPI_REFCLASS_LOCAL:
 
                                ACPI_ERROR((AE_INFO,
                                            "Uninitialized Local[%d] at node %p",
@@ -437,9 +439,10 @@ acpi_ds_method_data_get_value(u16 opcode,
                                return_ACPI_STATUS(AE_AML_UNINITIALIZED_LOCAL);
 
                        default:
+
                                ACPI_ERROR((AE_INFO,
                                            "Not a Arg/Local opcode: %X",
-                                           opcode));
+                                           type));
                                return_ACPI_STATUS(AE_AML_INTERNAL);
                        }
        }
@@ -458,7 +461,8 @@ acpi_ds_method_data_get_value(u16 opcode,
  *
  * FUNCTION:    acpi_ds_method_data_delete_value
  *
- * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
+ * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
+ *                                    ACPI_REFCLASS_ARG
  *              Index               - Which local_var or argument to delete
  *              walk_state          - Current walk state object
  *
@@ -470,7 +474,7 @@ acpi_ds_method_data_get_value(u16 opcode,
  ******************************************************************************/
 
 static void
-acpi_ds_method_data_delete_value(u16 opcode,
+acpi_ds_method_data_delete_value(u8 type,
                                 u32 index, struct acpi_walk_state *walk_state)
 {
        acpi_status status;
@@ -481,7 +485,7 @@ acpi_ds_method_data_delete_value(u16 opcode,
 
        /* Get the namespace node for the arg/local */
 
-       status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node);
+       status = acpi_ds_method_data_get_node(type, index, walk_state, &node);
        if (ACPI_FAILURE(status)) {
                return_VOID;
        }
@@ -514,7 +518,8 @@ acpi_ds_method_data_delete_value(u16 opcode,
  *
  * FUNCTION:    acpi_ds_store_object_to_local
  *
- * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
+ * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
+ *                                    ACPI_REFCLASS_ARG
  *              Index               - Which Local or Arg to set
  *              obj_desc            - Value to be stored
  *              walk_state          - Current walk state
@@ -528,7 +533,7 @@ acpi_ds_method_data_delete_value(u16 opcode,
  ******************************************************************************/
 
 acpi_status
-acpi_ds_store_object_to_local(u16 opcode,
+acpi_ds_store_object_to_local(u8 type,
                              u32 index,
                              union acpi_operand_object *obj_desc,
                              struct acpi_walk_state *walk_state)
@@ -539,8 +544,8 @@ acpi_ds_store_object_to_local(u16 opcode,
        union acpi_operand_object *new_obj_desc;
 
        ACPI_FUNCTION_TRACE(ds_store_object_to_local);
-       ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Opcode=%X Index=%d Obj=%p\n",
-                         opcode, index, obj_desc));
+       ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Type=%2.2X Index=%d Obj=%p\n",
+                         type, index, obj_desc));
 
        /* Parameter validation */
 
@@ -550,7 +555,7 @@ acpi_ds_store_object_to_local(u16 opcode,
 
        /* Get the namespace node for the arg/local */
 
-       status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node);
+       status = acpi_ds_method_data_get_node(type, index, walk_state, &node);
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
        }
@@ -602,7 +607,7 @@ acpi_ds_store_object_to_local(u16 opcode,
                 *
                 * Weird, but true.
                 */
-               if (opcode == AML_ARG_OP) {
+               if (type == ACPI_REFCLASS_ARG) {
                        /*
                         * If we have a valid reference object that came from ref_of(),
                         * do the indirect store
@@ -611,8 +616,8 @@ acpi_ds_store_object_to_local(u16 opcode,
                             ACPI_DESC_TYPE_OPERAND)
                            && (current_obj_desc->common.type ==
                                ACPI_TYPE_LOCAL_REFERENCE)
-                           && (current_obj_desc->reference.opcode ==
-                               AML_REF_OF_OP)) {
+                           && (current_obj_desc->reference.class ==
+                               ACPI_REFCLASS_REFOF)) {
                                ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
                                                  "Arg (%p) is an ObjRef(Node), storing in node %p\n",
                                                  new_obj_desc,
@@ -640,11 +645,9 @@ acpi_ds_store_object_to_local(u16 opcode,
                        }
                }
 
-               /*
-                * Delete the existing object
-                * before storing the new one
-                */
-               acpi_ds_method_data_delete_value(opcode, index, walk_state);
+               /* Delete the existing object before storing the new one */
+
+               acpi_ds_method_data_delete_value(type, index, walk_state);
        }
 
        /*
@@ -653,7 +656,7 @@ acpi_ds_store_object_to_local(u16 opcode,
         * (increments the object reference count by one)
         */
        status =
-           acpi_ds_method_data_set_value(opcode, index, new_obj_desc,
+           acpi_ds_method_data_set_value(type, index, new_obj_desc,
                                          walk_state);
 
        /* Remove local reference if we copied the object above */
index 0f280589921025c5e8f9f4e8caebc3ea5efc21b0..4f08e599d07e2a62eb257fefa2b6ba812b132578 100644 (file)
@@ -731,54 +731,70 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
                switch (op_info->type) {
                case AML_TYPE_LOCAL_VARIABLE:
 
-                       /* Split the opcode into a base opcode + offset */
+                       /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */
 
-                       obj_desc->reference.opcode = AML_LOCAL_OP;
-                       obj_desc->reference.offset = opcode - AML_LOCAL_OP;
+                       obj_desc->reference.value = opcode - AML_LOCAL_OP;
+                       obj_desc->reference.class = ACPI_REFCLASS_LOCAL;
 
 #ifndef ACPI_NO_METHOD_EXECUTION
-                       status = acpi_ds_method_data_get_node(AML_LOCAL_OP,
-                                                             obj_desc->
-                                                             reference.offset,
-                                                             walk_state,
-                                                             (struct
-                                                              acpi_namespace_node
-                                                              **)&obj_desc->
-                                                             reference.object);
+                       status =
+                           acpi_ds_method_data_get_node(ACPI_REFCLASS_LOCAL,
+                                                        obj_desc->reference.
+                                                        value, walk_state,
+                                                        ACPI_CAST_INDIRECT_PTR
+                                                        (struct
+                                                         acpi_namespace_node,
+                                                         &obj_desc->reference.
+                                                         object));
 #endif
                        break;
 
                case AML_TYPE_METHOD_ARGUMENT:
 
-                       /* Split the opcode into a base opcode + offset */
+                       /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */
 
-                       obj_desc->reference.opcode = AML_ARG_OP;
-                       obj_desc->reference.offset = opcode - AML_ARG_OP;
+                       obj_desc->reference.value = opcode - AML_ARG_OP;
+                       obj_desc->reference.class = ACPI_REFCLASS_ARG;
 
 #ifndef ACPI_NO_METHOD_EXECUTION
-                       status = acpi_ds_method_data_get_node(AML_ARG_OP,
+                       status = acpi_ds_method_data_get_node(ACPI_REFCLASS_ARG,
                                                              obj_desc->
-                                                             reference.offset,
+                                                             reference.value,
                                                              walk_state,
+                                                             ACPI_CAST_INDIRECT_PTR
                                                              (struct
-                                                              acpi_namespace_node
-                                                              **)&obj_desc->
-                                                             reference.object);
+                                                              acpi_namespace_node,
+                                                              &obj_desc->
+                                                              reference.
+                                                              object));
 #endif
                        break;
 
-               default:        /* Other literals, etc.. */
+               default:        /* Object name or Debug object */
 
-                       if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
+                       switch (op->common.aml_opcode) {
+                       case AML_INT_NAMEPATH_OP:
 
                                /* Node was saved in Op */
 
                                obj_desc->reference.node = op->common.node;
                                obj_desc->reference.object =
                                    op->common.node->object;
-                       }
+                               obj_desc->reference.class = ACPI_REFCLASS_NAME;
+                               break;
+
+                       case AML_DEBUG_OP:
 
-                       obj_desc->reference.opcode = opcode;
+                               obj_desc->reference.class = ACPI_REFCLASS_DEBUG;
+                               break;
+
+                       default:
+
+                               ACPI_ERROR((AE_INFO,
+                                           "Unimplemented reference type for AML opcode: %4.4X",
+                                           opcode));
+                               return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
+                       }
                        break;
                }
                break;
index 6a81c4400edf4767b770fcec8cfe807d8ce36ade..69fae5905bb8219af26b0e0684ae22cedc1b84dc 100644 (file)
@@ -1330,7 +1330,7 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
                             (walk_state->results->results.obj_desc[0]) ==
                             ACPI_TYPE_LOCAL_REFERENCE)
                            && ((walk_state->results->results.obj_desc[0])->
-                               reference.opcode != AML_INDEX_OP)) {
+                               reference.class != ACPI_REFCLASS_INDEX)) {
                                status =
                                    acpi_ex_resolve_to_value(&walk_state->
                                                             results->results.
index b5072fa9c9205210ac731f45237a22cfd52c0d8a..396fe12078cd1595f99199c8bf837be59df7f3ae 100644 (file)
@@ -166,6 +166,10 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state,
                status = AE_CTRL_FALSE;
        }
 
+       /* Predicate can be used for an implicit return value */
+
+       (void)acpi_ds_do_implicit_return(local_obj_desc, walk_state, TRUE);
+
       cleanup:
 
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n",
@@ -429,10 +433,10 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
                             ACPI_TYPE_LOCAL_REFERENCE)
                            && (walk_state->operands[1]->common.type ==
                                ACPI_TYPE_LOCAL_REFERENCE)
-                           && (walk_state->operands[0]->reference.opcode ==
-                               walk_state->operands[1]->reference.opcode)
-                           && (walk_state->operands[0]->reference.offset ==
-                               walk_state->operands[1]->reference.offset)) {
+                           && (walk_state->operands[0]->reference.class ==
+                               walk_state->operands[1]->reference.class)
+                           && (walk_state->operands[0]->reference.value ==
+                               walk_state->operands[1]->reference.value)) {
                                status = AE_OK;
                        } else {
                                ACPI_EXCEPTION((AE_INFO, status,
index 7d2edf143f1660f387a486829ce40b548bc96eaf..5b30b8d91d716126cdd3305d61ee8fd625eea016 100644 (file)
@@ -48,7 +48,6 @@ MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to "
        " before undocking");
 
 static struct atomic_notifier_head dock_notifier_list;
-static struct platform_device *dock_device;
 static char dock_device_name[] = "dock";
 
 static const struct acpi_device_id dock_device_ids[] = {
@@ -65,23 +64,29 @@ struct dock_station {
        struct mutex hp_lock;
        struct list_head dependent_devices;
        struct list_head hotplug_devices;
+
+       struct list_head sibiling;
+       struct platform_device *dock_device;
 };
+static LIST_HEAD(dock_stations);
+static int dock_station_count;
 
 struct dock_dependent_device {
        struct list_head list;
        struct list_head hotplug_list;
        acpi_handle handle;
-       acpi_notify_handler handler;
+       struct acpi_dock_ops *ops;
        void *context;
 };
 
 #define DOCK_DOCKING   0x00000001
 #define DOCK_UNDOCKING  0x00000002
+#define DOCK_IS_DOCK   0x00000010
+#define DOCK_IS_ATA    0x00000020
+#define DOCK_IS_BAT    0x00000040
 #define DOCK_EVENT     3
 #define UNDOCK_EVENT   2
 
-static struct dock_station *dock_station;
-
 /*****************************************************************************
  *                         Dock Dependent device functions                   *
  *****************************************************************************/
@@ -199,6 +204,60 @@ static int is_dock(acpi_handle handle)
        return 1;
 }
 
+static int is_ejectable(acpi_handle handle)
+{
+       acpi_status status;
+       acpi_handle tmp;
+
+       status = acpi_get_handle(handle, "_EJ0", &tmp);
+       if (ACPI_FAILURE(status))
+               return 0;
+       return 1;
+}
+
+static int is_ata(acpi_handle handle)
+{
+       acpi_handle tmp;
+
+       if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) ||
+          (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) ||
+          (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) ||
+          (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp))))
+               return 1;
+
+       return 0;
+}
+
+static int is_battery(acpi_handle handle)
+{
+       struct acpi_device_info *info;
+       struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+       int ret = 1;
+
+       if (!ACPI_SUCCESS(acpi_get_object_info(handle, &buffer)))
+               return 0;
+       info = buffer.pointer;
+       if (!(info->valid & ACPI_VALID_HID))
+               ret = 0;
+       else
+               ret = !strcmp("PNP0C0A", info->hardware_id.value);
+
+       kfree(buffer.pointer);
+       return ret;
+}
+
+static int is_ejectable_bay(acpi_handle handle)
+{
+       acpi_handle phandle;
+       if (!is_ejectable(handle))
+               return 0;
+       if (is_battery(handle) || is_ata(handle))
+               return 1;
+       if (!acpi_get_parent(handle, &phandle) && is_ata(phandle))
+               return 1;
+       return 0;
+}
+
 /**
  * is_dock_device - see if a device is on a dock station
  * @handle: acpi handle of the device
@@ -209,11 +268,17 @@ static int is_dock(acpi_handle handle)
  */
 int is_dock_device(acpi_handle handle)
 {
-       if (!dock_station)
+       struct dock_station *dock_station;
+
+       if (!dock_station_count)
                return 0;
 
-       if (is_dock(handle) || find_dock_dependent_device(dock_station, handle))
+       if (is_dock(handle))
                return 1;
+       list_for_each_entry(dock_station, &dock_stations, sibiling) {
+               if (find_dock_dependent_device(dock_station, handle))
+                       return 1;
+       }
 
        return 0;
 }
@@ -229,7 +294,7 @@ EXPORT_SYMBOL_GPL(is_dock_device);
  */
 static int dock_present(struct dock_station *ds)
 {
-       unsigned long sta;
+       unsigned long long sta;
        acpi_status status;
 
        if (ds) {
@@ -320,8 +385,8 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
         * First call driver specific hotplug functions
         */
        list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) {
-               if (dd->handler)
-                       dd->handler(dd->handle, event, dd->context);
+               if (dd->ops && dd->ops->handler)
+                       dd->ops->handler(dd->handle, event, dd->context);
        }
 
        /*
@@ -341,9 +406,10 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
 
 static void dock_event(struct dock_station *ds, u32 event, int num)
 {
-       struct device *dev = &dock_device->dev;
+       struct device *dev = &ds->dock_device->dev;
        char event_string[13];
        char *envp[] = { event_string, NULL };
+       struct dock_dependent_device *dd;
 
        if (num == UNDOCK_EVENT)
                sprintf(event_string, "EVENT=undock");
@@ -354,7 +420,14 @@ static void dock_event(struct dock_station *ds, u32 event, int num)
         * Indicate that the status of the dock station has
         * changed.
         */
-       kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
+       if (num == DOCK_EVENT)
+               kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
+
+       list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list)
+               if (dd->ops && dd->ops->uevent)
+                       dd->ops->uevent(dd->handle, event, dd->context);
+       if (num != DOCK_EVENT)
+               kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
 }
 
 /**
@@ -414,9 +487,10 @@ static void handle_dock(struct dock_station *ds, int dock)
        arg.type = ACPI_TYPE_INTEGER;
        arg.integer.value = dock;
        status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer);
-       if (ACPI_FAILURE(status))
-               printk(KERN_ERR PREFIX "%s - failed to execute _DCK\n",
-                        (char *)name_buffer.pointer);
+       if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
+               ACPI_EXCEPTION((AE_INFO, status, "%s - failed to execute"
+                       " _DCK\n", (char *)name_buffer.pointer));
+
        kfree(buffer.pointer);
        kfree(name_buffer.pointer);
 }
@@ -452,6 +526,25 @@ static inline void complete_undock(struct dock_station *ds)
        ds->flags &= ~(DOCK_UNDOCKING);
 }
 
+static void dock_lock(struct dock_station *ds, int lock)
+{
+       struct acpi_object_list arg_list;
+       union acpi_object arg;
+       acpi_status status;
+
+       arg_list.count = 1;
+       arg_list.pointer = &arg;
+       arg.type = ACPI_TYPE_INTEGER;
+       arg.integer.value = !!lock;
+       status = acpi_evaluate_object(ds->handle, "_LCK", &arg_list, NULL);
+       if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+               if (lock)
+                       printk(KERN_WARNING PREFIX "Locking device failed\n");
+               else
+                       printk(KERN_WARNING PREFIX "Unlocking device failed\n");
+       }
+}
+
 /**
  * dock_in_progress - see if we are in the middle of handling a dock event
  * @ds: the dock station
@@ -479,7 +572,7 @@ static int dock_in_progress(struct dock_station *ds)
  */
 int register_dock_notifier(struct notifier_block *nb)
 {
-       if (!dock_station)
+       if (!dock_station_count)
                return -ENODEV;
 
        return atomic_notifier_chain_register(&dock_notifier_list, nb);
@@ -493,7 +586,7 @@ EXPORT_SYMBOL_GPL(register_dock_notifier);
  */
 void unregister_dock_notifier(struct notifier_block *nb)
 {
-       if (!dock_station)
+       if (!dock_station_count)
                return;
 
        atomic_notifier_chain_unregister(&dock_notifier_list, nb);
@@ -504,7 +597,7 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier);
 /**
  * register_hotplug_dock_device - register a hotplug function
  * @handle: the handle of the device
- * @handler: the acpi_notifier_handler to call after docking
+ * @ops: handlers to call after docking
  * @context: device specific data
  *
  * If a driver would like to perform a hotplug operation after a dock
@@ -512,27 +605,36 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier);
  * the dock driver after _DCK is executed.
  */
 int
-register_hotplug_dock_device(acpi_handle handle, acpi_notify_handler handler,
+register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops,
                             void *context)
 {
        struct dock_dependent_device *dd;
+       struct dock_station *dock_station;
+       int ret = -EINVAL;
 
-       if (!dock_station)
+       if (!dock_station_count)
                return -ENODEV;
 
        /*
         * make sure this handle is for a device dependent on the dock,
         * this would include the dock station itself
         */
-       dd = find_dock_dependent_device(dock_station, handle);
-       if (dd) {
-               dd->handler = handler;
-               dd->context = context;
-               dock_add_hotplug_device(dock_station, dd);
-               return 0;
+       list_for_each_entry(dock_station, &dock_stations, sibiling) {
+               /*
+                * An ATA bay can be in a dock and itself can be ejected
+                * seperately, so there are two 'dock stations' which need the
+                * ops
+                */
+               dd = find_dock_dependent_device(dock_station, handle);
+               if (dd) {
+                       dd->ops = ops;
+                       dd->context = context;
+                       dock_add_hotplug_device(dock_station, dd);
+                       ret = 0;
+               }
        }
 
-       return -EINVAL;
+       return ret;
 }
 
 EXPORT_SYMBOL_GPL(register_hotplug_dock_device);
@@ -544,13 +646,16 @@ EXPORT_SYMBOL_GPL(register_hotplug_dock_device);
 void unregister_hotplug_dock_device(acpi_handle handle)
 {
        struct dock_dependent_device *dd;
+       struct dock_station *dock_station;
 
-       if (!dock_station)
+       if (!dock_station_count)
                return;
 
-       dd = find_dock_dependent_device(dock_station, handle);
-       if (dd)
-               dock_del_hotplug_device(dock_station, dd);
+       list_for_each_entry(dock_station, &dock_stations, sibiling) {
+               dd = find_dock_dependent_device(dock_station, handle);
+               if (dd)
+                       dock_del_hotplug_device(dock_station, dd);
+       }
 }
 
 EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
@@ -575,13 +680,9 @@ static int handle_eject_request(struct dock_station *ds, u32 event)
         */
        dock_event(ds, event, UNDOCK_EVENT);
 
-       if (!dock_present(ds)) {
-               complete_undock(ds);
-               return -ENODEV;
-       }
-
        hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST);
        undock(ds);
+       dock_lock(ds, 0);
        eject_dock(ds);
        if (dock_present(ds)) {
                printk(KERN_ERR PREFIX "Unable to undock!\n");
@@ -604,14 +705,36 @@ static int handle_eject_request(struct dock_station *ds, u32 event)
 static void dock_notify(acpi_handle handle, u32 event, void *data)
 {
        struct dock_station *ds = data;
+       struct acpi_device *tmp;
+       int surprise_removal = 0;
+
+       /*
+        * According to acpi spec 3.0a, if a DEVICE_CHECK notification
+        * is sent and _DCK is present, it is assumed to mean an undock
+        * request.
+        */
+       if ((ds->flags & DOCK_IS_DOCK) && event == ACPI_NOTIFY_DEVICE_CHECK)
+               event = ACPI_NOTIFY_EJECT_REQUEST;
 
+       /*
+        * dock station: BUS_CHECK - docked or surprise removal
+        *               DEVICE_CHECK - undocked
+        * other device: BUS_CHECK/DEVICE_CHECK - added or surprise removal
+        *
+        * To simplify event handling, dock dependent device handler always
+        * get ACPI_NOTIFY_BUS_CHECK/ACPI_NOTIFY_DEVICE_CHECK for add and
+        * ACPI_NOTIFY_EJECT_REQUEST for removal
+        */
        switch (event) {
        case ACPI_NOTIFY_BUS_CHECK:
-               if (!dock_in_progress(ds) && dock_present(ds)) {
+       case ACPI_NOTIFY_DEVICE_CHECK:
+               if (!dock_in_progress(ds) && acpi_bus_get_device(ds->handle,
+                  &tmp)) {
                        begin_dock(ds);
                        dock(ds);
                        if (!dock_present(ds)) {
                                printk(KERN_ERR PREFIX "Unable to dock!\n");
+                               complete_dock(ds);
                                break;
                        }
                        atomic_notifier_call_chain(&dock_notifier_list,
@@ -619,20 +742,19 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
                        hotplug_dock_devices(ds, event);
                        complete_dock(ds);
                        dock_event(ds, event, DOCK_EVENT);
+                       dock_lock(ds, 1);
+                       break;
                }
-               break;
-       case ACPI_NOTIFY_DEVICE_CHECK:
-       /*
-         * According to acpi spec 3.0a, if a DEVICE_CHECK notification
-         * is sent and _DCK is present, it is assumed to mean an
-         * undock request.  This notify routine will only be called
-         * for objects defining _DCK, so we will fall through to eject
-         * request here.  However, we will pass an eject request through
-        * to the driver who wish to hotplug.
-         */
+               if (dock_present(ds) || dock_in_progress(ds))
+                       break;
+               /* This is a surprise removal */
+               surprise_removal = 1;
+               event = ACPI_NOTIFY_EJECT_REQUEST;
+               /* Fall back */
        case ACPI_NOTIFY_EJECT_REQUEST:
                begin_undock(ds);
-               if (immediate_undock)
+               if ((immediate_undock && !(ds->flags & DOCK_IS_ATA))
+                  || surprise_removal)
                        handle_eject_request(ds, event);
                else
                        dock_event(ds, event, UNDOCK_EVENT);
@@ -642,6 +764,51 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
        }
 }
 
+struct dock_data {
+       acpi_handle handle;
+       unsigned long event;
+       struct dock_station *ds;
+};
+
+static void acpi_dock_deferred_cb(void *context)
+{
+       struct dock_data *data = (struct dock_data *)context;
+
+       dock_notify(data->handle, data->event, data->ds);
+       kfree(data);
+}
+
+static int acpi_dock_notifier_call(struct notifier_block *this,
+       unsigned long event, void *data)
+{
+       struct dock_station *dock_station;
+       acpi_handle handle = (acpi_handle)data;
+
+       if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
+          && event != ACPI_NOTIFY_EJECT_REQUEST)
+               return 0;
+       list_for_each_entry(dock_station, &dock_stations, sibiling) {
+               if (dock_station->handle == handle) {
+                       struct dock_data *dock_data;
+
+                       dock_data = kmalloc(sizeof(*dock_data), GFP_KERNEL);
+                       if (!dock_data)
+                               return 0;
+                       dock_data->handle = handle;
+                       dock_data->event = event;
+                       dock_data->ds = dock_station;
+                       acpi_os_hotplug_execute(acpi_dock_deferred_cb,
+                               dock_data);
+                       return 0 ;
+               }
+       }
+       return 0;
+}
+
+static struct notifier_block dock_acpi_notifier = {
+       .notifier_call = acpi_dock_notifier_call,
+};
+
 /**
  * find_dock_devices - find devices on the dock station
  * @handle: the handle of the device we are examining
@@ -688,6 +855,8 @@ fdd_out:
 static ssize_t show_docked(struct device *dev,
                           struct device_attribute *attr, char *buf)
 {
+       struct dock_station *dock_station = *((struct dock_station **)
+               dev->platform_data);
        return snprintf(buf, PAGE_SIZE, "%d\n", dock_present(dock_station));
 
 }
@@ -699,6 +868,8 @@ static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL);
 static ssize_t show_flags(struct device *dev,
                          struct device_attribute *attr, char *buf)
 {
+       struct dock_station *dock_station = *((struct dock_station **)
+               dev->platform_data);
        return snprintf(buf, PAGE_SIZE, "%d\n", dock_station->flags);
 
 }
@@ -711,6 +882,8 @@ static ssize_t write_undock(struct device *dev, struct device_attribute *attr,
                           const char *buf, size_t count)
 {
        int ret;
+       struct dock_station *dock_station = *((struct dock_station **)
+               dev->platform_data);
 
        if (!count)
                return -EINVAL;
@@ -727,16 +900,38 @@ static DEVICE_ATTR(undock, S_IWUSR, NULL, write_undock);
 static ssize_t show_dock_uid(struct device *dev,
                             struct device_attribute *attr, char *buf)
 {
-       unsigned long lbuf;
+       unsigned long long lbuf;
+       struct dock_station *dock_station = *((struct dock_station **)
+               dev->platform_data);
        acpi_status status = acpi_evaluate_integer(dock_station->handle,
                                        "_UID", NULL, &lbuf);
        if (ACPI_FAILURE(status))
            return 0;
 
-       return snprintf(buf, PAGE_SIZE, "%lx\n", lbuf);
+       return snprintf(buf, PAGE_SIZE, "%llx\n", lbuf);
 }
 static DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL);
 
+static ssize_t show_dock_type(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct dock_station *dock_station = *((struct dock_station **)
+               dev->platform_data);
+       char *type;
+
+       if (dock_station->flags & DOCK_IS_DOCK)
+               type = "dock_station";
+       else if (dock_station->flags & DOCK_IS_ATA)
+               type = "ata_bay";
+       else if (dock_station->flags & DOCK_IS_BAT)
+               type = "battery_bay";
+       else
+               type = "unknown";
+
+       return snprintf(buf, PAGE_SIZE, "%s\n", type);
+}
+static DEVICE_ATTR(type, S_IRUGO, show_dock_type, NULL);
+
 /**
  * dock_add - add a new dock station
  * @handle: the dock station handle
@@ -747,8 +942,9 @@ static DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL);
 static int dock_add(acpi_handle handle)
 {
        int ret;
-       acpi_status status;
        struct dock_dependent_device *dd;
+       struct dock_station *dock_station;
+       struct platform_device *dock_device;
 
        /* allocate & initialize the dock_station private data */
        dock_station = kzalloc(sizeof(*dock_station), GFP_KERNEL);
@@ -758,22 +954,34 @@ static int dock_add(acpi_handle handle)
        dock_station->last_dock_time = jiffies - HZ;
        INIT_LIST_HEAD(&dock_station->dependent_devices);
        INIT_LIST_HEAD(&dock_station->hotplug_devices);
+       INIT_LIST_HEAD(&dock_station->sibiling);
        spin_lock_init(&dock_station->dd_lock);
        mutex_init(&dock_station->hp_lock);
        ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
 
        /* initialize platform device stuff */
-       dock_device =
-               platform_device_register_simple(dock_device_name, 0, NULL, 0);
+       dock_station->dock_device =
+               platform_device_register_simple(dock_device_name,
+                       dock_station_count, NULL, 0);
+       dock_device = dock_station->dock_device;
        if (IS_ERR(dock_device)) {
                kfree(dock_station);
                dock_station = NULL;
                return PTR_ERR(dock_device);
        }
+       platform_device_add_data(dock_device, &dock_station,
+               sizeof(struct dock_station *));
 
        /* we want the dock device to send uevents */
        dock_device->dev.uevent_suppress = 0;
 
+       if (is_dock(handle))
+               dock_station->flags |= DOCK_IS_DOCK;
+       if (is_ata(handle))
+               dock_station->flags |= DOCK_IS_ATA;
+       if (is_battery(handle))
+               dock_station->flags |= DOCK_IS_BAT;
+
        ret = device_create_file(&dock_device->dev, &dev_attr_docked);
        if (ret) {
                printk("Error %d adding sysfs file\n", ret);
@@ -812,6 +1020,9 @@ static int dock_add(acpi_handle handle)
                dock_station = NULL;
                return ret;
        }
+       ret = device_create_file(&dock_device->dev, &dev_attr_type);
+       if (ret)
+               printk(KERN_ERR"Error %d adding sysfs file\n", ret);
 
        /* Find dependent devices */
        acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
@@ -828,24 +1039,12 @@ static int dock_add(acpi_handle handle)
        }
        add_dock_dependent_device(dock_station, dd);
 
-       /* register for dock events */
-       status = acpi_install_notify_handler(dock_station->handle,
-                                            ACPI_SYSTEM_NOTIFY,
-                                            dock_notify, dock_station);
-
-       if (ACPI_FAILURE(status)) {
-               printk(KERN_ERR PREFIX "Error installing notify handler\n");
-               ret = -ENODEV;
-               goto dock_add_err;
-       }
-
-       printk(KERN_INFO PREFIX "%s\n", ACPI_DOCK_DRIVER_DESCRIPTION);
-
+       dock_station_count++;
+       list_add(&dock_station->sibiling, &dock_stations);
        return 0;
 
-dock_add_err:
-       kfree(dd);
 dock_add_err_unregister:
+       device_remove_file(&dock_device->dev, &dev_attr_type);
        device_remove_file(&dock_device->dev, &dev_attr_docked);
        device_remove_file(&dock_device->dev, &dev_attr_undock);
        device_remove_file(&dock_device->dev, &dev_attr_uid);
@@ -859,12 +1058,12 @@ dock_add_err_unregister:
 /**
  * dock_remove - free up resources related to the dock station
  */
-static int dock_remove(void)
+static int dock_remove(struct dock_station *dock_station)
 {
        struct dock_dependent_device *dd, *tmp;
-       acpi_status status;
+       struct platform_device *dock_device = dock_station->dock_device;
 
-       if (!dock_station)
+       if (!dock_station_count)
                return 0;
 
        /* remove dependent devices */
@@ -872,14 +1071,8 @@ static int dock_remove(void)
                                 list)
            kfree(dd);
 
-       /* remove dock notify handler */
-       status = acpi_remove_notify_handler(dock_station->handle,
-                                           ACPI_SYSTEM_NOTIFY,
-                                           dock_notify);
-       if (ACPI_FAILURE(status))
-               printk(KERN_ERR "Error removing notify handler\n");
-
        /* cleanup sysfs */
+       device_remove_file(&dock_device->dev, &dev_attr_type);
        device_remove_file(&dock_device->dev, &dev_attr_docked);
        device_remove_file(&dock_device->dev, &dev_attr_undock);
        device_remove_file(&dock_device->dev, &dev_attr_uid);
@@ -904,41 +1097,60 @@ static int dock_remove(void)
 static acpi_status
 find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
-       int *count = context;
        acpi_status status = AE_OK;
 
        if (is_dock(handle)) {
                if (dock_add(handle) >= 0) {
-                       (*count)++;
                        status = AE_CTRL_TERMINATE;
                }
        }
        return status;
 }
 
-static int __init dock_init(void)
+static acpi_status
+find_bay(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
-       int num = 0;
-
-       dock_station = NULL;
+       /* If bay is a dock, it's already handled */
+       if (is_ejectable_bay(handle) && !is_dock(handle))
+               dock_add(handle);
+       return AE_OK;
+}
 
+static int __init dock_init(void)
+{
        if (acpi_disabled)
                return 0;
 
        /* look for a dock station */
        acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-                           ACPI_UINT32_MAX, find_dock, &num, NULL);
+                           ACPI_UINT32_MAX, find_dock, NULL, NULL);
 
-       if (!num)
-               printk(KERN_INFO "No dock devices found.\n");
+       /* look for bay */
+       acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+                       ACPI_UINT32_MAX, find_bay, NULL, NULL);
+       if (!dock_station_count) {
+               printk(KERN_INFO PREFIX "No dock devices found.\n");
+               return 0;
+       }
 
+       register_acpi_bus_notifier(&dock_acpi_notifier);
+       printk(KERN_INFO PREFIX "%s: %d docks/bays found\n",
+               ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count);
        return 0;
 }
 
 static void __exit dock_exit(void)
 {
-       dock_remove();
+       struct dock_station *dock_station;
+
+       unregister_acpi_bus_notifier(&dock_acpi_notifier);
+       list_for_each_entry(dock_station, &dock_stations, sibiling)
+               dock_remove(dock_station);
 }
 
-postcore_initcall(dock_init);
+/*
+ * Must be called before drivers of devices in dock, otherwise we can't know
+ * which devices are in a dock
+ */
+subsys_initcall(dock_init);
 module_exit(dock_exit);
index 13593f9f21970ec79af46f62b0233689065e848d..ef42316f89f52452f69192d89894ca9ba64f46ee 100644 (file)
@@ -1,7 +1,7 @@
 /*
- *  ec.c - ACPI Embedded Controller Driver (v2.0)
+ *  ec.c - ACPI Embedded Controller Driver (v2.1)
  *
- *  Copyright (C) 2006, 2007 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
+ *  Copyright (C) 2006-2008 Alexey Starikovskiy <astarikovskiy@suse.de>
  *  Copyright (C) 2006 Denis Sadykov <denis.m.sadykov@intel.com>
  *  Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
@@ -26,7 +26,7 @@
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
 
-/* Uncomment next line to get verbose print outs*/
+/* Uncomment next line to get verbose printout */
 /* #define DEBUG */
 
 #include <linux/kernel.h>
@@ -38,6 +38,7 @@
 #include <linux/seq_file.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/spinlock.h>
 #include <asm/io.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
@@ -65,22 +66,21 @@ enum ec_command {
        ACPI_EC_COMMAND_QUERY = 0x84,
 };
 
-/* EC events */
-enum ec_event {
-       ACPI_EC_EVENT_OBF_1 = 1,        /* Output buffer full */
-       ACPI_EC_EVENT_IBF_0,            /* Input buffer empty */
-};
-
 #define ACPI_EC_DELAY          500     /* Wait 500ms max. during EC ops */
 #define ACPI_EC_UDELAY_GLK     1000    /* Wait 1ms max. to get global lock */
 #define ACPI_EC_UDELAY         100     /* Wait 100us before polling EC again */
 
+#define ACPI_EC_STORM_THRESHOLD 20     /* number of false interrupts
+                                          per one transaction */
+
 enum {
-       EC_FLAGS_WAIT_GPE = 0,          /* Don't check status until GPE arrives */
        EC_FLAGS_QUERY_PENDING,         /* Query is pending */
-       EC_FLAGS_GPE_MODE,              /* Expect GPE to be sent for status change */
+       EC_FLAGS_GPE_MODE,              /* Expect GPE to be sent
+                                        * for status change */
        EC_FLAGS_NO_GPE,                /* Don't use GPE mode */
-       EC_FLAGS_RESCHEDULE_POLL        /* Re-schedule poll */
+       EC_FLAGS_GPE_STORM,             /* GPE storm detected */
+       EC_FLAGS_HANDLERS_INSTALLED     /* Handlers for GPE and
+                                        * OpReg are installed */
 };
 
 /* If we find an EC via the ECDT, we need to keep a ptr to its context */
@@ -95,6 +95,15 @@ struct acpi_ec_query_handler {
        u8 query_bit;
 };
 
+struct transaction {
+       const u8 *wdata;
+       u8 *rdata;
+       unsigned short irq_count;
+       u8 command;
+       u8 wlen;
+       u8 rlen;
+};
+
 static struct acpi_ec {
        acpi_handle handle;
        unsigned long gpe;
@@ -105,9 +114,8 @@ static struct acpi_ec {
        struct mutex lock;
        wait_queue_head_t wait;
        struct list_head list;
-       struct delayed_work work;
-       atomic_t irq_count;
-       u8 handlers_installed;
+       struct transaction *curr;
+       spinlock_t curr_lock;
 } *boot_ec, *first_ec;
 
 /* 
@@ -150,7 +158,7 @@ static inline u8 acpi_ec_read_data(struct acpi_ec *ec)
 {
        u8 x = inb(ec->data_addr);
        pr_debug(PREFIX "---> data = 0x%2.2x\n", x);
-       return inb(ec->data_addr);
+       return x;
 }
 
 static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command)
@@ -165,158 +173,172 @@ static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
        outb(data, ec->data_addr);
 }
 
-static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
+static int ec_transaction_done(struct acpi_ec *ec)
 {
-       if (test_bit(EC_FLAGS_WAIT_GPE, &ec->flags))
-               return 0;
-       if (event == ACPI_EC_EVENT_OBF_1) {
-               if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF)
-                       return 1;
-       } else if (event == ACPI_EC_EVENT_IBF_0) {
-               if (!(acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF))
-                       return 1;
-       }
-
-       return 0;
+       unsigned long flags;
+       int ret = 0;
+       spin_lock_irqsave(&ec->curr_lock, flags);
+       if (!ec->curr || (!ec->curr->wlen && !ec->curr->rlen))
+               ret = 1;
+       spin_unlock_irqrestore(&ec->curr_lock, flags);
+       return ret;
 }
 
-static void ec_schedule_ec_poll(struct acpi_ec *ec)
+static void gpe_transaction(struct acpi_ec *ec, u8 status)
 {
-       if (test_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags))
-               schedule_delayed_work(&ec->work,
-                                     msecs_to_jiffies(ACPI_EC_DELAY));
+       unsigned long flags;
+       spin_lock_irqsave(&ec->curr_lock, flags);
+       if (!ec->curr)
+               goto unlock;
+       if (ec->curr->wlen > 0) {
+               if ((status & ACPI_EC_FLAG_IBF) == 0) {
+                       acpi_ec_write_data(ec, *(ec->curr->wdata++));
+                       --ec->curr->wlen;
+               } else
+                       /* false interrupt, state didn't change */
+                       ++ec->curr->irq_count;
+
+       } else if (ec->curr->rlen > 0) {
+               if ((status & ACPI_EC_FLAG_OBF) == 1) {
+                       *(ec->curr->rdata++) = acpi_ec_read_data(ec);
+                       --ec->curr->rlen;
+               } else
+                       /* false interrupt, state didn't change */
+                       ++ec->curr->irq_count;
+       }
+unlock:
+       spin_unlock_irqrestore(&ec->curr_lock, flags);
 }
 
-static void ec_switch_to_poll_mode(struct acpi_ec *ec)
+static int acpi_ec_wait(struct acpi_ec *ec)
 {
+       if (wait_event_timeout(ec->wait, ec_transaction_done(ec),
+                              msecs_to_jiffies(ACPI_EC_DELAY)))
+               return 0;
+       /* missing GPEs, switch back to poll mode */
+       if (printk_ratelimit())
+               pr_info(PREFIX "missing confirmations, "
+                               "switch off interrupt mode.\n");
        set_bit(EC_FLAGS_NO_GPE, &ec->flags);
        clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
-       acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
-       set_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
+       return 1;
 }
 
-static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
+static void acpi_ec_gpe_query(void *ec_cxt);
+
+static int ec_check_sci(struct acpi_ec *ec, u8 state)
 {
-       atomic_set(&ec->irq_count, 0);
-       if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) &&
-           likely(!force_poll)) {
-               if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event),
-                                      msecs_to_jiffies(ACPI_EC_DELAY)))
-                       return 0;
-               clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
-               if (acpi_ec_check_status(ec, event)) {
-                       /* missing GPEs, switch back to poll mode */
-                       if (printk_ratelimit())
-                               pr_info(PREFIX "missing confirmations, "
-                                               "switch off interrupt mode.\n");
-                       ec_switch_to_poll_mode(ec);
-                       ec_schedule_ec_poll(ec);
-                       return 0;
-               }
-       } else {
-               unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
-               clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
-               while (time_before(jiffies, delay)) {
-                       if (acpi_ec_check_status(ec, event))
-                               return 0;
-                       msleep(1);
-               }
-               if (acpi_ec_check_status(ec,event))
+       if (state & ACPI_EC_FLAG_SCI) {
+               if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
+                       return acpi_os_execute(OSL_EC_BURST_HANDLER,
+                               acpi_ec_gpe_query, ec);
+       }
+       return 0;
+}
+
+static int ec_poll(struct acpi_ec *ec)
+{
+       unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
+       msleep(1);
+       while (time_before(jiffies, delay)) {
+               gpe_transaction(ec, acpi_ec_read_status(ec));
+               msleep(1);
+               if (ec_transaction_done(ec))
                        return 0;
        }
-       pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n",
-               acpi_ec_read_status(ec),
-               (event == ACPI_EC_EVENT_OBF_1) ? "\"b0=1\"" : "\"b1=0\"");
        return -ETIME;
 }
 
-static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
-                                       const u8 * wdata, unsigned wdata_len,
-                                       u8 * rdata, unsigned rdata_len,
+static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
+                                       struct transaction *t,
                                        int force_poll)
 {
-       int result = 0;
-       set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
+       unsigned long tmp;
+       int ret = 0;
        pr_debug(PREFIX "transaction start\n");
-       acpi_ec_write_cmd(ec, command);
-       for (; wdata_len > 0; --wdata_len) {
-               result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
-               if (result) {
-                       pr_err(PREFIX
-                              "write_cmd timeout, command = %d\n", command);
-                       goto end;
-               }
-               set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
-               acpi_ec_write_data(ec, *(wdata++));
+       /* disable GPE during transaction if storm is detected */
+       if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
+               clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
+               acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
        }
-
-       if (!rdata_len) {
-               result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
-               if (result) {
-                       pr_err(PREFIX
-                              "finish-write timeout, command = %d\n", command);
-                       goto end;
-               }
-       } else if (command == ACPI_EC_COMMAND_QUERY)
+       /* start transaction */
+       spin_lock_irqsave(&ec->curr_lock, tmp);
+       /* following two actions should be kept atomic */
+       t->irq_count = 0;
+       ec->curr = t;
+       acpi_ec_write_cmd(ec, ec->curr->command);
+       if (ec->curr->command == ACPI_EC_COMMAND_QUERY)
                clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
-
-       for (; rdata_len > 0; --rdata_len) {
-               result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, force_poll);
-               if (result) {
-                       pr_err(PREFIX "read timeout, command = %d\n", command);
-                       goto end;
-               }
-               /* Don't expect GPE after last read */
-               if (rdata_len > 1)
-                       set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
-               *(rdata++) = acpi_ec_read_data(ec);
-       }
-      end:
+       spin_unlock_irqrestore(&ec->curr_lock, tmp);
+       /* if we selected poll mode or failed in GPE-mode do a poll loop */
+       if (force_poll ||
+           !test_bit(EC_FLAGS_GPE_MODE, &ec->flags) ||
+           acpi_ec_wait(ec))
+               ret = ec_poll(ec);
        pr_debug(PREFIX "transaction end\n");
-       return result;
+       spin_lock_irqsave(&ec->curr_lock, tmp);
+       ec->curr = NULL;
+       spin_unlock_irqrestore(&ec->curr_lock, tmp);
+       if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
+               /* check if we received SCI during transaction */
+               ec_check_sci(ec, acpi_ec_read_status(ec));
+               /* it is safe to enable GPE outside of transaction */
+               acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+       } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
+                  t->irq_count > ACPI_EC_STORM_THRESHOLD) {
+               pr_debug(PREFIX "GPE storm detected\n");
+               set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
+       }
+       return ret;
+}
+
+static int ec_check_ibf0(struct acpi_ec *ec)
+{
+       u8 status = acpi_ec_read_status(ec);
+       return (status & ACPI_EC_FLAG_IBF) == 0;
 }
 
-static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
-                              const u8 * wdata, unsigned wdata_len,
-                              u8 * rdata, unsigned rdata_len,
+static int ec_wait_ibf0(struct acpi_ec *ec)
+{
+       unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
+       /* interrupt wait manually if GPE mode is not active */
+       unsigned long timeout = test_bit(EC_FLAGS_GPE_MODE, &ec->flags) ?
+               msecs_to_jiffies(ACPI_EC_DELAY) : msecs_to_jiffies(1);
+       while (time_before(jiffies, delay))
+               if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), timeout))
+                       return 0;
+       return -ETIME;
+}
+
+static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t,
                               int force_poll)
 {
        int status;
        u32 glk;
-
-       if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata))
+       if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata))
                return -EINVAL;
-
-       if (rdata)
-               memset(rdata, 0, rdata_len);
-
+       if (t->rdata)
+               memset(t->rdata, 0, t->rlen);
        mutex_lock(&ec->lock);
        if (ec->global_lock) {
                status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
                if (ACPI_FAILURE(status)) {
-                       mutex_unlock(&ec->lock);
-                       return -ENODEV;
+                       status = -ENODEV;
+                       goto unlock;
                }
        }
-
-       status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0);
-       if (status) {
+       if (ec_wait_ibf0(ec)) {
                pr_err(PREFIX "input buffer is not empty, "
                                "aborting transaction\n");
+               status = -ETIME;
                goto end;
        }
-
-       status = acpi_ec_transaction_unlocked(ec, command,
-                                             wdata, wdata_len,
-                                             rdata, rdata_len,
-                                             force_poll);
-
-      end:
-
+       status = acpi_ec_transaction_unlocked(ec, t, force_poll);
+end:
        if (ec->global_lock)
                acpi_release_global_lock(glk);
+unlock:
        mutex_unlock(&ec->lock);
-
        return status;
 }
 
@@ -327,21 +349,32 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
 int acpi_ec_burst_enable(struct acpi_ec *ec)
 {
        u8 d;
-       return acpi_ec_transaction(ec, ACPI_EC_BURST_ENABLE, NULL, 0, &d, 1, 0);
+       struct transaction t = {.command = ACPI_EC_BURST_ENABLE,
+                               .wdata = NULL, .rdata = &d,
+                               .wlen = 0, .rlen = 1};
+
+       return acpi_ec_transaction(ec, &t, 0);
 }
 
 int acpi_ec_burst_disable(struct acpi_ec *ec)
 {
-       return acpi_ec_transaction(ec, ACPI_EC_BURST_DISABLE, NULL, 0, NULL, 0, 0);
+       struct transaction t = {.command = ACPI_EC_BURST_DISABLE,
+                               .wdata = NULL, .rdata = NULL,
+                               .wlen = 0, .rlen = 0};
+
+       return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ?
+                               acpi_ec_transaction(ec, &t, 0) : 0;
 }
 
 static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data)
 {
        int result;
        u8 d;
+       struct transaction t = {.command = ACPI_EC_COMMAND_READ,
+                               .wdata = &address, .rdata = &d,
+                               .wlen = 1, .rlen = 1};
 
-       result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_READ,
-                                    &address, 1, &d, 1, 0);
+       result = acpi_ec_transaction(ec, &t, 0);
        *data = d;
        return result;
 }
@@ -349,8 +382,11 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data)
 static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
 {
        u8 wdata[2] = { address, data };
-       return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE,
-                                  wdata, 2, NULL, 0, 0);
+       struct transaction t = {.command = ACPI_EC_COMMAND_WRITE,
+                               .wdata = wdata, .rdata = NULL,
+                               .wlen = 2, .rlen = 0};
+
+       return acpi_ec_transaction(ec, &t, 0);
 }
 
 /*
@@ -412,12 +448,13 @@ int ec_transaction(u8 command,
                   u8 * rdata, unsigned rdata_len,
                   int force_poll)
 {
+       struct transaction t = {.command = command,
+                               .wdata = wdata, .rdata = rdata,
+                               .wlen = wdata_len, .rlen = rdata_len};
        if (!first_ec)
                return -ENODEV;
 
-       return acpi_ec_transaction(first_ec, command, wdata,
-                                  wdata_len, rdata, rdata_len,
-                                  force_poll);
+       return acpi_ec_transaction(first_ec, &t, force_poll);
 }
 
 EXPORT_SYMBOL(ec_transaction);
@@ -426,7 +463,9 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
 {
        int result;
        u8 d;
-
+       struct transaction t = {.command = ACPI_EC_COMMAND_QUERY,
+                               .wdata = NULL, .rdata = &d,
+                               .wlen = 0, .rlen = 1};
        if (!ec || !data)
                return -EINVAL;
 
@@ -436,7 +475,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
         * bit to be cleared (and thus clearing the interrupt source).
         */
 
-       result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1, 0);
+       result = acpi_ec_transaction(ec, &t, 0);
        if (result)
                return result;
 
@@ -513,46 +552,26 @@ static void acpi_ec_gpe_query(void *ec_cxt)
 
 static u32 acpi_ec_gpe_handler(void *data)
 {
-       acpi_status status = AE_OK;
        struct acpi_ec *ec = data;
-       u8 state = acpi_ec_read_status(ec);
+       u8 status;
 
        pr_debug(PREFIX "~~~> interrupt\n");
-       atomic_inc(&ec->irq_count);
-       if (atomic_read(&ec->irq_count) > 5) {
-               pr_err(PREFIX "GPE storm detected, disabling EC GPE\n");
-               ec_switch_to_poll_mode(ec);
-               goto end;
-       }
-       clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
-       if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))
+       status = acpi_ec_read_status(ec);
+
+       gpe_transaction(ec, status);
+       if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0)
                wake_up(&ec->wait);
 
-       if (state & ACPI_EC_FLAG_SCI) {
-               if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
-                       status = acpi_os_execute(OSL_EC_BURST_HANDLER,
-                               acpi_ec_gpe_query, ec);
-       } else if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
-                  !test_bit(EC_FLAGS_NO_GPE, &ec->flags) &&
-                  in_interrupt()) {
+       ec_check_sci(ec, status);
+       if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
+           !test_bit(EC_FLAGS_NO_GPE, &ec->flags)) {
                /* this is non-query, must be confirmation */
                if (printk_ratelimit())
                        pr_info(PREFIX "non-query interrupt received,"
                                " switching to interrupt mode\n");
                set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
-               clear_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
        }
-end:
-       ec_schedule_ec_poll(ec);
-       return ACPI_SUCCESS(status) ?
-           ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
-}
-
-static void do_ec_poll(struct work_struct *work)
-{
-       struct acpi_ec *ec = container_of(work, struct acpi_ec, work.work);
-       atomic_set(&ec->irq_count, 0);
-       (void)acpi_ec_gpe_handler(ec);
+       return ACPI_INTERRUPT_HANDLED;
 }
 
 /* --------------------------------------------------------------------------
@@ -696,8 +715,7 @@ static struct acpi_ec *make_acpi_ec(void)
        mutex_init(&ec->lock);
        init_waitqueue_head(&ec->wait);
        INIT_LIST_HEAD(&ec->list);
-       INIT_DELAYED_WORK_DEFERRABLE(&ec->work, do_ec_poll);
-       atomic_set(&ec->irq_count, 0);
+       spin_lock_init(&ec->curr_lock);
        return ec;
 }
 
@@ -718,6 +736,7 @@ static acpi_status
 ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
 {
        acpi_status status;
+       unsigned long long tmp;
 
        struct acpi_ec *ec = context;
        status = acpi_walk_resources(handle, METHOD_NAME__CRS,
@@ -727,31 +746,26 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
 
        /* Get GPE bit assignment (EC events). */
        /* TODO: Add support for _GPE returning a package */
-       status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
+       status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp);
        if (ACPI_FAILURE(status))
                return status;
+       ec->gpe = tmp;
        /* Use the global lock for all EC transactions? */
-       acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
+       acpi_evaluate_integer(handle, "_GLK", NULL, &tmp);
+       ec->global_lock = tmp;
        ec->handle = handle;
        return AE_CTRL_TERMINATE;
 }
 
-static void ec_poll_stop(struct acpi_ec *ec)
-{
-       clear_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
-       cancel_delayed_work(&ec->work);
-}
-
 static void ec_remove_handlers(struct acpi_ec *ec)
 {
-       ec_poll_stop(ec);
        if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
                                ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
                pr_err(PREFIX "failed to remove space handler\n");
        if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe,
                                &acpi_ec_gpe_handler)))
                pr_err(PREFIX "failed to remove gpe handler\n");
-       ec->handlers_installed = 0;
+       clear_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags);
 }
 
 static int acpi_ec_add(struct acpi_device *device)
@@ -788,7 +802,7 @@ static int acpi_ec_add(struct acpi_device *device)
 
        if (!first_ec)
                first_ec = ec;
-       acpi_driver_data(device) = ec;
+       device->driver_data = ec;
        acpi_ec_add_fs(device);
        pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
                          ec->gpe, ec->command_addr, ec->data_addr);
@@ -813,7 +827,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
        }
        mutex_unlock(&ec->lock);
        acpi_ec_remove_fs(device);
-       acpi_driver_data(device) = NULL;
+       device->driver_data = NULL;
        if (ec == first_ec)
                first_ec = NULL;
        kfree(ec);
@@ -846,27 +860,36 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context)
 static int ec_install_handlers(struct acpi_ec *ec)
 {
        acpi_status status;
-       if (ec->handlers_installed)
+       if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags))
                return 0;
        status = acpi_install_gpe_handler(NULL, ec->gpe,
-                                         ACPI_GPE_EDGE_TRIGGERED,
-                                         &acpi_ec_gpe_handler, ec);
+                                 ACPI_GPE_EDGE_TRIGGERED,
+                                 &acpi_ec_gpe_handler, ec);
        if (ACPI_FAILURE(status))
                return -ENODEV;
-
        acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
        acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
-
        status = acpi_install_address_space_handler(ec->handle,
                                                    ACPI_ADR_SPACE_EC,
                                                    &acpi_ec_space_handler,
                                                    NULL, ec);
        if (ACPI_FAILURE(status)) {
-               acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
-               return -ENODEV;
+               if (status == AE_NOT_FOUND) {
+                       /*
+                        * Maybe OS fails in evaluating the _REG object.
+                        * The AE_NOT_FOUND error will be ignored and OS
+                        * continue to initialize EC.
+                        */
+                       printk(KERN_ERR "Fail in evaluating the _REG object"
+                               " of EC device. Broken bios is suspected.\n");
+               } else {
+                       acpi_remove_gpe_handler(NULL, ec->gpe,
+                               &acpi_ec_gpe_handler);
+                       return -ENODEV;
+               }
        }
 
-       ec->handlers_installed = 1;
+       set_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags);
        return 0;
 }
 
@@ -887,7 +910,6 @@ static int acpi_ec_start(struct acpi_device *device)
 
        /* EC is fully operational, allow queries */
        clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
-       ec_schedule_ec_poll(ec);
        return ret;
 }
 
@@ -906,7 +928,7 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
 
 int __init acpi_boot_ec_enable(void)
 {
-       if (!boot_ec || boot_ec->handlers_installed)
+       if (!boot_ec || test_bit(EC_FLAGS_HANDLERS_INSTALLED, &boot_ec->flags))
                return 0;
        if (!ec_install_handlers(boot_ec)) {
                first_ec = boot_ec;
index 8892b9824fae7d8acad9c214356df84c528dc9b1..74da6fa52ef183e4db2b3e9db7b24c7d75da5f12 100644 (file)
@@ -43,7 +43,6 @@
 
 #include <acpi/acpi.h>
 #include <acpi/acinterp.h>
-#include <acpi/amlcode.h>
 #include <acpi/acnamesp.h>
 #include <acpi/actables.h>
 #include <acpi/acdispat.h>
@@ -91,13 +90,12 @@ acpi_ex_add_table(u32 table_index,
 
        /* Init the table handle */
 
-       obj_desc->reference.opcode = AML_LOAD_OP;
+       obj_desc->reference.class = ACPI_REFCLASS_TABLE;
        *ddb_handle = obj_desc;
 
        /* Install the new table into the local data structures */
 
-       obj_desc->reference.object = ACPI_CAST_PTR(void,
-                       (unsigned long)table_index);
+       obj_desc->reference.value = table_index;
 
        /* Add the table to the namespace */
 
@@ -280,6 +278,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
                struct acpi_walk_state *walk_state)
 {
        union acpi_operand_object *ddb_handle;
+       struct acpi_table_header *table;
        struct acpi_table_desc table_desc;
        u32 table_index;
        acpi_status status;
@@ -294,9 +293,8 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
        switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
        case ACPI_TYPE_REGION:
 
-               ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n",
-                                 obj_desc,
-                                 acpi_ut_get_object_type_name(obj_desc)));
+               ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+                                 "Load table from Region %p\n", obj_desc));
 
                /* Region must be system_memory (from ACPI spec) */
 
@@ -316,61 +314,112 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
                }
 
                /*
-                * We will simply map the memory region for the table. However, the
-                * memory region is technically not guaranteed to remain stable and
-                * we may eventually have to copy the table to a local buffer.
+                * Map the table header and get the actual table length. The region
+                * length is not guaranteed to be the same as the table length.
+                */
+               table = acpi_os_map_memory(obj_desc->region.address,
+                                          sizeof(struct acpi_table_header));
+               if (!table) {
+                       return_ACPI_STATUS(AE_NO_MEMORY);
+               }
+
+               length = table->length;
+               acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+
+               /* Must have at least an ACPI table header */
+
+               if (length < sizeof(struct acpi_table_header)) {
+                       return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
+               }
+
+               /*
+                * The memory region is not guaranteed to remain stable and we must
+                * copy the table to a local buffer. For example, the memory region
+                * is corrupted after suspend on some machines. Dynamically loaded
+                * tables are usually small, so this overhead is minimal.
                 */
+
+               /* Allocate a buffer for the table */
+
+               table_desc.pointer = ACPI_ALLOCATE(length);
+               if (!table_desc.pointer) {
+                       return_ACPI_STATUS(AE_NO_MEMORY);
+               }
+
+               /* Map the entire table and copy it */
+
+               table = acpi_os_map_memory(obj_desc->region.address, length);
+               if (!table) {
+                       ACPI_FREE(table_desc.pointer);
+                       return_ACPI_STATUS(AE_NO_MEMORY);
+               }
+
+               ACPI_MEMCPY(table_desc.pointer, table, length);
+               acpi_os_unmap_memory(table, length);
+
                table_desc.address = obj_desc->region.address;
-               table_desc.length = obj_desc->region.length;
-               table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED;
                break;
 
        case ACPI_TYPE_BUFFER:  /* Buffer or resolved region_field */
 
                ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                                 "Load from Buffer or Field %p %s\n", obj_desc,
-                                 acpi_ut_get_object_type_name(obj_desc)));
-
-               length = obj_desc->buffer.length;
+                                 "Load table from Buffer or Field %p\n",
+                                 obj_desc));
 
                /* Must have at least an ACPI table header */
 
-               if (length < sizeof(struct acpi_table_header)) {
+               if (obj_desc->buffer.length < sizeof(struct acpi_table_header)) {
                        return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
                }
 
-               /* Validate checksum here. It won't get validated in tb_add_table */
+               /* Get the actual table length from the table header */
 
-               status =
-                   acpi_tb_verify_checksum(ACPI_CAST_PTR
-                                           (struct acpi_table_header,
-                                            obj_desc->buffer.pointer), length);
-               if (ACPI_FAILURE(status)) {
-                       return_ACPI_STATUS(status);
+               table =
+                   ACPI_CAST_PTR(struct acpi_table_header,
+                                 obj_desc->buffer.pointer);
+               length = table->length;
+
+               /* Table cannot extend beyond the buffer */
+
+               if (length > obj_desc->buffer.length) {
+                       return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
+               }
+               if (length < sizeof(struct acpi_table_header)) {
+                       return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
                }
 
                /*
-                * We need to copy the buffer since the original buffer could be
-                * changed or deleted in the future
+                * Copy the table from the buffer because the buffer could be modified
+                * or even deleted in the future
                 */
                table_desc.pointer = ACPI_ALLOCATE(length);
                if (!table_desc.pointer) {
                        return_ACPI_STATUS(AE_NO_MEMORY);
                }
 
-               ACPI_MEMCPY(table_desc.pointer, obj_desc->buffer.pointer,
-                           length);
-               table_desc.length = length;
-               table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
+               ACPI_MEMCPY(table_desc.pointer, table, length);
+               table_desc.address = ACPI_TO_INTEGER(table_desc.pointer);
                break;
 
        default:
                return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
        }
 
-       /*
-        * Install the new table into the local data structures
-        */
+       /* Validate table checksum (will not get validated in tb_add_table) */
+
+       status = acpi_tb_verify_checksum(table_desc.pointer, length);
+       if (ACPI_FAILURE(status)) {
+               ACPI_FREE(table_desc.pointer);
+               return_ACPI_STATUS(status);
+       }
+
+       /* Complete the table descriptor */
+
+       table_desc.length = length;
+       table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
+
+       /* Install the new table into the local data structures */
+
        status = acpi_tb_add_table(&table_desc, &table_index);
        if (ACPI_FAILURE(status)) {
                goto cleanup;
@@ -379,7 +428,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
        /*
         * Add the table to the namespace.
         *
-        * Note: We load the table objects relative to the root of the namespace.
+        * Note: Load the table objects relative to the root of the namespace.
         * This appears to go against the ACPI specification, but we do it for
         * compatibility with other ACPI implementations.
         */
@@ -415,7 +464,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
       cleanup:
        if (ACPI_FAILURE(status)) {
 
-               /* Delete allocated buffer or mapping */
+               /* Delete allocated table buffer */
 
                acpi_tb_delete_table(&table_desc);
        }
@@ -455,9 +504,9 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
                return_ACPI_STATUS(AE_BAD_PARAMETER);
        }
 
-       /* Get the table index from the ddb_handle (acpi_size for 64-bit case) */
+       /* Get the table index from the ddb_handle */
 
-       table_index = (u32) (acpi_size) table_desc->reference.object;
+       table_index = table_desc->reference.value;
 
        /* Invoke table handler if present */
 
index 261d97516d9b3cf69451f0559560b846b265a875..1d1f35adddde65cfd0558ff4a2be97f087759c95 100644 (file)
@@ -57,7 +57,7 @@ acpi_ex_convert_to_ascii(acpi_integer integer,
  *
  * FUNCTION:    acpi_ex_convert_to_integer
  *
- * PARAMETERS:  obj_desc        - Object to be converted.  Must be an
+ * PARAMETERS:  obj_desc        - Object to be converted. Must be an
  *                                Integer, Buffer, or String
  *              result_desc     - Where the new Integer object is returned
  *              Flags           - Used for string conversion
@@ -103,7 +103,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
        }
 
        /*
-        * Convert the buffer/string to an integer.  Note that both buffers and
+        * Convert the buffer/string to an integer. Note that both buffers and
         * strings are treated as raw data - we don't convert ascii to hex for
         * strings.
         *
@@ -120,7 +120,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
 
                /*
                 * Convert string to an integer - for most cases, the string must be
-                * hexadecimal as per the ACPI specification.  The only exception (as
+                * hexadecimal as per the ACPI specification. The only exception (as
                 * of ACPI 3.0) is that the to_integer() operator allows both decimal
                 * and hexadecimal strings (hex prefixed with "0x").
                 */
@@ -159,6 +159,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
                break;
 
        default:
+
                /* No other types can get here */
                break;
        }
@@ -185,7 +186,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
  *
  * FUNCTION:    acpi_ex_convert_to_buffer
  *
- * PARAMETERS:  obj_desc        - Object to be converted.  Must be an
+ * PARAMETERS:  obj_desc        - Object to be converted. Must be an
  *                                Integer, Buffer, or String
  *              result_desc     - Where the new buffer object is returned
  *
@@ -365,7 +366,7 @@ acpi_ex_convert_to_ascii(acpi_integer integer,
        }
 
        /*
-        * Since leading zeros are supressed, we must check for the case where
+        * Since leading zeros are suppressed, we must check for the case where
         * the integer equals 0
         *
         * Finally, null terminate the string and return the length
@@ -383,7 +384,7 @@ acpi_ex_convert_to_ascii(acpi_integer integer,
  *
  * FUNCTION:    acpi_ex_convert_to_string
  *
- * PARAMETERS:  obj_desc        - Object to be converted.  Must be an
+ * PARAMETERS:  obj_desc        - Object to be converted. Must be an
  *                                Integer, Buffer, or String
  *              result_desc     - Where the string object is returned
  *              Type            - String flags (base and conversion type)
@@ -472,7 +473,7 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,
                        base = 10;
 
                        /*
-                        * Calculate the final string length.  Individual string values
+                        * Calculate the final string length. Individual string values
                         * are variable length (include separator for each)
                         */
                        for (i = 0; i < obj_desc->buffer.length; i++) {
@@ -511,9 +512,14 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,
                /*
                 * Create a new string object and string buffer
                 * (-1 because of extra separator included in string_length from above)
+                * Allow creation of zero-length strings from zero-length buffers.
                 */
+               if (string_length) {
+                       string_length--;
+               }
+
                return_desc = acpi_ut_create_string_object((acpi_size)
-                                                          (string_length - 1));
+                                                          string_length);
                if (!return_desc) {
                        return_ACPI_STATUS(AE_NO_MEMORY);
                }
@@ -536,7 +542,9 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,
                 * Null terminate the string
                 * (overwrites final comma/space from above)
                 */
-               new_buf--;
+               if (obj_desc->buffer.length) {
+                       new_buf--;
+               }
                *new_buf = 0;
                break;
 
@@ -617,7 +625,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type,
                case ACPI_TYPE_LOCAL_BANK_FIELD:
                case ACPI_TYPE_LOCAL_INDEX_FIELD:
                        /*
-                        * These types require an Integer operand.  We can convert
+                        * These types require an Integer operand. We can convert
                         * a Buffer or a String to an Integer if necessary.
                         */
                        status =
@@ -627,7 +635,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type,
 
                case ACPI_TYPE_STRING:
                        /*
-                        * The operand must be a String.  We can convert an
+                        * The operand must be a String. We can convert an
                         * Integer or Buffer if necessary
                         */
                        status =
@@ -637,7 +645,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type,
 
                case ACPI_TYPE_BUFFER:
                        /*
-                        * The operand must be a Buffer.  We can convert an
+                        * The operand must be a Buffer. We can convert an
                         * Integer or String if necessary
                         */
                        status =
index 2be2e2bf95bf1447aa031be9d1cf3a33a46f39a9..d087a7d28aa53f34173cb7d64d688db119017086 100644 (file)
@@ -45,7 +45,6 @@
 #include <acpi/acinterp.h>
 #include <acpi/amlcode.h>
 #include <acpi/acnamesp.h>
-#include <acpi/acparser.h>
 
 #define _COMPONENT          ACPI_EXECUTER
 ACPI_MODULE_NAME("exdump")
@@ -214,10 +213,11 @@ static struct acpi_exdump_info acpi_ex_dump_index_field[5] = {
        {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(index_field.data_obj), "Data Object"}
 };
 
-static struct acpi_exdump_info acpi_ex_dump_reference[7] = {
+static struct acpi_exdump_info acpi_ex_dump_reference[8] = {
        {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_reference), NULL},
+       {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(reference.class), "Class"},
        {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(reference.target_type), "Target Type"},
-       {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(reference.offset), "Offset"},
+       {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(reference.value), "Value"},
        {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.object), "Object Desc"},
        {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.node), "Node"},
        {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.where), "Where"},
@@ -413,10 +413,10 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc,
 
                case ACPI_EXD_REFERENCE:
 
-                       acpi_ex_out_string("Opcode",
-                                          (acpi_ps_get_opcode_info
-                                           (obj_desc->reference.opcode))->
-                                          name);
+                       acpi_ex_out_string("Class Name",
+                                          (char *)
+                                          acpi_ut_get_reference_name
+                                          (obj_desc));
                        acpi_ex_dump_reference_obj(obj_desc);
                        break;
 
@@ -494,40 +494,41 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
        switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
        case ACPI_TYPE_LOCAL_REFERENCE:
 
-               switch (obj_desc->reference.opcode) {
-               case AML_DEBUG_OP:
+               acpi_os_printf("Reference: [%s] ",
+                              acpi_ut_get_reference_name(obj_desc));
+
+               switch (obj_desc->reference.class) {
+               case ACPI_REFCLASS_DEBUG:
 
-                       acpi_os_printf("Reference: Debug\n");
+                       acpi_os_printf("\n");
                        break;
 
-               case AML_INDEX_OP:
+               case ACPI_REFCLASS_INDEX:
 
-                       acpi_os_printf("Reference: Index %p\n",
-                                      obj_desc->reference.object);
+                       acpi_os_printf("%p\n", obj_desc->reference.object);
                        break;
 
-               case AML_LOAD_OP:
+               case ACPI_REFCLASS_TABLE:
 
-                       acpi_os_printf("Reference: [DdbHandle] TableIndex %p\n",
-                                      obj_desc->reference.object);
+                       acpi_os_printf("Table Index %X\n",
+                                      obj_desc->reference.value);
                        break;
 
-               case AML_REF_OF_OP:
+               case ACPI_REFCLASS_REFOF:
 
-                       acpi_os_printf("Reference: (RefOf) %p [%s]\n",
-                                      obj_desc->reference.object,
+                       acpi_os_printf("%p [%s]\n", obj_desc->reference.object,
                                       acpi_ut_get_type_name(((union
                                                               acpi_operand_object
-                                                              *)obj_desc->
+                                                              *)
+                                                             obj_desc->
                                                              reference.
                                                              object)->common.
                                                             type));
                        break;
 
-               case AML_ARG_OP:
+               case ACPI_REFCLASS_ARG:
 
-                       acpi_os_printf("Reference: Arg%d",
-                                      obj_desc->reference.offset);
+                       acpi_os_printf("%X", obj_desc->reference.value);
 
                        if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
 
@@ -542,10 +543,9 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
                        acpi_os_printf("\n");
                        break;
 
-               case AML_LOCAL_OP:
+               case ACPI_REFCLASS_LOCAL:
 
-                       acpi_os_printf("Reference: Local%d",
-                                      obj_desc->reference.offset);
+                       acpi_os_printf("%X", obj_desc->reference.value);
 
                        if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
 
@@ -560,21 +560,16 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
                        acpi_os_printf("\n");
                        break;
 
-               case AML_INT_NAMEPATH_OP:
+               case ACPI_REFCLASS_NAME:
 
-                       acpi_os_printf("Reference: Namepath %X [%4.4s]\n",
-                                      obj_desc->reference.node->name.integer,
+                       acpi_os_printf("- [%4.4s]\n",
                                       obj_desc->reference.node->name.ascii);
                        break;
 
-               default:
-
-                       /* Unknown opcode */
+               default:        /* Unknown reference class */
 
-                       acpi_os_printf("Unknown Reference opcode=%X\n",
-                                      obj_desc->reference.opcode);
+                       acpi_os_printf("%2.2X\n", obj_desc->reference.class);
                        break;
-
                }
                break;
 
@@ -865,8 +860,8 @@ static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc)
 
        ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER;
 
-       if (obj_desc->reference.opcode == AML_INT_NAMEPATH_OP) {
-               acpi_os_printf(" Named Object %p ", obj_desc->reference.node);
+       if (obj_desc->reference.class == ACPI_REFCLASS_NAME) {
+               acpi_os_printf(" %p ", obj_desc->reference.node);
 
                status =
                    acpi_ns_handle_to_pathname(obj_desc->reference.node,
@@ -882,14 +877,12 @@ static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc)
                    ACPI_DESC_TYPE_OPERAND) {
                        acpi_os_printf(" Target: %p",
                                       obj_desc->reference.object);
-                       if (obj_desc->reference.opcode == AML_LOAD_OP) {
-                               /*
-                                * For DDBHandle reference,
-                                * obj_desc->Reference.Object is the table index
-                                */
-                               acpi_os_printf(" [DDBHandle]\n");
+                       if (obj_desc->reference.class == ACPI_REFCLASS_TABLE) {
+                               acpi_os_printf(" Table Index: %X\n",
+                                              obj_desc->reference.value);
                        } else {
-                               acpi_os_printf(" [%s]\n",
+                               acpi_os_printf(" Target: %p [%s]\n",
+                                              obj_desc->reference.object,
                                               acpi_ut_get_type_name(((union
                                                                       acpi_operand_object
                                                                       *)
@@ -988,9 +981,9 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc,
 
        case ACPI_TYPE_LOCAL_REFERENCE:
 
-               acpi_os_printf("[Object Reference] %s",
-                              (acpi_ps_get_opcode_info
-                               (obj_desc->reference.opcode))->name);
+               acpi_os_printf("[Object Reference] Type [%s] %2.2X",
+                              acpi_ut_get_reference_name(obj_desc),
+                              obj_desc->reference.class);
                acpi_ex_dump_reference_obj(obj_desc);
                break;
 
index 731414a581a6226f1d8c53fed278123465b6253c..efb19134005951cb8adce2b7b473c8734b44b610 100644 (file)
@@ -86,10 +86,10 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc,
                /*
                 * Must be a reference to a Local or Arg
                 */
-               switch (obj_desc->reference.opcode) {
-               case AML_LOCAL_OP:
-               case AML_ARG_OP:
-               case AML_DEBUG_OP:
+               switch (obj_desc->reference.class) {
+               case ACPI_REFCLASS_LOCAL:
+               case ACPI_REFCLASS_ARG:
+               case ACPI_REFCLASS_DEBUG:
 
                        /* The referenced object is the pseudo-node for the local/arg */
 
@@ -98,8 +98,8 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc,
 
                default:
 
-                       ACPI_ERROR((AE_INFO, "Unknown Reference opcode %X",
-                                   obj_desc->reference.opcode));
+                       ACPI_ERROR((AE_INFO, "Unknown Reference Class %2.2X",
+                                   obj_desc->reference.class));
                        return_ACPI_STATUS(AE_AML_INTERNAL);
                }
                break;
@@ -127,7 +127,7 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc,
                return_ACPI_STATUS(AE_NO_MEMORY);
        }
 
-       reference_obj->reference.opcode = AML_REF_OF_OP;
+       reference_obj->reference.class = ACPI_REFCLASS_REFOF;
        reference_obj->reference.object = referenced_obj;
        *return_desc = reference_obj;
 
index 7c3bea575e02653c2960a472c4b994a48ce9574b..f622f9eac8a1a85bfe0bfb4afbed5854b5435609 100644 (file)
@@ -825,16 +825,16 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
                                 *
                                 * Must resolve/dereference the local/arg reference first
                                 */
-                               switch (operand[0]->reference.opcode) {
-                               case AML_LOCAL_OP:
-                               case AML_ARG_OP:
+                               switch (operand[0]->reference.class) {
+                               case ACPI_REFCLASS_LOCAL:
+                               case ACPI_REFCLASS_ARG:
 
                                        /* Set Operand[0] to the value of the local/arg */
 
                                        status =
                                            acpi_ds_method_data_get_value
-                                           (operand[0]->reference.opcode,
-                                            operand[0]->reference.offset,
+                                           (operand[0]->reference.class,
+                                            operand[0]->reference.value,
                                             walk_state, &temp_desc);
                                        if (ACPI_FAILURE(status)) {
                                                goto cleanup;
@@ -848,7 +848,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
                                        operand[0] = temp_desc;
                                        break;
 
-                               case AML_REF_OF_OP:
+                               case ACPI_REFCLASS_REFOF:
 
                                        /* Get the object to which the reference refers */
 
@@ -928,8 +928,8 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
                         * This must be a reference object produced by either the
                         * Index() or ref_of() operator
                         */
-                       switch (operand[0]->reference.opcode) {
-                       case AML_INDEX_OP:
+                       switch (operand[0]->reference.class) {
+                       case ACPI_REFCLASS_INDEX:
 
                                /*
                                 * The target type for the Index operator must be
@@ -965,7 +965,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
                                        return_desc->integer.value =
                                            temp_desc->buffer.
                                            pointer[operand[0]->reference.
-                                                   offset];
+                                                   value];
                                        break;
 
                                case ACPI_TYPE_PACKAGE:
@@ -985,7 +985,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
                                default:
 
                                        ACPI_ERROR((AE_INFO,
-                                                   "Unknown Index TargetType %X in obj %p",
+                                                   "Unknown Index TargetType %X in reference object %p",
                                                    operand[0]->reference.
                                                    target_type, operand[0]));
                                        status = AE_AML_OPERAND_TYPE;
@@ -993,7 +993,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
                                }
                                break;
 
-                       case AML_REF_OF_OP:
+                       case ACPI_REFCLASS_REFOF:
 
                                return_desc = operand[0]->reference.object;
 
@@ -1013,9 +1013,9 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
 
                        default:
                                ACPI_ERROR((AE_INFO,
-                                           "Unknown opcode in reference(%p) - %X",
+                                           "Unknown class in reference(%p) - %2.2X",
                                            operand[0],
-                                           operand[0]->reference.opcode));
+                                           operand[0]->reference.class));
 
                                status = AE_TYPE;
                                goto cleanup;
index 8e8bbb6ccebd541008b0f15caa2ffacbe62eaf34..368def5dffceb0ffc47be5866d640b83e18f6c53 100644 (file)
@@ -391,8 +391,8 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state)
                /* Initialize the Index reference object */
 
                index = operand[1]->integer.value;
-               return_desc->reference.offset = (u32) index;
-               return_desc->reference.opcode = AML_INDEX_OP;
+               return_desc->reference.value = (u32) index;
+               return_desc->reference.class = ACPI_REFCLASS_INDEX;
 
                /*
                 * At this point, the Source operand is a String, Buffer, or Package.
index 5596f42c9676038c329f6f3d0f473773adbfcb3f..423ad3635f3d0aa702e8d5f3652ecf0b572af954 100644 (file)
@@ -46,8 +46,6 @@
 #include <acpi/acdispat.h>
 #include <acpi/acinterp.h>
 #include <acpi/acnamesp.h>
-#include <acpi/acparser.h>
-#include <acpi/amlcode.h>
 
 #define _COMPONENT          ACPI_EXECUTER
 ACPI_MODULE_NAME("exresnte")
@@ -238,10 +236,10 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
 
        case ACPI_TYPE_LOCAL_REFERENCE:
 
-               switch (source_desc->reference.opcode) {
-               case AML_LOAD_OP:       /* This is a ddb_handle */
-               case AML_REF_OF_OP:
-               case AML_INDEX_OP:
+               switch (source_desc->reference.class) {
+               case ACPI_REFCLASS_TABLE:       /* This is a ddb_handle */
+               case ACPI_REFCLASS_REFOF:
+               case ACPI_REFCLASS_INDEX:
 
                        /* Return an additional reference to the object */
 
@@ -253,10 +251,8 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
                        /* No named references are allowed here */
 
                        ACPI_ERROR((AE_INFO,
-                                   "Unsupported Reference opcode %X (%s)",
-                                   source_desc->reference.opcode,
-                                   acpi_ps_get_opcode_name(source_desc->
-                                                           reference.opcode)));
+                                   "Unsupported Reference type %X",
+                                   source_desc->reference.class));
 
                        return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
                }
index b35f7c817acf169a244b21e052d09d26db074504..89571b92a52279258812e7cc6f93ad5024acc28b 100644 (file)
@@ -47,7 +47,6 @@
 #include <acpi/acdispat.h>
 #include <acpi/acinterp.h>
 #include <acpi/acnamesp.h>
-#include <acpi/acparser.h>
 
 #define _COMPONENT          ACPI_EXECUTER
 ACPI_MODULE_NAME("exresolv")
@@ -141,7 +140,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
        acpi_status status = AE_OK;
        union acpi_operand_object *stack_desc;
        union acpi_operand_object *obj_desc = NULL;
-       u16 opcode;
+       u8 ref_type;
 
        ACPI_FUNCTION_TRACE(ex_resolve_object_to_value);
 
@@ -152,19 +151,19 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
        switch (ACPI_GET_OBJECT_TYPE(stack_desc)) {
        case ACPI_TYPE_LOCAL_REFERENCE:
 
-               opcode = stack_desc->reference.opcode;
+               ref_type = stack_desc->reference.class;
 
-               switch (opcode) {
-               case AML_LOCAL_OP:
-               case AML_ARG_OP:
+               switch (ref_type) {
+               case ACPI_REFCLASS_LOCAL:
+               case ACPI_REFCLASS_ARG:
 
                        /*
                         * Get the local from the method's state info
                         * Note: this increments the local's object reference count
                         */
-                       status = acpi_ds_method_data_get_value(opcode,
+                       status = acpi_ds_method_data_get_value(ref_type,
                                                               stack_desc->
-                                                              reference.offset,
+                                                              reference.value,
                                                               walk_state,
                                                               &obj_desc);
                        if (ACPI_FAILURE(status)) {
@@ -173,7 +172,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
 
                        ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
                                          "[Arg/Local %X] ValueObj is %p\n",
-                                         stack_desc->reference.offset,
+                                         stack_desc->reference.value,
                                          obj_desc));
 
                        /*
@@ -184,7 +183,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
                        *stack_ptr = obj_desc;
                        break;
 
-               case AML_INDEX_OP:
+               case ACPI_REFCLASS_INDEX:
 
                        switch (stack_desc->reference.target_type) {
                        case ACPI_TYPE_BUFFER_FIELD:
@@ -239,15 +238,15 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
                        }
                        break;
 
-               case AML_REF_OF_OP:
-               case AML_DEBUG_OP:
-               case AML_LOAD_OP:
+               case ACPI_REFCLASS_REFOF:
+               case ACPI_REFCLASS_DEBUG:
+               case ACPI_REFCLASS_TABLE:
 
                        /* Just leave the object as-is, do not dereference */
 
                        break;
 
-               case AML_INT_NAMEPATH_OP:       /* Reference to a named object */
+               case ACPI_REFCLASS_NAME:        /* Reference to a named object */
 
                        /* Dereference the name */
 
@@ -273,8 +272,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
                default:
 
                        ACPI_ERROR((AE_INFO,
-                                   "Unknown Reference opcode %X (%s) in %p",
-                                   opcode, acpi_ps_get_opcode_name(opcode),
+                                   "Unknown Reference type %X in %p", ref_type,
                                    stack_desc));
                        status = AE_AML_INTERNAL;
                        break;
@@ -388,13 +386,13 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
         * traversing the list of possibly many nested references.
         */
        while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
-               switch (obj_desc->reference.opcode) {
-               case AML_REF_OF_OP:
-               case AML_INT_NAMEPATH_OP:
+               switch (obj_desc->reference.class) {
+               case ACPI_REFCLASS_REFOF:
+               case ACPI_REFCLASS_NAME:
 
                        /* Dereference the reference pointer */
 
-                       if (obj_desc->reference.opcode == AML_REF_OF_OP) {
+                       if (obj_desc->reference.class == ACPI_REFCLASS_REFOF) {
                                node = obj_desc->reference.object;
                        } else {        /* AML_INT_NAMEPATH_OP */
 
@@ -429,7 +427,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
                        }
                        break;
 
-               case AML_INDEX_OP:
+               case ACPI_REFCLASS_INDEX:
 
                        /* Get the type of this reference (index into another object) */
 
@@ -455,22 +453,22 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
                        }
                        break;
 
-               case AML_LOAD_OP:
+               case ACPI_REFCLASS_TABLE:
 
                        type = ACPI_TYPE_DDB_HANDLE;
                        goto exit;
 
-               case AML_LOCAL_OP:
-               case AML_ARG_OP:
+               case ACPI_REFCLASS_LOCAL:
+               case ACPI_REFCLASS_ARG:
 
                        if (return_desc) {
                                status =
                                    acpi_ds_method_data_get_value(obj_desc->
                                                                  reference.
-                                                                 opcode,
+                                                                 class,
                                                                  obj_desc->
                                                                  reference.
-                                                                 offset,
+                                                                 value,
                                                                  walk_state,
                                                                  &obj_desc);
                                if (ACPI_FAILURE(status)) {
@@ -481,10 +479,10 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
                                status =
                                    acpi_ds_method_data_get_node(obj_desc->
                                                                 reference.
-                                                                opcode,
+                                                                class,
                                                                 obj_desc->
                                                                 reference.
-                                                                offset,
+                                                                value,
                                                                 walk_state,
                                                                 &node);
                                if (ACPI_FAILURE(status)) {
@@ -499,7 +497,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
                        }
                        break;
 
-               case AML_DEBUG_OP:
+               case ACPI_REFCLASS_DEBUG:
 
                        /* The Debug Object is of type "DebugObject" */
 
@@ -509,8 +507,8 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
                default:
 
                        ACPI_ERROR((AE_INFO,
-                                   "Unknown Reference subtype %X",
-                                   obj_desc->reference.opcode));
+                                   "Unknown Reference Class %2.2X",
+                                   obj_desc->reference.class));
                        return_ACPI_STATUS(AE_AML_INTERNAL);
                }
        }
index 54085f16ec28360d4f252c3f8e34dc230da3cbff..0bb82593da724d62ca766a2a843827a9cf33376c 100644 (file)
@@ -225,41 +225,36 @@ acpi_ex_resolve_operands(u16 opcode,
 
                        if (object_type == (u8) ACPI_TYPE_LOCAL_REFERENCE) {
 
-                               /* Decode the Reference */
+                               /* Validate the Reference */
 
-                               op_info = acpi_ps_get_opcode_info(opcode);
-                               if (op_info->class == AML_CLASS_UNKNOWN) {
-                                       return_ACPI_STATUS(AE_AML_BAD_OPCODE);
-                               }
+                               switch (obj_desc->reference.class) {
+                               case ACPI_REFCLASS_DEBUG:
 
-                               switch (obj_desc->reference.opcode) {
-                               case AML_DEBUG_OP:
                                        target_op = AML_DEBUG_OP;
 
                                        /*lint -fallthrough */
 
-                               case AML_INDEX_OP:
-                               case AML_REF_OF_OP:
-                               case AML_ARG_OP:
-                               case AML_LOCAL_OP:
-                               case AML_LOAD_OP:       /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */
-                               case AML_INT_NAMEPATH_OP:       /* Reference to a named object */
-
-                                       ACPI_DEBUG_ONLY_MEMBERS(ACPI_DEBUG_PRINT
-                                                               ((ACPI_DB_EXEC,
-                                                                 "Operand is a Reference, RefOpcode [%s]\n",
-                                                                 (acpi_ps_get_opcode_info
-                                                                  (obj_desc->
-                                                                   reference.
-                                                                   opcode))->
-                                                                 name)));
+                               case ACPI_REFCLASS_ARG:
+                               case ACPI_REFCLASS_LOCAL:
+                               case ACPI_REFCLASS_INDEX:
+                               case ACPI_REFCLASS_REFOF:
+                               case ACPI_REFCLASS_TABLE:       /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */
+                               case ACPI_REFCLASS_NAME:        /* Reference to a named object */
+
+                                       ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+                                                         "Operand is a Reference, Class [%s] %2.2X\n",
+                                                         acpi_ut_get_reference_name
+                                                         (obj_desc),
+                                                         obj_desc->reference.
+                                                         class));
                                        break;
 
                                default:
+
                                        ACPI_ERROR((AE_INFO,
-                                                   "Operand is a Reference, Unknown Reference Opcode: %X",
-                                                   obj_desc->reference.
-                                                   opcode));
+                                                   "Unknown Reference Class %2.2X in %p",
+                                                   obj_desc->reference.class,
+                                                   obj_desc));
 
                                        return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
                                }
@@ -270,8 +265,7 @@ acpi_ex_resolve_operands(u16 opcode,
 
                        /* Invalid descriptor */
 
-                       ACPI_ERROR((AE_INFO,
-                                   "Invalid descriptor %p [%s]",
+                       ACPI_ERROR((AE_INFO, "Invalid descriptor %p [%s]",
                                    obj_desc,
                                    acpi_ut_get_descriptor_name(obj_desc)));
 
@@ -343,7 +337,7 @@ acpi_ex_resolve_operands(u16 opcode,
                        if ((opcode == AML_STORE_OP) &&
                            (ACPI_GET_OBJECT_TYPE(*stack_ptr) ==
                             ACPI_TYPE_LOCAL_REFERENCE)
-                           && ((*stack_ptr)->reference.opcode == AML_INDEX_OP)) {
+                           && ((*stack_ptr)->reference.class == ACPI_REFCLASS_INDEX)) {
                                goto next_operand;
                        }
                        break;
index 38b55e352495df4ed3808ffe713995dafe05e8db..3318df4cbd989191fc46de95e3cbd209ccf0f525 100644 (file)
@@ -47,7 +47,6 @@
 #include <acpi/acinterp.h>
 #include <acpi/amlcode.h>
 #include <acpi/acnamesp.h>
-#include <acpi/acparser.h>
 
 #define _COMPONENT          ACPI_EXECUTER
 ACPI_MODULE_NAME("exstore")
@@ -179,22 +178,26 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
 
        case ACPI_TYPE_LOCAL_REFERENCE:
 
-               if (source_desc->reference.opcode == AML_INDEX_OP) {
-                       ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
-                                             "[%s, 0x%X]\n",
-                                             acpi_ps_get_opcode_name
-                                             (source_desc->reference.opcode),
-                                             source_desc->reference.offset));
-               } else {
-                       ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[%s]",
-                                             acpi_ps_get_opcode_name
-                                             (source_desc->reference.opcode)));
-               }
+               ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[%s] ",
+                                     acpi_ut_get_reference_name(source_desc)));
+
+               /* Decode the reference */
+
+               switch (source_desc->reference.class) {
+               case ACPI_REFCLASS_INDEX:
+
+                       ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "0x%X\n",
+                                             source_desc->reference.value));
+                       break;
+
+               case ACPI_REFCLASS_TABLE:
 
-               if (source_desc->reference.opcode == AML_LOAD_OP) {     /* Load and load_table */
                        ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
-                                             " Table OwnerId %p\n",
-                                             source_desc->reference.object));
+                                             "Table Index 0x%X\n",
+                                             source_desc->reference.value));
+                       break;
+
+               default:
                        break;
                }
 
@@ -347,15 +350,15 @@ acpi_ex_store(union acpi_operand_object *source_desc,
        }
 
        /*
-        * Examine the Reference opcode.  These cases are handled:
+        * Examine the Reference class. These cases are handled:
         *
         * 1) Store to Name (Change the object associated with a name)
         * 2) Store to an indexed area of a Buffer or Package
         * 3) Store to a Method Local or Arg
         * 4) Store to the debug object
         */
-       switch (ref_desc->reference.opcode) {
-       case AML_REF_OF_OP:
+       switch (ref_desc->reference.class) {
+       case ACPI_REFCLASS_REFOF:
 
                /* Storing an object into a Name "container" */
 
@@ -365,7 +368,7 @@ acpi_ex_store(union acpi_operand_object *source_desc,
                                                      ACPI_IMPLICIT_CONVERSION);
                break;
 
-       case AML_INDEX_OP:
+       case ACPI_REFCLASS_INDEX:
 
                /* Storing to an Index (pointer into a packager or buffer) */
 
@@ -374,18 +377,18 @@ acpi_ex_store(union acpi_operand_object *source_desc,
                                                  walk_state);
                break;
 
-       case AML_LOCAL_OP:
-       case AML_ARG_OP:
+       case ACPI_REFCLASS_LOCAL:
+       case ACPI_REFCLASS_ARG:
 
                /* Store to a method local/arg  */
 
                status =
-                   acpi_ds_store_object_to_local(ref_desc->reference.opcode,
-                                                 ref_desc->reference.offset,
+                   acpi_ds_store_object_to_local(ref_desc->reference.class,
+                                                 ref_desc->reference.value,
                                                  source_desc, walk_state);
                break;
 
-       case AML_DEBUG_OP:
+       case ACPI_REFCLASS_DEBUG:
 
                /*
                 * Storing to the Debug object causes the value stored to be
@@ -401,9 +404,9 @@ acpi_ex_store(union acpi_operand_object *source_desc,
 
        default:
 
-               ACPI_ERROR((AE_INFO, "Unknown Reference opcode %X",
-                           ref_desc->reference.opcode));
-               ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_ERROR);
+               ACPI_ERROR((AE_INFO, "Unknown Reference Class %2.2X",
+                           ref_desc->reference.class));
+               ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_INFO);
 
                status = AE_AML_INTERNAL;
                break;
@@ -458,7 +461,7 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
 
                if (ACPI_GET_OBJECT_TYPE(source_desc) ==
                    ACPI_TYPE_LOCAL_REFERENCE
-                   && source_desc->reference.opcode == AML_LOAD_OP) {
+                   && source_desc->reference.class == ACPI_REFCLASS_TABLE) {
 
                        /* This is a DDBHandle, just add a reference to it */
 
@@ -553,7 +556,7 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
 
                /* Store the source value into the target buffer byte */
 
-               obj_desc->buffer.pointer[index_desc->reference.offset] = value;
+               obj_desc->buffer.pointer[index_desc->reference.value] = value;
                break;
 
        default:
index a6d2168b81f99f9301f091ba3cf6ba4a0eb48b1d..eef61a00803edf560bf2917e1cf66d7c8587e9cc 100644 (file)
@@ -121,7 +121,8 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
                    (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) &&
                    !((ACPI_GET_OBJECT_TYPE(source_desc) ==
                       ACPI_TYPE_LOCAL_REFERENCE)
-                     && (source_desc->reference.opcode == AML_LOAD_OP))) {
+                     && (source_desc->reference.class ==
+                         ACPI_REFCLASS_TABLE))) {
 
                        /* Conversion successful but still not a valid type */
 
index 2655bc1b4eebc7cbb02a16afc715e703dd0e3499..60d54d1f6b195dc282528447682deb7cb3259d1d 100644 (file)
@@ -265,7 +265,7 @@ static int acpi_fan_add(struct acpi_device *device)
 
        dev_info(&device->dev, "registered as cooling_device%d\n", cdev->id);
 
-       acpi_driver_data(device) = cdev;
+       device->driver_data = cdev;
        result = sysfs_create_link(&device->dev.kobj,
                                   &cdev->device.kobj,
                                   "thermal_cooling");
@@ -327,8 +327,8 @@ static int acpi_fan_resume(struct acpi_device *device)
 
        result = acpi_bus_get_power(device->handle, &power_state);
        if (result) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                                 "Error reading fan power state\n"));
+               printk(KERN_ERR PREFIX
+                                 "Error reading fan power state\n");
                return result;
        }
 
index dba3cfbe8cba9e3235970e7b972e7f54da24c4af..25dccdf179b9e4814ca52669f268f4409b34ce6b 100644 (file)
@@ -78,19 +78,17 @@ acpi_set_firmware_waking_vector(acpi_physical_address physical_address)
                return_ACPI_STATUS(status);
        }
 
-       /* Set the vector */
+       /*
+        * According to the ACPI specification 2.0c and later, the 64-bit
+        * waking vector should be cleared and the 32-bit waking vector should
+        * be used, unless we want the wake-up code to be called by the BIOS in
+        * Protected Mode.  Some systems (for example HP dv5-1004nr) are known
+        * to fail to resume if the 64-bit vector is used.
+        */
+       if (facs->version >= 1)
+               facs->xfirmware_waking_vector = 0;
 
-       if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) {
-               /*
-                * ACPI 1.0 FACS or short table or optional X_ field is zero
-                */
-               facs->firmware_waking_vector = (u32) physical_address;
-       } else {
-               /*
-                * ACPI 2.0 FACS with valid X_ field
-                */
-               facs->xfirmware_waking_vector = physical_address;
-       }
+       facs->firmware_waking_vector = (u32)physical_address;
 
        return_ACPI_STATUS(AE_OK);
 }
@@ -134,20 +132,7 @@ acpi_get_firmware_waking_vector(acpi_physical_address * physical_address)
        }
 
        /* Get the vector */
-
-       if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) {
-               /*
-                * ACPI 1.0 FACS or short table or optional X_ field is zero
-                */
-               *physical_address =
-                   (acpi_physical_address) facs->firmware_waking_vector;
-       } else {
-               /*
-                * ACPI 2.0 FACS with valid X_ field
-                */
-               *physical_address =
-                   (acpi_physical_address) facs->xfirmware_waking_vector;
-       }
+       *physical_address = (acpi_physical_address)facs->firmware_waking_vector;
 
        return_ACPI_STATUS(AE_OK);
 }
@@ -627,6 +612,13 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
        }
        /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
 
+       /*
+        * Some BIOSes assume that WAK_STS will be cleared on resume and use
+        * it to determine whether the system is rebooting or resuming. Clear
+        * it for compatibility.
+        */
+       acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
+
        acpi_gbl_system_awake_and_running = TRUE;
 
        /* Enable power button */
index 3f63d36406966cda6a0821fe67fc741da8dd302e..371a2daf837f1c7806fb8b2ab4afb962bbcbed62 100644 (file)
@@ -5,7 +5,7 @@
 obj-y := nsaccess.o  nsload.o    nssearch.o  nsxfeval.o \
         nsalloc.o   nseval.o    nsnames.o   nsutils.o   nsxfname.o \
         nsdump.o    nsinit.o    nsobject.o  nswalk.o    nsxfobj.o  \
-        nsparse.o
+        nsparse.o   nspredef.o
 
 obj-$(ACPI_FUTURE_USAGE) += nsdumpdv.o
 
index 0ab22004728a9aae08f7697cb8230456177d0c9f..cc0ae39440e4358838626c73c63d43ccc8e15d01 100644 (file)
@@ -43,7 +43,6 @@
 
 #include <acpi/acpi.h>
 #include <acpi/acnamesp.h>
-#include <acpi/acparser.h>
 
 #define _COMPONENT          ACPI_NAMESPACE
 ACPI_MODULE_NAME("nsdump")
@@ -334,9 +333,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
                case ACPI_TYPE_LOCAL_REFERENCE:
 
                        acpi_os_printf("[%s]\n",
-                                      acpi_ps_get_opcode_name(obj_desc->
-                                                              reference.
-                                                              opcode));
+                                      acpi_ut_get_reference_name(obj_desc));
                        break;
 
                case ACPI_TYPE_BUFFER_FIELD:
index d369164e00b0bc16d594e8617e93be3ada99d95f..4cdf03ac2b467803189d97e8c5b7d11feabc073e 100644 (file)
@@ -78,6 +78,7 @@ ACPI_MODULE_NAME("nseval")
 acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
 {
        acpi_status status;
+       struct acpi_namespace_node *node;
 
        ACPI_FUNCTION_TRACE(ns_evaluate);
 
@@ -117,6 +118,8 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
                          info->resolved_node,
                          acpi_ns_get_attached_object(info->resolved_node)));
 
+       node = info->resolved_node;
+
        /*
         * Two major cases here:
         *
@@ -148,21 +151,22 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
                                info->param_count++;
                }
 
-               /* Error if too few arguments were passed in */
+               /*
+                * Warning if too few or too many arguments have been passed by the
+                * caller. We don't want to abort here with an error because an
+                * incorrect number of arguments may not cause the method to fail.
+                * However, the method will fail if there are too few arguments passed
+                * and the method attempts to use one of the missing ones.
+                */
 
                if (info->param_count < info->obj_desc->method.param_count) {
-                       ACPI_ERROR((AE_INFO,
+                       ACPI_WARNING((AE_INFO,
                                    "Insufficient arguments - "
                                    "method [%4.4s] needs %d, found %d",
                                    acpi_ut_get_node_name(info->resolved_node),
                                    info->obj_desc->method.param_count,
                                    info->param_count));
-                       return_ACPI_STATUS(AE_MISSING_ARGUMENTS);
-               }
-
-               /* Just a warning if too many arguments */
-
-               else if (info->param_count >
+               } else if (info->param_count >
                                info->obj_desc->method.param_count) {
                        ACPI_WARNING((AE_INFO,
                                      "Excess arguments - "
@@ -195,7 +199,28 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
        } else {
                /*
                 * 2) Object is not a method, return its current value
+                *
+                * Disallow certain object types. For these, "evaluation" is undefined.
                 */
+               switch (info->resolved_node->type) {
+               case ACPI_TYPE_DEVICE:
+               case ACPI_TYPE_EVENT:
+               case ACPI_TYPE_MUTEX:
+               case ACPI_TYPE_REGION:
+               case ACPI_TYPE_THERMAL:
+               case ACPI_TYPE_LOCAL_SCOPE:
+
+                       ACPI_ERROR((AE_INFO,
+                                   "[%4.4s] Evaluation of object type [%s] is not supported",
+                                   info->resolved_node->name.ascii,
+                                   acpi_ut_get_type_name(info->resolved_node->
+                                                         type)));
+
+                       return_ACPI_STATUS(AE_TYPE);
+
+               default:
+                       break;
+               }
 
                /*
                 * Objects require additional resolution steps (e.g., the Node may be
@@ -239,9 +264,35 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
                }
        }
 
-       /*
-        * Check if there is a return value that must be dealt with
-        */
+       /* Validation of return values for ACPI-predefined methods and objects */
+
+       if ((status == AE_OK) || (status == AE_CTRL_RETURN_VALUE)) {
+               /*
+                * If this is the first evaluation, check the return value. This
+                * ensures that any warnings will only be emitted during the very
+                * first evaluation of the object.
+                */
+               if (!(node->flags & ANOBJ_EVALUATED)) {
+                       /*
+                        * Check for a predefined ACPI name. If found, validate the
+                        * returned object.
+                        *
+                        * Note: Ignore return status for now, emit warnings if there are
+                        * problems with the returned object. May change later to abort
+                        * the method on invalid return object.
+                        */
+                       (void)acpi_ns_check_predefined_names(node,
+                                                            info->
+                                                            return_object);
+               }
+
+               /* Mark the node as having been evaluated */
+
+               node->flags |= ANOBJ_EVALUATED;
+       }
+
+       /* Check if there is a return value that must be dealt with */
+
        if (status == AE_CTRL_RETURN_VALUE) {
 
                /* If caller does not want the return value, delete it */
index bd5773878009eeb8b9ce38863465c92da6a0d660..42a39a7c96e913a519e6b1bf7b5a79d152dd4a4d 100644 (file)
@@ -115,7 +115,6 @@ acpi_ns_build_external_path(struct acpi_namespace_node *node,
        return (AE_OK);
 }
 
-#ifdef ACPI_DEBUG_OUTPUT
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_get_external_pathname
@@ -142,7 +141,7 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
 
        size = acpi_ns_get_pathname_length(node);
        if (!size) {
-               return (NULL);
+               return_PTR(NULL);
        }
 
        /* Allocate a buffer to be returned to caller */
@@ -157,12 +156,12 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
 
        status = acpi_ns_build_external_path(node, size, name_buffer);
        if (ACPI_FAILURE(status)) {
-               return (NULL);
+               ACPI_FREE(name_buffer);
+               return_PTR(NULL);
        }
 
        return_PTR(name_buffer);
 }
-#endif
 
 /*******************************************************************************
  *
diff --git a/drivers/acpi/namespace/nspredef.c b/drivers/acpi/namespace/nspredef.c
new file mode 100644 (file)
index 0000000..0f17cf0
--- /dev/null
@@ -0,0 +1,900 @@
+/******************************************************************************
+ *
+ * Module Name: nspredef - Validation of ACPI predefined methods and objects
+ *              $Revision: 1.1 $
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2008, Intel Corp.
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * 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 MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acpredef.h>
+
+#define _COMPONENT          ACPI_NAMESPACE
+ACPI_MODULE_NAME("nspredef")
+
+/*******************************************************************************
+ *
+ * This module validates predefined ACPI objects that appear in the namespace,
+ * at the time they are evaluated (via acpi_evaluate_object). The purpose of this
+ * validation is to detect problems with BIOS-exposed predefined ACPI objects
+ * before the results are returned to the ACPI-related drivers.
+ *
+ * There are several areas that are validated:
+ *
+ *  1) The number of input arguments as defined by the method/object in the
+ *      ASL is validated against the ACPI specification.
+ *  2) The type of the return object (if any) is validated against the ACPI
+ *      specification.
+ *  3) For returned package objects, the count of package elements is
+ *      validated, as well as the type of each package element. Nested
+ *      packages are supported.
+ *
+ * For any problems found, a warning message is issued.
+ *
+ ******************************************************************************/
+/* Local prototypes */
+static acpi_status
+acpi_ns_check_package(char *pathname,
+                     union acpi_operand_object *return_object,
+                     const union acpi_predefined_info *predefined);
+
+static acpi_status
+acpi_ns_check_package_elements(char *pathname,
+                              union acpi_operand_object **elements,
+                              u8 type1, u32 count1, u8 type2, u32 count2);
+
+static acpi_status
+acpi_ns_check_object_type(char *pathname,
+                         union acpi_operand_object *return_object,
+                         u32 expected_btypes, u32 package_index);
+
+static acpi_status
+acpi_ns_check_reference(char *pathname,
+                       union acpi_operand_object *return_object);
+
+/*
+ * Names for the types that can be returned by the predefined objects.
+ * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
+ */
+static const char *acpi_rtype_names[] = {
+       "/Integer",
+       "/String",
+       "/Buffer",
+       "/Package",
+       "/Reference",
+};
+
+#define ACPI_NOT_PACKAGE    ACPI_UINT32_MAX
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_predefined_names
+ *
+ * PARAMETERS:  Node            - Namespace node for the method/object
+ *              return_object   - Object returned from the evaluation of this
+ *                                method/object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check an ACPI name for a match in the predefined name list.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
+                              union acpi_operand_object *return_object)
+{
+       acpi_status status = AE_OK;
+       const union acpi_predefined_info *predefined;
+       char *pathname;
+
+       /* Match the name for this method/object against the predefined list */
+
+       predefined = acpi_ns_check_for_predefined_name(node);
+       if (!predefined) {
+
+               /* Name was not one of the predefined names */
+
+               return (AE_OK);
+       }
+
+       /* Get the full pathname to the object, for use in error messages */
+
+       pathname = acpi_ns_get_external_pathname(node);
+       if (!pathname) {
+               pathname = ACPI_CAST_PTR(char, predefined->info.name);
+       }
+
+       /*
+        * Check that the parameter count for this method is in accordance
+        * with the ACPI specification.
+        */
+       acpi_ns_check_parameter_count(pathname, node, predefined);
+
+       /*
+        * If there is no return value, check if we require a return value for
+        * this predefined name. Either one return value is expected, or none,
+        * for both methods and other objects.
+        *
+        * Exit now if there is no return object. Warning if one was expected.
+        */
+       if (!return_object) {
+               if ((predefined->info.expected_btypes) &&
+                   (!(predefined->info.expected_btypes & ACPI_RTYPE_NONE))) {
+                       ACPI_ERROR((AE_INFO,
+                                   "%s: Missing expected return value",
+                                   pathname));
+
+                       status = AE_AML_NO_RETURN_VALUE;
+               }
+               goto exit;
+       }
+
+       /*
+        * We have a return value, but if one wasn't expected, just exit, this is
+        * not a problem
+        *
+        * For example, if "Implicit return value" is enabled, methods will
+        * always return a value
+        */
+       if (!predefined->info.expected_btypes) {
+               goto exit;
+       }
+
+       /*
+        * Check that the type of the return object is what is expected for
+        * this predefined name
+        */
+       status = acpi_ns_check_object_type(pathname, return_object,
+                                          predefined->info.expected_btypes,
+                                          ACPI_NOT_PACKAGE);
+       if (ACPI_FAILURE(status)) {
+               goto exit;
+       }
+
+       /* For returned Package objects, check the type of all sub-objects */
+
+       if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_PACKAGE) {
+               status =
+                   acpi_ns_check_package(pathname, return_object, predefined);
+       }
+
+      exit:
+       if (pathname) {
+               ACPI_FREE(pathname);
+       }
+
+       return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_parameter_count
+ *
+ * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
+ *              Node            - Namespace node for the method/object
+ *              Predefined      - Pointer to entry in predefined name table
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a
+ *              predefined name is what is expected (i.e., what is defined in
+ *              the ACPI specification for this predefined name.)
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_check_parameter_count(char *pathname,
+                             struct acpi_namespace_node *node,
+                             const union acpi_predefined_info *predefined)
+{
+       u32 param_count;
+       u32 required_params_current;
+       u32 required_params_old;
+
+       /*
+        * Check that the ASL-defined parameter count is what is expected for
+        * this predefined name.
+        *
+        * Methods have 0-7 parameters. All other types have zero.
+        */
+       param_count = 0;
+       if (node->type == ACPI_TYPE_METHOD) {
+               param_count = node->object->method.param_count;
+       }
+
+       /* Validate parameter count - allow two different legal counts (_SCP) */
+
+       required_params_current = predefined->info.param_count & 0x0F;
+       required_params_old = predefined->info.param_count >> 4;
+
+       if ((param_count != required_params_current) &&
+           (param_count != required_params_old)) {
+               ACPI_WARNING((AE_INFO,
+                             "%s: Parameter count mismatch - ASL declared %d, expected %d",
+                             pathname, param_count, required_params_current));
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_for_predefined_name
+ *
+ * PARAMETERS:  Node            - Namespace node for the method/object
+ *
+ * RETURN:      Pointer to entry in predefined table. NULL indicates not found.
+ *
+ * DESCRIPTION: Check an object name against the predefined object list.
+ *
+ ******************************************************************************/
+
+const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct
+                                                                   acpi_namespace_node
+                                                                   *node)
+{
+       const union acpi_predefined_info *this_name;
+
+       /* Quick check for a predefined name, first character must be underscore */
+
+       if (node->name.ascii[0] != '_') {
+               return (NULL);
+       }
+
+       /* Search info table for a predefined method/object name */
+
+       this_name = predefined_names;
+       while (this_name->info.name[0]) {
+               if (ACPI_COMPARE_NAME(node->name.ascii, this_name->info.name)) {
+
+                       /* Return pointer to this table entry */
+
+                       return (this_name);
+               }
+
+               /*
+                * Skip next entry in the table if this name returns a Package
+                * (next entry contains the package info)
+                */
+               if (this_name->info.expected_btypes & ACPI_RTYPE_PACKAGE) {
+                       this_name++;
+               }
+
+               this_name++;
+       }
+
+       return (NULL);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_package
+ *
+ * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
+ *              return_object   - Object returned from the evaluation of a
+ *                                method or object
+ *              Predefined      - Pointer to entry in predefined name table
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check a returned package object for the correct count and
+ *              correct type of all sub-objects.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ns_check_package(char *pathname,
+                     union acpi_operand_object *return_object,
+                     const union acpi_predefined_info *predefined)
+{
+       const union acpi_predefined_info *package;
+       union acpi_operand_object *sub_package;
+       union acpi_operand_object **elements;
+       union acpi_operand_object **sub_elements;
+       acpi_status status;
+       u32 expected_count;
+       u32 count;
+       u32 i;
+       u32 j;
+
+       ACPI_FUNCTION_NAME(ns_check_package);
+
+       /* The package info for this name is in the next table entry */
+
+       package = predefined + 1;
+
+       ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+                         "%s Validating return Package of Type %X, Count %X\n",
+                         pathname, package->ret_info.type,
+                         return_object->package.count));
+
+       /* Extract package count and elements array */
+
+       elements = return_object->package.elements;
+       count = return_object->package.count;
+
+       /* The package must have at least one element, else invalid */
+
+       if (!count) {
+               ACPI_WARNING((AE_INFO,
+                             "%s: Return Package has no elements (empty)",
+                             pathname));
+
+               return (AE_AML_OPERAND_VALUE);
+       }
+
+       /*
+        * Decode the type of the expected package contents
+        *
+        * PTYPE1 packages contain no subpackages
+        * PTYPE2 packages contain sub-packages
+        */
+       switch (package->ret_info.type) {
+       case ACPI_PTYPE1_FIXED:
+
+               /*
+                * The package count is fixed and there are no sub-packages
+                *
+                * If package is too small, exit.
+                * If package is larger than expected, issue warning but continue
+                */
+               expected_count =
+                   package->ret_info.count1 + package->ret_info.count2;
+               if (count < expected_count) {
+                       goto package_too_small;
+               } else if (count > expected_count) {
+                       ACPI_WARNING((AE_INFO,
+                                     "%s: Return Package is larger than needed - "
+                                     "found %u, expected %u", pathname, count,
+                                     expected_count));
+               }
+
+               /* Validate all elements of the returned package */
+
+               status = acpi_ns_check_package_elements(pathname, elements,
+                                                       package->ret_info.
+                                                       object_type1,
+                                                       package->ret_info.
+                                                       count1,
+                                                       package->ret_info.
+                                                       object_type2,
+                                                       package->ret_info.
+                                                       count2);
+               if (ACPI_FAILURE(status)) {
+                       return (status);
+               }
+               break;
+
+       case ACPI_PTYPE1_VAR:
+
+               /*
+                * The package count is variable, there are no sub-packages, and all
+                * elements must be of the same type
+                */
+               for (i = 0; i < count; i++) {
+                       status = acpi_ns_check_object_type(pathname, *elements,
+                                                          package->ret_info.
+                                                          object_type1, i);
+                       if (ACPI_FAILURE(status)) {
+                               return (status);
+                       }
+                       elements++;
+               }
+               break;
+
+       case ACPI_PTYPE1_OPTION:
+
+               /*
+                * The package count is variable, there are no sub-packages. There are
+                * a fixed number of required elements, and a variable number of
+                * optional elements.
+                *
+                * Check if package is at least as large as the minimum required
+                */
+               expected_count = package->ret_info3.count;
+               if (count < expected_count) {
+                       goto package_too_small;
+               }
+
+               /* Variable number of sub-objects */
+
+               for (i = 0; i < count; i++) {
+                       if (i < package->ret_info3.count) {
+
+                               /* These are the required package elements (0, 1, or 2) */
+
+                               status =
+                                   acpi_ns_check_object_type(pathname,
+                                                             *elements,
+                                                             package->
+                                                             ret_info3.
+                                                             object_type[i],
+                                                             i);
+                               if (ACPI_FAILURE(status)) {
+                                       return (status);
+                               }
+                       } else {
+                               /* These are the optional package elements */
+
+                               status =
+                                   acpi_ns_check_object_type(pathname,
+                                                             *elements,
+                                                             package->
+                                                             ret_info3.
+                                                             tail_object_type,
+                                                             i);
+                               if (ACPI_FAILURE(status)) {
+                                       return (status);
+                               }
+                       }
+                       elements++;
+               }
+               break;
+
+       case ACPI_PTYPE2_PKG_COUNT:
+
+               /* First element is the (Integer) count of sub-packages to follow */
+
+               status = acpi_ns_check_object_type(pathname, *elements,
+                                                  ACPI_RTYPE_INTEGER, 0);
+               if (ACPI_FAILURE(status)) {
+                       return (status);
+               }
+
+               /*
+                * Count cannot be larger than the parent package length, but allow it
+                * to be smaller. The >= accounts for the Integer above.
+                */
+               expected_count = (u32) (*elements)->integer.value;
+               if (expected_count >= count) {
+                       goto package_too_small;
+               }
+
+               count = expected_count;
+               elements++;
+
+               /* Now we can walk the sub-packages */
+
+               /*lint -fallthrough */
+
+       case ACPI_PTYPE2:
+       case ACPI_PTYPE2_FIXED:
+       case ACPI_PTYPE2_MIN:
+       case ACPI_PTYPE2_COUNT:
+
+               /*
+                * These types all return a single package that consists of a variable
+                * number of sub-packages
+                */
+               for (i = 0; i < count; i++) {
+                       sub_package = *elements;
+                       sub_elements = sub_package->package.elements;
+
+                       /* Each sub-object must be of type Package */
+
+                       status =
+                           acpi_ns_check_object_type(pathname, sub_package,
+                                                     ACPI_RTYPE_PACKAGE, i);
+                       if (ACPI_FAILURE(status)) {
+                               return (status);
+                       }
+
+                       /* Examine the different types of sub-packages */
+
+                       switch (package->ret_info.type) {
+                       case ACPI_PTYPE2:
+                       case ACPI_PTYPE2_PKG_COUNT:
+
+                               /* Each subpackage has a fixed number of elements */
+
+                               expected_count =
+                                   package->ret_info.count1 +
+                                   package->ret_info.count2;
+                               if (sub_package->package.count !=
+                                   expected_count) {
+                                       count = sub_package->package.count;
+                                       goto package_too_small;
+                               }
+
+                               status =
+                                   acpi_ns_check_package_elements(pathname,
+                                                                  sub_elements,
+                                                                  package->
+                                                                  ret_info.
+                                                                  object_type1,
+                                                                  package->
+                                                                  ret_info.
+                                                                  count1,
+                                                                  package->
+                                                                  ret_info.
+                                                                  object_type2,
+                                                                  package->
+                                                                  ret_info.
+                                                                  count2);
+                               if (ACPI_FAILURE(status)) {
+                                       return (status);
+                               }
+                               break;
+
+                       case ACPI_PTYPE2_FIXED:
+
+                               /* Each sub-package has a fixed length */
+
+                               expected_count = package->ret_info2.count;
+                               if (sub_package->package.count < expected_count) {
+                                       count = sub_package->package.count;
+                                       goto package_too_small;
+                               }
+
+                               /* Check the type of each sub-package element */
+
+                               for (j = 0; j < expected_count; j++) {
+                                       status =
+                                           acpi_ns_check_object_type(pathname,
+                                                                     sub_elements
+                                                                     [j],
+                                                                     package->
+                                                                     ret_info2.
+                                                                     object_type
+                                                                     [j], j);
+                                       if (ACPI_FAILURE(status)) {
+                                               return (status);
+                                       }
+                               }
+                               break;
+
+                       case ACPI_PTYPE2_MIN:
+
+                               /* Each sub-package has a variable but minimum length */
+
+                               expected_count = package->ret_info.count1;
+                               if (sub_package->package.count < expected_count) {
+                                       count = sub_package->package.count;
+                                       goto package_too_small;
+                               }
+
+                               /* Check the type of each sub-package element */
+
+                               status =
+                                   acpi_ns_check_package_elements(pathname,
+                                                                  sub_elements,
+                                                                  package->
+                                                                  ret_info.
+                                                                  object_type1,
+                                                                  sub_package->
+                                                                  package.
+                                                                  count, 0, 0);
+                               if (ACPI_FAILURE(status)) {
+                                       return (status);
+                               }
+                               break;
+
+                       case ACPI_PTYPE2_COUNT:
+
+                               /* First element is the (Integer) count of elements to follow */
+
+                               status =
+                                   acpi_ns_check_object_type(pathname,
+                                                             *sub_elements,
+                                                             ACPI_RTYPE_INTEGER,
+                                                             0);
+                               if (ACPI_FAILURE(status)) {
+                                       return (status);
+                               }
+
+                               /* Make sure package is large enough for the Count */
+
+                               expected_count =
+                                   (u32) (*sub_elements)->integer.value;
+                               if (sub_package->package.count < expected_count) {
+                                       count = sub_package->package.count;
+                                       goto package_too_small;
+                               }
+
+                               /* Check the type of each sub-package element */
+
+                               status =
+                                   acpi_ns_check_package_elements(pathname,
+                                                                  (sub_elements
+                                                                   + 1),
+                                                                  package->
+                                                                  ret_info.
+                                                                  object_type1,
+                                                                  (expected_count
+                                                                   - 1), 0, 0);
+                               if (ACPI_FAILURE(status)) {
+                                       return (status);
+                               }
+                               break;
+
+                       default:
+                               break;
+                       }
+
+                       elements++;
+               }
+               break;
+
+       default:
+
+               /* Should not get here if predefined info table is correct */
+
+               ACPI_WARNING((AE_INFO,
+                             "%s: Invalid internal return type in table entry: %X",
+                             pathname, package->ret_info.type));
+
+               return (AE_AML_INTERNAL);
+       }
+
+       return (AE_OK);
+
+      package_too_small:
+
+       /* Error exit for the case with an incorrect package count */
+
+       ACPI_WARNING((AE_INFO, "%s: Return Package is too small - "
+                     "found %u, expected %u", pathname, count,
+                     expected_count));
+
+       return (AE_AML_OPERAND_VALUE);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_package_elements
+ *
+ * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
+ *              Elements        - Pointer to the package elements array
+ *              Type1           - Object type for first group
+ *              Count1          - Count for first group
+ *              Type2           - Object type for second group
+ *              Count2          - Count for second group
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check that all elements of a package are of the correct object
+ *              type. Supports up to two groups of different object types.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ns_check_package_elements(char *pathname,
+                              union acpi_operand_object **elements,
+                              u8 type1, u32 count1, u8 type2, u32 count2)
+{
+       union acpi_operand_object **this_element = elements;
+       acpi_status status;
+       u32 i;
+
+       /*
+        * Up to two groups of package elements are supported by the data
+        * structure. All elements in each group must be of the same type.
+        * The second group can have a count of zero.
+        */
+       for (i = 0; i < count1; i++) {
+               status = acpi_ns_check_object_type(pathname, *this_element,
+                                                  type1, i);
+               if (ACPI_FAILURE(status)) {
+                       return (status);
+               }
+               this_element++;
+       }
+
+       for (i = 0; i < count2; i++) {
+               status = acpi_ns_check_object_type(pathname, *this_element,
+                                                  type2, (i + count1));
+               if (ACPI_FAILURE(status)) {
+                       return (status);
+               }
+               this_element++;
+       }
+
+       return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_object_type
+ *
+ * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
+ *              return_object   - Object return from the execution of this
+ *                                method/object
+ *              expected_btypes - Bitmap of expected return type(s)
+ *              package_index   - Index of object within parent package (if
+ *                                applicable - ACPI_NOT_PACKAGE otherwise)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check the type of the return object against the expected object
+ *              type(s). Use of Btype allows multiple expected object types.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ns_check_object_type(char *pathname,
+                         union acpi_operand_object *return_object,
+                         u32 expected_btypes, u32 package_index)
+{
+       acpi_status status = AE_OK;
+       u32 return_btype;
+       char type_buffer[48];   /* Room for 5 types */
+       u32 this_rtype;
+       u32 i;
+       u32 j;
+
+       /*
+        * If we get a NULL return_object here, it is a NULL package element,
+        * and this is always an error.
+        */
+       if (!return_object) {
+               goto type_error_exit;
+       }
+
+       /* A Namespace node should not get here, but make sure */
+
+       if (ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) {
+               ACPI_WARNING((AE_INFO,
+                             "%s: Invalid return type - Found a Namespace node [%4.4s] type %s",
+                             pathname, return_object->node.name.ascii,
+                             acpi_ut_get_type_name(return_object->node.type)));
+               return (AE_AML_OPERAND_TYPE);
+       }
+
+       /*
+        * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type.
+        * The bitmapped type allows multiple possible return types.
+        *
+        * Note, the cases below must handle all of the possible types returned
+        * from all of the predefined names (including elements of returned
+        * packages)
+        */
+       switch (ACPI_GET_OBJECT_TYPE(return_object)) {
+       case ACPI_TYPE_INTEGER:
+               return_btype = ACPI_RTYPE_INTEGER;
+               break;
+
+       case ACPI_TYPE_BUFFER:
+               return_btype = ACPI_RTYPE_BUFFER;
+               break;
+
+       case ACPI_TYPE_STRING:
+               return_btype = ACPI_RTYPE_STRING;
+               break;
+
+       case ACPI_TYPE_PACKAGE:
+               return_btype = ACPI_RTYPE_PACKAGE;
+               break;
+
+       case ACPI_TYPE_LOCAL_REFERENCE:
+               return_btype = ACPI_RTYPE_REFERENCE;
+               break;
+
+       default:
+               /* Not one of the supported objects, must be incorrect */
+
+               goto type_error_exit;
+       }
+
+       /* Is the object one of the expected types? */
+
+       if (!(return_btype & expected_btypes)) {
+               goto type_error_exit;
+       }
+
+       /* For reference objects, check that the reference type is correct */
+
+       if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_LOCAL_REFERENCE) {
+               status = acpi_ns_check_reference(pathname, return_object);
+       }
+
+       return (status);
+
+      type_error_exit:
+
+       /* Create a string with all expected types for this predefined object */
+
+       j = 1;
+       type_buffer[0] = 0;
+       this_rtype = ACPI_RTYPE_INTEGER;
+
+       for (i = 0; i < ACPI_NUM_RTYPES; i++) {
+
+               /* If one of the expected types, concatenate the name of this type */
+
+               if (expected_btypes & this_rtype) {
+                       ACPI_STRCAT(type_buffer, &acpi_rtype_names[i][j]);
+                       j = 0;  /* Use name separator from now on */
+               }
+               this_rtype <<= 1;       /* Next Rtype */
+       }
+
+       if (package_index == ACPI_NOT_PACKAGE) {
+               ACPI_WARNING((AE_INFO,
+                             "%s: Return type mismatch - found %s, expected %s",
+                             pathname,
+                             acpi_ut_get_object_type_name(return_object),
+                             type_buffer));
+       } else {
+               ACPI_WARNING((AE_INFO,
+                             "%s: Return Package type mismatch at index %u - "
+                             "found %s, expected %s", pathname, package_index,
+                             acpi_ut_get_object_type_name(return_object),
+                             type_buffer));
+       }
+
+       return (AE_AML_OPERAND_TYPE);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_reference
+ *
+ * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
+ *              return_object   - Object returned from the evaluation of a
+ *                                method or object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check a returned reference object for the correct reference
+ *              type. The only reference type that can be returned from a
+ *              predefined method is a named reference. All others are invalid.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ns_check_reference(char *pathname,
+                       union acpi_operand_object *return_object)
+{
+
+       /*
+        * Check the reference object for the correct reference type (opcode).
+        * The only type of reference that can be converted to an union acpi_object is
+        * a reference to a named object (reference class: NAME)
+        */
+       if (return_object->reference.class == ACPI_REFCLASS_NAME) {
+               return (AE_OK);
+       }
+
+       ACPI_WARNING((AE_INFO,
+                     "%s: Return type mismatch - unexpected reference object type [%s] %2.2X",
+                     pathname, acpi_ut_get_reference_name(return_object),
+                     return_object->reference.class));
+
+       return (AE_AML_OPERAND_TYPE);
+}
index 8399276cba1e4049155ffd7229e9c06b4fdad8c9..a9a80bf811b3ecca3239006a41e546b6ce1973de 100644 (file)
@@ -331,7 +331,7 @@ acpi_ns_search_and_enter(u32 target_name,
                                      "Found bad character(s) in name, repaired: [%4.4s]\n",
                                      ACPI_CAST_PTR(char, &target_name)));
                } else {
-                       ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+                       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                          "Found bad character(s) in name, repaired: [%4.4s]\n",
                                          ACPI_CAST_PTR(char, &target_name)));
                }
index 38be5865d95df30e382f21b2adb8d2b6837aa2f9..a085cc39c055703bea5b144f01fb5db3478cff7e 100644 (file)
 
 #define _COMPONENT          ACPI_NAMESPACE
 ACPI_MODULE_NAME("nsxfeval")
+
+/* Local prototypes */
+static void acpi_ns_resolve_references(struct acpi_evaluate_info *info);
+
 #ifdef ACPI_FUTURE_USAGE
 /*******************************************************************************
  *
@@ -69,6 +73,7 @@ ACPI_MODULE_NAME("nsxfeval")
  *              be valid (non-null)
  *
  ******************************************************************************/
+
 acpi_status
 acpi_evaluate_object_typed(acpi_handle handle,
                           acpi_string pathname,
@@ -283,6 +288,10 @@ acpi_evaluate_object(acpi_handle handle,
 
                        if (ACPI_SUCCESS(status)) {
 
+                               /* Dereference Index and ref_of references */
+
+                               acpi_ns_resolve_references(info);
+
                                /* Get the size of the returned object */
 
                                status =
@@ -350,6 +359,74 @@ acpi_evaluate_object(acpi_handle handle,
 
 ACPI_EXPORT_SYMBOL(acpi_evaluate_object)
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_resolve_references
+ *
+ * PARAMETERS:  Info                    - Evaluation info block
+ *
+ * RETURN:      Info->return_object is replaced with the dereferenced object
+ *
+ * DESCRIPTION: Dereference certain reference objects. Called before an
+ *              internal return object is converted to an external union acpi_object.
+ *
+ * Performs an automatic dereference of Index and ref_of reference objects.
+ * These reference objects are not supported by the union acpi_object, so this is a
+ * last resort effort to return something useful. Also, provides compatibility
+ * with other ACPI implementations.
+ *
+ * NOTE: does not handle references within returned package objects or nested
+ * references, but this support could be added later if found to be necessary.
+ *
+ ******************************************************************************/
+static void acpi_ns_resolve_references(struct acpi_evaluate_info *info)
+{
+       union acpi_operand_object *obj_desc = NULL;
+       struct acpi_namespace_node *node;
+
+       /* We are interested in reference objects only */
+
+       if (ACPI_GET_OBJECT_TYPE(info->return_object) !=
+           ACPI_TYPE_LOCAL_REFERENCE) {
+               return;
+       }
+
+       /*
+        * Two types of references are supported - those created by Index and
+        * ref_of operators. A name reference (AML_NAMEPATH_OP) can be converted
+        * to an union acpi_object, so it is not dereferenced here. A ddb_handle
+        * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
+        * an union acpi_object.
+        */
+       switch (info->return_object->reference.class) {
+       case ACPI_REFCLASS_INDEX:
+
+               obj_desc = *(info->return_object->reference.where);
+               break;
+
+       case ACPI_REFCLASS_REFOF:
+
+               node = info->return_object->reference.object;
+               if (node) {
+                       obj_desc = node->object;
+               }
+               break;
+
+       default:
+               return;
+       }
+
+       /* Replace the existing reference object */
+
+       if (obj_desc) {
+               acpi_ut_add_reference(obj_desc);
+               acpi_ut_remove_reference(info->return_object);
+               info->return_object = obj_desc;
+       }
+
+       return;
+}
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_walk_namespace
@@ -379,6 +456,7 @@ ACPI_EXPORT_SYMBOL(acpi_evaluate_object)
  *              function, etc.
  *
  ******************************************************************************/
+
 acpi_status
 acpi_walk_namespace(acpi_object_type type,
                    acpi_handle start_object,
index a287ed550f5474db1802e2bb785ecd3531b33f10..5efa4e7ddb0b18088f8cf68a34ba262f9e8aa677 100644 (file)
@@ -253,6 +253,7 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer)
        node = acpi_ns_map_handle_to_node(handle);
        if (!node) {
                (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+               status = AE_BAD_PARAMETER;
                goto cleanup;
        }
 
@@ -264,6 +265,10 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer)
        info->name = node->name.integer;
        info->valid = 0;
 
+       if (node->type == ACPI_TYPE_METHOD) {
+               info->param_count = node->object->method.param_count;
+       }
+
        status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
        if (ACPI_FAILURE(status)) {
                goto cleanup;
index cb9864e39bae743f0943c41075e557dd696ac3ac..25ceae9191ef3f1bed834cd2f88d4094e3ba61cb 100644 (file)
@@ -258,7 +258,7 @@ int __init acpi_numa_init(void)
 
 int acpi_get_pxm(acpi_handle h)
 {
-       unsigned long pxm;
+       unsigned long long pxm;
        acpi_status status;
        acpi_handle handle;
        acpi_handle phandle = h;
index 235a1386888a42fb19c59f6080155a6e774071b3..4be252145cb45320cf82b14c4e579c525bf2776e 100644 (file)
@@ -608,7 +608,7 @@ static void acpi_os_derive_pci_id_2(acpi_handle rhandle,    /* upper bound  */
        acpi_handle handle;
        struct acpi_pci_id *pci_id = *id;
        acpi_status status;
-       unsigned long temp;
+       unsigned long long temp;
        acpi_object_type type;
 
        acpi_get_parent(chandle, &handle);
@@ -620,8 +620,7 @@ static void acpi_os_derive_pci_id_2(acpi_handle rhandle,    /* upper bound  */
                if ((ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE))
                        return;
 
-               status =
-                   acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL,
+               status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL,
                                          &temp);
                if (ACPI_SUCCESS(status)) {
                        u32 val;
@@ -682,6 +681,22 @@ static void acpi_os_execute_deferred(struct work_struct *work)
        return;
 }
 
+static void acpi_os_execute_hp_deferred(struct work_struct *work)
+{
+       struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
+       if (!dpc) {
+               printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
+               return;
+       }
+
+       acpi_os_wait_events_complete(NULL);
+
+       dpc->function(dpc->context);
+       kfree(dpc);
+
+       return;
+}
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_os_execute
@@ -697,12 +712,13 @@ static void acpi_os_execute_deferred(struct work_struct *work)
  *
  ******************************************************************************/
 
-acpi_status acpi_os_execute(acpi_execute_type type,
-                           acpi_osd_exec_callback function, void *context)
+static acpi_status __acpi_os_execute(acpi_execute_type type,
+       acpi_osd_exec_callback function, void *context, int hp)
 {
        acpi_status status = AE_OK;
        struct acpi_os_dpc *dpc;
        struct workqueue_struct *queue;
+       int ret;
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
                          "Scheduling function [%p(%p)] for deferred execution.\n",
                          function, context));
@@ -726,19 +742,38 @@ acpi_status acpi_os_execute(acpi_execute_type type,
        dpc->function = function;
        dpc->context = context;
 
-       INIT_WORK(&dpc->work, acpi_os_execute_deferred);
-       queue = (type == OSL_NOTIFY_HANDLER) ? kacpi_notify_wq : kacpid_wq;
-       if (!queue_work(queue, &dpc->work)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                         "Call to queue_work() failed.\n"));
+       if (!hp) {
+               INIT_WORK(&dpc->work, acpi_os_execute_deferred);
+               queue = (type == OSL_NOTIFY_HANDLER) ?
+                       kacpi_notify_wq : kacpid_wq;
+               ret = queue_work(queue, &dpc->work);
+       } else {
+               INIT_WORK(&dpc->work, acpi_os_execute_hp_deferred);
+               ret = schedule_work(&dpc->work);
+       }
+
+       if (!ret) {
+               printk(KERN_ERR PREFIX
+                         "Call to queue_work() failed.\n");
                status = AE_ERROR;
                kfree(dpc);
        }
        return_ACPI_STATUS(status);
 }
 
+acpi_status acpi_os_execute(acpi_execute_type type,
+                           acpi_osd_exec_callback function, void *context)
+{
+       return __acpi_os_execute(type, function, context, 0);
+}
 EXPORT_SYMBOL(acpi_os_execute);
 
+acpi_status acpi_os_hotplug_execute(acpi_osd_exec_callback function,
+       void *context)
+{
+       return __acpi_os_execute(0, function, context, 1);
+}
+
 void acpi_os_wait_events_complete(void *context)
 {
        flush_workqueue(kacpid_wq);
index c06238e55d98bebd1582536a684949e194c74229..4647039a0d8a2c7183f1cc25653a673cf7657ff4 100644 (file)
@@ -719,6 +719,8 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state,
                *op = NULL;
        }
 
+       ACPI_PREEMPTION_POINT();
+
        return_ACPI_STATUS(AE_OK);
 }
 
index 15e1702e48d606ad4313d547dafbc4b99b518d75..68e932f215ea5ef73c407a241a4d11d3367897fa 100644 (file)
@@ -137,6 +137,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
        union acpi_parse_object *next;
        const struct acpi_opcode_info *parent_info;
        union acpi_parse_object *replacement_op = NULL;
+       acpi_status status = AE_OK;
 
        ACPI_FUNCTION_TRACE_PTR(ps_complete_this_op, op);
 
@@ -186,7 +187,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
                        replacement_op =
                            acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);
                        if (!replacement_op) {
-                               goto allocate_error;
+                               status = AE_NO_MEMORY;
                        }
                        break;
 
@@ -211,7 +212,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
                                replacement_op =
                                    acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);
                                if (!replacement_op) {
-                                       goto allocate_error;
+                                       status = AE_NO_MEMORY;
                                }
                        } else
                            if ((op->common.parent->common.aml_opcode ==
@@ -226,13 +227,13 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
                                            acpi_ps_alloc_op(op->common.
                                                             aml_opcode);
                                        if (!replacement_op) {
-                                               goto allocate_error;
+                                               status = AE_NO_MEMORY;
+                                       } else {
+                                               replacement_op->named.data =
+                                                   op->named.data;
+                                               replacement_op->named.length =
+                                                   op->named.length;
                                        }
-
-                                       replacement_op->named.data =
-                                           op->named.data;
-                                       replacement_op->named.length =
-                                           op->named.length;
                                }
                        }
                        break;
@@ -242,7 +243,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
                        replacement_op =
                            acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);
                        if (!replacement_op) {
-                               goto allocate_error;
+                               status = AE_NO_MEMORY;
                        }
                }
 
@@ -302,14 +303,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
        /* Now we can actually delete the subtree rooted at Op */
 
        acpi_ps_delete_parse_tree(op);
-       return_ACPI_STATUS(AE_OK);
-
-      allocate_error:
-
-       /* Always delete the subtree, even on error */
-
-       acpi_ps_delete_parse_tree(op);
-       return_ACPI_STATUS(AE_NO_MEMORY);
+       return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
@@ -641,10 +635,12 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
                                            ACPI_WALK_METHOD_RESTART;
                                }
                        } else {
-                               /* On error, delete any return object */
+                               /* On error, delete any return object or implicit return */
 
                                acpi_ut_remove_reference(previous_walk_state->
                                                         return_desc);
+                               acpi_ds_clear_implicit_return
+                                   (previous_walk_state);
                        }
                }
 
index cf47805a7448ccc9ddfbec7009cc975be371c760..fcfdef7b4fddfb11f5a80a9540ad1475bf20e9da 100644 (file)
@@ -709,7 +709,7 @@ int acpi_pci_link_free_irq(acpi_handle handle)
                          acpi_device_bid(link->device)));
 
        if (link->refcnt == 0) {
-               acpi_ut_evaluate_object(link->device->handle, "_DIS", 0, NULL);
+               acpi_evaluate_object(link->device->handle, "_DIS", NULL, NULL);
        }
        mutex_unlock(&acpi_link_lock);
        return (link->irq.active);
@@ -737,7 +737,7 @@ static int acpi_pci_link_add(struct acpi_device *device)
        link->device = device;
        strcpy(acpi_device_name(device), ACPI_PCI_LINK_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS);
-       acpi_driver_data(device) = link;
+       device->driver_data = link;
 
        mutex_lock(&acpi_link_lock);
        result = acpi_pci_link_get_possible(link);
@@ -773,7 +773,7 @@ static int acpi_pci_link_add(struct acpi_device *device)
 
       end:
        /* disable all links -- to be activated on use */
-       acpi_ut_evaluate_object(device->handle, "_DIS", 0, NULL);
+       acpi_evaluate_object(device->handle, "_DIS", NULL, NULL);
        mutex_unlock(&acpi_link_lock);
 
        if (result)
index c3fed31166b552761f2bb9c3b26ef2b7c3e47592..1b8f67d21d539c427f29ef2b60b34c922e780abd 100644 (file)
@@ -190,7 +190,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
        struct acpi_pci_root *root = NULL;
        struct acpi_pci_root *tmp;
        acpi_status status = AE_OK;
-       unsigned long value = 0;
+       unsigned long long value = 0;
        acpi_handle handle = NULL;
        struct acpi_device *child;
 
@@ -206,7 +206,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
        root->device = device;
        strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
-       acpi_driver_data(device) = root;
+       device->driver_data = root;
 
        device->ops.bind = acpi_pci_bind;
 
index d5b4ef898879dd913853feb588c5c802f7425266..cd1f4467be7ba828162246d0596175652e8e7a25 100644 (file)
@@ -76,10 +76,10 @@ static struct acpi_pci_driver acpi_pci_slot_driver = {
 };
 
 static int
-check_slot(acpi_handle handle, unsigned long *sun)
+check_slot(acpi_handle handle, unsigned long long *sun)
 {
        int device = -1;
-       unsigned long adr, sta;
+       unsigned long long adr, sta;
        acpi_status status;
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 
@@ -132,7 +132,7 @@ static acpi_status
 register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
        int device;
-       unsigned long sun;
+       unsigned long long sun;
        char name[SLOT_NAME_SIZE];
        struct acpi_pci_slot *slot;
        struct pci_slot *pci_slot;
@@ -150,7 +150,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
        }
 
        snprintf(name, sizeof(name), "%u", (u32)sun);
-       pci_slot = pci_create_slot(pci_bus, device, name);
+       pci_slot = pci_create_slot(pci_bus, device, name, NULL);
        if (IS_ERR(pci_slot)) {
                err("pci_create_slot returned %ld\n", PTR_ERR(pci_slot));
                kfree(slot);
@@ -182,7 +182,7 @@ static acpi_status
 walk_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
        int device, function;
-       unsigned long adr;
+       unsigned long long adr;
        acpi_status status;
        acpi_handle dummy_handle;
        acpi_walk_callback user_function;
@@ -239,7 +239,7 @@ static int
 walk_root_bridge(acpi_handle handle, acpi_walk_callback user_function)
 {
        int seg, bus;
-       unsigned long tmp;
+       unsigned long long tmp;
        acpi_status status;
        acpi_handle dummy_handle;
        struct pci_bus *pci_bus;
index 4ab21cb1c8c7ebde037b51256de4c326efcfd7f6..a1718e56103b33b5da9909b23727c4474611f90f 100644 (file)
@@ -54,6 +54,14 @@ ACPI_MODULE_NAME("power");
 #define ACPI_POWER_RESOURCE_STATE_OFF  0x00
 #define ACPI_POWER_RESOURCE_STATE_ON   0x01
 #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
+
+#ifdef MODULE_PARAM_PREFIX
+#undef MODULE_PARAM_PREFIX
+#endif
+#define MODULE_PARAM_PREFIX "acpi."
+int acpi_power_nocheck;
+module_param_named(power_nocheck, acpi_power_nocheck, bool, 000);
+
 static int acpi_power_add(struct acpi_device *device);
 static int acpi_power_remove(struct acpi_device *device, int type);
 static int acpi_power_resume(struct acpi_device *device);
@@ -128,16 +136,16 @@ acpi_power_get_context(acpi_handle handle,
        return 0;
 }
 
-static int acpi_power_get_state(struct acpi_power_resource *resource, int *state)
+static int acpi_power_get_state(acpi_handle handle, int *state)
 {
        acpi_status status = AE_OK;
-       unsigned long sta = 0;
+       unsigned long long sta = 0;
 
 
-       if (!resource || !state)
+       if (!handle || !state)
                return -EINVAL;
 
-       status = acpi_evaluate_integer(resource->device->handle, "_STA", NULL, &sta);
+       status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
        if (ACPI_FAILURE(status))
                return -ENODEV;
 
@@ -145,7 +153,7 @@ static int acpi_power_get_state(struct acpi_power_resource *resource, int *state
                              ACPI_POWER_RESOURCE_STATE_OFF;
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n",
-                         resource->name, state ? "on" : "off"));
+                         acpi_ut_get_node_name(handle), state ? "on" : "off"));
 
        return 0;
 }
@@ -153,7 +161,6 @@ static int acpi_power_get_state(struct acpi_power_resource *resource, int *state
 static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
 {
        int result = 0, state1;
-       struct acpi_power_resource *resource = NULL;
        u32 i = 0;
 
 
@@ -161,12 +168,15 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
                return -EINVAL;
 
        /* The state of the list is 'on' IFF all resources are 'on'. */
+       /* */
 
        for (i = 0; i < list->count; i++) {
-               result = acpi_power_get_context(list->handles[i], &resource);
-               if (result)
-                       return result;
-               result = acpi_power_get_state(resource, &state1);
+               /*
+                * The state of the power resource can be obtained by
+                * using the ACPI handle. In such case it is unnecessary to
+                * get the Power resource first and then get its state again.
+                */
+               result = acpi_power_get_state(list->handles[i], &state1);
                if (result)
                        return result;
 
@@ -226,12 +236,18 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
        if (ACPI_FAILURE(status))
                return -ENODEV;
 
-       result = acpi_power_get_state(resource, &state);
-       if (result)
-               return result;
-       if (state != ACPI_POWER_RESOURCE_STATE_ON)
-               return -ENOEXEC;
-
+       if (!acpi_power_nocheck) {
+               /*
+                * If acpi_power_nocheck is set, it is unnecessary to check
+                * the power state after power transition.
+                */
+               result = acpi_power_get_state(resource->device->handle,
+                               &state);
+               if (result)
+                       return result;
+               if (state != ACPI_POWER_RESOURCE_STATE_ON)
+                       return -ENOEXEC;
+       }
        /* Update the power resource's _device_ power state */
        resource->device->power.state = ACPI_STATE_D0;
 
@@ -277,11 +293,17 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev)
        if (ACPI_FAILURE(status))
                return -ENODEV;
 
-       result = acpi_power_get_state(resource, &state);
-       if (result)
-               return result;
-       if (state != ACPI_POWER_RESOURCE_STATE_OFF)
-               return -ENOEXEC;
+       if (!acpi_power_nocheck) {
+               /*
+                * If acpi_power_nocheck is set, it is unnecessary to check
+                * the power state after power transition.
+                */
+               result = acpi_power_get_state(handle, &state);
+               if (result)
+                       return result;
+               if (state != ACPI_POWER_RESOURCE_STATE_OFF)
+                       return -ENOEXEC;
+       }
 
        /* Update the power resource's _device_ power state */
        resource->device->power.state = ACPI_STATE_D3;
@@ -555,7 +577,7 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset)
        if (!resource)
                goto end;
 
-       result = acpi_power_get_state(resource, &state);
+       result = acpi_power_get_state(resource->device->handle, &state);
        if (result)
                goto end;
 
@@ -657,7 +679,7 @@ static int acpi_power_add(struct acpi_device *device)
        strcpy(resource->name, device->pnp.bus_id);
        strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
-       acpi_driver_data(device) = resource;
+       device->driver_data = resource;
 
        /* Evalute the object to get the system level and resource order. */
        status = acpi_evaluate_object(device->handle, NULL, NULL, &buffer);
@@ -668,7 +690,7 @@ static int acpi_power_add(struct acpi_device *device)
        resource->system_level = acpi_object.power_resource.system_level;
        resource->order = acpi_object.power_resource.resource_order;
 
-       result = acpi_power_get_state(resource, &state);
+       result = acpi_power_get_state(device->handle, &state);
        if (result)
                goto end;
 
@@ -733,9 +755,9 @@ static int acpi_power_resume(struct acpi_device *device)
        if (!device || !acpi_driver_data(device))
                return -EINVAL;
 
-       resource = (struct acpi_power_resource *)acpi_driver_data(device);
+       resource = acpi_driver_data(device);
 
-       result = acpi_power_get_state(resource, &state);
+       result = acpi_power_get_state(device->handle, &state);
        if (result)
                return result;
 
index ee68ac54c0d412996aebefc58b6c51c1363da5af..24a362f8034c49a722005efec417714560b5b9cf 100644 (file)
@@ -563,7 +563,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid)
 
        /* Check if it is a Device with HID and UID */
        if (has_uid) {
-               unsigned long value;
+               unsigned long long value;
                status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
                                                NULL, &value);
                if (ACPI_FAILURE(status)) {
@@ -818,7 +818,7 @@ static int acpi_processor_add(struct acpi_device *device)
        pr->handle = device->handle;
        strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
-       acpi_driver_data(device) = pr;
+       device->driver_data = pr;
 
        return 0;
 }
@@ -875,7 +875,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
 static int is_processor_present(acpi_handle handle)
 {
        acpi_status status;
-       unsigned long sta = 0;
+       unsigned long long sta = 0;
 
 
        status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
index cf5b1b7b684f1de0473796d26ed8e2edc2213eef..81b40ed5379e76edcd02553aaa4881f1107a1422 100644 (file)
@@ -1587,6 +1587,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
 
        if (acpi_idle_bm_check()) {
                if (dev->safe_state) {
+                       dev->last_state = dev->safe_state;
                        return dev->safe_state->enter(dev, dev->safe_state);
                } else {
                        local_irq_disable();
index 80c251ec6d2aac7dff658a9c6df5fec5733bc168..dc98f7a6f2c49bfb701716f330fc70dff13012a5 100644 (file)
@@ -38,6 +38,7 @@
 
 #include <asm/uaccess.h>
 #endif
+#include <asm/cpufeature.h>
 
 #include <acpi/acpi_bus.h>
 #include <acpi/processor.h>
@@ -126,7 +127,7 @@ static struct notifier_block acpi_ppc_notifier_block = {
 static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
 {
        acpi_status status = 0;
-       unsigned long ppc = 0;
+       unsigned long long ppc = 0;
 
 
        if (!pr)
@@ -334,7 +335,6 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr)
        acpi_status status = AE_OK;
        acpi_handle handle = NULL;
 
-
        if (!pr || !pr->performance || !pr->handle)
                return -EINVAL;
 
@@ -347,13 +347,25 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr)
 
        result = acpi_processor_get_performance_control(pr);
        if (result)
-               return result;
+               goto update_bios;
 
        result = acpi_processor_get_performance_states(pr);
        if (result)
-               return result;
+               goto update_bios;
 
        return 0;
+
+       /*
+        * Having _PPC but missing frequencies (_PSS, _PCT) is a very good hint that
+        * the BIOS is older than the CPU and does not know its frequencies
+        */
+ update_bios:
+       if (ACPI_SUCCESS(acpi_get_handle(pr->handle, "_PPC", &handle))){
+               if(boot_cpu_has(X86_FEATURE_EST))
+                       printk(KERN_WARNING FW_BUG "BIOS needs update for CPU "
+                              "frequency support\n");
+       }
+       return result;
 }
 
 int acpi_processor_notify_smm(struct module *calling_module)
@@ -524,13 +536,13 @@ static int acpi_processor_get_psd(struct acpi_processor   *pr)
 
        psd = buffer.pointer;
        if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n"));
+               printk(KERN_ERR PREFIX "Invalid _PSD data\n");
                result = -EFAULT;
                goto end;
        }
 
        if (psd->package.count != 1) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n"));
+               printk(KERN_ERR PREFIX "Invalid _PSD data\n");
                result = -EFAULT;
                goto end;
        }
@@ -543,19 +555,19 @@ static int acpi_processor_get_psd(struct acpi_processor   *pr)
        status = acpi_extract_package(&(psd->package.elements[0]),
                &format, &state);
        if (ACPI_FAILURE(status)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n"));
+               printk(KERN_ERR PREFIX "Invalid _PSD data\n");
                result = -EFAULT;
                goto end;
        }
 
        if (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _PSD:num_entries\n"));
+               printk(KERN_ERR PREFIX "Unknown _PSD:num_entries\n");
                result = -EFAULT;
                goto end;
        }
 
        if (pdomain->revision != ACPI_PSD_REV0_REVISION) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _PSD:revision\n"));
+               printk(KERN_ERR PREFIX "Unknown _PSD:revision\n");
                result = -EFAULT;
                goto end;
        }
index a56fc6c4394bb1dab26cb06527d3f89239333683..3da2df93d924ddf534af4e24d16fd635f3c6ef3c 100644 (file)
@@ -274,7 +274,7 @@ static int acpi_processor_throttling_notifier(unsigned long event, void *data)
 static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
 {
        acpi_status status = 0;
-       unsigned long tpc = 0;
+       unsigned long long tpc = 0;
 
        if (!pr)
                return -EINVAL;
@@ -528,13 +528,13 @@ static int acpi_processor_get_tsd(struct acpi_processor *pr)
 
        tsd = buffer.pointer;
        if (!tsd || (tsd->type != ACPI_TYPE_PACKAGE)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n"));
+               printk(KERN_ERR PREFIX "Invalid _TSD data\n");
                result = -EFAULT;
                goto end;
        }
 
        if (tsd->package.count != 1) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n"));
+               printk(KERN_ERR PREFIX "Invalid _TSD data\n");
                result = -EFAULT;
                goto end;
        }
@@ -547,19 +547,19 @@ static int acpi_processor_get_tsd(struct acpi_processor *pr)
        status = acpi_extract_package(&(tsd->package.elements[0]),
                                      &format, &state);
        if (ACPI_FAILURE(status)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n"));
+               printk(KERN_ERR PREFIX "Invalid _TSD data\n");
                result = -EFAULT;
                goto end;
        }
 
        if (pdomain->num_entries != ACPI_TSD_REV0_ENTRIES) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _TSD:num_entries\n"));
+               printk(KERN_ERR PREFIX "Unknown _TSD:num_entries\n");
                result = -EFAULT;
                goto end;
        }
 
        if (pdomain->revision != ACPI_TSD_REV0_REVISION) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _TSD:revision\n"));
+               printk(KERN_ERR PREFIX "Unknown _TSD:revision\n");
                result = -EFAULT;
                goto end;
        }
index a6b662c00b67764d311366963171a1a5b289f73d..755baf2ca70ad5b44676390242038a737e0f46a2 100644 (file)
@@ -15,9 +15,28 @@ void acpi_reboot(void)
 
        rr = &acpi_gbl_FADT.reset_register;
 
-       /* Is the reset register supported? */
-       if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) ||
-           rr->bit_width != 8 || rr->bit_offset != 0)
+       /*
+        * Is the ACPI reset register supported?
+        *
+        * According to ACPI 3.0, FADT.flags.RESET_REG_SUP indicates
+        * whether the ACPI reset mechanism is supported.
+        *
+        * However, some boxes have this bit clear, yet a valid
+        * ACPI_RESET_REG & RESET_VALUE, and ACPI reboot is the only
+        * mechanism that works for them after S3.
+        *
+        * This suggests that other operating systems may not be checking
+        * the RESET_REG_SUP bit, and are using other means to decide
+        * whether to use the ACPI reboot mechanism or not.
+        *
+        * So when acpi reboot is requested,
+        * only the reset_register is checked. If the following
+        * conditions are met, it indicates that the reset register is supported.
+        *      a. reset_register is not zero
+        *      b. the access width is eight
+        *      c. the bit_offset is zero
+        */
+       if (!(rr->address) || rr->bit_width != 8 || rr->bit_offset != 0)
                return;
 
        reset_value = acpi_gbl_FADT.reset_value;
index d9063ea414e33d2cda60a796dd97eb41379cb1d0..8eaaecf9200939ea4cb72b9a2f9842e4b80af5a7 100644 (file)
@@ -43,7 +43,6 @@
 
 #include <acpi/acpi.h>
 #include <acpi/acresrc.h>
-#include <acpi/amlcode.h>
 #include <acpi/acnamesp.h>
 
 #define _COMPONENT          ACPI_RESOURCES
@@ -560,8 +559,8 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
                              ACPI_GET_OBJECT_TYPE(*sub_object_list)) ||
                             ((ACPI_TYPE_LOCAL_REFERENCE ==
                               ACPI_GET_OBJECT_TYPE(*sub_object_list)) &&
-                             ((*sub_object_list)->reference.opcode ==
-                              AML_INT_NAMEPATH_OP)))) {
+                             ((*sub_object_list)->reference.class ==
+                              ACPI_REFCLASS_NAME)))) {
                                name_found = TRUE;
                        } else {
                                /* Look at the next element */
index 7804a8c40e7a36e0d1505ee7b10994f1ef1805f3..c0bbfa2c419319f92d9f561a98afe0eabb296971 100644 (file)
@@ -43,7 +43,6 @@
 
 #include <acpi/acpi.h>
 #include <acpi/acresrc.h>
-#include <acpi/amlcode.h>
 #include <acpi/acnamesp.h>
 
 #define _COMPONENT          ACPI_RESOURCES
@@ -310,13 +309,12 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
                        switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
                        case ACPI_TYPE_LOCAL_REFERENCE:
 
-                               if (obj_desc->reference.opcode !=
-                                   AML_INT_NAMEPATH_OP) {
+                               if (obj_desc->reference.class !=
+                                   ACPI_REFCLASS_NAME) {
                                        ACPI_ERROR((AE_INFO,
-                                                   "(PRT[%X].Source) Need name, found reference op %X",
+                                                   "(PRT[%X].Source) Need name, found Reference Class %X",
                                                    index,
-                                                   obj_desc->reference.
-                                                   opcode));
+                                                   obj_desc->reference.class));
                                        return_ACPI_STATUS(AE_BAD_DATA);
                                }
 
index 7b011e7e29fe00b35ab1616d4c7a232c32ec8d2b..6050ce4818731fd2bcf8c6891d5a343414d0133a 100644 (file)
@@ -931,7 +931,7 @@ static int acpi_sbs_add(struct acpi_device *device)
        sbs->device = device;
        strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_SBS_CLASS);
-       acpi_driver_data(device) = sbs;
+       device->driver_data = sbs;
 
        result = acpi_charger_add(sbs);
        if (result)
index a4e3767b8c64241c6bd1c11010f0c2001fd7e7c1..e53e590252c01346e09ab317d6595cc218d3a72f 100644 (file)
@@ -258,7 +258,7 @@ extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
 static int acpi_smbus_hc_add(struct acpi_device *device)
 {
        int status;
-       unsigned long val;
+       unsigned long long val;
        struct acpi_smb_hc *hc;
 
        if (!device)
@@ -282,7 +282,7 @@ static int acpi_smbus_hc_add(struct acpi_device *device)
        hc->ec = acpi_driver_data(device->parent);
        hc->offset = (val >> 8) & 0xff;
        hc->query_bit = val & 0xff;
-       acpi_driver_data(device) = hc;
+       device->driver_data = hc;
 
        acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc);
        printk(KERN_INFO PREFIX "SBS HC: EC = 0x%p, offset = 0x%0x, query_bit = 0x%0x\n",
@@ -303,7 +303,7 @@ static int acpi_smbus_hc_remove(struct acpi_device *device, int type)
        hc = acpi_driver_data(device);
        acpi_ec_remove_query_handler(hc->ec, hc->query_bit);
        kfree(hc);
-       acpi_driver_data(device) = NULL;
+       device->driver_data = NULL;
        return 0;
 }
 
index f6f52c1a2abad88cecc73a41ea65c4bddfafc0ae..a9dda8e0f9f9c2c14859b027fcd80b1b88abdeda 100644 (file)
@@ -113,16 +113,16 @@ static int acpi_bus_hot_remove_device(void *context)
 
 
        if (acpi_bus_trim(device, 1)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                               "Removing device failed\n"));
+               printk(KERN_ERR PREFIX
+                               "Removing device failed\n");
                return -1;
        }
 
        /* power off device */
        status = acpi_evaluate_object(handle, "_PS3", NULL, NULL);
        if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
-               ACPI_DEBUG_PRINT((ACPI_DB_WARN,
-                               "Power-off device failed\n"));
+               printk(KERN_WARNING PREFIX
+                               "Power-off device failed\n");
 
        if (device->flags.lockable) {
                arg_list.count = 1;
@@ -276,6 +276,13 @@ int acpi_match_device_ids(struct acpi_device *device,
 {
        const struct acpi_device_id *id;
 
+       /*
+        * If the device is not present, it is unnecessary to load device
+        * driver for it.
+        */
+       if (!device->status.present)
+               return -ENODEV;
+
        if (device->flags.hardware_id) {
                for (id = ids; id->id[0]; id++) {
                        if (!strcmp((char*)id->id, device->pnp.hardware_id))
@@ -384,7 +391,7 @@ static int acpi_device_remove(struct device * dev)
                        acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type);
        }
        acpi_dev->driver = NULL;
-       acpi_driver_data(dev) = NULL;
+       acpi_dev->driver_data = NULL;
 
        put_device(dev);
        return 0;
@@ -477,7 +484,7 @@ static int acpi_device_register(struct acpi_device *device,
 
        result = acpi_device_setup_files(device);
        if(result)
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error creating sysfs interface for device %s\n", device->dev.bus_id));
+               printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", device->dev.bus_id);
 
        device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
        return 0;
@@ -537,7 +544,7 @@ acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
        result = driver->ops.add(device);
        if (result) {
                device->driver = NULL;
-               acpi_driver_data(device) = NULL;
+               device->driver_data = NULL;
                return result;
        }
 
@@ -744,6 +751,16 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
        if (!acpi_match_device_ids(device, button_device_ids))
                device->wakeup.flags.run_wake = 1;
 
+       /*
+        * Don't set Power button GPE as run_wake
+        * if Fixed Power button is used
+        */
+       if (!strcmp(device->pnp.hardware_id, "PNP0C0C") &&
+               !(acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON)) {
+               device->wakeup.flags.run_wake = 0;
+               device->wakeup.flags.valid = 0;
+       }
+
       end:
        if (ACPI_FAILURE(status))
                device->flags.wake_capable = 0;
@@ -807,6 +824,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
        /* TBD: System wake support and resource requirements. */
 
        device->power.state = ACPI_STATE_UNKNOWN;
+       acpi_bus_get_power(device->handle, &(device->power.state));
 
        return 0;
 }
@@ -1152,20 +1170,6 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
        return 0;
 }
 
-static int
-acpi_is_child_device(struct acpi_device *device,
-                       int (*matcher)(struct acpi_device *))
-{
-       int result = -ENODEV;
-
-       do {
-               if (ACPI_SUCCESS(matcher(device)))
-                       return AE_OK;
-       } while ((device = device->parent));
-
-       return result;
-}
-
 static int
 acpi_add_single_object(struct acpi_device **child,
                       struct acpi_device *parent, acpi_handle handle, int type,
@@ -1221,15 +1225,18 @@ acpi_add_single_object(struct acpi_device **child,
                        result = -ENODEV;
                        goto end;
                }
-               if (!device->status.present) {
-                       /* Bay and dock should be handled even if absent */
-                       if (!ACPI_SUCCESS(
-                            acpi_is_child_device(device, acpi_bay_match)) &&
-                           !ACPI_SUCCESS(
-                            acpi_is_child_device(device, acpi_dock_match))) {
-                                       result = -ENODEV;
-                                       goto end;
-                       }
+               /*
+                * When the device is neither present nor functional, the
+                * device should not be added to Linux ACPI device tree.
+                * When the status of the device is not present but functinal,
+                * it should be added to Linux ACPI tree. For example : bay
+                * device , dock device.
+                * In such conditions it is unncessary to check whether it is
+                * bay device or dock device.
+                */
+               if (!device->status.present && !device->status.functional) {
+                       result = -ENODEV;
+                       goto end;
                }
                break;
        default:
@@ -1251,6 +1258,16 @@ acpi_add_single_object(struct acpi_device **child,
         */
        acpi_device_set_id(device, parent, handle, type);
 
+       /*
+        * The ACPI device is attached to acpi handle before getting
+        * the power/wakeup/peformance flags. Otherwise OS can't get
+        * the corresponding ACPI device by the acpi handle in the course
+        * of getting the power/wakeup/performance flags.
+        */
+       result = acpi_device_set_context(device, type);
+       if (result)
+               goto end;
+
        /*
         * Power Management
         * ----------------
@@ -1281,8 +1298,6 @@ acpi_add_single_object(struct acpi_device **child,
                        goto end;
        }
 
-       if ((result = acpi_device_set_context(device, type)))
-               goto end;
 
        result = acpi_device_register(device, parent);
 
@@ -1402,7 +1417,12 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops)
                 * TBD: Need notifications and other detection mechanisms
                 *      in place before we can fully implement this.
                 */
-               if (child->status.present) {
+                /*
+                * When the device is not present but functional, it is also
+                * necessary to scan the children of this device.
+                */
+               if (child->status.present || (!child->status.present &&
+                                       child->status.functional)) {
                        status = acpi_get_next_object(ACPI_TYPE_ANY, chandle,
                                                      NULL, NULL);
                        if (ACPI_SUCCESS(status)) {
@@ -1545,7 +1565,6 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)
        return result;
 }
 
-int __init acpi_boot_ec_enable(void);
 
 static int __init acpi_scan_init(void)
 {
@@ -1579,9 +1598,6 @@ static int __init acpi_scan_init(void)
         */
        result = acpi_bus_scan_fixed(acpi_root);
 
-       /* EC region might be needed at bus_scan, so enable it now */
-       acpi_boot_ec_enable();
-
        if (!result)
                result = acpi_bus_scan(acpi_root, &ops);
 
index d13194a031bfbe0d1f9de3c83cd25471c10eda7a..26571bafb158a66380308ff04381f0744aa98325 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/dmi.h>
 #include <linux/device.h>
 #include <linux/suspend.h>
+#include <linux/reboot.h>
 
 #include <asm/io.h>
 
 
 u8 sleep_states[ACPI_S_STATE_COUNT];
 
+static void acpi_sleep_tts_switch(u32 acpi_state)
+{
+       union acpi_object in_arg = { ACPI_TYPE_INTEGER };
+       struct acpi_object_list arg_list = { 1, &in_arg };
+       acpi_status status = AE_OK;
+
+       in_arg.integer.value = acpi_state;
+       status = acpi_evaluate_object(NULL, "\\_TTS", &arg_list, NULL);
+       if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+               /*
+                * OS can't evaluate the _TTS object correctly. Some warning
+                * message will be printed. But it won't break anything.
+                */
+               printk(KERN_NOTICE "Failure in evaluating _TTS object\n");
+       }
+}
+
+static int tts_notify_reboot(struct notifier_block *this,
+                       unsigned long code, void *x)
+{
+       acpi_sleep_tts_switch(ACPI_STATE_S5);
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block tts_notifier = {
+       .notifier_call  = tts_notify_reboot,
+       .next           = NULL,
+       .priority       = 0,
+};
+
 static int acpi_sleep_prepare(u32 acpi_state)
 {
 #ifdef CONFIG_ACPI_SLEEP
@@ -45,9 +76,8 @@ static int acpi_sleep_prepare(u32 acpi_state)
        return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ACPI_SLEEP
 static u32 acpi_target_sleep_state = ACPI_STATE_S0;
-
 /*
  * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the
  * user to request that behavior by using the 'acpi_old_suspend_ordering'
@@ -131,8 +161,9 @@ static void acpi_pm_end(void)
         * failing transition to a sleep state.
         */
        acpi_target_sleep_state = ACPI_STATE_S0;
+       acpi_sleep_tts_switch(acpi_target_sleep_state);
 }
-#endif /* CONFIG_PM_SLEEP */
+#endif /* CONFIG_ACPI_SLEEP */
 
 #ifdef CONFIG_SUSPEND
 extern void do_suspend_lowlevel(void);
@@ -155,6 +186,7 @@ static int acpi_suspend_begin(suspend_state_t pm_state)
 
        if (sleep_states[acpi_state]) {
                acpi_target_sleep_state = acpi_state;
+               acpi_sleep_tts_switch(acpi_target_sleep_state);
        } else {
                printk(KERN_ERR "ACPI does not support this state: %d\n",
                        pm_state);
@@ -200,6 +232,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
                break;
        }
 
+       /* If ACPI is not enabled by the BIOS, we need to enable it here. */
+       acpi_enable();
        /* Reprogram control registers and execute _BFS */
        acpi_leave_sleep_state_prep(acpi_state);
 
@@ -296,6 +330,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
                DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"),
                },
        },
+       {
+       .callback = init_old_suspend_ordering,
+       .ident = "HP xw4600 Workstation",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"),
+               },
+       },
        {},
 };
 #endif /* CONFIG_SUSPEND */
@@ -313,6 +355,7 @@ void __init acpi_no_s4_hw_signature(void)
 static int acpi_hibernation_begin(void)
 {
        acpi_target_sleep_state = ACPI_STATE_S4;
+       acpi_sleep_tts_switch(acpi_target_sleep_state);
        return 0;
 }
 
@@ -376,7 +419,15 @@ static struct platform_hibernation_ops acpi_hibernation_ops = {
  */
 static int acpi_hibernation_begin_old(void)
 {
-       int error = acpi_sleep_prepare(ACPI_STATE_S4);
+       int error;
+       /*
+        * The _TTS object should always be evaluated before the _PTS object.
+        * When the old_suspended_ordering is true, the _PTS object is
+        * evaluated in the acpi_sleep_prepare.
+        */
+       acpi_sleep_tts_switch(ACPI_STATE_S4);
+
+       error = acpi_sleep_prepare(ACPI_STATE_S4);
 
        if (!error)
                acpi_target_sleep_state = ACPI_STATE_S4;
@@ -444,7 +495,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p)
        acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
        struct acpi_device *adev;
        char acpi_method[] = "_SxD";
-       unsigned long d_min, d_max;
+       unsigned long long d_min, d_max;
 
        if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {
                printk(KERN_DEBUG "ACPI handle has no context!\n");
@@ -596,5 +647,10 @@ int __init acpi_sleep_init(void)
                pm_power_off = acpi_power_off;
        }
        printk(")\n");
+       /*
+        * Register the tts_notifier to reboot notifier list so that the _TTS
+        * object can also be evaluated when the system enters S5.
+        */
+       register_reboot_notifier(&tts_notifier);
        return 0;
 }
index 24e80fd927e238a6e8ea60ebafe2d4ae57f5f2c1..1d74171b7940ff3e1975cf9f071069666ebed303 100644 (file)
@@ -386,8 +386,8 @@ static ssize_t counter_set(struct kobject *kobj,
                goto end;
 
        if (!(all_counters[index].flags & ACPI_EVENT_VALID)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_WARN,
-                       "Can not change Invalid GPE/Fixed Event status\n"));
+               printk(KERN_WARNING PREFIX
+                       "Can not change Invalid GPE/Fixed Event status\n");
                return -EINVAL;
        }
 
index a4a41ba2484b93404ae948e3d50e5dcff81577a1..2c7885e7ffba6c06508e261f5ef547819661db51 100644 (file)
@@ -50,7 +50,7 @@ ACPI_MODULE_NAME("tbfadt")
 /* Local prototypes */
 static void inline
 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
-                            u8 bit_width, u64 address);
+                            u8 byte_width, u64 address);
 
 static void acpi_tb_convert_fadt(void);
 
@@ -111,7 +111,7 @@ static struct acpi_fadt_info fadt_info_table[] = {
  * FUNCTION:    acpi_tb_init_generic_address
  *
  * PARAMETERS:  generic_address     - GAS struct to be initialized
- *              bit_width           - Width of this register
+ *              byte_width          - Width of this register
  *              Address             - Address of the register
  *
  * RETURN:      None
@@ -124,7 +124,7 @@ static struct acpi_fadt_info fadt_info_table[] = {
 
 static void inline
 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
-                            u8 bit_width, u64 address)
+                            u8 byte_width, u64 address)
 {
 
        /*
@@ -136,7 +136,7 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
        /* All other fields are byte-wide */
 
        generic_address->space_id = ACPI_ADR_SPACE_SYSTEM_IO;
-       generic_address->bit_width = bit_width;
+       generic_address->bit_width = byte_width << 3;
        generic_address->bit_offset = 0;
        generic_address->access_width = 0;
 }
@@ -342,9 +342,20 @@ static void acpi_tb_convert_fadt(void)
         * useful to calculate them once, here.
         *
         * The PM event blocks are split into two register blocks, first is the
-        * PM Status Register block, followed immediately by the PM Enable Register
-        * block. Each is of length (pm1_event_length/2)
+        * PM Status Register block, followed immediately by the PM Enable
+        * Register block. Each is of length (xpm1x_event_block.bit_width/2).
+        *
+        * On various systems the v2 fields (and particularly the bit widths)
+        * cannot be relied upon, though. Hence resort to using the v1 length
+        * here (and warn about the inconsistency).
         */
+       if (acpi_gbl_FADT.xpm1a_event_block.bit_width
+           != acpi_gbl_FADT.pm1_event_length * 8)
+               printk(KERN_WARNING "FADT: "
+                      "X_PM1a_EVT_BLK.bit_width (%u) does not match"
+                      " PM1_EVT_LEN (%u)\n",
+                      acpi_gbl_FADT.xpm1a_event_block.bit_width,
+                      acpi_gbl_FADT.pm1_event_length);
        pm1_register_length = (u8) ACPI_DIV_2(acpi_gbl_FADT.pm1_event_length);
 
        /* The PM1A register block is required */
@@ -360,13 +371,20 @@ static void acpi_tb_convert_fadt(void)
        /* The PM1B register block is optional, ignore if not present */
 
        if (acpi_gbl_FADT.xpm1b_event_block.address) {
+               if (acpi_gbl_FADT.xpm1b_event_block.bit_width
+                   != acpi_gbl_FADT.pm1_event_length * 8)
+                       printk(KERN_WARNING "FADT: "
+                              "X_PM1b_EVT_BLK.bit_width (%u) does not match"
+                              " PM1_EVT_LEN (%u)\n",
+                              acpi_gbl_FADT.xpm1b_event_block.bit_width,
+                              acpi_gbl_FADT.pm1_event_length);
                acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable,
                                             pm1_register_length,
                                             (acpi_gbl_FADT.xpm1b_event_block.
                                              address + pm1_register_length));
                /* Don't forget to copy space_id of the GAS */
                acpi_gbl_xpm1b_enable.space_id =
-                   acpi_gbl_FADT.xpm1a_event_block.space_id;
+                   acpi_gbl_FADT.xpm1b_event_block.space_id;
 
        }
 }
index b22185f55a16acf80e9814059acff89a4a1e508b..18747ce8dd2f2b15b83e6e5465fc8b34c8118258 100644 (file)
@@ -110,7 +110,6 @@ acpi_status
 acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
 {
        u32 i;
-       u32 length;
        acpi_status status = AE_OK;
 
        ACPI_FUNCTION_TRACE(tb_add_table);
@@ -145,25 +144,64 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
                        }
                }
 
-               length = ACPI_MIN(table_desc->length,
-                                 acpi_gbl_root_table_list.tables[i].length);
+               /*
+                * Check for a table match on the entire table length,
+                * not just the header.
+                */
+               if (table_desc->length !=
+                   acpi_gbl_root_table_list.tables[i].length) {
+                       continue;
+               }
+
                if (ACPI_MEMCMP(table_desc->pointer,
                                acpi_gbl_root_table_list.tables[i].pointer,
-                               length)) {
+                               acpi_gbl_root_table_list.tables[i].length)) {
                        continue;
                }
 
-               /* Table is already registered */
-
+               /*
+                * Note: the current mechanism does not unregister a table if it is
+                * dynamically unloaded. The related namespace entries are deleted,
+                * but the table remains in the root table list.
+                *
+                * The assumption here is that the number of different tables that
+                * will be loaded is actually small, and there is minimal overhead
+                * in just keeping the table in case it is needed again.
+                *
+                * If this assumption changes in the future (perhaps on large
+                * machines with many table load/unload operations), tables will
+                * need to be unregistered when they are unloaded, and slots in the
+                * root table list should be reused when empty.
+                */
+
+               /*
+                * Table is already registered.
+                * We can delete the table that was passed as a parameter.
+                */
                acpi_tb_delete_table(table_desc);
                *table_index = i;
-               status = AE_ALREADY_EXISTS;
-               goto release;
+
+               if (acpi_gbl_root_table_list.tables[i].
+                   flags & ACPI_TABLE_IS_LOADED) {
+
+                       /* Table is still loaded, this is an error */
+
+                       status = AE_ALREADY_EXISTS;
+                       goto release;
+               } else {
+                       /* Table was unloaded, allow it to be reloaded */
+
+                       table_desc->pointer =
+                           acpi_gbl_root_table_list.tables[i].pointer;
+                       table_desc->address =
+                           acpi_gbl_root_table_list.tables[i].address;
+                       status = AE_OK;
+                       goto print_header;
+               }
        }
 
-       /*
-        * Add the table to the global table list
-        */
+       /* Add the table to the global root table list */
+
        status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
                                     table_desc->length, table_desc->flags,
                                     table_index);
@@ -171,6 +209,7 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
                goto release;
        }
 
+      print_header:
        acpi_tb_print_table_header(table_desc->address, table_desc->pointer);
 
       release:
index 912703691d36306b0d2256ba345570cab139f688..ad6cae938f0b8cabfff04f305c577f0970bd1cb8 100644 (file)
@@ -246,18 +246,18 @@ static const struct file_operations acpi_thermal_polling_fops = {
 static int acpi_thermal_get_temperature(struct acpi_thermal *tz)
 {
        acpi_status status = AE_OK;
-
+       unsigned long long tmp;
 
        if (!tz)
                return -EINVAL;
 
        tz->last_temperature = tz->temperature;
 
-       status =
-           acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tz->temperature);
+       status = acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tmp);
        if (ACPI_FAILURE(status))
                return -ENODEV;
 
+       tz->temperature = tmp;
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n",
                          tz->temperature));
 
@@ -267,17 +267,16 @@ static int acpi_thermal_get_temperature(struct acpi_thermal *tz)
 static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz)
 {
        acpi_status status = AE_OK;
-
+       unsigned long long tmp;
 
        if (!tz)
                return -EINVAL;
 
-       status =
-           acpi_evaluate_integer(tz->device->handle, "_TZP", NULL,
-                                 &tz->polling_frequency);
+       status = acpi_evaluate_integer(tz->device->handle, "_TZP", NULL, &tmp);
        if (ACPI_FAILURE(status))
                return -ENODEV;
 
+       tz->polling_frequency = tmp;
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n",
                          tz->polling_frequency));
 
@@ -356,6 +355,7 @@ do {        \
 static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
 {
        acpi_status status = AE_OK;
+       unsigned long long tmp;
        struct acpi_handle_list devices;
        int valid = 0;
        int i;
@@ -363,7 +363,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
        /* Critical Shutdown (required) */
        if (flag & ACPI_TRIPS_CRITICAL) {
                status = acpi_evaluate_integer(tz->device->handle,
-                               "_CRT", NULL, &tz->trips.critical.temperature);
+                               "_CRT", NULL, &tmp);
+               tz->trips.critical.temperature = tmp;
                /*
                 * Treat freezing temperatures as invalid as well; some
                 * BIOSes return really low values and cause reboots at startup.
@@ -388,10 +389,12 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
                        } else if (crt > 0) {
                                unsigned long crt_k = CELSIUS_TO_KELVIN(crt);
                                /*
-                                * Allow override to lower critical threshold
+                                * Allow override critical threshold
                                 */
-                               if (crt_k < tz->trips.critical.temperature)
-                                       tz->trips.critical.temperature = crt_k;
+                               if (crt_k > tz->trips.critical.temperature)
+                                       printk(KERN_WARNING PREFIX
+                                               "Critical threshold %d C\n", crt);
+                               tz->trips.critical.temperature = crt_k;
                        }
                }
        }
@@ -399,12 +402,13 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
        /* Critical Sleep (optional) */
        if (flag & ACPI_TRIPS_HOT) {
                status = acpi_evaluate_integer(tz->device->handle,
-                               "_HOT", NULL, &tz->trips.hot.temperature);
+                               "_HOT", NULL, &tmp);
                if (ACPI_FAILURE(status)) {
                        tz->trips.hot.flags.valid = 0;
                        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                        "No hot threshold\n"));
                } else {
+                       tz->trips.hot.temperature = tmp;
                        tz->trips.hot.flags.valid = 1;
                        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                        "Found hot threshold [%lu]\n",
@@ -418,33 +422,40 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
                if (psv == -1) {
                        status = AE_SUPPORT;
                } else if (psv > 0) {
-                       tz->trips.passive.temperature = CELSIUS_TO_KELVIN(psv);
+                       tmp = CELSIUS_TO_KELVIN(psv);
                        status = AE_OK;
                } else {
                        status = acpi_evaluate_integer(tz->device->handle,
-                               "_PSV", NULL, &tz->trips.passive.temperature);
+                               "_PSV", NULL, &tmp);
                }
 
                if (ACPI_FAILURE(status))
                        tz->trips.passive.flags.valid = 0;
                else {
+                       tz->trips.passive.temperature = tmp;
                        tz->trips.passive.flags.valid = 1;
                        if (flag == ACPI_TRIPS_INIT) {
                                status = acpi_evaluate_integer(
                                                tz->device->handle, "_TC1",
-                                               NULL, &tz->trips.passive.tc1);
+                                               NULL, &tmp);
                                if (ACPI_FAILURE(status))
                                        tz->trips.passive.flags.valid = 0;
+                               else
+                                       tz->trips.passive.tc1 = tmp;
                                status = acpi_evaluate_integer(
                                                tz->device->handle, "_TC2",
-                                               NULL, &tz->trips.passive.tc2);
+                                               NULL, &tmp);
                                if (ACPI_FAILURE(status))
                                        tz->trips.passive.flags.valid = 0;
+                               else
+                                       tz->trips.passive.tc2 = tmp;
                                status = acpi_evaluate_integer(
                                                tz->device->handle, "_TSP",
-                                               NULL, &tz->trips.passive.tsp);
+                                               NULL, &tmp);
                                if (ACPI_FAILURE(status))
                                        tz->trips.passive.flags.valid = 0;
+                               else
+                                       tz->trips.passive.tsp = tmp;
                        }
                }
        }
@@ -479,7 +490,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
 
                if (flag & ACPI_TRIPS_ACTIVE) {
                        status = acpi_evaluate_integer(tz->device->handle,
-                               name, NULL, &tz->trips.active[i].temperature);
+                                                       name, NULL, &tmp);
                        if (ACPI_FAILURE(status)) {
                                tz->trips.active[i].flags.valid = 0;
                                if (i == 0)
@@ -500,8 +511,10 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
                                                tz->trips.active[i - 2].temperature :
                                                CELSIUS_TO_KELVIN(act));
                                break;
-                       } else
+                       } else {
+                               tz->trips.active[i].temperature = tmp;
                                tz->trips.active[i].flags.valid = 1;
+                       }
                }
 
                name[2] = 'L';
@@ -1213,8 +1226,8 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
                                  acpi_bus_private_data_handler,
                                  tz->thermal_zone);
        if (ACPI_FAILURE(status)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                               "Error attaching device data\n"));
+               printk(KERN_ERR PREFIX
+                               "Error attaching device data\n");
                return -ENODEV;
        }
 
@@ -1647,7 +1660,7 @@ static int acpi_thermal_add(struct acpi_device *device)
        strcpy(tz->name, device->pnp.bus_id);
        strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
-       acpi_driver_data(device) = tz;
+       device->driver_data = tz;
        mutex_init(&tz->lock);
 
 
index 8a649f40d1620f0d9610e33f81a87da1d75a45f9..2a632f8b7a053911723a9259155a464ccb745aa8 100644 (file)
@@ -548,7 +548,7 @@ static unsigned long write_video(const char *buffer, unsigned long count)
 
        hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result);
        if (hci_result == HCI_SUCCESS) {
-               int new_video_out = video_out;
+               unsigned int new_video_out = video_out;
                if (lcd_out != -1)
                        _set_bit(&new_video_out, HCI_VIDEO_OUT_LCD, lcd_out);
                if (crt_out != -1)
index 7dcb67e0b215d1d56de71cff60edf3f4e56b2b9b..241c535c1753bb7f844a14805a8aaea88960e586 100644 (file)
@@ -232,7 +232,7 @@ acpi_status acpi_ut_validate_buffer(struct acpi_buffer * buffer)
  * RETURN:      Status
  *
  * DESCRIPTION: Validate that the buffer is of the required length or
- *              allocate a new buffer.  Returned buffer is always zeroed.
+ *              allocate a new buffer. Returned buffer is always zeroed.
  *
  ******************************************************************************/
 
@@ -240,7 +240,7 @@ acpi_status
 acpi_ut_initialize_buffer(struct acpi_buffer * buffer,
                          acpi_size required_length)
 {
-       acpi_status status = AE_OK;
+       acpi_size input_buffer_length;
 
        /* Parameter validation */
 
@@ -248,55 +248,58 @@ acpi_ut_initialize_buffer(struct acpi_buffer * buffer,
                return (AE_BAD_PARAMETER);
        }
 
-       switch (buffer->length) {
+       /*
+        * Buffer->Length is used as both an input and output parameter. Get the
+        * input actual length and set the output required buffer length.
+        */
+       input_buffer_length = buffer->length;
+       buffer->length = required_length;
+
+       /*
+        * The input buffer length contains the actual buffer length, or the type
+        * of buffer to be allocated by this routine.
+        */
+       switch (input_buffer_length) {
        case ACPI_NO_BUFFER:
 
-               /* Set the exception and returned the required length */
+               /* Return the exception (and the required buffer length) */
 
-               status = AE_BUFFER_OVERFLOW;
-               break;
+               return (AE_BUFFER_OVERFLOW);
 
        case ACPI_ALLOCATE_BUFFER:
 
                /* Allocate a new buffer */
 
                buffer->pointer = acpi_os_allocate(required_length);
-               if (!buffer->pointer) {
-                       return (AE_NO_MEMORY);
-               }
-
-               /* Clear the buffer */
-
-               ACPI_MEMSET(buffer->pointer, 0, required_length);
                break;
 
        case ACPI_ALLOCATE_LOCAL_BUFFER:
 
                /* Allocate a new buffer with local interface to allow tracking */
 
-               buffer->pointer = ACPI_ALLOCATE_ZEROED(required_length);
-               if (!buffer->pointer) {
-                       return (AE_NO_MEMORY);
-               }
+               buffer->pointer = ACPI_ALLOCATE(required_length);
                break;
 
        default:
 
                /* Existing buffer: Validate the size of the buffer */
 
-               if (buffer->length < required_length) {
-                       status = AE_BUFFER_OVERFLOW;
-                       break;
+               if (input_buffer_length < required_length) {
+                       return (AE_BUFFER_OVERFLOW);
                }
+               break;
+       }
 
-               /* Clear the buffer */
+       /* Validate allocation from above or input buffer pointer */
 
-               ACPI_MEMSET(buffer->pointer, 0, required_length);
-               break;
+       if (!buffer->pointer) {
+               return (AE_NO_MEMORY);
        }
 
-       buffer->length = required_length;
-       return (status);
+       /* Have a valid buffer, clear it */
+
+       ACPI_MEMSET(buffer->pointer, 0, required_length);
+       return (AE_OK);
 }
 
 #ifdef NOT_USED_BY_LINUX
index 53499ac90988a19477b39bd9c0113c14594cbf5f..5b2f7c27b705f2714c9fce18f997837ff8bdf6f3 100644 (file)
@@ -42,7 +42,6 @@
  */
 
 #include <acpi/acpi.h>
-#include <acpi/amlcode.h>
 #include <acpi/acnamesp.h>
 
 
@@ -176,20 +175,24 @@ acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
 
                /* This is an object reference. */
 
-               switch (internal_object->reference.opcode) {
-               case AML_INT_NAMEPATH_OP:
-
-                       /* For namepath, return the object handle ("reference") */
-
-               default:
-
-                       /* We are referring to the namespace node */
+               switch (internal_object->reference.class) {
+               case ACPI_REFCLASS_NAME:
 
+                       /*
+                        * For namepath, return the object handle ("reference")
+                        * We are referring to the namespace node
+                        */
                        external_object->reference.handle =
                            internal_object->reference.node;
                        external_object->reference.actual_type =
                            acpi_ns_get_type(internal_object->reference.node);
                        break;
+
+               default:
+
+                       /* All other reference types are unsupported */
+
+                       return_ACPI_STATUS(AE_TYPE);
                }
                break;
 
@@ -533,7 +536,7 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
 
                /* TBD: should validate incoming handle */
 
-               internal_object->reference.opcode = AML_INT_NAMEPATH_OP;
+               internal_object->reference.class = ACPI_REFCLASS_NAME;
                internal_object->reference.node =
                    external_object->reference.handle;
                break;
@@ -743,11 +746,11 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
                 * We copied the reference object, so we now must add a reference
                 * to the object pointed to by the reference
                 *
-                * DDBHandle reference (from Load/load_table is a special reference,
-                * it's Reference.Object is the table index, so does not need to
+                * DDBHandle reference (from Load/load_table) is a special reference,
+                * it does not have a Reference.Object, so does not need to
                 * increase the reference count
                 */
-               if (source_desc->reference.opcode == AML_LOAD_OP) {
+               if (source_desc->reference.class == ACPI_REFCLASS_TABLE) {
                        break;
                }
 
index 42609d3a8aa9db23f3852743f767ee1641b631af..d197c6b29e170e2381e2fcd0765c4368e090121a 100644 (file)
@@ -45,7 +45,6 @@
 #include <acpi/acinterp.h>
 #include <acpi/acnamesp.h>
 #include <acpi/acevents.h>
-#include <acpi/amlcode.h>
 
 #define _COMPONENT          ACPI_UTILITIES
 ACPI_MODULE_NAME("utdelete")
@@ -548,8 +547,8 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
                         * reference must track changes to the ref count of the index or
                         * target object.
                         */
-                       if ((object->reference.opcode == AML_INDEX_OP) ||
-                           (object->reference.opcode == AML_INT_NAMEPATH_OP)) {
+                       if ((object->reference.class == ACPI_REFCLASS_INDEX) ||
+                           (object->reference.class == ACPI_REFCLASS_NAME)) {
                                next_object = object->reference.object;
                        }
                        break;
@@ -586,6 +585,13 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
        ACPI_EXCEPTION((AE_INFO, status,
                        "Could not update object reference count"));
 
+       /* Free any stacked Update State objects */
+
+       while (state_list) {
+               state = acpi_ut_pop_generic_state(&state_list);
+               acpi_ut_delete_generic_state(state);
+       }
+
        return_ACPI_STATUS(status);
 }
 
index a6e71b801d2d5708642a90b76549175957aa2662..670551b95e56e44fecfc075d9cbd5255a2aebc55 100644 (file)
@@ -281,7 +281,6 @@ struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG] = {
        /* ACPI_BITREG_RT_CLOCK_ENABLE      */ {ACPI_REGISTER_PM1_ENABLE,
                                                ACPI_BITPOSITION_RT_CLOCK_ENABLE,
                                                ACPI_BITMASK_RT_CLOCK_ENABLE},
-       /* ACPI_BITREG_WAKE_ENABLE          */ {ACPI_REGISTER_PM1_ENABLE, 0, 0},
        /* ACPI_BITREG_PCIEXP_WAKE_DISABLE  */ {ACPI_REGISTER_PM1_ENABLE,
                                                ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE,
                                                ACPI_BITMASK_PCIEXP_WAKE_DISABLE},
@@ -575,6 +574,47 @@ char *acpi_ut_get_descriptor_name(void *object)
 
 }
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_reference_name
+ *
+ * PARAMETERS:  Object               - An ACPI reference object
+ *
+ * RETURN:      Pointer to a string
+ *
+ * DESCRIPTION: Decode a reference object sub-type to a string.
+ *
+ ******************************************************************************/
+
+/* Printable names of reference object sub-types */
+
+static const char *acpi_gbl_ref_class_names[] = {
+       /* 00 */ "Local",
+       /* 01 */ "Argument",
+       /* 02 */ "RefOf",
+       /* 03 */ "Index",
+       /* 04 */ "DdbHandle",
+       /* 05 */ "Named Object",
+       /* 06 */ "Debug"
+};
+
+const char *acpi_ut_get_reference_name(union acpi_operand_object *object)
+{
+       if (!object)
+               return "NULL Object";
+
+       if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND)
+               return "Not an Operand object";
+
+       if (object->common.type != ACPI_TYPE_LOCAL_REFERENCE)
+               return "Not a Reference object";
+
+       if (object->reference.class > ACPI_REFCLASS_MAX)
+               return "Unknown Reference class";
+
+       return acpi_gbl_ref_class_names[object->reference.class];
+}
+
 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
 /*
  * Strings and procedures used for debug only
@@ -677,14 +717,14 @@ u8 acpi_ut_valid_object_type(acpi_object_type type)
  *
  * PARAMETERS:  None
  *
- * RETURN:      None
+ * RETURN:      Status
  *
  * DESCRIPTION: Init library globals.  All globals that require specific
  *              initialization should be initialized here!
  *
  ******************************************************************************/
 
-void acpi_ut_init_globals(void)
+acpi_status acpi_ut_init_globals(void)
 {
        acpi_status status;
        u32 i;
@@ -695,7 +735,7 @@ void acpi_ut_init_globals(void)
 
        status = acpi_ut_create_caches();
        if (ACPI_FAILURE(status)) {
-               return;
+               return_ACPI_STATUS(status);
        }
 
        /* Mutex locked flags */
@@ -772,8 +812,8 @@ void acpi_ut_init_globals(void)
        acpi_gbl_display_final_mem_stats = FALSE;
 #endif
 
-       return_VOID;
+       return_ACPI_STATUS(AE_OK);
 }
 
 ACPI_EXPORT_SYMBOL(acpi_dbg_level)
-    ACPI_EXPORT_SYMBOL(acpi_dbg_layer)
+ACPI_EXPORT_SYMBOL(acpi_dbg_layer)
index f34be6773556beebd53f3dde5f63bc03a78e07cf..9089a158a8740c4fd47d5b75d56c6b3d6e350e67 100644 (file)
@@ -995,6 +995,15 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object,
                                                         state->pkg.
                                                         this_target_obj, 0);
                        if (!state) {
+
+                               /* Free any stacked Update State objects */
+
+                               while (state_list) {
+                                       state =
+                                           acpi_ut_pop_generic_state
+                                           (&state_list);
+                                       acpi_ut_delete_generic_state(state);
+                               }
                                return_ACPI_STATUS(AE_NO_MEMORY);
                        }
                }
index 916eff399eb3e6c8c9fdd7a00d8a37006621a0d0..c354e7a42bcde3ea4168ea0a0107a4b9ccfa358d 100644 (file)
@@ -43,7 +43,6 @@
 
 #include <acpi/acpi.h>
 #include <acpi/acnamesp.h>
-#include <acpi/amlcode.h>
 
 #define _COMPONENT          ACPI_UTILITIES
 ACPI_MODULE_NAME("utobject")
@@ -478,8 +477,8 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
 
        case ACPI_TYPE_LOCAL_REFERENCE:
 
-               switch (internal_object->reference.opcode) {
-               case AML_INT_NAMEPATH_OP:
+               switch (internal_object->reference.class) {
+               case ACPI_REFCLASS_NAME:
 
                        /*
                         * Get the actual length of the full pathname to this object.
@@ -503,8 +502,10 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
                         * required eventually.
                         */
                        ACPI_ERROR((AE_INFO,
-                                   "Unsupported Reference opcode=%X in object %p",
-                                   internal_object->reference.opcode,
+                                   "Cannot convert to external object - "
+                                   "unsupported Reference Class [%s] %X in object %p",
+                                   acpi_ut_get_reference_name(internal_object),
+                                   internal_object->reference.class,
                                    internal_object));
                        status = AE_TYPE;
                        break;
@@ -513,7 +514,9 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
 
        default:
 
-               ACPI_ERROR((AE_INFO, "Unsupported type=%X in object %p",
+               ACPI_ERROR((AE_INFO, "Cannot convert to external object - "
+                           "unsupported type [%s] %X in object %p",
+                           acpi_ut_get_object_type_name(internal_object),
                            ACPI_GET_OBJECT_TYPE(internal_object),
                            internal_object));
                status = AE_TYPE;
index f8bdadf3c32fffba99a72c5e4d905d9634331fdc..c198a4d40583e7f14fc0e1a545d496c118c98b96 100644 (file)
@@ -81,7 +81,12 @@ acpi_status __init acpi_initialize_subsystem(void)
 
        /* Initialize all globals used by the subsystem */
 
-       acpi_ut_init_globals();
+       status = acpi_ut_init_globals();
+       if (ACPI_FAILURE(status)) {
+               ACPI_EXCEPTION((AE_INFO, status,
+                               "During initialization of globals"));
+               return_ACPI_STATUS(status);
+       }
 
        /* Create the default mutex objects */
 
index 1009261438187d90e201f08ae4fd08d937a92bc1..e827be36ee8db99b4b8d648389cb7cc40df4064a 100644 (file)
@@ -256,7 +256,7 @@ EXPORT_SYMBOL(acpi_extract_package);
 acpi_status
 acpi_evaluate_integer(acpi_handle handle,
                      acpi_string pathname,
-                     struct acpi_object_list *arguments, unsigned long *data)
+                     struct acpi_object_list *arguments, unsigned long long *data)
 {
        acpi_status status = AE_OK;
        union acpi_object *element;
@@ -288,7 +288,7 @@ acpi_evaluate_integer(acpi_handle handle,
        *data = element->integer.value;
        kfree(element);
 
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%lu]\n", *data));
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%llu]\n", *data));
 
        return AE_OK;
 }
index e8a51a1700f710ca45d7ceba5a22429f7d348fbe..a29b0ccac65aa05c8e739526a27ea2b6e09e31b9 100644 (file)
@@ -291,20 +291,20 @@ static int acpi_video_device_lcd_set_level(struct acpi_video_device *device,
                        int level);
 static int acpi_video_device_lcd_get_level_current(
                        struct acpi_video_device *device,
-                       unsigned long *level);
+                       unsigned long long *level);
 static int acpi_video_get_next_level(struct acpi_video_device *device,
                                     u32 level_current, u32 event);
 static void acpi_video_switch_brightness(struct acpi_video_device *device,
                                         int event);
 static int acpi_video_device_get_state(struct acpi_video_device *device,
-                           unsigned long *state);
+                           unsigned long long *state);
 static int acpi_video_output_get(struct output_device *od);
 static int acpi_video_device_set_state(struct acpi_video_device *device, int state);
 
 /*backlight device sysfs support*/
 static int acpi_video_get_brightness(struct backlight_device *bd)
 {
-       unsigned long cur_level;
+       unsigned long long cur_level;
        int i;
        struct acpi_video_device *vd =
                (struct acpi_video_device *)bl_get_data(bd);
@@ -336,7 +336,7 @@ static struct backlight_ops acpi_backlight_ops = {
 /*video output device sysfs support*/
 static int acpi_video_output_get(struct output_device *od)
 {
-       unsigned long state;
+       unsigned long long state;
        struct acpi_video_device *vd =
                (struct acpi_video_device *)dev_get_drvdata(&od->dev);
        acpi_video_device_get_state(vd, &state);
@@ -370,7 +370,7 @@ static int video_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
 {
        struct acpi_device *device = cdev->devdata;
        struct acpi_video_device *video = acpi_driver_data(device);
-       unsigned long level;
+       unsigned long long level;
        int state;
 
        acpi_video_device_lcd_get_level_current(video, &level);
@@ -410,7 +410,7 @@ static struct thermal_cooling_device_ops video_cooling_ops = {
 /* device */
 
 static int
-acpi_video_device_query(struct acpi_video_device *device, unsigned long *state)
+acpi_video_device_query(struct acpi_video_device *device, unsigned long long *state)
 {
        int status;
 
@@ -421,7 +421,7 @@ acpi_video_device_query(struct acpi_video_device *device, unsigned long *state)
 
 static int
 acpi_video_device_get_state(struct acpi_video_device *device,
-                           unsigned long *state)
+                           unsigned long long *state)
 {
        int status;
 
@@ -436,7 +436,7 @@ acpi_video_device_set_state(struct acpi_video_device *device, int state)
        int status;
        union acpi_object arg0 = { ACPI_TYPE_INTEGER };
        struct acpi_object_list args = { 1, &arg0 };
-       unsigned long ret;
+       unsigned long long ret;
 
 
        arg0.integer.value = state;
@@ -495,7 +495,7 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
 
 static int
 acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
-                                       unsigned long *level)
+                                       unsigned long long *level)
 {
        if (device->cap._BQC)
                return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,
@@ -549,7 +549,7 @@ static int
 acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option)
 {
        int status;
-       unsigned long tmp;
+       unsigned long long tmp;
        union acpi_object arg0 = { ACPI_TYPE_INTEGER };
        struct acpi_object_list args = { 1, &arg0 };
 
@@ -564,7 +564,7 @@ acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option)
 }
 
 static int
-acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long *id)
+acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id)
 {
        int status;
 
@@ -575,7 +575,7 @@ acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long *id)
 
 static int
 acpi_video_bus_POST_options(struct acpi_video_bus *video,
-                           unsigned long *options)
+                           unsigned long long *options)
 {
        int status;
 
@@ -918,7 +918,7 @@ static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset)
 {
        int status;
        struct acpi_video_device *dev = seq->private;
-       unsigned long state;
+       unsigned long long state;
 
 
        if (!dev)
@@ -927,14 +927,14 @@ static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset)
        status = acpi_video_device_get_state(dev, &state);
        seq_printf(seq, "state:     ");
        if (ACPI_SUCCESS(status))
-               seq_printf(seq, "0x%02lx\n", state);
+               seq_printf(seq, "0x%02llx\n", state);
        else
                seq_printf(seq, "<not supported>\n");
 
        status = acpi_video_device_query(dev, &state);
        seq_printf(seq, "query:     ");
        if (ACPI_SUCCESS(status))
-               seq_printf(seq, "0x%02lx\n", state);
+               seq_printf(seq, "0x%02llx\n", state);
        else
                seq_printf(seq, "<not supported>\n");
 
@@ -1217,7 +1217,7 @@ static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file)
 static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
 {
        struct acpi_video_bus *video = seq->private;
-       unsigned long options;
+       unsigned long long options;
        int status;
 
 
@@ -1232,7 +1232,7 @@ static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
                        printk(KERN_WARNING PREFIX
                               "This indicates a BIOS bug. Please contact the manufacturer.\n");
                }
-               printk("%lx\n", options);
+               printk("%llx\n", options);
                seq_printf(seq, "can POST: <integrated video>");
                if (options & 2)
                        seq_printf(seq, " <PCI video>");
@@ -1256,7 +1256,7 @@ static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset)
 {
        struct acpi_video_bus *video = seq->private;
        int status;
-       unsigned long id;
+       unsigned long long id;
 
 
        if (!video)
@@ -1303,7 +1303,7 @@ acpi_video_bus_write_POST(struct file *file,
        struct seq_file *m = file->private_data;
        struct acpi_video_bus *video = m->private;
        char str[12] = { 0 };
-       unsigned long opt, options;
+       unsigned long long opt, options;
 
 
        if (!video || count + 1 > sizeof str)
@@ -1473,7 +1473,7 @@ static int
 acpi_video_bus_get_one_device(struct acpi_device *device,
                              struct acpi_video_bus *video)
 {
-       unsigned long device_id;
+       unsigned long long device_id;
        int status;
        struct acpi_video_device *data;
        struct acpi_video_device_attrib* attribute;
@@ -1491,7 +1491,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
 
                strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
                strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
-               acpi_driver_data(device) = data;
+               device->driver_data = data;
 
                data->device_id = device_id;
                data->video = video;
@@ -1530,8 +1530,8 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
                                                     acpi_video_device_notify,
                                                     data);
                if (ACPI_FAILURE(status)) {
-                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                                         "Error installing notify handler\n"));
+                       printk(KERN_ERR PREFIX
+                                         "Error installing notify handler\n");
                        if(data->brightness)
                                kfree(data->brightness->levels);
                        kfree(data->brightness);
@@ -1724,7 +1724,7 @@ acpi_video_get_next_level(struct acpi_video_device *device,
 static void
 acpi_video_switch_brightness(struct acpi_video_device *device, int event)
 {
-       unsigned long level_current, level_next;
+       unsigned long long level_current, level_next;
        if (!device->brightness)
                return;
        acpi_video_device_lcd_get_level_current(device, &level_current);
@@ -1745,8 +1745,8 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video,
 
                status = acpi_video_bus_get_one_device(dev, video);
                if (ACPI_FAILURE(status)) {
-                       ACPI_DEBUG_PRINT((ACPI_DB_WARN,
-                                       "Cant attach device"));
+                       printk(KERN_WARNING PREFIX
+                                       "Cant attach device");
                        continue;
                }
        }
@@ -1982,7 +1982,7 @@ static int acpi_video_bus_add(struct acpi_device *device)
        video->device = device;
        strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
        strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
-       acpi_driver_data(device) = video;
+       device->driver_data = video;
 
        acpi_video_bus_find_cap(video);
        error = acpi_video_bus_check(video);
@@ -2003,8 +2003,8 @@ static int acpi_video_bus_add(struct acpi_device *device)
                                             ACPI_DEVICE_NOTIFY,
                                             acpi_video_bus_notify, video);
        if (ACPI_FAILURE(status)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                                 "Error installing notify handler\n"));
+               printk(KERN_ERR PREFIX
+                                 "Error installing notify handler\n");
                error = -ENODEV;
                goto err_stop_video;
        }
@@ -2058,7 +2058,7 @@ static int acpi_video_bus_add(struct acpi_device *device)
        acpi_video_bus_remove_fs(device);
  err_free_video:
        kfree(video);
-       acpi_driver_data(device) = NULL;
+       device->driver_data = NULL;
 
        return error;
 }
index cfe2c833474d07e0a7dc6ddc35b6656c9bc4523a..47cd7baf9b1bd85fb327efc79186a7e6f5b1c461 100644 (file)
@@ -217,6 +217,35 @@ static bool find_guid(const char *guid_string, struct wmi_block **out)
        return 0;
 }
 
+static acpi_status wmi_method_enable(struct wmi_block *wblock, int enable)
+{
+       struct guid_block *block = NULL;
+       char method[5];
+       struct acpi_object_list input;
+       union acpi_object params[1];
+       acpi_status status;
+       acpi_handle handle;
+
+       block = &wblock->gblock;
+       handle = wblock->handle;
+
+       if (!block)
+               return AE_NOT_EXIST;
+
+       input.count = 1;
+       input.pointer = params;
+       params[0].type = ACPI_TYPE_INTEGER;
+       params[0].integer.value = enable;
+
+       snprintf(method, 5, "WE%02X", block->notify_id);
+       status = acpi_evaluate_object(handle, method, &input, NULL);
+
+       if (status != AE_OK && status != AE_NOT_FOUND)
+               return status;
+       else
+               return AE_OK;
+}
+
 /*
  * Exported WMI functions
  */
@@ -242,7 +271,7 @@ u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out)
        char method[4] = "WM";
 
        if (!find_guid(guid_string, &wblock))
-               return AE_BAD_ADDRESS;
+               return AE_ERROR;
 
        block = &wblock->gblock;
        handle = wblock->handle;
@@ -304,7 +333,7 @@ struct acpi_buffer *out)
                return AE_BAD_PARAMETER;
 
        if (!find_guid(guid_string, &wblock))
-               return AE_BAD_ADDRESS;
+               return AE_ERROR;
 
        block = &wblock->gblock;
        handle = wblock->handle;
@@ -314,7 +343,7 @@ struct acpi_buffer *out)
 
        /* Check GUID is a data block */
        if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD))
-               return AE_BAD_ADDRESS;
+               return AE_ERROR;
 
        input.count = 1;
        input.pointer = wq_params;
@@ -385,7 +414,7 @@ const struct acpi_buffer *in)
                return AE_BAD_DATA;
 
        if (!find_guid(guid_string, &wblock))
-               return AE_BAD_ADDRESS;
+               return AE_ERROR;
 
        block = &wblock->gblock;
        handle = wblock->handle;
@@ -395,7 +424,7 @@ const struct acpi_buffer *in)
 
        /* Check GUID is a data block */
        if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD))
-               return AE_BAD_ADDRESS;
+               return AE_ERROR;
 
        input.count = 2;
        input.pointer = params;
@@ -427,6 +456,7 @@ acpi_status wmi_install_notify_handler(const char *guid,
 wmi_notify_handler handler, void *data)
 {
        struct wmi_block *block;
+       acpi_status status;
 
        if (!guid || !handler)
                return AE_BAD_PARAMETER;
@@ -441,7 +471,9 @@ wmi_notify_handler handler, void *data)
        block->handler = handler;
        block->handler_data = data;
 
-       return AE_OK;
+       status = wmi_method_enable(block, 1);
+
+       return status;
 }
 EXPORT_SYMBOL_GPL(wmi_install_notify_handler);
 
@@ -453,6 +485,7 @@ EXPORT_SYMBOL_GPL(wmi_install_notify_handler);
 acpi_status wmi_remove_notify_handler(const char *guid)
 {
        struct wmi_block *block;
+       acpi_status status;
 
        if (!guid)
                return AE_BAD_PARAMETER;
@@ -464,10 +497,12 @@ acpi_status wmi_remove_notify_handler(const char *guid)
        if (!block->handler)
                return AE_NULL_ENTRY;
 
+       status = wmi_method_enable(block, 0);
+
        block->handler = NULL;
        block->handler_data = NULL;
 
-       return AE_OK;
+       return status;
 }
 EXPORT_SYMBOL_GPL(wmi_remove_notify_handler);
 
index 9330b7922f6281e758a795603d18e2550fb70da1..c012307d0ba6a726f7a0c9b30eac55f698da5b0b 100644 (file)
@@ -120,21 +120,6 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap)
                ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
 }
 
-static void ata_acpi_eject_device(acpi_handle handle)
-{
-       struct acpi_object_list arg_list;
-       union acpi_object arg;
-
-       arg_list.count = 1;
-       arg_list.pointer = &arg;
-       arg.type = ACPI_TYPE_INTEGER;
-       arg.integer.value = 1;
-
-       if (ACPI_FAILURE(acpi_evaluate_object(handle, "_EJ0",
-                                             &arg_list, NULL)))
-               printk(KERN_ERR "Failed to evaluate _EJ0!\n");
-}
-
 /* @ap and @dev are the same as ata_acpi_handle_hotplug() */
 static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
 {
@@ -157,7 +142,6 @@ static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
  * @ap: ATA port ACPI event occurred
  * @dev: ATA device ACPI event occurred (can be NULL)
  * @event: ACPI event which occurred
- * @is_dock_event: boolean indicating whether the event was a dock one
  *
  * All ACPI bay / device realted events end up in this function.  If
  * the event is port-wide @dev is NULL.  If the event is specific to a
@@ -171,117 +155,100 @@ static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
  * ACPI notify handler context.  May sleep.
  */
 static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
-                                   u32 event, int is_dock_event)
+                                   u32 event)
 {
-       char event_string[12];
-       char *envp[] = { event_string, NULL };
        struct ata_eh_info *ehi = &ap->link.eh_info;
-       struct kobject *kobj = NULL;
        int wait = 0;
        unsigned long flags;
-       acpi_handle handle, tmphandle;
-       unsigned long sta;
-       acpi_status status;
+       acpi_handle handle;
 
-       if (dev) {
-               if (dev->sdev)
-                       kobj = &dev->sdev->sdev_gendev.kobj;
+       if (dev)
                handle = dev->acpi_handle;
-       } else {
-               kobj = &ap->dev->kobj;
+       else
                handle = ap->acpi_handle;
-       }
-
-       status = acpi_get_handle(handle, "_EJ0", &tmphandle);
-       if (ACPI_FAILURE(status))
-               /* This device does not support hotplug */
-               return;
-
-       if (event == ACPI_NOTIFY_BUS_CHECK ||
-           event == ACPI_NOTIFY_DEVICE_CHECK)
-               status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
 
        spin_lock_irqsave(ap->lock, flags);
-
+       /*
+        * When dock driver calls into the routine, it will always use
+        * ACPI_NOTIFY_BUS_CHECK/ACPI_NOTIFY_DEVICE_CHECK for add and
+        * ACPI_NOTIFY_EJECT_REQUEST for remove
+        */
        switch (event) {
        case ACPI_NOTIFY_BUS_CHECK:
        case ACPI_NOTIFY_DEVICE_CHECK:
                ata_ehi_push_desc(ehi, "ACPI event");
 
-               if (ACPI_FAILURE(status)) {
-                       ata_port_printk(ap, KERN_ERR,
-                               "acpi: failed to determine bay status (0x%x)\n",
-                               status);
-                       break;
-               }
-
-               if (sta) {
-                       ata_ehi_hotplugged(ehi);
-                       ata_port_freeze(ap);
-               } else {
-                       /* The device has gone - unplug it */
-                       ata_acpi_detach_device(ap, dev);
-                       wait = 1;
-               }
+               ata_ehi_hotplugged(ehi);
+               ata_port_freeze(ap);
                break;
        case ACPI_NOTIFY_EJECT_REQUEST:
                ata_ehi_push_desc(ehi, "ACPI event");
 
-               if (!is_dock_event)
-                       break;
-
-               /* undock event - immediate unplug */
                ata_acpi_detach_device(ap, dev);
                wait = 1;
                break;
        }
 
-       /* make sure kobj doesn't go away while ap->lock is released */
-       kobject_get(kobj);
-
        spin_unlock_irqrestore(ap->lock, flags);
 
-       if (wait) {
+       if (wait)
                ata_port_wait_eh(ap);
-               ata_acpi_eject_device(handle);
-       }
-
-       if (kobj && !is_dock_event) {
-               sprintf(event_string, "BAY_EVENT=%d", event);
-               kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
-       }
-
-       kobject_put(kobj);
 }
 
 static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data)
 {
        struct ata_device *dev = data;
 
-       ata_acpi_handle_hotplug(dev->link->ap, dev, event, 1);
+       ata_acpi_handle_hotplug(dev->link->ap, dev, event);
 }
 
 static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data)
 {
        struct ata_port *ap = data;
 
-       ata_acpi_handle_hotplug(ap, NULL, event, 1);
+       ata_acpi_handle_hotplug(ap, NULL, event);
 }
 
-static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data)
+static void ata_acpi_uevent(struct ata_port *ap, struct ata_device *dev,
+       u32 event)
 {
-       struct ata_device *dev = data;
+       struct kobject *kobj = NULL;
+       char event_string[20];
+       char *envp[] = { event_string, NULL };
+
+       if (dev) {
+               if (dev->sdev)
+                       kobj = &dev->sdev->sdev_gendev.kobj;
+       } else
+               kobj = &ap->dev->kobj;
 
-       ata_acpi_handle_hotplug(dev->link->ap, dev, event, 0);
+       if (kobj) {
+               snprintf(event_string, 20, "BAY_EVENT=%d", event);
+               kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
+       }
 }
 
-static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data)
+static void ata_acpi_ap_uevent(acpi_handle handle, u32 event, void *data)
 {
-       struct ata_port *ap = data;
+       ata_acpi_uevent(data, NULL, event);
+}
 
-       ata_acpi_handle_hotplug(ap, NULL, event, 0);
+static void ata_acpi_dev_uevent(acpi_handle handle, u32 event, void *data)
+{
+       struct ata_device *dev = data;
+       ata_acpi_uevent(dev->link->ap, dev, event);
 }
 
+static struct acpi_dock_ops ata_acpi_dev_dock_ops = {
+       .handler = ata_acpi_dev_notify_dock,
+       .uevent = ata_acpi_dev_uevent,
+};
+
+static struct acpi_dock_ops ata_acpi_ap_dock_ops = {
+       .handler = ata_acpi_ap_notify_dock,
+       .uevent = ata_acpi_ap_uevent,
+};
+
 /**
  * ata_acpi_associate - associate ATA host with ACPI objects
  * @host: target ATA host
@@ -315,24 +282,18 @@ void ata_acpi_associate(struct ata_host *host)
                        ata_acpi_associate_ide_port(ap);
 
                if (ap->acpi_handle) {
-                       acpi_install_notify_handler(ap->acpi_handle,
-                                                   ACPI_SYSTEM_NOTIFY,
-                                                   ata_acpi_ap_notify, ap);
                        /* we might be on a docking station */
                        register_hotplug_dock_device(ap->acpi_handle,
-                                            ata_acpi_ap_notify_dock, ap);
+                                            &ata_acpi_ap_dock_ops, ap);
                }
 
                for (j = 0; j < ata_link_max_devices(&ap->link); j++) {
                        struct ata_device *dev = &ap->link.device[j];
 
                        if (dev->acpi_handle) {
-                               acpi_install_notify_handler(dev->acpi_handle,
-                                               ACPI_SYSTEM_NOTIFY,
-                                               ata_acpi_dev_notify, dev);
                                /* we might be on a docking station */
                                register_hotplug_dock_device(dev->acpi_handle,
-                                            ata_acpi_dev_notify_dock, dev);
+                                            &ata_acpi_dev_dock_ops, dev);
                        }
                }
        }
index 1ee9499bd343717ca95252a775c01d77ef3f892f..8cb0b360bfd83e7ae88909e3c5884f39c0191b7f 100644 (file)
@@ -1713,8 +1713,6 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
        else
                tag = 0;
 
-       if (test_and_set_bit(tag, &ap->qc_allocated))
-               BUG();
        qc = __ata_qc_from_tag(ap, tag);
 
        qc->tag = tag;
@@ -4552,37 +4550,6 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
 #endif /* __BIG_ENDIAN */
 }
 
-/**
- *     ata_qc_new - Request an available ATA command, for queueing
- *     @ap: Port associated with device @dev
- *     @dev: Device from whom we request an available command structure
- *
- *     LOCKING:
- *     None.
- */
-
-static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
-{
-       struct ata_queued_cmd *qc = NULL;
-       unsigned int i;
-
-       /* no command while frozen */
-       if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
-               return NULL;
-
-       /* the last tag is reserved for internal command. */
-       for (i = 0; i < ATA_MAX_QUEUE - 1; i++)
-               if (!test_and_set_bit(i, &ap->qc_allocated)) {
-                       qc = __ata_qc_from_tag(ap, i);
-                       break;
-               }
-
-       if (qc)
-               qc->tag = i;
-
-       return qc;
-}
-
 /**
  *     ata_qc_new_init - Request an available ATA command, and initialize it
  *     @dev: Device from whom we request an available command structure
@@ -4591,16 +4558,20 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
  *     None.
  */
 
-struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev)
+struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag)
 {
        struct ata_port *ap = dev->link->ap;
        struct ata_queued_cmd *qc;
 
-       qc = ata_qc_new(ap);
+       if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
+               return NULL;
+
+       qc = __ata_qc_from_tag(ap, tag);
        if (qc) {
                qc->scsicmd = NULL;
                qc->ap = ap;
                qc->dev = dev;
+               qc->tag = tag;
 
                ata_qc_reinit(qc);
        }
@@ -4608,31 +4579,6 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev)
        return qc;
 }
 
-/**
- *     ata_qc_free - free unused ata_queued_cmd
- *     @qc: Command to complete
- *
- *     Designed to free unused ata_queued_cmd object
- *     in case something prevents using it.
- *
- *     LOCKING:
- *     spin_lock_irqsave(host lock)
- */
-void ata_qc_free(struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       unsigned int tag;
-
-       WARN_ON(qc == NULL);    /* ata_qc_from_tag _might_ return NULL */
-
-       qc->flags = 0;
-       tag = qc->tag;
-       if (likely(ata_tag_valid(tag))) {
-               qc->tag = ATA_TAG_POISON;
-               clear_bit(tag, &ap->qc_allocated);
-       }
-}
-
 void __ata_qc_complete(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
@@ -5373,6 +5319,8 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
 
 #ifdef CONFIG_ATA_SFF
        INIT_DELAYED_WORK(&ap->port_task, ata_pio_task);
+#else
+       INIT_DELAYED_WORK(&ap->port_task, NULL);
 #endif
        INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug);
        INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);
index a93247cc395af0437ff2f88adbc2c9bac6ab5239..5d687d7cffaea9a3e50d28eae19e9cffdb08c975 100644 (file)
@@ -1206,7 +1206,10 @@ void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev,
 
        ata_eh_clear_action(link, dev, ehi, action);
 
-       if (!(ehc->i.flags & ATA_EHI_QUIET))
+       /* About to take EH action, set RECOVERED.  Ignore actions on
+        * slave links as master will do them again.
+        */
+       if (!(ehc->i.flags & ATA_EHI_QUIET) && link != ap->slave_link)
                ap->pflags |= ATA_PFLAG_RECOVERED;
 
        spin_unlock_irqrestore(ap->lock, flags);
@@ -2010,8 +2013,13 @@ void ata_eh_autopsy(struct ata_port *ap)
                struct ata_eh_context *mehc = &ap->link.eh_context;
                struct ata_eh_context *sehc = &ap->slave_link->eh_context;
 
+               /* transfer control flags from master to slave */
+               sehc->i.flags |= mehc->i.flags & ATA_EHI_TO_SLAVE_MASK;
+
+               /* perform autopsy on the slave link */
                ata_eh_link_autopsy(ap->slave_link);
 
+               /* transfer actions from slave to master and clear slave */
                ata_eh_about_to_do(ap->slave_link, NULL, ATA_EH_ALL_ACTIONS);
                mehc->i.action          |= sehc->i.action;
                mehc->i.dev_action[1]   |= sehc->i.dev_action[1];
@@ -2447,14 +2455,14 @@ int ata_eh_reset(struct ata_link *link, int classify,
                dev->pio_mode = XFER_PIO_0;
                dev->flags &= ~ATA_DFLAG_SLEEPING;
 
-               if (ata_phys_link_offline(ata_dev_phys_link(dev)))
-                       continue;
-
-               /* apply class override */
-               if (lflags & ATA_LFLAG_ASSUME_ATA)
-                       classes[dev->devno] = ATA_DEV_ATA;
-               else if (lflags & ATA_LFLAG_ASSUME_SEMB)
-                       classes[dev->devno] = ATA_DEV_SEMB_UNSUP; /* not yet */
+               if (!ata_phys_link_offline(ata_dev_phys_link(dev))) {
+                       /* apply class override */
+                       if (lflags & ATA_LFLAG_ASSUME_ATA)
+                               classes[dev->devno] = ATA_DEV_ATA;
+                       else if (lflags & ATA_LFLAG_ASSUME_SEMB)
+                               classes[dev->devno] = ATA_DEV_SEMB_UNSUP;
+               } else
+                       classes[dev->devno] = ATA_DEV_NONE;
        }
 
        /* record current link speed */
index 5d312dc9be9ff85fde2df8b7eca8274e3181fce2..d5b9b7266c8bc9c6549acc679ec7be1b827f6f22 100644 (file)
@@ -708,7 +708,7 @@ static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev,
 {
        struct ata_queued_cmd *qc;
 
-       qc = ata_qc_new_init(dev);
+       qc = ata_qc_new_init(dev, cmd->request->tag);
        if (qc) {
                qc->scsicmd = cmd;
                qc->scsidone = done;
@@ -1103,7 +1103,8 @@ static int ata_scsi_dev_config(struct scsi_device *sdev,
 
                depth = min(sdev->host->can_queue, ata_id_queue_depth(dev->id));
                depth = min(ATA_MAX_QUEUE - 1, depth);
-               scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth);
+               scsi_set_tag_type(sdev, MSG_SIMPLE_TAG);
+               scsi_activate_tcq(sdev, depth);
        }
 
        return 0;
@@ -1943,6 +1944,11 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
                hdr[1] |= (1 << 7);
 
        memcpy(rbuf, hdr, sizeof(hdr));
+
+       /* if ncq, set tags supported */
+       if (ata_id_has_ncq(args->id))
+               rbuf[7] |= (1 << 1);
+
        memcpy(&rbuf[8], "ATA     ", 8);
        ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16);
        ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV, 4);
index 2a4c516894f0018c7c370168b4ae004f25598546..4b47394863279606dc7427d79789bdc8c8485d99 100644 (file)
@@ -2153,8 +2153,17 @@ void ata_sff_error_handler(struct ata_port *ap)
  */
 void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc)
 {
-       if (qc->ap->ioaddr.bmdma_addr)
+       struct ata_port *ap = qc->ap;
+       unsigned long flags;
+
+       spin_lock_irqsave(ap->lock, flags);
+
+       ap->hsm_task_state = HSM_ST_IDLE;
+
+       if (ap->ioaddr.bmdma_addr)
                ata_bmdma_stop(qc);
+
+       spin_unlock_irqrestore(ap->lock, flags);
 }
 
 /**
index fe2839e58774f01b86b589e3aa59a9c140e0c0d2..d3831d39bdaa09980b44d46aa2bd773cd6949f5e 100644 (file)
@@ -74,7 +74,7 @@ extern struct ata_link *ata_dev_phys_link(struct ata_device *dev);
 extern void ata_force_cbl(struct ata_port *ap);
 extern u64 ata_tf_to_lba(const struct ata_taskfile *tf);
 extern u64 ata_tf_to_lba48(const struct ata_taskfile *tf);
-extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
+extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag);
 extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
                           u64 block, u32 n_block, unsigned int tf_flags,
                           unsigned int tag);
@@ -103,7 +103,6 @@ extern int ata_dev_configure(struct ata_device *dev);
 extern int sata_down_spd_limit(struct ata_link *link);
 extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel);
 extern void ata_sg_clean(struct ata_queued_cmd *qc);
-extern void ata_qc_free(struct ata_queued_cmd *qc);
 extern void ata_qc_issue(struct ata_queued_cmd *qc);
 extern void __ata_qc_complete(struct ata_queued_cmd *qc);
 extern int atapi_check_dma(struct ata_queued_cmd *qc);
@@ -119,6 +118,22 @@ extern struct ata_port *ata_port_alloc(struct ata_host *host);
 extern void ata_dev_enable_pm(struct ata_device *dev, enum link_pm policy);
 extern void ata_lpm_schedule(struct ata_port *ap, enum link_pm);
 
+/**
+ *     ata_qc_free - free unused ata_queued_cmd
+ *     @qc: Command to complete
+ *
+ *     Designed to free unused ata_queued_cmd object
+ *     in case something prevents using it.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host lock)
+ */
+static inline void ata_qc_free(struct ata_queued_cmd *qc)
+{
+       qc->flags = 0;
+       qc->tag = ATA_TAG_POISON;
+}
+
 /* libata-acpi.c */
 #ifdef CONFIG_ATA_ACPI
 extern void ata_acpi_associate_sata_port(struct ata_port *ap);
index 1cfa74535d91abed8d42a8c5699f9e2c30462c38..5b72e734300a19ff9bbc5554c46e80cc7f5edde7 100644 (file)
@@ -70,6 +70,7 @@ enum {
 static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 static int svia_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
 static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
+static void svia_tf_load(struct ata_port *ap, const struct ata_taskfile *tf);
 static void svia_noop_freeze(struct ata_port *ap);
 static int vt6420_prereset(struct ata_link *link, unsigned long deadline);
 static int vt6421_pata_cable_detect(struct ata_port *ap);
@@ -103,21 +104,26 @@ static struct scsi_host_template svia_sht = {
        ATA_BMDMA_SHT(DRV_NAME),
 };
 
-static struct ata_port_operations vt6420_sata_ops = {
+static struct ata_port_operations svia_base_ops = {
        .inherits               = &ata_bmdma_port_ops,
+       .sff_tf_load            = svia_tf_load,
+};
+
+static struct ata_port_operations vt6420_sata_ops = {
+       .inherits               = &svia_base_ops,
        .freeze                 = svia_noop_freeze,
        .prereset               = vt6420_prereset,
 };
 
 static struct ata_port_operations vt6421_pata_ops = {
-       .inherits               = &ata_bmdma_port_ops,
+       .inherits               = &svia_base_ops,
        .cable_detect           = vt6421_pata_cable_detect,
        .set_piomode            = vt6421_set_pio_mode,
        .set_dmamode            = vt6421_set_dma_mode,
 };
 
 static struct ata_port_operations vt6421_sata_ops = {
-       .inherits               = &ata_bmdma_port_ops,
+       .inherits               = &svia_base_ops,
        .scr_read               = svia_scr_read,
        .scr_write              = svia_scr_write,
 };
@@ -168,6 +174,29 @@ static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
        return 0;
 }
 
+/**
+ *     svia_tf_load - send taskfile registers to host controller
+ *     @ap: Port to which output is sent
+ *     @tf: ATA taskfile register set
+ *
+ *     Outputs ATA taskfile to standard ATA host controller.
+ *
+ *     This is to fix the internal bug of via chipsets, which will
+ *     reset the device register after changing the IEN bit on ctl
+ *     register.
+ */
+static void svia_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
+{
+       struct ata_taskfile ttf;
+
+       if (tf->ctl != ap->last_ctl)  {
+               ttf = *tf;
+               ttf.flags |= ATA_TFLAG_DEVICE;
+               tf = &ttf;
+       }
+       ata_sff_tf_load(ap, tf);
+}
+
 static void svia_noop_freeze(struct ata_port *ap)
 {
        /* Some VIA controllers choke if ATA_NIEN is manipulated in
index a002a381df921f466b1293574aafb7a4b52e2b6b..f6a337c34ac47e84a3d542b6d8e8af071bb49ffc 100644 (file)
@@ -72,9 +72,9 @@ static long disk_size(DAC960_Controller_T *p, int drive_nr)
        }
 }
 
-static int DAC960_open(struct inode *inode, struct file *file)
+static int DAC960_open(struct block_device *bdev, fmode_t mode)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
+       struct gendisk *disk = bdev->bd_disk;
        DAC960_Controller_T *p = disk->queue->queuedata;
        int drive_nr = (long)disk->private_data;
 
@@ -89,7 +89,7 @@ static int DAC960_open(struct inode *inode, struct file *file)
                        return -ENXIO;
        }
 
-       check_disk_change(inode->i_bdev);
+       check_disk_change(bdev);
 
        if (!get_capacity(p->disks[drive_nr]))
                return -ENXIO;
index 7516baff3bb914116742b12a634ba4ab95db361a..4b1d4ac960f1d87e39880372fa2cd29b703e1b29 100644 (file)
@@ -1437,10 +1437,11 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
        return 0;
 }
 
-static int fd_ioctl(struct inode *inode, struct file *filp,
+static int fd_ioctl(struct block_device *bdev, fmode_t mode,
                    unsigned int cmd, unsigned long param)
 {
-       int drive = iminor(inode) & 3;
+       struct amiga_floppy_struct *p = bdev->bd_disk->private_data;
+       int drive = p - unit;
        static struct floppy_struct getprm;
        void __user *argp = (void __user *)param;
 
@@ -1451,7 +1452,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
                        rel_fdc();
                        return -EBUSY;
                }
-               fsync_bdev(inode->i_bdev);
+               fsync_bdev(bdev);
                if (fd_motor_on(drive) == 0) {
                        rel_fdc();
                        return -ENODEV;
@@ -1464,12 +1465,12 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
                rel_fdc();
                break;
        case FDFMTTRK:
-               if (param < unit[drive].type->tracks * unit[drive].type->heads)
+               if (param < p->type->tracks * p->type->heads)
                {
                        get_fdc(drive);
                        if (fd_seek(drive,param) != 0){
-                               memset(unit[drive].trackbuf, FD_FILL_BYTE,
-                                      unit[drive].dtype->sects * unit[drive].type->sect_mult * 512);
+                               memset(p->trackbuf, FD_FILL_BYTE,
+                                      p->dtype->sects * p->type->sect_mult * 512);
                                non_int_flush_track(drive);
                        }
                        floppy_off(drive);
@@ -1480,14 +1481,14 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
                break;
        case FDFMTEND:
                floppy_off(drive);
-               invalidate_bdev(inode->i_bdev);
+               invalidate_bdev(bdev);
                break;
        case FDGETPRM:
                memset((void *)&getprm, 0, sizeof (getprm));
-               getprm.track=unit[drive].type->tracks;
-               getprm.head=unit[drive].type->heads;
-               getprm.sect=unit[drive].dtype->sects * unit[drive].type->sect_mult;
-               getprm.size=unit[drive].blocks;
+               getprm.track=p->type->tracks;
+               getprm.head=p->type->heads;
+               getprm.sect=p->dtype->sects * p->type->sect_mult;
+               getprm.size=p->blocks;
                if (copy_to_user(argp, &getprm, sizeof(struct floppy_struct)))
                        return -EFAULT;
                break;
@@ -1500,10 +1501,10 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
                break;
 #ifdef RAW_IOCTL
        case IOCTL_RAW_TRACK:
-               if (copy_to_user(argp, raw_buf, unit[drive].type->read_size))
+               if (copy_to_user(argp, raw_buf, p->type->read_size))
                        return -EFAULT;
                else
-                       return unit[drive].type->read_size;
+                       return p->type->read_size;
 #endif
        default:
                printk(KERN_DEBUG "fd_ioctl: unknown cmd %d for drive %d.",
@@ -1548,10 +1549,10 @@ static void fd_probe(int dev)
  * /dev/PS0 etc), and disallows simultaneous access to the same
  * drive with different device numbers.
  */
-static int floppy_open(struct inode *inode, struct file *filp)
+static int floppy_open(struct block_device *bdev, fmode_t mode)
 {
-       int drive = iminor(inode) & 3;
-       int system =  (iminor(inode) & 4) >> 2;
+       int drive = MINOR(bdev->bd_dev) & 3;
+       int system =  (MINOR(bdev->bd_dev) & 4) >> 2;
        int old_dev;
        unsigned long flags;
 
@@ -1560,9 +1561,9 @@ static int floppy_open(struct inode *inode, struct file *filp)
        if (fd_ref[drive] && old_dev != system)
                return -EBUSY;
 
-       if (filp && filp->f_mode & 3) {
-               check_disk_change(inode->i_bdev);
-               if (filp->f_mode & 2 ) {
+       if (mode & (FMODE_READ|FMODE_WRITE)) {
+               check_disk_change(bdev);
+               if (mode & FMODE_WRITE) {
                        int wrprot;
 
                        get_fdc(drive);
@@ -1592,9 +1593,10 @@ static int floppy_open(struct inode *inode, struct file *filp)
        return 0;
 }
 
-static int floppy_release(struct inode * inode, struct file * filp)
+static int floppy_release(struct gendisk *disk, fmode_t mode)
 {
-       int drive = iminor(inode) & 3;
+       struct amiga_floppy_struct *p = disk->private_data;
+       int drive = p - unit;
 
        if (unit[drive].dirty == 1) {
                del_timer (flush_track_timer + drive);
@@ -1650,7 +1652,7 @@ static struct block_device_operations floppy_fops = {
        .owner          = THIS_MODULE,
        .open           = floppy_open,
        .release        = floppy_release,
-       .ioctl          = fd_ioctl,
+       .locked_ioctl   = fd_ioctl,
        .getgeo         = fd_getgeo,
        .media_changed  = amiga_floppy_change,
 };
index d876ad861237d9367abdf3df8ef9606274d0ebfb..1747dd272cd476bd1c14b03be0ee0c8f5faf17dd 100644 (file)
@@ -118,13 +118,11 @@ aoedisk_rm_sysfs(struct aoedev *d)
 }
 
 static int
-aoeblk_open(struct inode *inode, struct file *filp)
+aoeblk_open(struct block_device *bdev, fmode_t mode)
 {
-       struct aoedev *d;
+       struct aoedev *d = bdev->bd_disk->private_data;
        ulong flags;
 
-       d = inode->i_bdev->bd_disk->private_data;
-
        spin_lock_irqsave(&d->lock, flags);
        if (d->flags & DEVFL_UP) {
                d->nopen++;
@@ -136,13 +134,11 @@ aoeblk_open(struct inode *inode, struct file *filp)
 }
 
 static int
-aoeblk_release(struct inode *inode, struct file *filp)
+aoeblk_release(struct gendisk *disk, fmode_t mode)
 {
-       struct aoedev *d;
+       struct aoedev *d = disk->private_data;
        ulong flags;
 
-       d = inode->i_bdev->bd_disk->private_data;
-
        spin_lock_irqsave(&d->lock, flags);
 
        if (--d->nopen == 0) {
index 432cf40182916366b71fad0b9c4f8e1131b2ef66..69e1df7dfa14a4447c6797a0b6f1f6d8c18993fb 100644 (file)
@@ -361,13 +361,13 @@ static void finish_fdc( void );
 static void finish_fdc_done( int dummy );
 static void setup_req_params( int drive );
 static void redo_fd_request( void);
-static int fd_ioctl( struct inode *inode, struct file *filp, unsigned int
+static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int
                      cmd, unsigned long param);
 static void fd_probe( int drive );
 static int fd_test_drive_present( int drive );
 static void config_types( void );
-static int floppy_open( struct inode *inode, struct file *filp );
-static int floppy_release( struct inode * inode, struct file * filp );
+static int floppy_open(struct block_device *bdev, fmode_t mode);
+static int floppy_release(struct gendisk *disk, fmode_t mode);
 
 /************************* End of Prototypes **************************/
 
@@ -1483,10 +1483,10 @@ void do_fd_request(struct request_queue * q)
        atari_enable_irq( IRQ_MFP_FDC );
 }
 
-static int fd_ioctl(struct inode *inode, struct file *filp,
+static int fd_ioctl(struct block_device *bdev, fmode_t mode,
                    unsigned int cmd, unsigned long param)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
+       struct gendisk *disk = bdev->bd_disk;
        struct atari_floppy_struct *floppy = disk->private_data;
        int drive = floppy - unit;
        int type = floppy->type;
@@ -1661,7 +1661,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
                /* invalidate the buffer track to force a reread */
                BufferDrive = -1;
                set_bit(drive, &fake_change);
-               check_disk_change(inode->i_bdev);
+               check_disk_change(bdev);
                return 0;
        default:
                return -EINVAL;
@@ -1804,37 +1804,36 @@ static void __init config_types( void )
  * drive with different device numbers.
  */
 
-static int floppy_open( struct inode *inode, struct file *filp )
+static int floppy_open(struct block_device *bdev, fmode_t mode)
 {
-       struct atari_floppy_struct *p = inode->i_bdev->bd_disk->private_data;
-       int type  = iminor(inode) >> 2;
+       struct atari_floppy_struct *p = bdev->bd_disk->private_data;
+       int type  = MINOR(bdev->bd_dev) >> 2;
 
        DPRINT(("fd_open: type=%d\n",type));
        if (p->ref && p->type != type)
                return -EBUSY;
 
-       if (p->ref == -1 || (p->ref && filp->f_flags & O_EXCL))
+       if (p->ref == -1 || (p->ref && mode & FMODE_EXCL))
                return -EBUSY;
 
-       if (filp->f_flags & O_EXCL)
+       if (mode & FMODE_EXCL)
                p->ref = -1;
        else
                p->ref++;
 
        p->type = type;
 
-       if (filp->f_flags & O_NDELAY)
+       if (mode & FMODE_NDELAY)
                return 0;
 
-       if (filp->f_mode & 3) {
-               check_disk_change(inode->i_bdev);
-               if (filp->f_mode & 2) {
+       if (mode & (FMODE_READ|FMODE_WRITE)) {
+               check_disk_change(bdev);
+               if (mode & FMODE_WRITE) {
                        if (p->wpstat) {
                                if (p->ref < 0)
                                        p->ref = 0;
                                else
                                        p->ref--;
-                               floppy_release(inode, filp);
                                return -EROFS;
                        }
                }
@@ -1843,9 +1842,9 @@ static int floppy_open( struct inode *inode, struct file *filp )
 }
 
 
-static int floppy_release( struct inode * inode, struct file * filp )
+static int floppy_release(struct gendisk *disk, fmode_t mode)
 {
-       struct atari_floppy_struct *p = inode->i_bdev->bd_disk->private_data;
+       struct atari_floppy_struct *p = disk->private_data;
        if (p->ref < 0)
                p->ref = 0;
        else if (!p->ref--) {
@@ -1859,7 +1858,7 @@ static struct block_device_operations floppy_fops = {
        .owner          = THIS_MODULE,
        .open           = floppy_open,
        .release        = floppy_release,
-       .ioctl          = fd_ioctl,
+       .locked_ioctl   = fd_ioctl,
        .media_changed  = check_floppy_change,
        .revalidate_disk= floppy_revalidate,
 };
index d070d492e385b26893e34d514cbda0fa6cb5e34f..bdd4f5f45575bbf1b0bd69df7f68ed09a52a3776 100644 (file)
@@ -340,11 +340,10 @@ static int brd_direct_access (struct block_device *bdev, sector_t sector,
 }
 #endif
 
-static int brd_ioctl(struct inode *inode, struct file *file,
+static int brd_ioctl(struct block_device *bdev, fmode_t mode,
                        unsigned int cmd, unsigned long arg)
 {
        int error;
-       struct block_device *bdev = inode->i_bdev;
        struct brd_device *brd = bdev->bd_disk->private_data;
 
        if (cmd != BLKFLSBUF)
@@ -376,7 +375,7 @@ static int brd_ioctl(struct inode *inode, struct file *file,
 
 static struct block_device_operations brd_fops = {
        .owner =                THIS_MODULE,
-       .ioctl =                brd_ioctl,
+       .locked_ioctl =         brd_ioctl,
 #ifdef CONFIG_BLK_DEV_XIP
        .direct_access =        brd_direct_access,
 #endif
index 1e1f9153000c27638e854142017fc61f6b49a094..4023885353e095e75d179f7ed8f649cd1abbb5a2 100644 (file)
@@ -152,9 +152,9 @@ static ctlr_info_t *hba[MAX_CTLR];
 
 static void do_cciss_request(struct request_queue *q);
 static irqreturn_t do_cciss_intr(int irq, void *dev_id);
-static int cciss_open(struct inode *inode, struct file *filep);
-static int cciss_release(struct inode *inode, struct file *filep);
-static int cciss_ioctl(struct inode *inode, struct file *filep,
+static int cciss_open(struct block_device *bdev, fmode_t mode);
+static int cciss_release(struct gendisk *disk, fmode_t mode);
+static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
                       unsigned int cmd, unsigned long arg);
 static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo);
 
@@ -192,14 +192,15 @@ static void cciss_procinit(int i)
 #endif                         /* CONFIG_PROC_FS */
 
 #ifdef CONFIG_COMPAT
-static long cciss_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg);
+static int cciss_compat_ioctl(struct block_device *, fmode_t,
+                             unsigned, unsigned long);
 #endif
 
 static struct block_device_operations cciss_fops = {
        .owner = THIS_MODULE,
        .open = cciss_open,
        .release = cciss_release,
-       .ioctl = cciss_ioctl,
+       .locked_ioctl = cciss_ioctl,
        .getgeo = cciss_getgeo,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = cciss_compat_ioctl,
@@ -547,13 +548,13 @@ static inline drive_info_struct *get_drv(struct gendisk *disk)
 /*
  * Open.  Make sure the device is really there.
  */
-static int cciss_open(struct inode *inode, struct file *filep)
+static int cciss_open(struct block_device *bdev, fmode_t mode)
 {
-       ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
-       drive_info_struct *drv = get_drv(inode->i_bdev->bd_disk);
+       ctlr_info_t *host = get_host(bdev->bd_disk);
+       drive_info_struct *drv = get_drv(bdev->bd_disk);
 
 #ifdef CCISS_DEBUG
-       printk(KERN_DEBUG "cciss_open %s\n", inode->i_bdev->bd_disk->disk_name);
+       printk(KERN_DEBUG "cciss_open %s\n", bdev->bd_disk->disk_name);
 #endif                         /* CCISS_DEBUG */
 
        if (host->busy_initializing || drv->busy_configuring)
@@ -567,9 +568,9 @@ static int cciss_open(struct inode *inode, struct file *filep)
         * for "raw controller".
         */
        if (drv->heads == 0) {
-               if (iminor(inode) != 0) {       /* not node 0? */
+               if (MINOR(bdev->bd_dev) != 0) { /* not node 0? */
                        /* if not node 0 make sure it is a partition = 0 */
-                       if (iminor(inode) & 0x0f) {
+                       if (MINOR(bdev->bd_dev) & 0x0f) {
                                return -ENXIO;
                                /* if it is, make sure we have a LUN ID */
                        } else if (drv->LunID == 0) {
@@ -587,14 +588,13 @@ static int cciss_open(struct inode *inode, struct file *filep)
 /*
  * Close.  Sync first.
  */
-static int cciss_release(struct inode *inode, struct file *filep)
+static int cciss_release(struct gendisk *disk, fmode_t mode)
 {
-       ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
-       drive_info_struct *drv = get_drv(inode->i_bdev->bd_disk);
+       ctlr_info_t *host = get_host(disk);
+       drive_info_struct *drv = get_drv(disk);
 
 #ifdef CCISS_DEBUG
-       printk(KERN_DEBUG "cciss_release %s\n",
-              inode->i_bdev->bd_disk->disk_name);
+       printk(KERN_DEBUG "cciss_release %s\n", disk->disk_name);
 #endif                         /* CCISS_DEBUG */
 
        drv->usage_count--;
@@ -604,21 +604,23 @@ static int cciss_release(struct inode *inode, struct file *filep)
 
 #ifdef CONFIG_COMPAT
 
-static int do_ioctl(struct file *f, unsigned cmd, unsigned long arg)
+static int do_ioctl(struct block_device *bdev, fmode_t mode,
+                   unsigned cmd, unsigned long arg)
 {
        int ret;
        lock_kernel();
-       ret = cciss_ioctl(f->f_path.dentry->d_inode, f, cmd, arg);
+       ret = cciss_ioctl(bdev, mode, cmd, arg);
        unlock_kernel();
        return ret;
 }
 
-static int cciss_ioctl32_passthru(struct file *f, unsigned cmd,
-                                 unsigned long arg);
-static int cciss_ioctl32_big_passthru(struct file *f, unsigned cmd,
-                                     unsigned long arg);
+static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode,
+                                 unsigned cmd, unsigned long arg);
+static int cciss_ioctl32_big_passthru(struct block_device *bdev, fmode_t mode,
+                                     unsigned cmd, unsigned long arg);
 
-static long cciss_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg)
+static int cciss_compat_ioctl(struct block_device *bdev, fmode_t mode,
+                             unsigned cmd, unsigned long arg)
 {
        switch (cmd) {
        case CCISS_GETPCIINFO:
@@ -636,20 +638,20 @@ static long cciss_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg)
        case CCISS_REGNEWD:
        case CCISS_RESCANDISK:
        case CCISS_GETLUNINFO:
-               return do_ioctl(f, cmd, arg);
+               return do_ioctl(bdev, mode, cmd, arg);
 
        case CCISS_PASSTHRU32:
-               return cciss_ioctl32_passthru(f, cmd, arg);
+               return cciss_ioctl32_passthru(bdev, mode, cmd, arg);
        case CCISS_BIG_PASSTHRU32:
-               return cciss_ioctl32_big_passthru(f, cmd, arg);
+               return cciss_ioctl32_big_passthru(bdev, mode, cmd, arg);
 
        default:
                return -ENOIOCTLCMD;
        }
 }
 
-static int cciss_ioctl32_passthru(struct file *f, unsigned cmd,
-                                 unsigned long arg)
+static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode,
+                                 unsigned cmd, unsigned long arg)
 {
        IOCTL32_Command_struct __user *arg32 =
            (IOCTL32_Command_struct __user *) arg;
@@ -676,7 +678,7 @@ static int cciss_ioctl32_passthru(struct file *f, unsigned cmd,
        if (err)
                return -EFAULT;
 
-       err = do_ioctl(f, CCISS_PASSTHRU, (unsigned long)p);
+       err = do_ioctl(bdev, mode, CCISS_PASSTHRU, (unsigned long)p);
        if (err)
                return err;
        err |=
@@ -687,8 +689,8 @@ static int cciss_ioctl32_passthru(struct file *f, unsigned cmd,
        return err;
 }
 
-static int cciss_ioctl32_big_passthru(struct file *file, unsigned cmd,
-                                     unsigned long arg)
+static int cciss_ioctl32_big_passthru(struct block_device *bdev, fmode_t mode,
+                                     unsigned cmd, unsigned long arg)
 {
        BIG_IOCTL32_Command_struct __user *arg32 =
            (BIG_IOCTL32_Command_struct __user *) arg;
@@ -717,7 +719,7 @@ static int cciss_ioctl32_big_passthru(struct file *file, unsigned cmd,
        if (err)
                return -EFAULT;
 
-       err = do_ioctl(file, CCISS_BIG_PASSTHRU, (unsigned long)p);
+       err = do_ioctl(bdev, mode, CCISS_BIG_PASSTHRU, (unsigned long)p);
        if (err)
                return err;
        err |=
@@ -745,10 +747,9 @@ static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 /*
  * ioctl
  */
-static int cciss_ioctl(struct inode *inode, struct file *filep,
+static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
                       unsigned int cmd, unsigned long arg)
 {
-       struct block_device *bdev = inode->i_bdev;
        struct gendisk *disk = bdev->bd_disk;
        ctlr_info_t *host = get_host(disk);
        drive_info_struct *drv = get_drv(disk);
@@ -1232,7 +1233,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
        case SG_EMULATED_HOST:
        case SG_IO:
        case SCSI_IOCTL_SEND_COMMAND:
-               return scsi_cmd_ioctl(filep, disk->queue, disk, cmd, argp);
+               return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp);
 
        /* scsi_cmd_ioctl would normally handle these, below, but */
        /* they aren't a good fit for cciss, as CD-ROMs are */
index 3d967525e9a96f0bfafcb7aa1d95a9e9e42b4fc8..47d233c6d0b33879b83994c8d39757de940e82cd 100644 (file)
@@ -156,9 +156,9 @@ static int sendcmd(
        unsigned int blkcnt,
        unsigned int log_unit );
 
-static int ida_open(struct inode *inode, struct file *filep);
-static int ida_release(struct inode *inode, struct file *filep);
-static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg);
+static int ida_open(struct block_device *bdev, fmode_t mode);
+static int ida_release(struct gendisk *disk, fmode_t mode);
+static int ida_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg);
 static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo);
 static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io);
 
@@ -197,7 +197,7 @@ static struct block_device_operations ida_fops  = {
        .owner          = THIS_MODULE,
        .open           = ida_open,
        .release        = ida_release,
-       .ioctl          = ida_ioctl,
+       .locked_ioctl   = ida_ioctl,
        .getgeo         = ida_getgeo,
        .revalidate_disk= ida_revalidate,
 };
@@ -818,12 +818,12 @@ DBGINFO(
 /*
  * Open.  Make sure the device is really there.
  */
-static int ida_open(struct inode *inode, struct file *filep)
+static int ida_open(struct block_device *bdev, fmode_t mode)
 {
-       drv_info_t *drv = get_drv(inode->i_bdev->bd_disk);
-       ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
+       drv_info_t *drv = get_drv(bdev->bd_disk);
+       ctlr_info_t *host = get_host(bdev->bd_disk);
 
-       DBGINFO(printk("ida_open %s\n", inode->i_bdev->bd_disk->disk_name));
+       DBGINFO(printk("ida_open %s\n", bdev->bd_disk->disk_name));
        /*
         * Root is allowed to open raw volume zero even if it's not configured
         * so array config can still work.  I don't think I really like this,
@@ -843,9 +843,9 @@ static int ida_open(struct inode *inode, struct file *filep)
 /*
  * Close.  Sync first.
  */
-static int ida_release(struct inode *inode, struct file *filep)
+static int ida_release(struct gendisk *disk, fmode_t mode)
 {
-       ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
+       ctlr_info_t *host = get_host(disk);
        host->usage_count--;
        return 0;
 }
@@ -1128,10 +1128,10 @@ static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo)
  *  ida_ioctl does some miscellaneous stuff like reporting drive geometry,
  *  setting readahead and submitting commands from userspace to the controller.
  */
-static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg)
+static int ida_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg)
 {
-       drv_info_t *drv = get_drv(inode->i_bdev->bd_disk);
-       ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
+       drv_info_t *drv = get_drv(bdev->bd_disk);
+       ctlr_info_t *host = get_host(bdev->bd_disk);
        int error;
        ida_ioctl_t __user *io = (ida_ioctl_t __user *)arg;
        ida_ioctl_t *my_io;
@@ -1165,7 +1165,7 @@ out_passthru:
                put_user(host->ctlr_sig, (int __user *)arg);
                return 0;
        case IDAREVALIDATEVOLS:
-               if (iminor(inode) != 0)
+               if (MINOR(bdev->bd_dev) != 0)
                        return -ENXIO;
                return revalidate_allvol(host);
        case IDADRIVERVERSION:
index 2cea27aba9a06c385d62efc49749753da0ae26ce..14db747a636e93a33766e4faf23dbd5b48e5e8bd 100644 (file)
@@ -3450,14 +3450,14 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
        return 0;
 }
 
-static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
+static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
                    unsigned long param)
 {
-#define FD_IOCTL_ALLOWED ((filp) && (filp)->private_data)
+#define FD_IOCTL_ALLOWED (mode & (FMODE_WRITE|FMODE_WRITE_IOCTL))
 #define OUT(c,x) case c: outparam = (const char *) (x); break
 #define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0
 
-       int drive = (long)inode->i_bdev->bd_disk->private_data;
+       int drive = (long)bdev->bd_disk->private_data;
        int type = ITYPE(UDRS->fd_device);
        int i;
        int ret;
@@ -3516,11 +3516,11 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
                        current_type[drive] = NULL;
                        floppy_sizes[drive] = MAX_DISK_SIZE << 1;
                        UDRS->keep_data = 0;
-                       return invalidate_drive(inode->i_bdev);
+                       return invalidate_drive(bdev);
                case FDSETPRM:
                case FDDEFPRM:
                        return set_geometry(cmd, &inparam.g,
-                                           drive, type, inode->i_bdev);
+                                           drive, type, bdev);
                case FDGETPRM:
                        ECALL(get_floppy_geometry(drive, type,
                                                  (struct floppy_struct **)
@@ -3551,7 +3551,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
                case FDFMTEND:
                case FDFLUSH:
                        LOCK_FDC(drive, 1);
-                       return invalidate_drive(inode->i_bdev);
+                       return invalidate_drive(bdev);
 
                case FDSETEMSGTRESH:
                        UDP->max_errors.reporting =
@@ -3659,9 +3659,9 @@ static void __init config_types(void)
                printk("\n");
 }
 
-static int floppy_release(struct inode *inode, struct file *filp)
+static int floppy_release(struct gendisk *disk, fmode_t mode)
 {
-       int drive = (long)inode->i_bdev->bd_disk->private_data;
+       int drive = (long)disk->private_data;
 
        mutex_lock(&open_lock);
        if (UDRS->fd_ref < 0)
@@ -3682,18 +3682,17 @@ static int floppy_release(struct inode *inode, struct file *filp)
  * /dev/PS0 etc), and disallows simultaneous access to the same
  * drive with different device numbers.
  */
-static int floppy_open(struct inode *inode, struct file *filp)
+static int floppy_open(struct block_device *bdev, fmode_t mode)
 {
-       int drive = (long)inode->i_bdev->bd_disk->private_data;
-       int old_dev;
+       int drive = (long)bdev->bd_disk->private_data;
+       int old_dev, new_dev;
        int try;
        int res = -EBUSY;
        char *tmp;
 
-       filp->private_data = (void *)0;
        mutex_lock(&open_lock);
        old_dev = UDRS->fd_device;
-       if (opened_bdev[drive] && opened_bdev[drive] != inode->i_bdev)
+       if (opened_bdev[drive] && opened_bdev[drive] != bdev)
                goto out2;
 
        if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)) {
@@ -3701,15 +3700,15 @@ static int floppy_open(struct inode *inode, struct file *filp)
                USETF(FD_VERIFY);
        }
 
-       if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
+       if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (mode & FMODE_EXCL)))
                goto out2;
 
-       if (filp->f_flags & O_EXCL)
+       if (mode & FMODE_EXCL)
                UDRS->fd_ref = -1;
        else
                UDRS->fd_ref++;
 
-       opened_bdev[drive] = inode->i_bdev;
+       opened_bdev[drive] = bdev;
 
        res = -ENXIO;
 
@@ -3744,31 +3743,26 @@ static int floppy_open(struct inode *inode, struct file *filp)
                }
        }
 
-       UDRS->fd_device = iminor(inode);
-       set_capacity(disks[drive], floppy_sizes[iminor(inode)]);
-       if (old_dev != -1 && old_dev != iminor(inode)) {
+       new_dev = MINOR(bdev->bd_dev);
+       UDRS->fd_device = new_dev;
+       set_capacity(disks[drive], floppy_sizes[new_dev]);
+       if (old_dev != -1 && old_dev != new_dev) {
                if (buffer_drive == drive)
                        buffer_track = -1;
        }
 
-       /* Allow ioctls if we have write-permissions even if read-only open.
-        * Needed so that programs such as fdrawcmd still can work on write
-        * protected disks */
-       if ((filp->f_mode & FMODE_WRITE) || !file_permission(filp, MAY_WRITE))
-               filp->private_data = (void *)8;
-
        if (UFDCS->rawcmd == 1)
                UFDCS->rawcmd = 2;
 
-       if (!(filp->f_flags & O_NDELAY)) {
-               if (filp->f_mode & 3) {
+       if (!(mode & FMODE_NDELAY)) {
+               if (mode & (FMODE_READ|FMODE_WRITE)) {
                        UDRS->last_checked = 0;
-                       check_disk_change(inode->i_bdev);
+                       check_disk_change(bdev);
                        if (UTESTF(FD_DISK_CHANGED))
                                goto out;
                }
                res = -EROFS;
-               if ((filp->f_mode & 2) && !(UTESTF(FD_DISK_WRITABLE)))
+               if ((mode & FMODE_WRITE) && !(UTESTF(FD_DISK_WRITABLE)))
                        goto out;
        }
        mutex_unlock(&open_lock);
@@ -3911,7 +3905,7 @@ static struct block_device_operations floppy_fops = {
        .owner                  = THIS_MODULE,
        .open                   = floppy_open,
        .release                = floppy_release,
-       .ioctl                  = fd_ioctl,
+       .locked_ioctl           = fd_ioctl,
        .getgeo                 = fd_getgeo,
        .media_changed          = check_floppy_change,
        .revalidate_disk        = floppy_revalidate,
index d3a25b027ff9fc5e6331372a252b5e134b6270c4..3f09cd8bcc38e1d1b16787c2d83114316406585f 100644 (file)
@@ -210,7 +210,7 @@ lo_do_transfer(struct loop_device *lo, int cmd,
  * space operations write_begin and write_end.
  */
 static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec,
-               int bsize, loff_t pos, struct page *unused)
+               loff_t pos, struct page *unused)
 {
        struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */
        struct address_space *mapping = file->f_mapping;
@@ -302,7 +302,7 @@ static int __do_lo_send_write(struct file *file,
  * filesystems.
  */
 static int do_lo_send_direct_write(struct loop_device *lo,
-               struct bio_vec *bvec, int bsize, loff_t pos, struct page *page)
+               struct bio_vec *bvec, loff_t pos, struct page *page)
 {
        ssize_t bw = __do_lo_send_write(lo->lo_backing_file,
                        kmap(bvec->bv_page) + bvec->bv_offset,
@@ -326,7 +326,7 @@ static int do_lo_send_direct_write(struct loop_device *lo,
  * destination pages of the backing file.
  */
 static int do_lo_send_write(struct loop_device *lo, struct bio_vec *bvec,
-               int bsize, loff_t pos, struct page *page)
+               loff_t pos, struct page *page)
 {
        int ret = lo_do_transfer(lo, WRITE, page, 0, bvec->bv_page,
                        bvec->bv_offset, bvec->bv_len, pos >> 9);
@@ -341,10 +341,9 @@ static int do_lo_send_write(struct loop_device *lo, struct bio_vec *bvec,
        return ret;
 }
 
-static int lo_send(struct loop_device *lo, struct bio *bio, int bsize,
-               loff_t pos)
+static int lo_send(struct loop_device *lo, struct bio *bio, loff_t pos)
 {
-       int (*do_lo_send)(struct loop_device *, struct bio_vec *, int, loff_t,
+       int (*do_lo_send)(struct loop_device *, struct bio_vec *, loff_t,
                        struct page *page);
        struct bio_vec *bvec;
        struct page *page = NULL;
@@ -362,7 +361,7 @@ static int lo_send(struct loop_device *lo, struct bio *bio, int bsize,
                }
        }
        bio_for_each_segment(bvec, bio, i) {
-               ret = do_lo_send(lo, bvec, bsize, pos, page);
+               ret = do_lo_send(lo, bvec, pos, page);
                if (ret < 0)
                        break;
                pos += bvec->bv_len;
@@ -478,7 +477,7 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
 
        pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset;
        if (bio_rw(bio) == WRITE)
-               ret = lo_send(lo, bio, lo->lo_blocksize, pos);
+               ret = lo_send(lo, bio, pos);
        else
                ret = lo_receive(lo, bio, lo->lo_blocksize, pos);
        return ret;
@@ -652,8 +651,8 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
  * This can only work if the loop device is used read-only, and if the
  * new backing store is the same size and type as the old backing store.
  */
-static int loop_change_fd(struct loop_device *lo, struct file *lo_file,
-                      struct block_device *bdev, unsigned int arg)
+static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
+                         unsigned int arg)
 {
        struct file     *file, *old_file;
        struct inode    *inode;
@@ -712,7 +711,7 @@ static inline int is_loop_device(struct file *file)
        return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
 }
 
-static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
+static int loop_set_fd(struct loop_device *lo, fmode_t mode,
                       struct block_device *bdev, unsigned int arg)
 {
        struct file     *file, *f;
@@ -740,7 +739,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
        while (is_loop_device(f)) {
                struct loop_device *l;
 
-               if (f->f_mapping->host->i_rdev == lo_file->f_mapping->host->i_rdev)
+               if (f->f_mapping->host->i_bdev == bdev)
                        goto out_putf;
 
                l = f->f_mapping->host->i_bdev->bd_disk->private_data;
@@ -786,7 +785,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
                goto out_putf;
        }
 
-       if (!(lo_file->f_mode & FMODE_WRITE))
+       if (!(mode & FMODE_WRITE))
                lo_flags |= LO_FLAGS_READ_ONLY;
 
        set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0);
@@ -918,9 +917,11 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
        memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
        memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
        memset(lo->lo_file_name, 0, LO_NAME_SIZE);
-       invalidate_bdev(bdev);
+       if (bdev)
+               invalidate_bdev(bdev);
        set_capacity(lo->lo_disk, 0);
-       bd_set_size(bdev, 0);
+       if (bdev)
+               bd_set_size(bdev, 0);
        mapping_set_gfp_mask(filp->f_mapping, gfp);
        lo->lo_state = Lo_unbound;
        fput(filp);
@@ -1137,22 +1138,22 @@ loop_get_status64(struct loop_device *lo, struct loop_info64 __user *arg) {
        return err;
 }
 
-static int lo_ioctl(struct inode * inode, struct file * file,
+static int lo_ioctl(struct block_device *bdev, fmode_t mode,
        unsigned int cmd, unsigned long arg)
 {
-       struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
+       struct loop_device *lo = bdev->bd_disk->private_data;
        int err;
 
        mutex_lock(&lo->lo_ctl_mutex);
        switch (cmd) {
        case LOOP_SET_FD:
-               err = loop_set_fd(lo, file, inode->i_bdev, arg);
+               err = loop_set_fd(lo, mode, bdev, arg);
                break;
        case LOOP_CHANGE_FD:
-               err = loop_change_fd(lo, file, inode->i_bdev, arg);
+               err = loop_change_fd(lo, bdev, arg);
                break;
        case LOOP_CLR_FD:
-               err = loop_clr_fd(lo, inode->i_bdev);
+               err = loop_clr_fd(lo, bdev);
                break;
        case LOOP_SET_STATUS:
                err = loop_set_status_old(lo, (struct loop_info __user *) arg);
@@ -1292,10 +1293,10 @@ loop_get_status_compat(struct loop_device *lo,
        return err;
 }
 
-static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode,
+                          unsigned int cmd, unsigned long arg)
 {
-       struct inode *inode = file->f_path.dentry->d_inode;
-       struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
+       struct loop_device *lo = bdev->bd_disk->private_data;
        int err;
 
        switch(cmd) {
@@ -1317,7 +1318,7 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a
                arg = (unsigned long) compat_ptr(arg);
        case LOOP_SET_FD:
        case LOOP_CHANGE_FD:
-               err = lo_ioctl(inode, file, cmd, arg);
+               err = lo_ioctl(bdev, mode, cmd, arg);
                break;
        default:
                err = -ENOIOCTLCMD;
@@ -1327,9 +1328,9 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a
 }
 #endif
 
-static int lo_open(struct inode *inode, struct file *file)
+static int lo_open(struct block_device *bdev, fmode_t mode)
 {
-       struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
+       struct loop_device *lo = bdev->bd_disk->private_data;
 
        mutex_lock(&lo->lo_ctl_mutex);
        lo->lo_refcnt++;
@@ -1338,15 +1339,15 @@ static int lo_open(struct inode *inode, struct file *file)
        return 0;
 }
 
-static int lo_release(struct inode *inode, struct file *file)
+static int lo_release(struct gendisk *disk, fmode_t mode)
 {
-       struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
+       struct loop_device *lo = disk->private_data;
 
        mutex_lock(&lo->lo_ctl_mutex);
        --lo->lo_refcnt;
 
        if ((lo->lo_flags & LO_FLAGS_AUTOCLEAR) && !lo->lo_refcnt)
-               loop_clr_fd(lo, inode->i_bdev);
+               loop_clr_fd(lo, NULL);
 
        mutex_unlock(&lo->lo_ctl_mutex);
 
index 9034ca585afd710d6425d53f7b6357c13357a6af..d3a91cacee8c6aff410bc9a8567ce89cb1ae477f 100644 (file)
@@ -557,10 +557,11 @@ static void do_nbd_request(struct request_queue * q)
        }
 }
 
-static int nbd_ioctl(struct inode *inode, struct file *file,
+static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
                     unsigned int cmd, unsigned long arg)
 {
-       struct nbd_device *lo = inode->i_bdev->bd_disk->private_data;
+       struct nbd_device *lo = bdev->bd_disk->private_data;
+       struct file *file;
        int error;
        struct request sreq ;
        struct task_struct *thread;
@@ -612,8 +613,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
                error = -EINVAL;
                file = fget(arg);
                if (file) {
-                       struct block_device *bdev = inode->i_bdev;
-                       inode = file->f_path.dentry->d_inode;
+                       struct inode *inode = file->f_path.dentry->d_inode;
                        if (S_ISSOCK(inode->i_mode)) {
                                lo->file = file;
                                lo->sock = SOCKET_I(inode);
@@ -628,14 +628,14 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
        case NBD_SET_BLKSIZE:
                lo->blksize = arg;
                lo->bytesize &= ~(lo->blksize-1);
-               inode->i_bdev->bd_inode->i_size = lo->bytesize;
-               set_blocksize(inode->i_bdev, lo->blksize);
+               bdev->bd_inode->i_size = lo->bytesize;
+               set_blocksize(bdev, lo->blksize);
                set_capacity(lo->disk, lo->bytesize >> 9);
                return 0;
        case NBD_SET_SIZE:
                lo->bytesize = arg & ~(lo->blksize-1);
-               inode->i_bdev->bd_inode->i_size = lo->bytesize;
-               set_blocksize(inode->i_bdev, lo->blksize);
+               bdev->bd_inode->i_size = lo->bytesize;
+               set_blocksize(bdev, lo->blksize);
                set_capacity(lo->disk, lo->bytesize >> 9);
                return 0;
        case NBD_SET_TIMEOUT:
@@ -643,8 +643,8 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
                return 0;
        case NBD_SET_SIZE_BLOCKS:
                lo->bytesize = ((u64) arg) * lo->blksize;
-               inode->i_bdev->bd_inode->i_size = lo->bytesize;
-               set_blocksize(inode->i_bdev, lo->blksize);
+               bdev->bd_inode->i_size = lo->bytesize;
+               set_blocksize(bdev, lo->blksize);
                set_capacity(lo->disk, lo->bytesize >> 9);
                return 0;
        case NBD_DO_IT:
@@ -666,10 +666,10 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
                if (file)
                        fput(file);
                lo->bytesize = 0;
-               inode->i_bdev->bd_inode->i_size = 0;
+               bdev->bd_inode->i_size = 0;
                set_capacity(lo->disk, 0);
                if (max_part > 0)
-                       ioctl_by_bdev(inode->i_bdev, BLKRRPART, 0);
+                       ioctl_by_bdev(bdev, BLKRRPART, 0);
                return lo->harderror;
        case NBD_CLEAR_QUE:
                /*
@@ -680,7 +680,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
                return 0;
        case NBD_PRINT_DEBUG:
                printk(KERN_INFO "%s: next = %p, prev = %p, head = %p\n",
-                       inode->i_bdev->bd_disk->disk_name,
+                       bdev->bd_disk->disk_name,
                        lo->queue_head.next, lo->queue_head.prev,
                        &lo->queue_head);
                return 0;
@@ -691,7 +691,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
 static struct block_device_operations nbd_fops =
 {
        .owner =        THIS_MODULE,
-       .ioctl =        nbd_ioctl,
+       .locked_ioctl = nbd_ioctl,
 };
 
 /*
index b8a994a2b0132b01f7c2ef5ba141c7aae4de7ad0..e91d4b4b014fc5997ce88ef3edbf09366cb95a80 100644 (file)
@@ -223,23 +223,24 @@ static int pcd_warned;            /* Have we logged a phase warning ? */
 
 /* kernel glue structures */
 
-static int pcd_block_open(struct inode *inode, struct file *file)
+static int pcd_block_open(struct block_device *bdev, fmode_t mode)
 {
-       struct pcd_unit *cd = inode->i_bdev->bd_disk->private_data;
-       return cdrom_open(&cd->info, inode, file);
+       struct pcd_unit *cd = bdev->bd_disk->private_data;
+       return cdrom_open(&cd->info, bdev, mode);
 }
 
-static int pcd_block_release(struct inode *inode, struct file *file)
+static int pcd_block_release(struct gendisk *disk, fmode_t mode)
 {
-       struct pcd_unit *cd = inode->i_bdev->bd_disk->private_data;
-       return cdrom_release(&cd->info, file);
+       struct pcd_unit *cd = disk->private_data;
+       cdrom_release(&cd->info, mode);
+       return 0;
 }
 
-static int pcd_block_ioctl(struct inode *inode, struct file *file,
+static int pcd_block_ioctl(struct block_device *bdev, fmode_t mode,
                                unsigned cmd, unsigned long arg)
 {
-       struct pcd_unit *cd = inode->i_bdev->bd_disk->private_data;
-       return cdrom_ioctl(file, &cd->info, inode, cmd, arg);
+       struct pcd_unit *cd = bdev->bd_disk->private_data;
+       return cdrom_ioctl(&cd->info, bdev, mode, cmd, arg);
 }
 
 static int pcd_block_media_changed(struct gendisk *disk)
@@ -252,7 +253,7 @@ static struct block_device_operations pcd_bdops = {
        .owner          = THIS_MODULE,
        .open           = pcd_block_open,
        .release        = pcd_block_release,
-       .ioctl          = pcd_block_ioctl,
+       .locked_ioctl   = pcd_block_ioctl,
        .media_changed  = pcd_block_media_changed,
 };
 
index 5fdfa7c888cebc98aacc9873a9f7216f79c3a1f5..9299455b0af678d3176a9c7a431f544583e13faa 100644 (file)
@@ -728,9 +728,9 @@ static int pd_special_command(struct pd_unit *disk,
 
 /* kernel glue structures */
 
-static int pd_open(struct inode *inode, struct file *file)
+static int pd_open(struct block_device *bdev, fmode_t mode)
 {
-       struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
+       struct pd_unit *disk = bdev->bd_disk->private_data;
 
        disk->access++;
 
@@ -758,10 +758,10 @@ static int pd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
        return 0;
 }
 
-static int pd_ioctl(struct inode *inode, struct file *file,
+static int pd_ioctl(struct block_device *bdev, fmode_t mode,
         unsigned int cmd, unsigned long arg)
 {
-       struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
+       struct pd_unit *disk = bdev->bd_disk->private_data;
 
        switch (cmd) {
        case CDROMEJECT:
@@ -773,9 +773,9 @@ static int pd_ioctl(struct inode *inode, struct file *file,
        }
 }
 
-static int pd_release(struct inode *inode, struct file *file)
+static int pd_release(struct gendisk *p, fmode_t mode)
 {
-       struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
+       struct pd_unit *disk = p->private_data;
 
        if (!--disk->access && disk->removable)
                pd_special_command(disk, pd_door_unlock);
@@ -809,7 +809,7 @@ static struct block_device_operations pd_fops = {
        .owner          = THIS_MODULE,
        .open           = pd_open,
        .release        = pd_release,
-       .ioctl          = pd_ioctl,
+       .locked_ioctl   = pd_ioctl,
        .getgeo         = pd_getgeo,
        .media_changed  = pd_check_media,
        .revalidate_disk= pd_revalidate
index e7fe6ca97dd8a4027142a763bcc8cdc4018e52f4..bef3b997ba3e39d11b85917b31b20f6e96a27f1c 100644 (file)
@@ -201,13 +201,13 @@ module_param_array(drive3, int, NULL, 0);
 #define ATAPI_READ_10          0x28
 #define ATAPI_WRITE_10         0x2a
 
-static int pf_open(struct inode *inode, struct file *file);
+static int pf_open(struct block_device *bdev, fmode_t mode);
 static void do_pf_request(struct request_queue * q);
-static int pf_ioctl(struct inode *inode, struct file *file,
+static int pf_ioctl(struct block_device *bdev, fmode_t mode,
                    unsigned int cmd, unsigned long arg);
 static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo);
 
-static int pf_release(struct inode *inode, struct file *file);
+static int pf_release(struct gendisk *disk, fmode_t mode);
 
 static int pf_detect(void);
 static void do_pf_read(void);
@@ -266,7 +266,7 @@ static struct block_device_operations pf_fops = {
        .owner          = THIS_MODULE,
        .open           = pf_open,
        .release        = pf_release,
-       .ioctl          = pf_ioctl,
+       .locked_ioctl   = pf_ioctl,
        .getgeo         = pf_getgeo,
        .media_changed  = pf_check_media,
 };
@@ -296,16 +296,16 @@ static void __init pf_init_units(void)
        }
 }
 
-static int pf_open(struct inode *inode, struct file *file)
+static int pf_open(struct block_device *bdev, fmode_t mode)
 {
-       struct pf_unit *pf = inode->i_bdev->bd_disk->private_data;
+       struct pf_unit *pf = bdev->bd_disk->private_data;
 
        pf_identify(pf);
 
        if (pf->media_status == PF_NM)
                return -ENODEV;
 
-       if ((pf->media_status == PF_RO) && (file->f_mode & 2))
+       if ((pf->media_status == PF_RO) && (mode & FMODE_WRITE))
                return -EROFS;
 
        pf->access++;
@@ -333,9 +333,9 @@ static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo)
        return 0;
 }
 
-static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static int pf_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg)
 {
-       struct pf_unit *pf = inode->i_bdev->bd_disk->private_data;
+       struct pf_unit *pf = bdev->bd_disk->private_data;
 
        if (cmd != CDROMEJECT)
                return -EINVAL;
@@ -346,9 +346,9 @@ static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
        return 0;
 }
 
-static int pf_release(struct inode *inode, struct file *file)
+static int pf_release(struct gendisk *disk, fmode_t mode)
 {
-       struct pf_unit *pf = inode->i_bdev->bd_disk->private_data;
+       struct pf_unit *pf = disk->private_data;
 
        if (pf->access <= 0)
                return -EINVAL;
index 5ae229656eaa0114e6d80508d1b3ad4417726fd8..1e4006e18f03060138709ed6930e770211e5706e 100644 (file)
@@ -667,7 +667,7 @@ static int pt_open(struct inode *inode, struct file *file)
                goto out;
 
        err = -EROFS;
-       if ((!(tape->flags & PT_WRITE_OK)) && (file->f_mode & 2))
+       if ((!(tape->flags & PT_WRITE_OK)) && (file->f_mode & FMODE_WRITE))
                goto out;
 
        if (!(iminor(inode) & 128))
index 195ca7c720f584efd0592e072096547423773357..f20bf359b84f20e7ff10f7081f54b37371e12f18 100644 (file)
@@ -2320,7 +2320,7 @@ static int pkt_open_write(struct pktcdvd_device *pd)
 /*
  * called at open time.
  */
-static int pkt_open_dev(struct pktcdvd_device *pd, int write)
+static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write)
 {
        int ret;
        long lba;
@@ -2332,7 +2332,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write)
         * so bdget() can't fail.
         */
        bdget(pd->bdev->bd_dev);
-       if ((ret = blkdev_get(pd->bdev, FMODE_READ, O_RDONLY)))
+       if ((ret = blkdev_get(pd->bdev, FMODE_READ)))
                goto out;
 
        if ((ret = bd_claim(pd->bdev, pd)))
@@ -2381,7 +2381,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write)
 out_unclaim:
        bd_release(pd->bdev);
 out_putdev:
-       blkdev_put(pd->bdev);
+       blkdev_put(pd->bdev, FMODE_READ);
 out:
        return ret;
 }
@@ -2399,7 +2399,7 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush)
 
        pkt_set_speed(pd, MAX_SPEED, MAX_SPEED);
        bd_release(pd->bdev);
-       blkdev_put(pd->bdev);
+       blkdev_put(pd->bdev, FMODE_READ);
 
        pkt_shrink_pktlist(pd);
 }
@@ -2411,7 +2411,7 @@ static struct pktcdvd_device *pkt_find_dev_from_minor(int dev_minor)
        return pkt_devs[dev_minor];
 }
 
-static int pkt_open(struct inode *inode, struct file *file)
+static int pkt_open(struct block_device *bdev, fmode_t mode)
 {
        struct pktcdvd_device *pd = NULL;
        int ret;
@@ -2419,7 +2419,7 @@ static int pkt_open(struct inode *inode, struct file *file)
        VPRINTK(DRIVER_NAME": entering open\n");
 
        mutex_lock(&ctl_mutex);
-       pd = pkt_find_dev_from_minor(iminor(inode));
+       pd = pkt_find_dev_from_minor(MINOR(bdev->bd_dev));
        if (!pd) {
                ret = -ENODEV;
                goto out;
@@ -2428,20 +2428,20 @@ static int pkt_open(struct inode *inode, struct file *file)
 
        pd->refcnt++;
        if (pd->refcnt > 1) {
-               if ((file->f_mode & FMODE_WRITE) &&
+               if ((mode & FMODE_WRITE) &&
                    !test_bit(PACKET_WRITABLE, &pd->flags)) {
                        ret = -EBUSY;
                        goto out_dec;
                }
        } else {
-               ret = pkt_open_dev(pd, file->f_mode & FMODE_WRITE);
+               ret = pkt_open_dev(pd, mode & FMODE_WRITE);
                if (ret)
                        goto out_dec;
                /*
                 * needed here as well, since ext2 (among others) may change
                 * the blocksize at mount time
                 */
-               set_blocksize(inode->i_bdev, CD_FRAMESIZE);
+               set_blocksize(bdev, CD_FRAMESIZE);
        }
 
        mutex_unlock(&ctl_mutex);
@@ -2455,9 +2455,9 @@ out:
        return ret;
 }
 
-static int pkt_close(struct inode *inode, struct file *file)
+static int pkt_close(struct gendisk *disk, fmode_t mode)
 {
-       struct pktcdvd_device *pd = inode->i_bdev->bd_disk->private_data;
+       struct pktcdvd_device *pd = disk->private_data;
        int ret = 0;
 
        mutex_lock(&ctl_mutex);
@@ -2765,7 +2765,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
        bdev = bdget(dev);
        if (!bdev)
                return -ENOMEM;
-       ret = blkdev_get(bdev, FMODE_READ, O_RDONLY | O_NONBLOCK);
+       ret = blkdev_get(bdev, FMODE_READ | FMODE_NDELAY);
        if (ret)
                return ret;
 
@@ -2790,19 +2790,28 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
        return 0;
 
 out_mem:
-       blkdev_put(bdev);
+       blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
        /* This is safe: open() is still holding a reference. */
        module_put(THIS_MODULE);
        return ret;
 }
 
-static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static int pkt_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg)
 {
-       struct pktcdvd_device *pd = inode->i_bdev->bd_disk->private_data;
+       struct pktcdvd_device *pd = bdev->bd_disk->private_data;
 
-       VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, imajor(inode), iminor(inode));
+       VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd,
+               MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev));
 
        switch (cmd) {
+       case CDROMEJECT:
+               /*
+                * The door gets locked when the device is opened, so we
+                * have to unlock it or else the eject command fails.
+                */
+               if (pd->refcnt == 1)
+                       pkt_lock_door(pd, 0);
+               /* fallthru */
        /*
         * forward selected CDROM ioctls to CD-ROM, for UDF
         */
@@ -2811,16 +2820,7 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
        case CDROM_LAST_WRITTEN:
        case CDROM_SEND_PACKET:
        case SCSI_IOCTL_SEND_COMMAND:
-               return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg);
-
-       case CDROMEJECT:
-               /*
-                * The door gets locked when the device is opened, so we
-                * have to unlock it or else the eject command fails.
-                */
-               if (pd->refcnt == 1)
-                       pkt_lock_door(pd, 0);
-               return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg);
+               return __blkdev_driver_ioctl(pd->bdev, mode, cmd, arg);
 
        default:
                VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd);
@@ -2849,7 +2849,7 @@ static struct block_device_operations pktcdvd_ops = {
        .owner =                THIS_MODULE,
        .open =                 pkt_open,
        .release =              pkt_close,
-       .ioctl =                pkt_ioctl,
+       .locked_ioctl =         pkt_ioctl,
        .media_changed =        pkt_media_changed,
 };
 
@@ -2975,7 +2975,7 @@ static int pkt_remove_dev(dev_t pkt_dev)
        pkt_debugfs_dev_remove(pd);
        pkt_sysfs_dev_remove(pd);
 
-       blkdev_put(pd->bdev);
+       blkdev_put(pd->bdev, FMODE_READ|FMODE_WRITE);
 
        remove_proc_entry(pd->name, pkt_proc);
        DPRINTK(DRIVER_NAME": writer %s unmapped\n", pd->name);
index 730ccea78e45e0f112a4ff256b90f6cf5475ffb7..612965307ba009e04c8f733a870a5b4df69b4572 100644 (file)
@@ -244,10 +244,10 @@ static int grab_drive(struct floppy_state *fs, enum swim_state state,
                      int interruptible);
 static void release_drive(struct floppy_state *fs);
 static int fd_eject(struct floppy_state *fs);
-static int floppy_ioctl(struct inode *inode, struct file *filp,
+static int floppy_ioctl(struct block_device *bdev, fmode_t mode,
                        unsigned int cmd, unsigned long param);
-static int floppy_open(struct inode *inode, struct file *filp);
-static int floppy_release(struct inode *inode, struct file *filp);
+static int floppy_open(struct block_device *bdev, fmode_t mode);
+static int floppy_release(struct gendisk *disk, fmode_t mode);
 static int floppy_check_change(struct gendisk *disk);
 static int floppy_revalidate(struct gendisk *disk);
 
@@ -839,10 +839,10 @@ static int fd_eject(struct floppy_state *fs)
 static struct floppy_struct floppy_type =
        { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL };    /*  7 1.44MB 3.5"   */
 
-static int floppy_ioctl(struct inode *inode, struct file *filp,
+static int floppy_ioctl(struct block_device *bdev, fmode_t mode,
                        unsigned int cmd, unsigned long param)
 {
-       struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
+       struct floppy_state *fs = bdev->bd_disk->private_data;
        int err;
                
        if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
@@ -868,9 +868,9 @@ static int floppy_ioctl(struct inode *inode, struct file *filp,
        return -ENOTTY;
 }
 
-static int floppy_open(struct inode *inode, struct file *filp)
+static int floppy_open(struct block_device *bdev, fmode_t mode)
 {
-       struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
+       struct floppy_state *fs = bdev->bd_disk->private_data;
        struct swim3 __iomem *sw = fs->swim3;
        int n, err = 0;
 
@@ -904,17 +904,17 @@ static int floppy_open(struct inode *inode, struct file *filp)
                swim3_action(fs, SETMFM);
                swim3_select(fs, RELAX);
 
-       } else if (fs->ref_count == -1 || filp->f_flags & O_EXCL)
+       } else if (fs->ref_count == -1 || mode & FMODE_EXCL)
                return -EBUSY;
 
-       if (err == 0 && (filp->f_flags & O_NDELAY) == 0
-           && (filp->f_mode & 3)) {
-               check_disk_change(inode->i_bdev);
+       if (err == 0 && (mode & FMODE_NDELAY) == 0
+           && (mode & (FMODE_READ|FMODE_WRITE))) {
+               check_disk_change(bdev);
                if (fs->ejected)
                        err = -ENXIO;
        }
 
-       if (err == 0 && (filp->f_mode & 2)) {
+       if (err == 0 && (mode & FMODE_WRITE)) {
                if (fs->write_prot < 0)
                        fs->write_prot = swim3_readbit(fs, WRITE_PROT);
                if (fs->write_prot)
@@ -930,7 +930,7 @@ static int floppy_open(struct inode *inode, struct file *filp)
                return err;
        }
 
-       if (filp->f_flags & O_EXCL)
+       if (mode & FMODE_EXCL)
                fs->ref_count = -1;
        else
                ++fs->ref_count;
@@ -938,9 +938,9 @@ static int floppy_open(struct inode *inode, struct file *filp)
        return 0;
 }
 
-static int floppy_release(struct inode *inode, struct file *filp)
+static int floppy_release(struct gendisk *disk, fmode_t mode)
 {
-       struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
+       struct floppy_state *fs = disk->private_data;
        struct swim3 __iomem *sw = fs->swim3;
        if (fs->ref_count > 0 && --fs->ref_count == 0) {
                swim3_action(fs, MOTOR_OFF);
@@ -1000,7 +1000,7 @@ static int floppy_revalidate(struct gendisk *disk)
 static struct block_device_operations floppy_fops = {
        .open           = floppy_open,
        .release        = floppy_release,
-       .ioctl          = floppy_ioctl,
+       .locked_ioctl   = floppy_ioctl,
        .media_changed  = floppy_check_change,
        .revalidate_disk= floppy_revalidate,
 };
index f60e41833f6996e43fc6f2e68a3e25b8c189ca4c..fccac18d311121d01f28ca4ce819886f79cf300f 100644 (file)
@@ -1667,10 +1667,9 @@ static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun)
  * This is mostly needed to keep refcounting, but also to support
  * media checks on removable media drives.
  */
-static int ub_bd_open(struct inode *inode, struct file *filp)
+static int ub_bd_open(struct block_device *bdev, fmode_t mode)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct ub_lun *lun = disk->private_data;
+       struct ub_lun *lun = bdev->bd_disk->private_data;
        struct ub_dev *sc = lun->udev;
        unsigned long flags;
        int rc;
@@ -1684,19 +1683,19 @@ static int ub_bd_open(struct inode *inode, struct file *filp)
        spin_unlock_irqrestore(&ub_lock, flags);
 
        if (lun->removable || lun->readonly)
-               check_disk_change(inode->i_bdev);
+               check_disk_change(bdev);
 
        /*
         * The sd.c considers ->media_present and ->changed not equivalent,
         * under some pretty murky conditions (a failure of READ CAPACITY).
         * We may need it one day.
         */
-       if (lun->removable && lun->changed && !(filp->f_flags & O_NDELAY)) {
+       if (lun->removable && lun->changed && !(mode & FMODE_NDELAY)) {
                rc = -ENOMEDIUM;
                goto err_open;
        }
 
-       if (lun->readonly && (filp->f_mode & FMODE_WRITE)) {
+       if (lun->readonly && (mode & FMODE_WRITE)) {
                rc = -EROFS;
                goto err_open;
        }
@@ -1710,9 +1709,8 @@ err_open:
 
 /*
  */
-static int ub_bd_release(struct inode *inode, struct file *filp)
+static int ub_bd_release(struct gendisk *disk, fmode_t mode)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
        struct ub_lun *lun = disk->private_data;
        struct ub_dev *sc = lun->udev;
 
@@ -1723,13 +1721,13 @@ static int ub_bd_release(struct inode *inode, struct file *filp)
 /*
  * The ioctl interface.
  */
-static int ub_bd_ioctl(struct inode *inode, struct file *filp,
+static int ub_bd_ioctl(struct block_device *bdev, fmode_t mode,
     unsigned int cmd, unsigned long arg)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
+       struct gendisk *disk = bdev->bd_disk;
        void __user *usermem = (void __user *) arg;
 
-       return scsi_cmd_ioctl(filp, disk->queue, disk, cmd, usermem);
+       return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, usermem);
 }
 
 /*
@@ -1793,7 +1791,7 @@ static struct block_device_operations ub_bd_fops = {
        .owner          = THIS_MODULE,
        .open           = ub_bd_open,
        .release        = ub_bd_release,
-       .ioctl          = ub_bd_ioctl,
+       .locked_ioctl   = ub_bd_ioctl,
        .media_changed  = ub_bd_media_changed,
        .revalidate_disk = ub_bd_revalidate,
 };
index 1730d29e6044039d12a2da60ebfdf23ea225d0ef..ecccf65dce2f07a7a41a12cdfcbab7633da409c5 100644 (file)
@@ -130,15 +130,15 @@ struct viodasd_device {
 /*
  * External open entry point.
  */
-static int viodasd_open(struct inode *ino, struct file *fil)
+static int viodasd_open(struct block_device *bdev, fmode_t mode)
 {
-       struct viodasd_device *d = ino->i_bdev->bd_disk->private_data;
+       struct viodasd_device *d = bdev->bd_disk->private_data;
        HvLpEvent_Rc hvrc;
        struct viodasd_waitevent we;
        u16 flags = 0;
 
        if (d->read_only) {
-               if ((fil != NULL) && (fil->f_mode & FMODE_WRITE))
+               if (mode & FMODE_WRITE)
                        return -EROFS;
                flags = vioblockflags_ro;
        }
@@ -179,9 +179,9 @@ static int viodasd_open(struct inode *ino, struct file *fil)
 /*
  * External release entry point.
  */
-static int viodasd_release(struct inode *ino, struct file *fil)
+static int viodasd_release(struct gendisk *disk, fmode_t mode)
 {
-       struct viodasd_device *d = ino->i_bdev->bd_disk->private_data;
+       struct viodasd_device *d = disk->private_data;
        HvLpEvent_Rc hvrc;
 
        /* Send the event to OS/400.  We DON'T expect a response */
index 6ec5fc052786cae3c45cda835afe4ebbb9ca7b82..85d79a02d48726c150e6f8f1b17889f84bc8cc8d 100644 (file)
@@ -146,11 +146,11 @@ static void do_virtblk_request(struct request_queue *q)
                vblk->vq->vq_ops->kick(vblk->vq);
 }
 
-static int virtblk_ioctl(struct inode *inode, struct file *filp,
+static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
                         unsigned cmd, unsigned long data)
 {
-       return scsi_cmd_ioctl(filp, inode->i_bdev->bd_disk->queue,
-                             inode->i_bdev->bd_disk, cmd,
+       return scsi_cmd_ioctl(bdev->bd_disk->queue,
+                             bdev->bd_disk, mode, cmd,
                              (void __user *)data);
 }
 
@@ -180,7 +180,7 @@ static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo)
 }
 
 static struct block_device_operations virtblk_fops = {
-       .ioctl  = virtblk_ioctl,
+       .locked_ioctl = virtblk_ioctl,
        .owner  = THIS_MODULE,
        .getgeo = virtblk_getgeo,
 };
index 624d30f7da3fc0ba125de8c46b5f9ec8d1f4efc8..64b496fce98bb2a19fd17eb22ef5a192f67ae7bb 100644 (file)
@@ -132,7 +132,7 @@ static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
 
 static struct block_device_operations xd_fops = {
        .owner  = THIS_MODULE,
-       .ioctl  = xd_ioctl,
+       .locked_ioctl   = xd_ioctl,
        .getgeo = xd_getgeo,
 };
 static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
@@ -343,7 +343,7 @@ static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 }
 
 /* xd_ioctl: handle device ioctl's */
-static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
+static int xd_ioctl(struct block_device *bdev, fmode_t mode, u_int cmd, u_long arg)
 {
        switch (cmd) {
                case HDIO_SET_DMA:
index cffd44a2038325078d306a5c940862e3c1f75927..37cacef16e936d87fbfe2d07980431f885971d81 100644 (file)
@@ -105,7 +105,7 @@ static u_char xd_detect (u_char *controller, unsigned int *address);
 static u_char xd_initdrives (void (*init_drive)(u_char drive));
 
 static void do_xd_request (struct request_queue * q);
-static int xd_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg);
+static int xd_ioctl (struct block_device *bdev,fmode_t mode,unsigned int cmd,unsigned long arg);
 static int xd_readwrite (u_char operation,XD_INFO *disk,char *buffer,u_int block,u_int count);
 static void xd_recalibrate (u_char drive);
 
index 1a50ae70f716a28d2ca2146196fa4fc60f7e1f1a..b220c686089d82b5ffc41eada6efd59c7f7ca7e5 100644 (file)
@@ -156,11 +156,10 @@ static int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg)
        return 0;
 }
 
-static int blkif_ioctl(struct inode *inode, struct file *filep,
+static int blkif_ioctl(struct block_device *bdev, fmode_t mode,
                       unsigned command, unsigned long argument)
 {
-       struct blkfront_info *info =
-               inode->i_bdev->bd_disk->private_data;
+       struct blkfront_info *info = bdev->bd_disk->private_data;
        int i;
 
        dev_dbg(&info->xbdev->dev, "command: 0x%x, argument: 0x%lx\n",
@@ -1014,16 +1013,16 @@ static int blkfront_is_ready(struct xenbus_device *dev)
        return info->is_ready;
 }
 
-static int blkif_open(struct inode *inode, struct file *filep)
+static int blkif_open(struct block_device *bdev, fmode_t mode)
 {
-       struct blkfront_info *info = inode->i_bdev->bd_disk->private_data;
+       struct blkfront_info *info = bdev->bd_disk->private_data;
        info->users++;
        return 0;
 }
 
-static int blkif_release(struct inode *inode, struct file *filep)
+static int blkif_release(struct gendisk *disk, fmode_t mode)
 {
-       struct blkfront_info *info = inode->i_bdev->bd_disk->private_data;
+       struct blkfront_info *info = disk->private_data;
        info->users--;
        if (info->users == 0) {
                /* Check whether we have been instructed to close.  We will
@@ -1044,7 +1043,7 @@ static struct block_device_operations xlvbd_block_fops =
        .open = blkif_open,
        .release = blkif_release,
        .getgeo = blkif_getgeo,
-       .ioctl = blkif_ioctl,
+       .locked_ioctl = blkif_ioctl,
 };
 
 
index 4a7a059ebaf70b83f564430883ad517966c635de..ecab9e67d47a3985b2cfb67d1c2a16e04981eb1f 100644 (file)
@@ -870,25 +870,24 @@ static int ace_revalidate_disk(struct gendisk *gd)
        return ace->id_result;
 }
 
-static int ace_open(struct inode *inode, struct file *filp)
+static int ace_open(struct block_device *bdev, fmode_t mode)
 {
-       struct ace_device *ace = inode->i_bdev->bd_disk->private_data;
+       struct ace_device *ace = bdev->bd_disk->private_data;
        unsigned long flags;
 
        dev_dbg(ace->dev, "ace_open() users=%i\n", ace->users + 1);
 
-       filp->private_data = ace;
        spin_lock_irqsave(&ace->lock, flags);
        ace->users++;
        spin_unlock_irqrestore(&ace->lock, flags);
 
-       check_disk_change(inode->i_bdev);
+       check_disk_change(bdev);
        return 0;
 }
 
-static int ace_release(struct inode *inode, struct file *filp)
+static int ace_release(struct gendisk *disk, fmode_t mode)
 {
-       struct ace_device *ace = inode->i_bdev->bd_disk->private_data;
+       struct ace_device *ace = disk->private_data;
        unsigned long flags;
        u16 val;
 
index be20a67f1fa8c78397be751954a1d225e511af77..80754cdd31190c16d9c65e4e0538b979310b42cb 100644 (file)
@@ -137,8 +137,7 @@ get_chipram( void )
     return;
 }
 
-static int
-z2_open( struct inode *inode, struct file *filp )
+static int z2_open(struct block_device *bdev, fmode_t mode)
 {
     int device;
     int max_z2_map = ( Z2RAM_SIZE / Z2RAM_CHUNKSIZE ) *
@@ -147,7 +146,7 @@ z2_open( struct inode *inode, struct file *filp )
        sizeof( z2ram_map[0] );
     int rc = -ENOMEM;
 
-    device = iminor(inode);
+    device = MINOR(bdev->bd_dev);
 
     if ( current_device != -1 && current_device != device )
     {
@@ -299,7 +298,7 @@ err_out:
 }
 
 static int
-z2_release( struct inode *inode, struct file *filp )
+z2_release(struct gendisk *disk, fmode_t mode)
 {
     if ( current_device == -1 )
        return 0;     
index d47f2f80accdd226118ac10192c8f9bd10fe4b0f..d16b02423d6192f43ad8121776ca419f08cc01c2 100644 (file)
@@ -973,7 +973,7 @@ static int cdrom_close_write(struct cdrom_device_info *cdi)
  * is in their own interest: device control becomes a lot easier
  * this way.
  */
-int cdrom_open(struct cdrom_device_info *cdi, struct inode *ip, struct file *fp)
+int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev, fmode_t mode)
 {
        int ret;
 
@@ -982,14 +982,14 @@ int cdrom_open(struct cdrom_device_info *cdi, struct inode *ip, struct file *fp)
        /* if this was a O_NONBLOCK open and we should honor the flags,
         * do a quick open without drive/disc integrity checks. */
        cdi->use_count++;
-       if ((fp->f_flags & O_NONBLOCK) && (cdi->options & CDO_USE_FFLAGS)) {
+       if ((mode & FMODE_NDELAY) && (cdi->options & CDO_USE_FFLAGS)) {
                ret = cdi->ops->open(cdi, 1);
        } else {
                ret = open_for_data(cdi);
                if (ret)
                        goto err;
                cdrom_mmc3_profile(cdi);
-               if (fp->f_mode & FMODE_WRITE) {
+               if (mode & FMODE_WRITE) {
                        ret = -EROFS;
                        if (cdrom_open_write(cdi))
                                goto err_release;
@@ -1007,7 +1007,7 @@ int cdrom_open(struct cdrom_device_info *cdi, struct inode *ip, struct file *fp)
                        cdi->name, cdi->use_count);
        /* Do this on open.  Don't wait for mount, because they might
            not be mounting, but opening with O_NONBLOCK */
-       check_disk_change(ip->i_bdev);
+       check_disk_change(bdev);
        return 0;
 err_release:
        if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) {
@@ -1184,7 +1184,7 @@ static int check_for_audio_disc(struct cdrom_device_info * cdi,
        return 0;
 }
 
-int cdrom_release(struct cdrom_device_info *cdi, struct file *fp)
+void cdrom_release(struct cdrom_device_info *cdi, fmode_t mode)
 {
        struct cdrom_device_ops *cdo = cdi->ops;
        int opened_for_data;
@@ -1205,7 +1205,7 @@ int cdrom_release(struct cdrom_device_info *cdi, struct file *fp)
        }
 
        opened_for_data = !(cdi->options & CDO_USE_FFLAGS) ||
-               !(fp && fp->f_flags & O_NONBLOCK);
+               !(mode & FMODE_NDELAY);
 
        /*
         * flush cache on last write release
@@ -1219,7 +1219,6 @@ int cdrom_release(struct cdrom_device_info *cdi, struct file *fp)
                    cdi->options & CDO_AUTO_EJECT && CDROM_CAN(CDC_OPEN_TRAY))
                        cdo->tray_move(cdi, 1);
        }
-       return 0;
 }
 
 static int cdrom_read_mech_status(struct cdrom_device_info *cdi, 
@@ -2662,17 +2661,17 @@ static int cdrom_ioctl_audioctl(struct cdrom_device_info *cdi,
  * these days.
  * ATAPI / SCSI specific code now mainly resides in mmc_ioctl().
  */
-int cdrom_ioctl(struct file * file, struct cdrom_device_info *cdi,
-               struct inode *ip, unsigned int cmd, unsigned long arg)
+int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev,
+               fmode_t mode, unsigned int cmd, unsigned long arg)
 {
        void __user *argp = (void __user *)arg;
        int ret;
-       struct gendisk *disk = ip->i_bdev->bd_disk;
+       struct gendisk *disk = bdev->bd_disk;
 
        /*
         * Try the generic SCSI command ioctl's first.
         */
-       ret = scsi_cmd_ioctl(file, disk->queue, disk, cmd, argp);
+       ret = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp);
        if (ret != -ENOTTY)
                return ret;
 
@@ -2696,7 +2695,7 @@ int cdrom_ioctl(struct file * file, struct cdrom_device_info *cdi,
        case CDROM_SELECT_DISC:
                return cdrom_ioctl_select_disc(cdi, arg);
        case CDROMRESET:
-               return cdrom_ioctl_reset(cdi, ip->i_bdev);
+               return cdrom_ioctl_reset(cdi, bdev);
        case CDROM_LOCKDOOR:
                return cdrom_ioctl_lock_door(cdi, arg);
        case CDROM_DEBUG:
index d6ba77a2dd7bbbe6a8329a6485246299226c22fe..9aaa86b232b190a1622c2ddf8ffcfc32be011cad 100644 (file)
@@ -490,14 +490,14 @@ static struct cdrom_device_ops gdrom_ops = {
        .n_minors               = 1,
 };
 
-static int gdrom_bdops_open(struct inode *inode, struct file *file)
+static int gdrom_bdops_open(struct block_device *bdev, fmode_t mode)
 {
-       return cdrom_open(gd.cd_info, inode, file);
+       return cdrom_open(gd.cd_info, bdev, mode);
 }
 
-static int gdrom_bdops_release(struct inode *inode, struct file *file)
+static int gdrom_bdops_release(struct block_device *bdev, fmode_t mode)
 {
-       return cdrom_release(gd.cd_info, file);
+       return cdrom_release(gd.cd_info, mode);
 }
 
 static int gdrom_bdops_mediachanged(struct gendisk *disk)
@@ -505,10 +505,10 @@ static int gdrom_bdops_mediachanged(struct gendisk *disk)
        return cdrom_media_changed(gd.cd_info);
 }
 
-static int gdrom_bdops_ioctl(struct inode *inode, struct file *file,
+static int gdrom_bdops_ioctl(struct block_device *bdev, fmode_t mode,
        unsigned cmd, unsigned long arg)
 {
-       return cdrom_ioctl(file, gd.cd_info, inode, cmd, arg);
+       return cdrom_ioctl(gd.cd_info, bdev, mode, cmd, arg);
 }
 
 static struct block_device_operations gdrom_bdops = {
@@ -516,7 +516,7 @@ static struct block_device_operations gdrom_bdops = {
        .open                   = gdrom_bdops_open,
        .release                = gdrom_bdops_release,
        .media_changed          = gdrom_bdops_mediachanged,
-       .ioctl                  = gdrom_bdops_ioctl,
+       .locked_ioctl           = gdrom_bdops_ioctl,
 };
 
 static irqreturn_t gdrom_command_interrupt(int irq, void *dev_id)
index 031e0e1a1a3bb4f89f94762b8d6c84e395ee0c06..13929356135c837743f130c2f7de4d3cd85cc4fb 100644 (file)
@@ -151,23 +151,24 @@ static const struct file_operations proc_viocd_operations = {
        .release        = single_release,
 };
 
-static int viocd_blk_open(struct inode *inode, struct file *file)
+static int viocd_blk_open(struct block_device *bdev, fmode_t mode)
 {
-       struct disk_info *di = inode->i_bdev->bd_disk->private_data;
-       return cdrom_open(&di->viocd_info, inode, file);
+       struct disk_info *di = bdev->bd_disk->private_data;
+       return cdrom_open(&di->viocd_info, bdev, mode);
 }
 
-static int viocd_blk_release(struct inode *inode, struct file *file)
+static int viocd_blk_release(struct gendisk *disk, fmode_t mode)
 {
-       struct disk_info *di = inode->i_bdev->bd_disk->private_data;
-       return cdrom_release(&di->viocd_info, file);
+       struct disk_info *di = disk->private_data;
+       cdrom_release(&di->viocd_info, mode);
+       return 0;
 }
 
-static int viocd_blk_ioctl(struct inode *inode, struct file *file,
+static int viocd_blk_ioctl(struct block_device *bdev, fmode_t mode,
                unsigned cmd, unsigned long arg)
 {
-       struct disk_info *di = inode->i_bdev->bd_disk->private_data;
-       return cdrom_ioctl(file, &di->viocd_info, inode, cmd, arg);
+       struct disk_info *di = bdev->bd_disk->private_data;
+       return cdrom_ioctl(&di->viocd_info, bdev, mode, cmd, arg);
 }
 
 static int viocd_blk_media_changed(struct gendisk *disk)
@@ -180,7 +181,7 @@ struct block_device_operations viocd_fops = {
        .owner =                THIS_MODULE,
        .open =                 viocd_blk_open,
        .release =              viocd_blk_release,
-       .ioctl =                viocd_blk_ioctl,
+       .locked_ioctl =         viocd_blk_ioctl,
        .media_changed =        viocd_blk_media_changed,
 };
 
index 31dcd9142d54416f623f5a53e587c2c0ed33fafc..dc8d1a90971f78134015c7dadf811717bac10a16 100644 (file)
@@ -417,6 +417,6 @@ static void __exit agp_ali_cleanup(void)
 module_init(agp_ali_init);
 module_exit(agp_ali_cleanup);
 
-MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
 MODULE_LICENSE("GPL and additional rights");
 
index 2812ee2b165a407ff802d737695c4818f8ea917e..52f4361eb6e41fde34a1e6fa53d981725a3485bd 100644 (file)
@@ -772,6 +772,6 @@ module_init(agp_amd64_init);
 module_exit(agp_amd64_cleanup);
 #endif
 
-MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>, Andi Kleen");
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>, Andi Kleen");
 module_param(agp_try_unsupported, bool, 0);
 MODULE_LICENSE("GPL");
index ae2791b926b9fe705a80e7540c4482675ad25de0..f1537eece07f7977af412097ed564a54ec2f812a 100644 (file)
@@ -561,6 +561,6 @@ static void __exit agp_ati_cleanup(void)
 module_init(agp_ati_init);
 module_exit(agp_ati_cleanup);
 
-MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
 MODULE_LICENSE("GPL and additional rights");
 
index 3a3cc03d401ce3d3d1484f681bfaae6ba6d88e28..8c617ad7497fef739a7e5f1e24d0d629bba61455 100644 (file)
@@ -349,7 +349,7 @@ static __init int agp_setup(char *s)
 __setup("agp=", agp_setup);
 #endif
 
-MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
 MODULE_DESCRIPTION("AGP GART driver");
 MODULE_LICENSE("GPL and additional rights");
 MODULE_ALIAS_MISCDEV(AGPGART_MINOR);
index 1108665913e207da892459750377400db809c961..9cf6e9bb017e6dca0b537bb04b70e5c49dbf705b 100644 (file)
@@ -2390,5 +2390,5 @@ static void __exit agp_intel_cleanup(void)
 module_init(agp_intel_init);
 module_exit(agp_intel_cleanup);
 
-MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
 MODULE_LICENSE("GPL and additional rights");
index 5bbed3d79db95f9d62ec32132817d645a961c7d2..16acee2de11790546599695eeaf83df1338d0501 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Nvidia AGPGART routines.
  * Based upon a 2.4 agpgart diff by the folks from NVIDIA, and hacked up
- * to work in 2.5 by Dave Jones <davej@codemonkey.org.uk>
+ * to work in 2.5 by Dave Jones <davej@redhat.com>
  */
 
 #include <linux/module.h>
index f2492ecf082410da192b140d9a0615624ca79f3b..db60539bf67a1ed81216b35f29819cadfc43a83c 100644 (file)
@@ -20,8 +20,8 @@
 #include <linux/agp_backend.h>
 #include <linux/log2.h>
 
-#include <asm-parisc/parisc-device.h>
-#include <asm-parisc/ropes.h>
+#include <asm/parisc-device.h>
+#include <asm/ropes.h>
 
 #include "agp.h"
 
index 9f4d49e1b59a909249ac6297aacd0a3aebfd3669..d3bd243867fc51248a16d101eeb5bbd9c8385079 100644 (file)
@@ -595,4 +595,4 @@ module_init(agp_via_init);
 module_exit(agp_via_cleanup);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
index f3cfb4c761259d5b8f6d331c24ea1108fde307fc..408f5f92cb4e1f56959fae99936b34d030f67d70 100644 (file)
@@ -219,7 +219,7 @@ static void hpet_timer_set_irq(struct hpet_dev *devp)
        for (irq = find_first_bit(&v, HPET_MAX_IRQ); irq < HPET_MAX_IRQ;
                irq = find_next_bit(&v, HPET_MAX_IRQ, 1 + irq)) {
 
-               if (irq >= NR_IRQS) {
+               if (irq >= nr_irqs) {
                        irq = HPET_MAX_IRQ;
                        break;
                }
index bf70450a49ccbc403c62917c53f0db73f7328f5d..5b819b12675a9dd855ceda7e2465577831af7460 100644 (file)
@@ -161,7 +161,7 @@ static void hvc_console_print(struct console *co, const char *b,
                        }
                } else {
                        r = cons_ops[index]->put_chars(vtermnos[index], c, i);
-                       if (r < 0) {
+                       if (r <= 0) {
                                /* throw away chars on error */
                                i = 0;
                        } else if (r > 0) {
@@ -374,6 +374,9 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
                if (hp->ops->notifier_del)
                        hp->ops->notifier_del(hp, hp->data);
 
+               /* cancel pending tty resize work */
+               cancel_work_sync(&hp->tty_resize);
+
                /*
                 * Chain calls chars_in_buffer() and returns immediately if
                 * there is no buffered data otherwise sleeps on a wait queue
@@ -399,6 +402,9 @@ static void hvc_hangup(struct tty_struct *tty)
        if (!hp)
                return;
 
+       /* cancel pending tty resize work */
+       cancel_work_sync(&hp->tty_resize);
+
        spin_lock_irqsave(&hp->lock, flags);
 
        /*
@@ -418,8 +424,8 @@ static void hvc_hangup(struct tty_struct *tty)
 
        spin_unlock_irqrestore(&hp->lock, flags);
 
-       if (hp->ops->notifier_del)
-                       hp->ops->notifier_del(hp, hp->data);
+       if (hp->ops->notifier_hangup)
+                       hp->ops->notifier_hangup(hp, hp->data);
 
        while(temp_open_count) {
                --temp_open_count;
@@ -431,7 +437,7 @@ static void hvc_hangup(struct tty_struct *tty)
  * Push buffered characters whether they were just recently buffered or waiting
  * on a blocked hypervisor.  Call this function with hp->lock held.
  */
-static void hvc_push(struct hvc_struct *hp)
+static int hvc_push(struct hvc_struct *hp)
 {
        int n;
 
@@ -439,7 +445,7 @@ static void hvc_push(struct hvc_struct *hp)
        if (n <= 0) {
                if (n == 0) {
                        hp->do_wakeup = 1;
-                       return;
+                       return 0;
                }
                /* throw away output on error; this happens when
                   there is no session connected to the vterm. */
@@ -450,6 +456,8 @@ static void hvc_push(struct hvc_struct *hp)
                memmove(hp->outbuf, hp->outbuf + n, hp->n_outbuf);
        else
                hp->do_wakeup = 1;
+
+       return n;
 }
 
 static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count)
@@ -492,6 +500,39 @@ static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count
        return written;
 }
 
+/**
+ * hvc_set_winsz() - Resize the hvc tty terminal window.
+ * @work:      work structure.
+ *
+ * The routine shall not be called within an atomic context because it
+ * might sleep.
+ *
+ * Locking:    hp->lock
+ */
+static void hvc_set_winsz(struct work_struct *work)
+{
+       struct hvc_struct *hp;
+       unsigned long hvc_flags;
+       struct tty_struct *tty;
+       struct winsize ws;
+
+       hp = container_of(work, struct hvc_struct, tty_resize);
+       if (!hp)
+               return;
+
+       spin_lock_irqsave(&hp->lock, hvc_flags);
+       if (!hp->tty) {
+               spin_unlock_irqrestore(&hp->lock, hvc_flags);
+               return;
+       }
+       ws  = hp->ws;
+       tty = tty_kref_get(hp->tty);
+       spin_unlock_irqrestore(&hp->lock, hvc_flags);
+
+       tty_do_resize(tty, tty, &ws);
+       tty_kref_put(tty);
+}
+
 /*
  * This is actually a contract between the driver and the tty layer outlining
  * how much write room the driver can guarantee will be sent OR BUFFERED.  This
@@ -538,16 +579,20 @@ int hvc_poll(struct hvc_struct *hp)
        char buf[N_INBUF] __ALIGNED__;
        unsigned long flags;
        int read_total = 0;
+       int written_total = 0;
 
        spin_lock_irqsave(&hp->lock, flags);
 
        /* Push pending writes */
        if (hp->n_outbuf > 0)
-               hvc_push(hp);
+               written_total = hvc_push(hp);
 
        /* Reschedule us if still some write pending */
-       if (hp->n_outbuf > 0)
+       if (hp->n_outbuf > 0) {
                poll_mask |= HVC_POLL_WRITE;
+               /* If hvc_push() was not able to write, sleep a few msecs */
+               timeout = (written_total) ? 0 : MIN_TIMEOUT;
+       }
 
        /* No tty attached, just skip */
        tty = hp->tty;
@@ -632,6 +677,24 @@ int hvc_poll(struct hvc_struct *hp)
 }
 EXPORT_SYMBOL_GPL(hvc_poll);
 
+/**
+ * hvc_resize() - Update terminal window size information.
+ * @hp:                HVC console pointer
+ * @ws:                Terminal window size structure
+ *
+ * Stores the specified window size information in the hvc structure of @hp.
+ * The function schedule the tty resize update.
+ *
+ * Locking:    Locking free; the function MUST be called holding hp->lock
+ */
+void hvc_resize(struct hvc_struct *hp, struct winsize ws)
+{
+       if ((hp->ws.ws_row != ws.ws_row) || (hp->ws.ws_col != ws.ws_col)) {
+               hp->ws = ws;
+               schedule_work(&hp->tty_resize);
+       }
+}
+
 /*
  * This kthread is either polling or interrupt driven.  This is determined by
  * calling hvc_poll() who determines whether a console adapter support
@@ -659,10 +722,6 @@ static int khvcd(void *unused)
                        poll_mask |= HVC_POLL_READ;
                if (hvc_kicked)
                        continue;
-               if (poll_mask & HVC_POLL_WRITE) {
-                       yield();
-                       continue;
-               }
                set_current_state(TASK_INTERRUPTIBLE);
                if (!hvc_kicked) {
                        if (poll_mask == 0)
@@ -718,6 +777,7 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int data,
 
        kref_init(&hp->kref);
 
+       INIT_WORK(&hp->tty_resize, hvc_set_winsz);
        spin_lock_init(&hp->lock);
        spin_lock(&hvc_structs_lock);
 
@@ -743,7 +803,7 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int data,
 }
 EXPORT_SYMBOL_GPL(hvc_alloc);
 
-int __devexit hvc_remove(struct hvc_struct *hp)
+int hvc_remove(struct hvc_struct *hp)
 {
        unsigned long flags;
        struct tty_struct *tty;
@@ -796,7 +856,7 @@ static int hvc_init(void)
        drv->minor_start = HVC_MINOR;
        drv->type = TTY_DRIVER_TYPE_SYSTEM;
        drv->init_termios = tty_std_termios;
-       drv->flags = TTY_DRIVER_REAL_RAW;
+       drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
        tty_set_operations(drv, &hvc_ops);
 
        /* Always start the kthread because there can be hotplug vty adapters
index 9790201718ae6ce6892c65d3b10de8d7c102d4d0..8297dbc2e6ec99f80b2db8fc2eb4e01da6028020 100644 (file)
@@ -27,6 +27,7 @@
 #ifndef HVC_CONSOLE_H
 #define HVC_CONSOLE_H
 #include <linux/kref.h>
+#include <linux/tty.h>
 
 /*
  * This is the max number of console adapters that can/will be found as
@@ -56,6 +57,8 @@ struct hvc_struct {
        struct hv_ops *ops;
        int irq_requested;
        int data;
+       struct winsize ws;
+       struct work_struct tty_resize;
        struct list_head next;
        struct kref kref; /* ref count & hvc_struct lifetime */
 };
@@ -65,9 +68,10 @@ struct hv_ops {
        int (*get_chars)(uint32_t vtermno, char *buf, int count);
        int (*put_chars)(uint32_t vtermno, const char *buf, int count);
 
-       /* Callbacks for notification. Called in open and close */
+       /* Callbacks for notification. Called in open, close and hangup */
        int (*notifier_add)(struct hvc_struct *hp, int irq);
        void (*notifier_del)(struct hvc_struct *hp, int irq);
+       void (*notifier_hangup)(struct hvc_struct *hp, int irq);
 };
 
 /* Register a vterm and a slot index for use as a console (console_init) */
@@ -77,15 +81,19 @@ extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops);
 extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int data,
                                struct hv_ops *ops, int outbuf_size);
 /* remove a vterm from hvc tty operation (module_exit or hotplug remove) */
-extern int __devexit hvc_remove(struct hvc_struct *hp);
+extern int hvc_remove(struct hvc_struct *hp);
 
 /* data available */
 int hvc_poll(struct hvc_struct *hp);
 void hvc_kick(void);
 
+/* Resize hvc tty terminal window */
+extern void hvc_resize(struct hvc_struct *hp, struct winsize ws);
+
 /* default notifier for irq based notification */
 extern int notifier_add_irq(struct hvc_struct *hp, int data);
 extern void notifier_del_irq(struct hvc_struct *hp, int data);
+extern void notifier_hangup_irq(struct hvc_struct *hp, int data);
 
 
 #if defined(CONFIG_XMON) && defined(CONFIG_SMP)
index 73a59cdb8947c3d8436ee07f6a8d982d8ec91898..d09e5688d4497242d4bcc6dcad23abc1a4f96202 100644 (file)
@@ -42,3 +42,8 @@ void notifier_del_irq(struct hvc_struct *hp, int irq)
        free_irq(irq, hp);
        hp->irq_requested = 0;
 }
+
+void notifier_hangup_irq(struct hvc_struct *hp, int irq)
+{
+       notifier_del_irq(hp, irq);
+}
index b71c610fe5ae0584092b8badbc4c9c93fe52f117..b74a2f8ab9080fe995b21c370857d54c7ff3db02 100644 (file)
@@ -202,6 +202,7 @@ static struct hv_ops hvc_get_put_ops = {
        .put_chars = put_chars,
        .notifier_add = notifier_add_irq,
        .notifier_del = notifier_del_irq,
+       .notifier_hangup = notifier_hangup_irq,
 };
 
 static int __devinit hvc_vio_probe(struct vio_dev *vdev,
index 93f3840c1682e53e9f2e20c2f21330ba4a9a71e5..019e0b58593da4f2356ef3725d03cd7f186ed1ad 100644 (file)
@@ -82,6 +82,7 @@ static struct hv_ops hvc_get_put_ops = {
        .put_chars = hvc_put_chars,
        .notifier_add = notifier_add_irq,
        .notifier_del = notifier_del_irq,
+       .notifier_hangup = notifier_hangup_irq,
 };
 
 static int __devinit hvc_vio_probe(struct vio_dev *vdev,
index 538ceea5e7df364a1f059a482b6cc0adc1d68bc6..eba999f8598d07a8a29fe03bac5bb4de18d39f62 100644 (file)
@@ -102,6 +102,7 @@ static struct hv_ops hvc_ops = {
        .put_chars = write_console,
        .notifier_add = notifier_add_irq,
        .notifier_del = notifier_del_irq,
+       .notifier_hangup = notifier_hangup_irq,
 };
 
 static int __init xen_init(void)
index 39f6357e3b5d0a63e432cf0238cc84aba4b8d33f..8054ee839b3c36acb0b57c7f477d139f2c3ac06c 100644 (file)
@@ -338,7 +338,7 @@ nvram_open(struct inode *inode, struct file *file)
 
        if ((nvram_open_cnt && (file->f_flags & O_EXCL)) ||
            (nvram_open_mode & NVRAM_EXCL) ||
-           ((file->f_mode & 2) && (nvram_open_mode & NVRAM_WRITE))) {
+           ((file->f_mode & FMODE_WRITE) && (nvram_open_mode & NVRAM_WRITE))) {
                spin_unlock(&nvram_state_lock);
                unlock_kernel();
                return -EBUSY;
@@ -346,7 +346,7 @@ nvram_open(struct inode *inode, struct file *file)
 
        if (file->f_flags & O_EXCL)
                nvram_open_mode |= NVRAM_EXCL;
-       if (file->f_mode & 2)
+       if (file->f_mode & FMODE_WRITE)
                nvram_open_mode |= NVRAM_WRITE;
        nvram_open_cnt++;
 
@@ -366,7 +366,7 @@ nvram_release(struct inode *inode, struct file *file)
        /* if only one instance is open, clear the EXCL bit */
        if (nvram_open_mode & NVRAM_EXCL)
                nvram_open_mode &= ~NVRAM_EXCL;
-       if (file->f_mode & 2)
+       if (file->f_mode & FMODE_WRITE)
                nvram_open_mode &= ~NVRAM_WRITE;
 
        spin_unlock(&nvram_state_lock);
index c8752eaad483eea52b4dbc8c8af87eaf931ad189..705a839f1796125b257925dc8c3aac722d992018 100644 (file)
@@ -558,9 +558,26 @@ struct timer_rand_state {
        unsigned dont_count_entropy:1;
 };
 
-static struct timer_rand_state input_timer_state;
 static struct timer_rand_state *irq_timer_state[NR_IRQS];
 
+static struct timer_rand_state *get_timer_rand_state(unsigned int irq)
+{
+       if (irq >= nr_irqs)
+               return NULL;
+
+       return irq_timer_state[irq];
+}
+
+static void set_timer_rand_state(unsigned int irq, struct timer_rand_state *state)
+{
+       if (irq >= nr_irqs)
+               return;
+
+       irq_timer_state[irq] = state;
+}
+
+static struct timer_rand_state input_timer_state;
+
 /*
  * This function adds entropy to the entropy "pool" by using timing
  * delays.  It uses the timer_rand_state structure to make an estimate
@@ -648,11 +665,15 @@ EXPORT_SYMBOL_GPL(add_input_randomness);
 
 void add_interrupt_randomness(int irq)
 {
-       if (irq >= NR_IRQS || irq_timer_state[irq] == NULL)
+       struct timer_rand_state *state;
+
+       state = get_timer_rand_state(irq);
+
+       if (state == NULL)
                return;
 
        DEBUG_ENT("irq event %d\n", irq);
-       add_timer_randomness(irq_timer_state[irq], 0x100 + irq);
+       add_timer_randomness(state, 0x100 + irq);
 }
 
 #ifdef CONFIG_BLOCK
@@ -912,7 +933,12 @@ void rand_initialize_irq(int irq)
 {
        struct timer_rand_state *state;
 
-       if (irq >= NR_IRQS || irq_timer_state[irq])
+       if (irq >= nr_irqs)
+               return;
+
+       state = get_timer_rand_state(irq);
+
+       if (state)
                return;
 
        /*
@@ -921,7 +947,7 @@ void rand_initialize_irq(int irq)
         */
        state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL);
        if (state)
-               irq_timer_state[irq] = state;
+               set_timer_rand_state(irq, state);
 }
 
 #ifdef CONFIG_BLOCK
index e139372d0e6913f1d09a385a8d60617b3e25e089..96adf28a17e43b309d8af6858d695015c84cc6d1 100644 (file)
@@ -65,7 +65,7 @@ static int raw_open(struct inode *inode, struct file *filp)
        if (!bdev)
                goto out;
        igrab(bdev->bd_inode);
-       err = blkdev_get(bdev, filp->f_mode, 0);
+       err = blkdev_get(bdev, filp->f_mode);
        if (err)
                goto out;
        err = bd_claim(bdev, raw_open);
@@ -87,7 +87,7 @@ static int raw_open(struct inode *inode, struct file *filp)
 out2:
        bd_release(bdev);
 out1:
-       blkdev_put(bdev);
+       blkdev_put(bdev, filp->f_mode);
 out:
        mutex_unlock(&raw_mutex);
        return err;
@@ -112,7 +112,7 @@ static int raw_release(struct inode *inode, struct file *filp)
        mutex_unlock(&raw_mutex);
 
        bd_release(bdev);
-       blkdev_put(bdev);
+       blkdev_put(bdev, filp->f_mode);
        return 0;
 }
 
@@ -125,7 +125,7 @@ raw_ioctl(struct inode *inode, struct file *filp,
 {
        struct block_device *bdev = filp->private_data;
 
-       return blkdev_ioctl(bdev->bd_inode, NULL, command, arg);
+       return blkdev_ioctl(bdev, 0, command, arg);
 }
 
 static void bind_device(struct raw_config_request *rq)
index d0c0d64ed366ce9e961c7dbbfca03a9764e29321..ce0d9da52a8ab808a24e8d30bff27d631b474713 100644 (file)
@@ -168,7 +168,7 @@ static void sysrq_handle_show_timers(int key, struct tty_struct *tty)
 static struct sysrq_key_op sysrq_show_timers_op = {
        .handler        = sysrq_handle_show_timers,
        .help_msg       = "show-all-timers(Q)",
-       .action_msg     = "Show pending hrtimers (no others)",
+       .action_msg     = "Show clockevent devices & pending hrtimers (no others)",
 };
 
 static void sysrq_handle_mountro(int key, struct tty_struct *tty)
index 553b0e9d8d17a5513747337ddf5bcf49caaba95b..c8f8024cb40e5d6b4fcc6ad1a8f4408104e9f81a 100644 (file)
@@ -90,7 +90,7 @@ void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
        spin_lock_irqsave(&port->lock, flags);
        if (port->tty)
                tty_kref_put(port->tty);
-       port->tty = tty;
+       port->tty = tty_kref_get(tty);
        spin_unlock_irqrestore(&port->lock, flags);
 }
 EXPORT_SYMBOL(tty_port_tty_set);
index d0f4eb6fdb7fee27eca6cfec84ff8cf25af209e4..3fb0d2c88ba5fd3252bf7d773c8ecdaafc9de395 100644 (file)
@@ -198,6 +198,7 @@ static int __devinit virtcons_probe(struct virtio_device *dev)
        virtio_cons.put_chars = put_chars;
        virtio_cons.notifier_add = notifier_add_vio;
        virtio_cons.notifier_del = notifier_del_vio;
+       virtio_cons.notifier_hangup = notifier_del_vio;
 
        /* The first argument of hvc_alloc() is the virtual console number, so
         * we use zero.  The second argument is the parameter for the
index ffe9b4e3072e50b02e57c2fa0ac2f58240c85a45..54c837288d19453ff2baf3756d28b8cbc5b1092e 100644 (file)
@@ -641,7 +641,7 @@ static int __devinit giu_probe(struct platform_device *dev)
        }
 
        irq = platform_get_irq(dev, 0);
-       if (irq < 0 || irq >= NR_IRQS)
+       if (irq < 0 || irq >= nr_irqs)
                return -EBUSY;
 
        return cascade_irq(irq, giu_get_irq);
index 71d2ac4e3f46cc0e33410a2d8f7889ac1ae8de09..c20171078d1d6f475f04a23fc0be9e63101d5d76 100644 (file)
@@ -237,9 +237,12 @@ static int __init parse_pmtmr(char *arg)
 
        if (strict_strtoul(arg, 16, &base))
                return -EINVAL;
-
+#ifdef CONFIG_X86_64
+       if (base > UINT_MAX)
+               return -ERANGE;
+#endif
        printk(KERN_INFO "PMTMR IOPort override: 0x%04x -> 0x%04lx\n",
-              (unsigned int)pmtmr_ioport, base);
+              pmtmr_ioport, base);
        pmtmr_ioport = base;
 
        return 1;
index 5ce07b517c5875def9106c5041402032c3f70fc1..5bed73329ef825e2f423f04f4540d57330d30b73 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/cpu.h>
 #include <linux/cpuidle.h>
 #include <linux/ktime.h>
+#include <linux/hrtimer.h>
 
 #include "cpuidle.h"
 
@@ -56,10 +57,20 @@ static void cpuidle_idle_call(void)
                if (pm_idle_old)
                        pm_idle_old();
                else
+#if defined(CONFIG_ARCH_HAS_DEFAULT_IDLE)
+                       default_idle();
+#else
                        local_irq_enable();
+#endif
                return;
        }
 
+       /*
+        * run any timers that can be run now, at this point
+        * before calculating the idle duration etc.
+        */
+       hrtimer_peek_ahead_timers();
+
        /* ask the governor for the next state */
        next_state = cpuidle_curr_governor->select(dev);
        if (need_resched())
@@ -67,8 +78,11 @@ static void cpuidle_idle_call(void)
        target_state = &dev->states[next_state];
 
        /* enter the state and update stats */
-       dev->last_residency = target_state->enter(dev, target_state);
        dev->last_state = target_state;
+       dev->last_residency = target_state->enter(dev, target_state);
+       if (dev->last_state)
+               target_state = dev->last_state;
+
        target_state->time += (unsigned long long)dev->last_residency;
        target_state->usage++;
 
index cd303901eb5b20c13b1636ec32614d3ac8800a60..904e57558bb5ea9f34dae3d3df84f5070b36744f 100644 (file)
@@ -48,13 +48,13 @@ config DW_DMAC
          can be integrated in chips such as the Atmel AT32ap7000.
 
 config FSL_DMA
-       bool "Freescale MPC85xx/MPC83xx DMA support"
-       depends on PPC
+       tristate "Freescale Elo and Elo Plus DMA support"
+       depends on FSL_SOC
        select DMA_ENGINE
        ---help---
-         Enable support for the Freescale DMA engine. Now, it support
-         MPC8560/40, MPC8555, MPC8548 and MPC8641 processors.
-         The MPC8349, MPC8360 is also supported.
+         Enable support for the Freescale Elo and Elo Plus DMA controllers.
+         The Elo is the DMA controller on some 82xx and 83xx parts, and the
+         Elo Plus is the DMA controller on 85xx and 86xx parts.
 
 config MV_XOR
        bool "Marvell XOR engine support"
index a08d1970474362d7d8514ca3a74b8cbb2ffe6519..d1e381e35a9e1887e79667d3df734d3dd37ad5b9 100644 (file)
@@ -325,7 +325,12 @@ static enum dma_state_client dmatest_add_channel(struct dma_chan *chan)
        struct dmatest_thread   *thread;
        unsigned int            i;
 
-       dtc = kmalloc(sizeof(struct dmatest_chan), GFP_ATOMIC);
+       /* Have we already been told about this channel? */
+       list_for_each_entry(dtc, &dmatest_channels, node)
+               if (dtc->chan == chan)
+                       return DMA_DUP;
+
+       dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL);
        if (!dtc) {
                pr_warning("dmatest: No memory for %s\n", chan->dev.bus_id);
                return DMA_NAK;
index c0059ca5834075e70f3fc59512d9ff69617bee29..0b95dcce447e91baef611d769026386ac7c252c3 100644 (file)
@@ -370,7 +370,10 @@ static int fsl_dma_alloc_chan_resources(struct dma_chan *chan,
                                        struct dma_client *client)
 {
        struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
-       LIST_HEAD(tmp_list);
+
+       /* Has this channel already been allocated? */
+       if (fsl_chan->desc_pool)
+               return 1;
 
        /* We need the descriptor to be aligned to 32bytes
         * for meeting FSL DMA specification requirement.
@@ -410,6 +413,8 @@ static void fsl_dma_free_chan_resources(struct dma_chan *chan)
        }
        spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
        dma_pool_destroy(fsl_chan->desc_pool);
+
+       fsl_chan->desc_pool = NULL;
 }
 
 static struct dma_async_tx_descriptor *
@@ -786,159 +791,29 @@ static void dma_do_tasklet(unsigned long data)
        fsl_chan_ld_cleanup(fsl_chan);
 }
 
-static void fsl_dma_callback_test(void *param)
-{
-       struct fsl_dma_chan *fsl_chan = param;
-       if (fsl_chan)
-               dev_dbg(fsl_chan->dev, "selftest: callback is ok!\n");
-}
-
-static int fsl_dma_self_test(struct fsl_dma_chan *fsl_chan)
-{
-       struct dma_chan *chan;
-       int err = 0;
-       dma_addr_t dma_dest, dma_src;
-       dma_cookie_t cookie;
-       u8 *src, *dest;
-       int i;
-       size_t test_size;
-       struct dma_async_tx_descriptor *tx1, *tx2, *tx3;
-
-       test_size = 4096;
-
-       src = kmalloc(test_size * 2, GFP_KERNEL);
-       if (!src) {
-               dev_err(fsl_chan->dev,
-                               "selftest: Cannot alloc memory for test!\n");
-               return -ENOMEM;
-       }
-
-       dest = src + test_size;
-
-       for (i = 0; i < test_size; i++)
-               src[i] = (u8) i;
-
-       chan = &fsl_chan->common;
-
-       if (fsl_dma_alloc_chan_resources(chan, NULL) < 1) {
-               dev_err(fsl_chan->dev,
-                               "selftest: Cannot alloc resources for DMA\n");
-               err = -ENODEV;
-               goto out;
-       }
-
-       /* TX 1 */
-       dma_src = dma_map_single(fsl_chan->dev, src, test_size / 2,
-                                DMA_TO_DEVICE);
-       dma_dest = dma_map_single(fsl_chan->dev, dest, test_size / 2,
-                                 DMA_FROM_DEVICE);
-       tx1 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 2, 0);
-       async_tx_ack(tx1);
-
-       cookie = fsl_dma_tx_submit(tx1);
-       fsl_dma_memcpy_issue_pending(chan);
-       msleep(2);
-
-       if (fsl_dma_is_complete(chan, cookie, NULL, NULL) != DMA_SUCCESS) {
-               dev_err(fsl_chan->dev, "selftest: Time out!\n");
-               err = -ENODEV;
-               goto free_resources;
-       }
-
-       /* Test free and re-alloc channel resources */
-       fsl_dma_free_chan_resources(chan);
-
-       if (fsl_dma_alloc_chan_resources(chan, NULL) < 1) {
-               dev_err(fsl_chan->dev,
-                               "selftest: Cannot alloc resources for DMA\n");
-               err = -ENODEV;
-               goto free_resources;
-       }
-
-       /* Continue to test
-        * TX 2
-        */
-       dma_src = dma_map_single(fsl_chan->dev, src + test_size / 2,
-                                       test_size / 4, DMA_TO_DEVICE);
-       dma_dest = dma_map_single(fsl_chan->dev, dest + test_size / 2,
-                                       test_size / 4, DMA_FROM_DEVICE);
-       tx2 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 4, 0);
-       async_tx_ack(tx2);
-
-       /* TX 3 */
-       dma_src = dma_map_single(fsl_chan->dev, src + test_size * 3 / 4,
-                                       test_size / 4, DMA_TO_DEVICE);
-       dma_dest = dma_map_single(fsl_chan->dev, dest + test_size * 3 / 4,
-                                       test_size / 4, DMA_FROM_DEVICE);
-       tx3 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 4, 0);
-       async_tx_ack(tx3);
-
-       /* Interrupt tx test */
-       tx1 = fsl_dma_prep_interrupt(chan, 0);
-       async_tx_ack(tx1);
-       cookie = fsl_dma_tx_submit(tx1);
-
-       /* Test exchanging the prepared tx sort */
-       cookie = fsl_dma_tx_submit(tx3);
-       cookie = fsl_dma_tx_submit(tx2);
-
-       if (dma_has_cap(DMA_INTERRUPT, ((struct fsl_dma_device *)
-           dev_get_drvdata(fsl_chan->dev->parent))->common.cap_mask)) {
-               tx3->callback = fsl_dma_callback_test;
-               tx3->callback_param = fsl_chan;
-       }
-       fsl_dma_memcpy_issue_pending(chan);
-       msleep(2);
-
-       if (fsl_dma_is_complete(chan, cookie, NULL, NULL) != DMA_SUCCESS) {
-               dev_err(fsl_chan->dev, "selftest: Time out!\n");
-               err = -ENODEV;
-               goto free_resources;
-       }
-
-       err = memcmp(src, dest, test_size);
-       if (err) {
-               for (i = 0; (*(src + i) == *(dest + i)) && (i < test_size);
-                               i++);
-               dev_err(fsl_chan->dev, "selftest: Test failed, data %d/%ld is "
-                               "error! src 0x%x, dest 0x%x\n",
-                               i, (long)test_size, *(src + i), *(dest + i));
-       }
-
-free_resources:
-       fsl_dma_free_chan_resources(chan);
-out:
-       kfree(src);
-       return err;
-}
-
-static int __devinit of_fsl_dma_chan_probe(struct of_device *dev,
-                       const struct of_device_id *match)
+static int __devinit fsl_dma_chan_probe(struct fsl_dma_device *fdev,
+       struct device_node *node, u32 feature, const char *compatible)
 {
-       struct fsl_dma_device *fdev;
        struct fsl_dma_chan *new_fsl_chan;
        int err;
 
-       fdev = dev_get_drvdata(dev->dev.parent);
-       BUG_ON(!fdev);
-
        /* alloc channel */
        new_fsl_chan = kzalloc(sizeof(struct fsl_dma_chan), GFP_KERNEL);
        if (!new_fsl_chan) {
-               dev_err(&dev->dev, "No free memory for allocating "
+               dev_err(fdev->dev, "No free memory for allocating "
                                "dma channels!\n");
                return -ENOMEM;
        }
 
        /* get dma channel register base */
-       err = of_address_to_resource(dev->node, 0, &new_fsl_chan->reg);
+       err = of_address_to_resource(node, 0, &new_fsl_chan->reg);
        if (err) {
-               dev_err(&dev->dev, "Can't get %s property 'reg'\n",
-                               dev->node->full_name);
+               dev_err(fdev->dev, "Can't get %s property 'reg'\n",
+                               node->full_name);
                goto err_no_reg;
        }
 
-       new_fsl_chan->feature = *(u32 *)match->data;
+       new_fsl_chan->feature = feature;
 
        if (!fdev->feature)
                fdev->feature = new_fsl_chan->feature;
@@ -948,13 +823,13 @@ static int __devinit of_fsl_dma_chan_probe(struct of_device *dev,
         */
        WARN_ON(fdev->feature != new_fsl_chan->feature);
 
-       new_fsl_chan->dev = &dev->dev;
+       new_fsl_chan->dev = &new_fsl_chan->common.dev;
        new_fsl_chan->reg_base = ioremap(new_fsl_chan->reg.start,
                        new_fsl_chan->reg.end - new_fsl_chan->reg.start + 1);
 
        new_fsl_chan->id = ((new_fsl_chan->reg.start - 0x100) & 0xfff) >> 7;
        if (new_fsl_chan->id > FSL_DMA_MAX_CHANS_PER_DEVICE) {
-               dev_err(&dev->dev, "There is no %d channel!\n",
+               dev_err(fdev->dev, "There is no %d channel!\n",
                                new_fsl_chan->id);
                err = -EINVAL;
                goto err_no_chan;
@@ -988,29 +863,23 @@ static int __devinit of_fsl_dma_chan_probe(struct of_device *dev,
                        &fdev->common.channels);
        fdev->common.chancnt++;
 
-       new_fsl_chan->irq = irq_of_parse_and_map(dev->node, 0);
+       new_fsl_chan->irq = irq_of_parse_and_map(node, 0);
        if (new_fsl_chan->irq != NO_IRQ) {
                err = request_irq(new_fsl_chan->irq,
                                        &fsl_dma_chan_do_interrupt, IRQF_SHARED,
                                        "fsldma-channel", new_fsl_chan);
                if (err) {
-                       dev_err(&dev->dev, "DMA channel %s request_irq error "
-                               "with return %d\n", dev->node->full_name, err);
+                       dev_err(fdev->dev, "DMA channel %s request_irq error "
+                               "with return %d\n", node->full_name, err);
                        goto err_no_irq;
                }
        }
 
-       err = fsl_dma_self_test(new_fsl_chan);
-       if (err)
-               goto err_self_test;
-
-       dev_info(&dev->dev, "#%d (%s), irq %d\n", new_fsl_chan->id,
-                               match->compatible, new_fsl_chan->irq);
+       dev_info(fdev->dev, "#%d (%s), irq %d\n", new_fsl_chan->id,
+                               compatible, new_fsl_chan->irq);
 
        return 0;
 
-err_self_test:
-       free_irq(new_fsl_chan->irq, new_fsl_chan);
 err_no_irq:
        list_del(&new_fsl_chan->common.device_node);
 err_no_chan:
@@ -1020,38 +889,20 @@ err_no_reg:
        return err;
 }
 
-const u32 mpc8540_dma_ip_feature = FSL_DMA_IP_85XX | FSL_DMA_BIG_ENDIAN;
-const u32 mpc8349_dma_ip_feature = FSL_DMA_IP_83XX | FSL_DMA_LITTLE_ENDIAN;
-
-static struct of_device_id of_fsl_dma_chan_ids[] = {
-       {
-               .compatible = "fsl,eloplus-dma-channel",
-               .data = (void *)&mpc8540_dma_ip_feature,
-       },
-       {
-               .compatible = "fsl,elo-dma-channel",
-               .data = (void *)&mpc8349_dma_ip_feature,
-       },
-       {}
-};
-
-static struct of_platform_driver of_fsl_dma_chan_driver = {
-       .name = "of-fsl-dma-channel",
-       .match_table = of_fsl_dma_chan_ids,
-       .probe = of_fsl_dma_chan_probe,
-};
-
-static __init int of_fsl_dma_chan_init(void)
+static void fsl_dma_chan_remove(struct fsl_dma_chan *fchan)
 {
-       return of_register_platform_driver(&of_fsl_dma_chan_driver);
+       free_irq(fchan->irq, fchan);
+       list_del(&fchan->common.device_node);
+       iounmap(fchan->reg_base);
+       kfree(fchan);
 }
 
 static int __devinit of_fsl_dma_probe(struct of_device *dev,
                        const struct of_device_id *match)
 {
        int err;
-       unsigned int irq;
        struct fsl_dma_device *fdev;
+       struct device_node *child;
 
        fdev = kzalloc(sizeof(struct fsl_dma_device), GFP_KERNEL);
        if (!fdev) {
@@ -1085,9 +936,9 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev,
        fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending;
        fdev->common.dev = &dev->dev;
 
-       irq = irq_of_parse_and_map(dev->node, 0);
-       if (irq != NO_IRQ) {
-               err = request_irq(irq, &fsl_dma_do_interrupt, IRQF_SHARED,
+       fdev->irq = irq_of_parse_and_map(dev->node, 0);
+       if (fdev->irq != NO_IRQ) {
+               err = request_irq(fdev->irq, &fsl_dma_do_interrupt, IRQF_SHARED,
                                        "fsldma-device", fdev);
                if (err) {
                        dev_err(&dev->dev, "DMA device request_irq error "
@@ -1097,7 +948,21 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev,
        }
 
        dev_set_drvdata(&(dev->dev), fdev);
-       of_platform_bus_probe(dev->node, of_fsl_dma_chan_ids, &dev->dev);
+
+       /* We cannot use of_platform_bus_probe() because there is no
+        * of_platform_bus_remove.  Instead, we manually instantiate every DMA
+        * channel object.
+        */
+       for_each_child_of_node(dev->node, child) {
+               if (of_device_is_compatible(child, "fsl,eloplus-dma-channel"))
+                       fsl_dma_chan_probe(fdev, child,
+                               FSL_DMA_IP_85XX | FSL_DMA_BIG_ENDIAN,
+                               "fsl,eloplus-dma-channel");
+               if (of_device_is_compatible(child, "fsl,elo-dma-channel"))
+                       fsl_dma_chan_probe(fdev, child,
+                               FSL_DMA_IP_83XX | FSL_DMA_LITTLE_ENDIAN,
+                               "fsl,elo-dma-channel");
+       }
 
        dma_async_device_register(&fdev->common);
        return 0;
@@ -1109,6 +974,30 @@ err_no_reg:
        return err;
 }
 
+static int of_fsl_dma_remove(struct of_device *of_dev)
+{
+       struct fsl_dma_device *fdev;
+       unsigned int i;
+
+       fdev = dev_get_drvdata(&of_dev->dev);
+
+       dma_async_device_unregister(&fdev->common);
+
+       for (i = 0; i < FSL_DMA_MAX_CHANS_PER_DEVICE; i++)
+               if (fdev->chan[i])
+                       fsl_dma_chan_remove(fdev->chan[i]);
+
+       if (fdev->irq != NO_IRQ)
+               free_irq(fdev->irq, fdev);
+
+       iounmap(fdev->reg_base);
+
+       kfree(fdev);
+       dev_set_drvdata(&of_dev->dev, NULL);
+
+       return 0;
+}
+
 static struct of_device_id of_fsl_dma_ids[] = {
        { .compatible = "fsl,eloplus-dma", },
        { .compatible = "fsl,elo-dma", },
@@ -1116,15 +1005,32 @@ static struct of_device_id of_fsl_dma_ids[] = {
 };
 
 static struct of_platform_driver of_fsl_dma_driver = {
-       .name = "of-fsl-dma",
+       .name = "fsl-elo-dma",
        .match_table = of_fsl_dma_ids,
        .probe = of_fsl_dma_probe,
+       .remove = of_fsl_dma_remove,
 };
 
 static __init int of_fsl_dma_init(void)
 {
-       return of_register_platform_driver(&of_fsl_dma_driver);
+       int ret;
+
+       pr_info("Freescale Elo / Elo Plus DMA driver\n");
+
+       ret = of_register_platform_driver(&of_fsl_dma_driver);
+       if (ret)
+               pr_err("fsldma: failed to register platform driver\n");
+
+       return ret;
+}
+
+static void __exit of_fsl_dma_exit(void)
+{
+       of_unregister_platform_driver(&of_fsl_dma_driver);
 }
 
-subsys_initcall(of_fsl_dma_chan_init);
 subsys_initcall(of_fsl_dma_init);
+module_exit(of_fsl_dma_exit);
+
+MODULE_DESCRIPTION("Freescale Elo / Elo Plus DMA driver");
+MODULE_LICENSE("GPL");
index 6faf07ba0d0eb4d095f1968dee4bdd8d5ea803c0..4f21a512d84852cf2074084ffc8f7035228a2fe7 100644 (file)
@@ -114,6 +114,7 @@ struct fsl_dma_device {
        struct dma_device common;
        struct fsl_dma_chan *chan[FSL_DMA_MAX_CHANS_PER_DEVICE];
        u32 feature;            /* The same as DMA channels */
+       int irq;                /* Channel IRQ */
 };
 
 /* Define macros for fsl_dma_chan->feature property */
index bc8c6e3470ca258f6646c0ad2cd9278425296ec2..43b8cefad2c6ddfb57276e53a6ce19710677ea5a 100644 (file)
@@ -171,6 +171,9 @@ static int ioat_dma_enumerate_channels(struct ioatdma_device *device)
        xfercap_scale = readb(device->reg_base + IOAT_XFERCAP_OFFSET);
        xfercap = (xfercap_scale == 0 ? -1 : (1UL << xfercap_scale));
 
+#if CONFIG_I7300_IDLE_IOAT_CHANNEL
+       device->common.chancnt--;
+#endif
        for (i = 0; i < device->common.chancnt; i++) {
                ioat_chan = kzalloc(sizeof(*ioat_chan), GFP_KERNEL);
                if (!ioat_chan) {
@@ -971,11 +974,9 @@ static struct ioat_desc_sw *ioat_dma_get_next_descriptor(
        switch (ioat_chan->device->version) {
        case IOAT_VER_1_2:
                return ioat1_dma_get_next_descriptor(ioat_chan);
-               break;
        case IOAT_VER_2_0:
        case IOAT_VER_3_0:
                return ioat2_dma_get_next_descriptor(ioat_chan);
-               break;
        }
        return NULL;
 }
index dbd42d6c93a701b2a0e52ec4a118f36ed538701e..7f2ee27fe76be15a947db4f5fdf1f7690cbe4caa 100644 (file)
@@ -127,6 +127,13 @@ config GPIO_PCF857X
          This driver provides an in-kernel interface to those GPIOs using
          platform-neutral GPIO calls.
 
+config GPIO_TWL4030
+       tristate "TWL4030, TWL5030, and TPS659x0 GPIOs"
+       depends on TWL4030_CORE
+       help
+         Say yes here to access the GPIO signals of various multi-function
+         power management chips from Texas Instruments.
+
 comment "PCI GPIO expanders:"
 
 config GPIO_BT8XX
index 01b4bbde1956e48933d23d60c782ef94f8dff63e..6aafdeb9ad03c04a4e932c33c7ff3d7f53954cd4 100644 (file)
@@ -9,4 +9,5 @@ obj-$(CONFIG_GPIO_MAX732X)      += max732x.o
 obj-$(CONFIG_GPIO_MCP23S08)    += mcp23s08.o
 obj-$(CONFIG_GPIO_PCA953X)     += pca953x.o
 obj-$(CONFIG_GPIO_PCF857X)     += pcf857x.o
+obj-$(CONFIG_GPIO_TWL4030)     += twl4030-gpio.o
 obj-$(CONFIG_GPIO_BT8XX)       += bt8xxgpio.o
index 22edc4273ef68cd46eceabe2ec249cca93faf0a5..faa1cc66e9cf43a527beb4ce824d966dc407b494 100644 (file)
@@ -1143,7 +1143,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 
                if (!is_out) {
                        int             irq = gpio_to_irq(gpio);
-                       struct irq_desc *desc = irq_desc + irq;
+                       struct irq_desc *desc = irq_to_desc(irq);
 
                        /* This races with request_irq(), set_irq_type(),
                         * and set_irq_wake() ... but those are "rare".
diff --git a/drivers/gpio/twl4030-gpio.c b/drivers/gpio/twl4030-gpio.c
new file mode 100644 (file)
index 0000000..37d3eec
--- /dev/null
@@ -0,0 +1,521 @@
+/*
+ * twl4030_gpio.c -- access to GPIOs on TWL4030/TPS659x0 chips
+ *
+ * Copyright (C) 2006-2007 Texas Instruments, Inc.
+ * Copyright (C) 2006 MontaVista Software, Inc.
+ *
+ * Code re-arranged and cleaned up by:
+ *     Syed Mohammed Khasim <x0khasim@ti.com>
+ *
+ * Initial Code:
+ *     Andy Lowe / Nishanth Menon
+ *
+ * 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/init.h>
+#include <linux/interrupt.h>
+#include <linux/kthread.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <linux/i2c/twl4030.h>
+
+
+/*
+ * The GPIO "subchip" supports 18 GPIOs which can be configured as
+ * inputs or outputs, with pullups or pulldowns on each pin.  Each
+ * GPIO can trigger interrupts on either or both edges.
+ *
+ * GPIO interrupts can be fed to either of two IRQ lines; this is
+ * intended to support multiple hosts.
+ *
+ * There are also two LED pins used sometimes as output-only GPIOs.
+ */
+
+
+static struct gpio_chip twl_gpiochip;
+static int twl4030_gpio_irq_base;
+
+/* genirq interfaces are not available to modules */
+#ifdef MODULE
+#define is_module()    true
+#else
+#define is_module()    false
+#endif
+
+/* GPIO_CTRL Fields */
+#define MASK_GPIO_CTRL_GPIO0CD1                BIT(0)
+#define MASK_GPIO_CTRL_GPIO1CD2                BIT(1)
+#define MASK_GPIO_CTRL_GPIO_ON         BIT(2)
+
+/* Mask for GPIO registers when aggregated into a 32-bit integer */
+#define GPIO_32_MASK                   0x0003ffff
+
+/* Data structures */
+static DEFINE_MUTEX(gpio_lock);
+
+/* store usage of each GPIO. - each bit represents one GPIO */
+static unsigned int gpio_usage_count;
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * To configure TWL4030 GPIO module registers
+ */
+static inline int gpio_twl4030_write(u8 address, u8 data)
+{
+       return twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, data, address);
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * LED register offsets (use TWL4030_MODULE_{LED,PWMA,PWMB}))
+ * PWMs A and B are dedicated to LEDs A and B, respectively.
+ */
+
+#define TWL4030_LED_LEDEN      0x0
+
+/* LEDEN bits */
+#define LEDEN_LEDAON           BIT(0)
+#define LEDEN_LEDBON           BIT(1)
+#define LEDEN_LEDAEXT          BIT(2)
+#define LEDEN_LEDBEXT          BIT(3)
+#define LEDEN_LEDAPWM          BIT(4)
+#define LEDEN_LEDBPWM          BIT(5)
+#define LEDEN_PWM_LENGTHA      BIT(6)
+#define LEDEN_PWM_LENGTHB      BIT(7)
+
+#define TWL4030_PWMx_PWMxON    0x0
+#define TWL4030_PWMx_PWMxOFF   0x1
+
+#define PWMxON_LENGTH          BIT(7)
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * To read a TWL4030 GPIO module register
+ */
+static inline int gpio_twl4030_read(u8 address)
+{
+       u8 data;
+       int ret = 0;
+
+       ret = twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &data, address);
+       return (ret < 0) ? ret : data;
+}
+
+/*----------------------------------------------------------------------*/
+
+static u8 cached_leden;                /* protected by gpio_lock */
+
+/* The LED lines are open drain outputs ... a FET pulls to GND, so an
+ * external pullup is needed.  We could also expose the integrated PWM
+ * as a LED brightness control; we initialize it as "always on".
+ */
+static void twl4030_led_set_value(int led, int value)
+{
+       u8 mask = LEDEN_LEDAON | LEDEN_LEDAPWM;
+       int status;
+
+       if (led)
+               mask <<= 1;
+
+       mutex_lock(&gpio_lock);
+       if (value)
+               cached_leden &= ~mask;
+       else
+               cached_leden |= mask;
+       status = twl4030_i2c_write_u8(TWL4030_MODULE_LED, cached_leden,
+                       TWL4030_LED_LEDEN);
+       mutex_unlock(&gpio_lock);
+}
+
+static int twl4030_set_gpio_direction(int gpio, int is_input)
+{
+       u8 d_bnk = gpio >> 3;
+       u8 d_msk = BIT(gpio & 0x7);
+       u8 reg = 0;
+       u8 base = REG_GPIODATADIR1 + d_bnk;
+       int ret = 0;
+
+       mutex_lock(&gpio_lock);
+       ret = gpio_twl4030_read(base);
+       if (ret >= 0) {
+               if (is_input)
+                       reg = ret & ~d_msk;
+               else
+                       reg = ret | d_msk;
+
+               ret = gpio_twl4030_write(base, reg);
+       }
+       mutex_unlock(&gpio_lock);
+       return ret;
+}
+
+static int twl4030_set_gpio_dataout(int gpio, int enable)
+{
+       u8 d_bnk = gpio >> 3;
+       u8 d_msk = BIT(gpio & 0x7);
+       u8 base = 0;
+
+       if (enable)
+               base = REG_SETGPIODATAOUT1 + d_bnk;
+       else
+               base = REG_CLEARGPIODATAOUT1 + d_bnk;
+
+       return gpio_twl4030_write(base, d_msk);
+}
+
+static int twl4030_get_gpio_datain(int gpio)
+{
+       u8 d_bnk = gpio >> 3;
+       u8 d_off = gpio & 0x7;
+       u8 base = 0;
+       int ret = 0;
+
+       if (unlikely((gpio >= TWL4030_GPIO_MAX)
+               || !(gpio_usage_count & BIT(gpio))))
+               return -EPERM;
+
+       base = REG_GPIODATAIN1 + d_bnk;
+       ret = gpio_twl4030_read(base);
+       if (ret > 0)
+               ret = (ret >> d_off) & 0x1;
+
+       return ret;
+}
+
+/*
+ * Configure debounce timing value for a GPIO pin on TWL4030
+ */
+int twl4030_set_gpio_debounce(int gpio, int enable)
+{
+       u8 d_bnk = gpio >> 3;
+       u8 d_msk = BIT(gpio & 0x7);
+       u8 reg = 0;
+       u8 base = 0;
+       int ret = 0;
+
+       if (unlikely((gpio >= TWL4030_GPIO_MAX)
+               || !(gpio_usage_count & BIT(gpio))))
+               return -EPERM;
+
+       base = REG_GPIO_DEBEN1 + d_bnk;
+       mutex_lock(&gpio_lock);
+       ret = gpio_twl4030_read(base);
+       if (ret >= 0) {
+               if (enable)
+                       reg = ret | d_msk;
+               else
+                       reg = ret & ~d_msk;
+
+               ret = gpio_twl4030_write(base, reg);
+       }
+       mutex_unlock(&gpio_lock);
+       return ret;
+}
+EXPORT_SYMBOL(twl4030_set_gpio_debounce);
+
+/*----------------------------------------------------------------------*/
+
+static int twl_request(struct gpio_chip *chip, unsigned offset)
+{
+       int status = 0;
+
+       mutex_lock(&gpio_lock);
+
+       /* Support the two LED outputs as output-only GPIOs. */
+       if (offset >= TWL4030_GPIO_MAX) {
+               u8      ledclr_mask = LEDEN_LEDAON | LEDEN_LEDAEXT
+                               | LEDEN_LEDAPWM | LEDEN_PWM_LENGTHA;
+               u8      module = TWL4030_MODULE_PWMA;
+
+               offset -= TWL4030_GPIO_MAX;
+               if (offset) {
+                       ledclr_mask <<= 1;
+                       module = TWL4030_MODULE_PWMB;
+               }
+
+               /* initialize PWM to always-drive */
+               status = twl4030_i2c_write_u8(module, 0x7f,
+                               TWL4030_PWMx_PWMxOFF);
+               if (status < 0)
+                       goto done;
+               status = twl4030_i2c_write_u8(module, 0x7f,
+                               TWL4030_PWMx_PWMxON);
+               if (status < 0)
+                       goto done;
+
+               /* init LED to not-driven (high) */
+               module = TWL4030_MODULE_LED;
+               status = twl4030_i2c_read_u8(module, &cached_leden,
+                               TWL4030_LED_LEDEN);
+               if (status < 0)
+                       goto done;
+               cached_leden &= ~ledclr_mask;
+               status = twl4030_i2c_write_u8(module, cached_leden,
+                               TWL4030_LED_LEDEN);
+               if (status < 0)
+                       goto done;
+
+               status = 0;
+               goto done;
+       }
+
+       /* on first use, turn GPIO module "on" */
+       if (!gpio_usage_count) {
+               struct twl4030_gpio_platform_data *pdata;
+               u8 value = MASK_GPIO_CTRL_GPIO_ON;
+
+               /* optionally have the first two GPIOs switch vMMC1
+                * and vMMC2 power supplies based on card presence.
+                */
+               pdata = chip->dev->platform_data;
+               value |= pdata->mmc_cd & 0x03;
+
+               status = gpio_twl4030_write(REG_GPIO_CTRL, value);
+       }
+
+       if (!status)
+               gpio_usage_count |= (0x1 << offset);
+
+done:
+       mutex_unlock(&gpio_lock);
+       return status;
+}
+
+static void twl_free(struct gpio_chip *chip, unsigned offset)
+{
+       if (offset >= TWL4030_GPIO_MAX) {
+               twl4030_led_set_value(offset - TWL4030_GPIO_MAX, 1);
+               return;
+       }
+
+       mutex_lock(&gpio_lock);
+
+       gpio_usage_count &= ~BIT(offset);
+
+       /* on last use, switch off GPIO module */
+       if (!gpio_usage_count)
+               gpio_twl4030_write(REG_GPIO_CTRL, 0x0);
+
+       mutex_unlock(&gpio_lock);
+}
+
+static int twl_direction_in(struct gpio_chip *chip, unsigned offset)
+{
+       return (offset < TWL4030_GPIO_MAX)
+               ? twl4030_set_gpio_direction(offset, 1)
+               : -EINVAL;
+}
+
+static int twl_get(struct gpio_chip *chip, unsigned offset)
+{
+       int status = 0;
+
+       if (offset < TWL4030_GPIO_MAX)
+               status = twl4030_get_gpio_datain(offset);
+       else if (offset == TWL4030_GPIO_MAX)
+               status = cached_leden & LEDEN_LEDAON;
+       else
+               status = cached_leden & LEDEN_LEDBON;
+       return (status < 0) ? 0 : status;
+}
+
+static int twl_direction_out(struct gpio_chip *chip, unsigned offset, int value)
+{
+       if (offset < TWL4030_GPIO_MAX) {
+               twl4030_set_gpio_dataout(offset, value);
+               return twl4030_set_gpio_direction(offset, 0);
+       } else {
+               twl4030_led_set_value(offset - TWL4030_GPIO_MAX, value);
+               return 0;
+       }
+}
+
+static void twl_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+       if (offset < TWL4030_GPIO_MAX)
+               twl4030_set_gpio_dataout(offset, value);
+       else
+               twl4030_led_set_value(offset - TWL4030_GPIO_MAX, value);
+}
+
+static int twl_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+       return (twl4030_gpio_irq_base && (offset < TWL4030_GPIO_MAX))
+               ? (twl4030_gpio_irq_base + offset)
+               : -EINVAL;
+}
+
+static struct gpio_chip twl_gpiochip = {
+       .label                  = "twl4030",
+       .owner                  = THIS_MODULE,
+       .request                = twl_request,
+       .free                   = twl_free,
+       .direction_input        = twl_direction_in,
+       .get                    = twl_get,
+       .direction_output       = twl_direction_out,
+       .set                    = twl_set,
+       .to_irq                 = twl_to_irq,
+       .can_sleep              = 1,
+};
+
+/*----------------------------------------------------------------------*/
+
+static int __devinit gpio_twl4030_pulls(u32 ups, u32 downs)
+{
+       u8              message[6];
+       unsigned        i, gpio_bit;
+
+       /* For most pins, a pulldown was enabled by default.
+        * We should have data that's specific to this board.
+        */
+       for (gpio_bit = 1, i = 1; i < 6; i++) {
+               u8              bit_mask;
+               unsigned        j;
+
+               for (bit_mask = 0, j = 0; j < 8; j += 2, gpio_bit <<= 1) {
+                       if (ups & gpio_bit)
+                               bit_mask |= 1 << (j + 1);
+                       else if (downs & gpio_bit)
+                               bit_mask |= 1 << (j + 0);
+               }
+               message[i] = bit_mask;
+       }
+
+       return twl4030_i2c_write(TWL4030_MODULE_GPIO, message,
+                               REG_GPIOPUPDCTR1, 5);
+}
+
+static int gpio_twl4030_remove(struct platform_device *pdev);
+
+static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
+{
+       struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
+       int ret;
+
+       /* maybe setup IRQs */
+       if (pdata->irq_base) {
+               if (is_module()) {
+                       dev_err(&pdev->dev,
+                               "can't dispatch IRQs from modules\n");
+                       goto no_irqs;
+               }
+               ret = twl4030_sih_setup(TWL4030_MODULE_GPIO);
+               if (ret < 0)
+                       return ret;
+               WARN_ON(ret != pdata->irq_base);
+               twl4030_gpio_irq_base = ret;
+       }
+
+no_irqs:
+       /*
+        * NOTE:  boards may waste power if they don't set pullups
+        * and pulldowns correctly ... default for non-ULPI pins is
+        * pulldown, and some other pins may have external pullups
+        * or pulldowns.  Careful!
+        */
+       ret = gpio_twl4030_pulls(pdata->pullups, pdata->pulldowns);
+       if (ret)
+               dev_dbg(&pdev->dev, "pullups %.05x %.05x --> %d\n",
+                               pdata->pullups, pdata->pulldowns,
+                               ret);
+
+       twl_gpiochip.base = pdata->gpio_base;
+       twl_gpiochip.ngpio = TWL4030_GPIO_MAX;
+       twl_gpiochip.dev = &pdev->dev;
+
+       /* NOTE: we assume VIBRA_CTL.VIBRA_EN, in MODULE_AUDIO_VOICE,
+        * is (still) clear if use_leds is set.
+        */
+       if (pdata->use_leds)
+               twl_gpiochip.ngpio += 2;
+
+       ret = gpiochip_add(&twl_gpiochip);
+       if (ret < 0) {
+               dev_err(&pdev->dev,
+                               "could not register gpiochip, %d\n",
+                               ret);
+               twl_gpiochip.ngpio = 0;
+               gpio_twl4030_remove(pdev);
+       } else if (pdata->setup) {
+               int status;
+
+               status = pdata->setup(&pdev->dev,
+                               pdata->gpio_base, TWL4030_GPIO_MAX);
+               if (status)
+                       dev_dbg(&pdev->dev, "setup --> %d\n", status);
+       }
+
+       return ret;
+}
+
+static int __devexit gpio_twl4030_remove(struct platform_device *pdev)
+{
+       struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
+       int status;
+
+       if (pdata->teardown) {
+               status = pdata->teardown(&pdev->dev,
+                               pdata->gpio_base, TWL4030_GPIO_MAX);
+               if (status) {
+                       dev_dbg(&pdev->dev, "teardown --> %d\n", status);
+                       return status;
+               }
+       }
+
+       status = gpiochip_remove(&twl_gpiochip);
+       if (status < 0)
+               return status;
+
+       if (is_module())
+               return 0;
+
+       /* REVISIT no support yet for deregistering all the IRQs */
+       WARN_ON(1);
+       return -EIO;
+}
+
+/* Note:  this hardware lives inside an I2C-based multi-function device. */
+MODULE_ALIAS("platform:twl4030_gpio");
+
+static struct platform_driver gpio_twl4030_driver = {
+       .driver.name    = "twl4030_gpio",
+       .driver.owner   = THIS_MODULE,
+       .probe          = gpio_twl4030_probe,
+       .remove         = __devexit_p(gpio_twl4030_remove),
+};
+
+static int __init gpio_twl4030_init(void)
+{
+       return platform_driver_register(&gpio_twl4030_driver);
+}
+subsys_initcall(gpio_twl4030_init);
+
+static void __exit gpio_twl4030_exit(void)
+{
+       platform_driver_unregister(&gpio_twl4030_driver);
+}
+module_exit(gpio_twl4030_exit);
+
+MODULE_AUTHOR("Texas Instruments, Inc.");
+MODULE_DESCRIPTION("GPIO interface for TWL4030");
+MODULE_LICENSE("GPL");
index 9097500de5f466249417c13cb4a4b804679726a5..a8b33c2ec8d2fa951a4b81509cf944eb0e4759af 100644 (file)
@@ -6,7 +6,7 @@
 #
 menuconfig DRM
        tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
-       depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG && SHMEM
+       depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG && MMU
        help
          Kernel-level support for the Direct Rendering Infrastructure (DRI)
          introduced in XFree86 4.0. If you say Y here, you need to select
index 1839c57663c550e5a487df49b4d040c40e582074..80be1cab62afe77bc386bb39f1e0ca92113e4206 100644 (file)
@@ -76,11 +76,18 @@ int drm_rmdraw(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
        struct drm_draw *draw = data;
        unsigned long irqflags;
+       struct drm_drawable_info *info;
 
        spin_lock_irqsave(&dev->drw_lock, irqflags);
 
-       drm_free(drm_get_drawable_info(dev, draw->handle),
-                sizeof(struct drm_drawable_info), DRM_MEM_BUFS);
+       info = drm_get_drawable_info(dev, draw->handle);
+       if (info == NULL) {
+               spin_unlock_irqrestore(&dev->drw_lock, irqflags);
+               return -EINVAL;
+       }
+       drm_free(info->rects, info->num_rects * sizeof(struct drm_clip_rect),
+                       DRM_MEM_BUFS);
+       drm_free(info, sizeof(struct drm_drawable_info), DRM_MEM_BUFS);
 
        idr_remove(&dev->drw_idr, draw->handle);
 
@@ -111,7 +118,9 @@ int drm_update_drawable_info(struct drm_device *dev, void *data, struct drm_file
 
        switch (update->type) {
        case DRM_DRAWABLE_CLIPRECTS:
-               if (update->num != info->num_rects) {
+               if (update->num == 0)
+                       rects = NULL;
+               else if (update->num != info->num_rects) {
                        rects = drm_alloc(update->num * sizeof(struct drm_clip_rect),
                                         DRM_MEM_BUFS);
                } else
index 90f5a8d9bdcb67057ecf97301dee8d2f5ceb1566..920b72fbc958f30eb097f7effcbb7935a881dfe4 100644 (file)
@@ -64,6 +64,8 @@
 #define DRM_IOCTL_SG_ALLOC32           DRM_IOW( 0x38, drm_scatter_gather32_t)
 #define DRM_IOCTL_SG_FREE32            DRM_IOW( 0x39, drm_scatter_gather32_t)
 
+#define DRM_IOCTL_UPDATE_DRAW32                DRM_IOW( 0x3f, drm_update_draw32_t)
+
 #define DRM_IOCTL_WAIT_VBLANK32                DRM_IOWR(0x3a, drm_wait_vblank32_t)
 
 typedef struct drm_version_32 {
@@ -952,6 +954,37 @@ static int compat_drm_sg_free(struct file *file, unsigned int cmd,
                         DRM_IOCTL_SG_FREE, (unsigned long)request);
 }
 
+typedef struct drm_update_draw32 {
+       drm_drawable_t handle;
+       unsigned int type;
+       unsigned int num;
+       /* 64-bit version has a 32-bit pad here */
+       u64 data;       /**< Pointer */
+} __attribute__((packed)) drm_update_draw32_t;
+
+static int compat_drm_update_draw(struct file *file, unsigned int cmd,
+                                 unsigned long arg)
+{
+       drm_update_draw32_t update32;
+       struct drm_update_draw __user *request;
+       int err;
+
+       if (copy_from_user(&update32, (void __user *)arg, sizeof(update32)))
+               return -EFAULT;
+
+       request = compat_alloc_user_space(sizeof(*request));
+       if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) ||
+           __put_user(update32.handle, &request->handle) ||
+           __put_user(update32.type, &request->type) ||
+           __put_user(update32.num, &request->num) ||
+           __put_user(update32.data, &request->data))
+               return -EFAULT;
+
+       err = drm_ioctl(file->f_path.dentry->d_inode, file,
+                       DRM_IOCTL_UPDATE_DRAW, (unsigned long)request);
+       return err;
+}
+
 struct drm_wait_vblank_request32 {
        enum drm_vblank_seq_type type;
        unsigned int sequence;
@@ -1033,6 +1066,7 @@ drm_ioctl_compat_t *drm_compat_ioctls[] = {
 #endif
        [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC32)] = compat_drm_sg_alloc,
        [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE32)] = compat_drm_sg_free,
+       [DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW32)] = compat_drm_update_draw,
        [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank,
 };
 
index 4091b9e291f918be5f23a8391b48aa391d498f9c..212a94f715b23cf2db6103a301c91f9c6545a4ce 100644 (file)
@@ -594,11 +594,14 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
                        goto done;
                }
 
+               /* Get a refcount on the vblank, which will be released by
+                * drm_vbl_send_signals().
+                */
                ret = drm_vblank_get(dev, crtc);
                if (ret) {
                        drm_free(vbl_sig, sizeof(struct drm_vbl_sig),
                                 DRM_MEM_DRIVER);
-                       return ret;
+                       goto done;
                }
 
                atomic_inc(&dev->vbl_signal_pending);
index a4caf95485d7c6826482393ecf803d408b7047dd..888159e03d268c77b4102e3d6d1e430a2f682bf6 100644 (file)
@@ -232,6 +232,7 @@ int drm_lock_take(struct drm_lock_data *lock_data,
        }
        return 0;
 }
+EXPORT_SYMBOL(drm_lock_take);
 
 /**
  * This takes a lock forcibly and hands it to context. Should ONLY be used
@@ -299,6 +300,7 @@ int drm_lock_free(struct drm_lock_data *lock_data, unsigned int context)
        wake_up_interruptible(&lock_data->lock_queue);
        return 0;
 }
+EXPORT_SYMBOL(drm_lock_free);
 
 /**
  * If we get here, it means that the process has called DRM_IOCTL_LOCK
index d490db4c0de06a11ea3de7579681f3b76177c2a5..ae73b7f7249ad36059dde96219fe2fb33022b082 100644 (file)
@@ -522,12 +522,12 @@ static int drm_gem_one_name_info(int id, void *ptr, void *data)
        struct drm_gem_object *obj = ptr;
        struct drm_gem_name_info_data   *nid = data;
 
-       DRM_INFO("name %d size %d\n", obj->name, obj->size);
+       DRM_INFO("name %d size %zd\n", obj->name, obj->size);
        if (nid->eof)
                return 0;
 
        nid->len += sprintf(&nid->buf[nid->len],
-                           "%6d%9d%8d%9d\n",
+                           "%6d %8zd %7d %8d\n",
                            obj->name, obj->size,
                            atomic_read(&obj->handlecount.refcount),
                            atomic_read(&obj->refcount.refcount));
index db34780edbb274d9fe44a96463cea638e177bed5..01de536e0211772ba3df3154af63e5cab652a1f4 100644 (file)
@@ -844,8 +844,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
         * correctly in testing on 945G.
         * This may be a side effect of MSI having been made available for PEG
         * and the registers being closely associated.
+        *
+        * According to chipset errata, on the 965GM, MSI interrupts may
+        * be lost or delayed
         */
-       if (!IS_I945G(dev) && !IS_I945GM(dev))
+       if (!IS_I945G(dev) && !IS_I945GM(dev) && !IS_I965GM(dev))
                if (pci_enable_msi(dev->pdev))
                        DRM_ERROR("failed to enable MSI\n");
 
index eae4ed3956e0b456f3a58e0aa29c9dbb4ee3d6f1..f20ffe17df71d36cae69df56536d329be4c7ea27 100644 (file)
@@ -90,7 +90,7 @@ struct mem_block {
 typedef struct _drm_i915_vbl_swap {
        struct list_head head;
        drm_drawable_t drw_id;
-       unsigned int plane;
+       unsigned int pipe;
        unsigned int sequence;
 } drm_i915_vbl_swap_t;
 
@@ -240,6 +240,9 @@ typedef struct drm_i915_private {
        u8 saveDACDATA[256*3]; /* 256 3-byte colors */
        u8 saveCR[37];
 
+       /** Work task for vblank-related ring access */
+       struct work_struct vblank_work;
+
        struct {
                struct drm_mm gtt_space;
 
@@ -285,9 +288,6 @@ typedef struct drm_i915_private {
                 */
                struct delayed_work retire_work;
 
-               /** Work task for vblank-related ring access */
-               struct work_struct vblank_work;
-
                uint32_t next_gem_seqno;
 
                /**
@@ -441,7 +441,7 @@ extern int i915_irq_wait(struct drm_device *dev, void *data,
 void i915_user_irq_get(struct drm_device *dev);
 void i915_user_irq_put(struct drm_device *dev);
 
-extern void i915_gem_vblank_work_handler(struct work_struct *work);
+extern void i915_vblank_work_handler(struct work_struct *work);
 extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
 extern void i915_driver_irq_preinstall(struct drm_device * dev);
 extern int i915_driver_irq_postinstall(struct drm_device *dev);
index 9ac73dd1b422db554758061d7d8786403bf64b9e..17ae330ff269b10610d12a237ed9412f8e5e5856 100644 (file)
@@ -171,6 +171,37 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
        return 0;
 }
 
+/*
+ * Try to write quickly with an atomic kmap. Return true on success.
+ *
+ * If this fails (which includes a partial write), we'll redo the whole
+ * thing with the slow version.
+ *
+ * This is a workaround for the low performance of iounmap (approximate
+ * 10% cpu cost on normal 3D workloads).  kmap_atomic on HIGHMEM kernels
+ * happens to let us map card memory without taking IPIs.  When the vmap
+ * rework lands we should be able to dump this hack.
+ */
+static inline int fast_user_write(unsigned long pfn, char __user *user_data,
+                                 int l, int o)
+{
+#ifdef CONFIG_HIGHMEM
+       unsigned long unwritten;
+       char *vaddr_atomic;
+
+       vaddr_atomic = kmap_atomic_pfn(pfn, KM_USER0);
+#if WATCH_PWRITE
+       DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n",
+                i, o, l, pfn, vaddr_atomic);
+#endif
+       unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + o, user_data, l);
+       kunmap_atomic(vaddr_atomic, KM_USER0);
+       return !unwritten;
+#else
+       return 0;
+#endif
+}
+
 static int
 i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
                    struct drm_i915_gem_pwrite *args,
@@ -180,12 +211,7 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
        ssize_t remain;
        loff_t offset;
        char __user *user_data;
-       char __iomem *vaddr;
-       char *vaddr_atomic;
-       int i, o, l;
        int ret = 0;
-       unsigned long pfn;
-       unsigned long unwritten;
 
        user_data = (char __user *) (uintptr_t) args->data_ptr;
        remain = args->size;
@@ -209,6 +235,9 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
        obj_priv->dirty = 1;
 
        while (remain > 0) {
+               unsigned long pfn;
+               int i, o, l;
+
                /* Operation in this page
                 *
                 * i = page number
@@ -223,25 +252,10 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
 
                pfn = (dev->agp->base >> PAGE_SHIFT) + i;
 
-#ifdef CONFIG_HIGHMEM
-               /* This is a workaround for the low performance of iounmap
-                * (approximate 10% cpu cost on normal 3D workloads).
-                * kmap_atomic on HIGHMEM kernels happens to let us map card
-                * memory without taking IPIs.  When the vmap rework lands
-                * we should be able to dump this hack.
-                */
-               vaddr_atomic = kmap_atomic_pfn(pfn, KM_USER0);
-#if WATCH_PWRITE
-               DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n",
-                        i, o, l, pfn, vaddr_atomic);
-#endif
-               unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + o,
-                                                             user_data, l);
-               kunmap_atomic(vaddr_atomic, KM_USER0);
+               if (!fast_user_write(pfn, user_data, l, o)) {
+                       unsigned long unwritten;
+                       char __iomem *vaddr;
 
-               if (unwritten)
-#endif /* CONFIG_HIGHMEM */
-               {
                        vaddr = ioremap_wc(pfn << PAGE_SHIFT, PAGE_SIZE);
 #if WATCH_PWRITE
                        DRM_INFO("pwrite slow i %d o %d l %d "
@@ -2550,8 +2564,6 @@ i915_gem_load(struct drm_device *dev)
        INIT_LIST_HEAD(&dev_priv->mm.request_list);
        INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
                          i915_gem_retire_work_handler);
-       INIT_WORK(&dev_priv->mm.vblank_work,
-                 i915_gem_vblank_work_handler);
        dev_priv->mm.next_gem_seqno = 1;
 
        i915_gem_detect_bit_6_swizzle(dev);
index 15d4160415b053ce82c5bcbe593ece7bb866e429..93de15b4c9a722749d69d417d88cc1aba49d8280 100644 (file)
@@ -192,7 +192,12 @@ static int i915_gem_seqno_info(char *buf, char **start, off_t offset,
 
        *start = &buf[offset];
        *eof = 0;
-       DRM_PROC_PRINT("Current sequence: %d\n", i915_get_gem_seqno(dev));
+       if (dev_priv->hw_status_page != NULL) {
+               DRM_PROC_PRINT("Current sequence: %d\n",
+                              i915_get_gem_seqno(dev));
+       } else {
+               DRM_PROC_PRINT("Current sequence: hws uninitialized\n");
+       }
        DRM_PROC_PRINT("Waiter sequence:  %d\n",
                       dev_priv->mm.waiting_gem_seqno);
        DRM_PROC_PRINT("IRQ sequence:     %d\n", dev_priv->mm.irq_gem_seqno);
@@ -230,8 +235,12 @@ static int i915_interrupt_info(char *buf, char **start, off_t offset,
                       I915_READ(PIPEBSTAT));
        DRM_PROC_PRINT("Interrupts received: %d\n",
                       atomic_read(&dev_priv->irq_received));
-       DRM_PROC_PRINT("Current sequence:    %d\n",
-                      i915_get_gem_seqno(dev));
+       if (dev_priv->hw_status_page != NULL) {
+               DRM_PROC_PRINT("Current sequence:    %d\n",
+                              i915_get_gem_seqno(dev));
+       } else {
+               DRM_PROC_PRINT("Current sequence:    hws uninitialized\n");
+       }
        DRM_PROC_PRINT("Waiter sequence:     %d\n",
                       dev_priv->mm.waiting_gem_seqno);
        DRM_PROC_PRINT("IRQ sequence:        %d\n",
index baae511c785b6297115b47a20a23e6568bb8cca3..26f48932a51e53da571c6028409102bc071329b8 100644 (file)
@@ -59,43 +59,6 @@ i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
        }
 }
 
-/**
- * i915_get_pipe - return the the pipe associated with a given plane
- * @dev: DRM device
- * @plane: plane to look for
- *
- * The Intel Mesa & 2D drivers call the vblank routines with a plane number
- * rather than a pipe number, since they may not always be equal.  This routine
- * maps the given @plane back to a pipe number.
- */
-static int
-i915_get_pipe(struct drm_device *dev, int plane)
-{
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       u32 dspcntr;
-
-       dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR);
-
-       return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0;
-}
-
-/**
- * i915_get_plane - return the the plane associated with a given pipe
- * @dev: DRM device
- * @pipe: pipe to look for
- *
- * The Intel Mesa & 2D drivers call the vblank routines with a plane number
- * rather than a plane number, since they may not always be equal.  This routine
- * maps the given @pipe back to a plane number.
- */
-static int
-i915_get_plane(struct drm_device *dev, int pipe)
-{
-       if (i915_get_pipe(dev, 0) == pipe)
-               return 0;
-       return 1;
-}
-
 /**
  * i915_pipe_enabled - check if a pipe is enabled
  * @dev: DRM device
@@ -121,6 +84,9 @@ i915_pipe_enabled(struct drm_device *dev, int pipe)
  * Emit blits for scheduled buffer swaps.
  *
  * This function will be called with the HW lock held.
+ * Because this function must grab the ring mutex (dev->struct_mutex),
+ * it can no longer run at soft irq time. We'll fix this when we do
+ * the DRI2 swap buffer work.
  */
 static void i915_vblank_tasklet(struct drm_device *dev)
 {
@@ -141,6 +107,8 @@ static void i915_vblank_tasklet(struct drm_device *dev)
        u32 ropcpp = (0xcc << 16) | ((cpp - 1) << 24);
        RING_LOCALS;
 
+       mutex_lock(&dev->struct_mutex);
+
        if (IS_I965G(dev) && sarea_priv->front_tiled) {
                cmd |= XY_SRC_COPY_BLT_DST_TILED;
                dst_pitch >>= 2;
@@ -165,7 +133,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
        list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
                drm_i915_vbl_swap_t *vbl_swap =
                        list_entry(list, drm_i915_vbl_swap_t, head);
-               int pipe = i915_get_pipe(dev, vbl_swap->plane);
+               int pipe = vbl_swap->pipe;
 
                if ((counter[pipe] - vbl_swap->sequence) > (1<<23))
                        continue;
@@ -179,20 +147,19 @@ static void i915_vblank_tasklet(struct drm_device *dev)
 
                drw = drm_get_drawable_info(dev, vbl_swap->drw_id);
 
-               if (!drw) {
-                       spin_unlock(&dev->drw_lock);
-                       drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
-                       spin_lock(&dev_priv->swaps_lock);
-                       continue;
-               }
-
                list_for_each(hit, &hits) {
                        drm_i915_vbl_swap_t *swap_cmp =
                                list_entry(hit, drm_i915_vbl_swap_t, head);
                        struct drm_drawable_info *drw_cmp =
                                drm_get_drawable_info(dev, swap_cmp->drw_id);
 
-                       if (drw_cmp &&
+                       /* Make sure both drawables are still
+                        * around and have some rectangles before
+                        * we look inside to order them for the
+                        * blts below.
+                        */
+                       if (drw_cmp && drw_cmp->num_rects > 0 &&
+                           drw && drw->num_rects > 0 &&
                            drw_cmp->rects[0].y1 > drw->rects[0].y1) {
                                list_add_tail(list, hit);
                                break;
@@ -212,6 +179,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
 
        if (nhits == 0) {
                spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
+               mutex_unlock(&dev->struct_mutex);
                return;
        }
 
@@ -265,18 +233,21 @@ static void i915_vblank_tasklet(struct drm_device *dev)
                        drm_i915_vbl_swap_t *swap_hit =
                                list_entry(hit, drm_i915_vbl_swap_t, head);
                        struct drm_clip_rect *rect;
-                       int num_rects, plane;
+                       int num_rects, pipe;
                        unsigned short top, bottom;
 
                        drw = drm_get_drawable_info(dev, swap_hit->drw_id);
 
+                       /* The drawable may have been destroyed since
+                        * the vblank swap was queued
+                        */
                        if (!drw)
                                continue;
 
                        rect = drw->rects;
-                       plane = swap_hit->plane;
-                       top = upper[plane];
-                       bottom = lower[plane];
+                       pipe = swap_hit->pipe;
+                       top = upper[pipe];
+                       bottom = lower[pipe];
 
                        for (num_rects = drw->num_rects; num_rects--; rect++) {
                                int y1 = max(rect->y1, top);
@@ -302,6 +273,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
        }
 
        spin_unlock_irqrestore(&dev->drw_lock, irqflags);
+       mutex_unlock(&dev->struct_mutex);
 
        list_for_each_safe(hit, tmp, &hits) {
                drm_i915_vbl_swap_t *swap_hit =
@@ -313,15 +285,16 @@ static void i915_vblank_tasklet(struct drm_device *dev)
        }
 }
 
-u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
+/* Called from drm generic code, passed a 'crtc', which
+ * we use as a pipe index
+ */
+u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        unsigned long high_frame;
        unsigned long low_frame;
        u32 high1, high2, low, count;
-       int pipe;
 
-       pipe = i915_get_pipe(dev, plane);
        high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
        low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
 
@@ -350,18 +323,37 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
 }
 
 void
-i915_gem_vblank_work_handler(struct work_struct *work)
+i915_vblank_work_handler(struct work_struct *work)
 {
-       drm_i915_private_t *dev_priv;
-       struct drm_device *dev;
+       drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
+                                                   vblank_work);
+       struct drm_device *dev = dev_priv->dev;
+       unsigned long irqflags;
 
-       dev_priv = container_of(work, drm_i915_private_t,
-                               mm.vblank_work);
-       dev = dev_priv->dev;
+       if (dev->lock.hw_lock == NULL) {
+               i915_vblank_tasklet(dev);
+               return;
+       }
+
+       spin_lock_irqsave(&dev->tasklet_lock, irqflags);
+       dev->locked_tasklet_func = i915_vblank_tasklet;
+       spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
+
+       /* Try to get the lock now, if this fails, the lock
+        * holder will execute the tasklet during unlock
+        */
+       if (!drm_lock_take(&dev->lock, DRM_KERNEL_CONTEXT))
+               return;
+
+       dev->lock.lock_time = jiffies;
+       atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
+
+       spin_lock_irqsave(&dev->tasklet_lock, irqflags);
+       dev->locked_tasklet_func = NULL;
+       spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
 
-       mutex_lock(&dev->struct_mutex);
        i915_vblank_tasklet(dev);
-       mutex_unlock(&dev->struct_mutex);
+       drm_lock_free(&dev->lock, DRM_KERNEL_CONTEXT);
 }
 
 irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
@@ -398,7 +390,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
                else if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
                                        PIPE_VBLANK_INTERRUPT_STATUS)) {
                        vblank++;
-                       drm_handle_vblank(dev, i915_get_plane(dev, 0));
+                       drm_handle_vblank(dev, 0);
                }
 
                I915_WRITE(PIPEASTAT, pipea_stats);
@@ -416,7 +408,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
                else if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
                                        PIPE_VBLANK_INTERRUPT_STATUS)) {
                        vblank++;
-                       drm_handle_vblank(dev, i915_get_plane(dev, 1));
+                       drm_handle_vblank(dev, 1);
                }
 
                if (pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS)
@@ -441,12 +433,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
        if (iir & I915_ASLE_INTERRUPT)
                opregion_asle_intr(dev);
 
-       if (vblank && dev_priv->swaps_pending > 0) {
-               if (dev_priv->ring.ring_obj == NULL)
-                       drm_locked_tasklet(dev, i915_vblank_tasklet);
-               else
-                       schedule_work(&dev_priv->mm.vblank_work);
-       }
+       if (vblank && dev_priv->swaps_pending > 0)
+               schedule_work(&dev_priv->vblank_work);
 
        return IRQ_HANDLED;
 }
@@ -481,22 +469,24 @@ static int i915_emit_irq(struct drm_device * dev)
 void i915_user_irq_get(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       unsigned long irqflags;
 
-       spin_lock(&dev_priv->user_irq_lock);
+       spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
        if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1))
                i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
-       spin_unlock(&dev_priv->user_irq_lock);
+       spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
 }
 
 void i915_user_irq_put(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       unsigned long irqflags;
 
-       spin_lock(&dev_priv->user_irq_lock);
+       spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
        BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
        if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0))
                i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
-       spin_unlock(&dev_priv->user_irq_lock);
+       spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
 }
 
 static int i915_wait_irq(struct drm_device * dev, int irq_nr)
@@ -578,74 +568,95 @@ int i915_irq_wait(struct drm_device *dev, void *data,
        return i915_wait_irq(dev, irqwait->irq_seq);
 }
 
-int i915_enable_vblank(struct drm_device *dev, int plane)
+/* Called from drm generic code, passed 'crtc' which
+ * we use as a pipe index
+ */
+int i915_enable_vblank(struct drm_device *dev, int pipe)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       int pipe = i915_get_pipe(dev, plane);
        u32     pipestat_reg = 0;
        u32     pipestat;
+       u32     interrupt = 0;
+       unsigned long irqflags;
 
        switch (pipe) {
        case 0:
                pipestat_reg = PIPEASTAT;
-               i915_enable_irq(dev_priv, I915_DISPLAY_PIPE_A_EVENT_INTERRUPT);
+               interrupt = I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
                break;
        case 1:
                pipestat_reg = PIPEBSTAT;
-               i915_enable_irq(dev_priv, I915_DISPLAY_PIPE_B_EVENT_INTERRUPT);
+               interrupt = I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
                break;
        default:
                DRM_ERROR("tried to enable vblank on non-existent pipe %d\n",
                          pipe);
-               break;
+               return 0;
        }
 
-       if (pipestat_reg) {
-               pipestat = I915_READ(pipestat_reg);
-               if (IS_I965G(dev))
-                       pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE;
-               else
-                       pipestat |= PIPE_VBLANK_INTERRUPT_ENABLE;
-               /* Clear any stale interrupt status */
-               pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
-                            PIPE_VBLANK_INTERRUPT_STATUS);
-               I915_WRITE(pipestat_reg, pipestat);
-       }
+       spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
+       /* Enabling vblank events in IMR comes before PIPESTAT write, or
+        * there's a race where the PIPESTAT vblank bit gets set to 1, so
+        * the OR of enabled PIPESTAT bits goes to 1, so the PIPExEVENT in
+        * ISR flashes to 1, but the IIR bit doesn't get set to 1 because
+        * IMR masks it.  It doesn't ever get set after we clear the masking
+        * in IMR because the ISR bit is edge, not level-triggered, on the
+        * OR of PIPESTAT bits.
+        */
+       i915_enable_irq(dev_priv, interrupt);
+       pipestat = I915_READ(pipestat_reg);
+       if (IS_I965G(dev))
+               pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE;
+       else
+               pipestat |= PIPE_VBLANK_INTERRUPT_ENABLE;
+       /* Clear any stale interrupt status */
+       pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
+                    PIPE_VBLANK_INTERRUPT_STATUS);
+       I915_WRITE(pipestat_reg, pipestat);
+       (void) I915_READ(pipestat_reg); /* Posting read */
+       spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
 
        return 0;
 }
 
-void i915_disable_vblank(struct drm_device *dev, int plane)
+/* Called from drm generic code, passed 'crtc' which
+ * we use as a pipe index
+ */
+void i915_disable_vblank(struct drm_device *dev, int pipe)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       int pipe = i915_get_pipe(dev, plane);
        u32     pipestat_reg = 0;
        u32     pipestat;
+       u32     interrupt = 0;
+       unsigned long irqflags;
 
        switch (pipe) {
        case 0:
                pipestat_reg = PIPEASTAT;
-               i915_disable_irq(dev_priv, I915_DISPLAY_PIPE_A_EVENT_INTERRUPT);
+               interrupt = I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
                break;
        case 1:
                pipestat_reg = PIPEBSTAT;
-               i915_disable_irq(dev_priv, I915_DISPLAY_PIPE_B_EVENT_INTERRUPT);
+               interrupt = I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
                break;
        default:
                DRM_ERROR("tried to disable vblank on non-existent pipe %d\n",
                          pipe);
+               return;
                break;
        }
 
-       if (pipestat_reg) {
-               pipestat = I915_READ(pipestat_reg);
-               pipestat &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
-                             PIPE_VBLANK_INTERRUPT_ENABLE);
-               /* Clear any stale interrupt status */
-               pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
-                            PIPE_VBLANK_INTERRUPT_STATUS);
-               I915_WRITE(pipestat_reg, pipestat);
-       }
+       spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
+       i915_disable_irq(dev_priv, interrupt);
+       pipestat = I915_READ(pipestat_reg);
+       pipestat &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
+                     PIPE_VBLANK_INTERRUPT_ENABLE);
+       /* Clear any stale interrupt status */
+       pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
+                    PIPE_VBLANK_INTERRUPT_STATUS);
+       I915_WRITE(pipestat_reg, pipestat);
+       (void) I915_READ(pipestat_reg); /* Posting read */
+       spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
 }
 
 /* Set the vblank monitor pipe
@@ -687,8 +698,8 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        drm_i915_vblank_swap_t *swap = data;
-       drm_i915_vbl_swap_t *vbl_swap;
-       unsigned int pipe, seqtype, curseq, plane;
+       drm_i915_vbl_swap_t *vbl_swap, *vbl_old;
+       unsigned int pipe, seqtype, curseq;
        unsigned long irqflags;
        struct list_head *list;
        int ret;
@@ -709,8 +720,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
                return -EINVAL;
        }
 
-       plane = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;
-       pipe = i915_get_pipe(dev, plane);
+       pipe = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;
 
        seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE);
 
@@ -751,44 +761,52 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
                }
        }
 
+       vbl_swap = drm_calloc(1, sizeof(*vbl_swap), DRM_MEM_DRIVER);
+
+       if (!vbl_swap) {
+               DRM_ERROR("Failed to allocate memory to queue swap\n");
+               drm_vblank_put(dev, pipe);
+               return -ENOMEM;
+       }
+
+       vbl_swap->drw_id = swap->drawable;
+       vbl_swap->pipe = pipe;
+       vbl_swap->sequence = swap->sequence;
+
        spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
 
        list_for_each(list, &dev_priv->vbl_swaps.head) {
-               vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head);
+               vbl_old = list_entry(list, drm_i915_vbl_swap_t, head);
 
-               if (vbl_swap->drw_id == swap->drawable &&
-                   vbl_swap->plane == plane &&
-                   vbl_swap->sequence == swap->sequence) {
+               if (vbl_old->drw_id == swap->drawable &&
+                   vbl_old->pipe == pipe &&
+                   vbl_old->sequence == swap->sequence) {
                        spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
+                       drm_vblank_put(dev, pipe);
+                       drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
                        DRM_DEBUG("Already scheduled\n");
                        return 0;
                }
        }
 
-       spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
-
-       if (dev_priv->swaps_pending >= 100) {
+       if (dev_priv->swaps_pending >= 10) {
                DRM_DEBUG("Too many swaps queued\n");
+               DRM_DEBUG(" pipe 0: %d pipe 1: %d\n",
+                         drm_vblank_count(dev, 0),
+                         drm_vblank_count(dev, 1));
+
+               list_for_each(list, &dev_priv->vbl_swaps.head) {
+                       vbl_old = list_entry(list, drm_i915_vbl_swap_t, head);
+                       DRM_DEBUG("\tdrw %x pipe %d seq %x\n",
+                                 vbl_old->drw_id, vbl_old->pipe,
+                                 vbl_old->sequence);
+               }
+               spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
                drm_vblank_put(dev, pipe);
+               drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
                return -EBUSY;
        }
 
-       vbl_swap = drm_calloc(1, sizeof(*vbl_swap), DRM_MEM_DRIVER);
-
-       if (!vbl_swap) {
-               DRM_ERROR("Failed to allocate memory to queue swap\n");
-               drm_vblank_put(dev, pipe);
-               return -ENOMEM;
-       }
-
-       DRM_DEBUG("\n");
-
-       vbl_swap->drw_id = swap->drawable;
-       vbl_swap->plane = plane;
-       vbl_swap->sequence = swap->sequence;
-
-       spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
-
        list_add_tail(&vbl_swap->head, &dev_priv->vbl_swaps.head);
        dev_priv->swaps_pending++;
 
@@ -815,6 +833,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
 
        spin_lock_init(&dev_priv->swaps_lock);
        INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
+       INIT_WORK(&dev_priv->vblank_work, i915_vblank_work_handler);
        dev_priv->swaps_pending = 0;
 
        /* Set initial unmasked IRQs to just the selected vblank pipes. */
index 1e328d19cd6dd9aaf79573a7521f96579ff7cf0b..3e01992230b8bb3214ff424a3923b72da1606e10 100644 (file)
@@ -135,7 +135,7 @@ static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) {
        *status = get_pcf(adap, 1);
 #ifndef STUB_I2C
        while (timeout-- && (*status & I2C_PCF_PIN)) {
-               adap->waitforpin();
+               adap->waitforpin(adap->data);
                *status = get_pcf(adap, 1);
        }
        if (*status & I2C_PCF_LAB) {
@@ -208,7 +208,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
                return -ENXIO;
        }
        
-       printk(KERN_DEBUG "i2c-algo-pcf.o: deteted and initialized PCF8584.\n");
+       printk(KERN_DEBUG "i2c-algo-pcf.o: detected and initialized PCF8584.\n");
 
        return 0;
 }
@@ -331,13 +331,16 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
        int i;
        int ret=0, timeout, status;
     
+       if (adap->xfer_begin)
+               adap->xfer_begin(adap->data);
 
        /* Check for bus busy */
        timeout = wait_for_bb(adap);
        if (timeout) {
                DEB2(printk(KERN_ERR "i2c-algo-pcf.o: "
                            "Timeout waiting for BB in pcf_xfer\n");)
-               return -EIO;
+               i = -EIO;
+               goto out;
        }
        
        for (i = 0;ret >= 0 && i < num; i++) {
@@ -359,12 +362,14 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
                if (timeout) {
                        if (timeout == -EINTR) {
                                /* arbitration lost */
-                               return (-EINTR);
+                               i = -EINTR;
+                               goto out;
                        }
                        i2c_stop(adap);
                        DEB2(printk(KERN_ERR "i2c-algo-pcf.o: Timeout waiting "
                                    "for PIN(1) in pcf_xfer\n");)
-                       return (-EREMOTEIO);
+                       i = -EREMOTEIO;
+                       goto out;
                }
     
 #ifndef STUB_I2C
@@ -372,7 +377,8 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
                if (status & I2C_PCF_LRB) {
                        i2c_stop(adap);
                        DEB2(printk(KERN_ERR "i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");)
-                       return (-EREMOTEIO);
+                       i = -EREMOTEIO;
+                       goto out;
                }
 #endif
     
@@ -404,6 +410,9 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
                }
        }
 
+out:
+       if (adap->xfer_end)
+               adap->xfer_end(adap->data);
        return (i);
 }
 
index acadbc51fc0f35f6f1b9f261fc909cfffcef5c3a..7f95905bbb9d497603985dd02750ecc29e71b92d 100644 (file)
@@ -97,6 +97,7 @@ config I2C_I801
            ICH9
            Tolapai
            ICH10
+           PCH
 
          This driver can also be built as a module.  If so, the module
          will be called i2c-i801.
index 1ea39254dac6e41dbd66fb0252d9016f1b95195d..424dad6f18d83a13488cfb0b8653db8631859ea1 100644 (file)
@@ -332,10 +332,6 @@ static int __devinit amd756_probe(struct pci_dev *pdev,
        int error;
        u8 temp;
        
-       /* driver_data might come from user-space, so check it */
-       if (id->driver_data >= ARRAY_SIZE(chipname))
-               return -EINVAL;
-
        if (amd756_ioport) {
                dev_err(&pdev->dev, "Only one device supported "
                       "(you have a strange motherboard, btw)\n");
@@ -412,7 +408,6 @@ static struct pci_driver amd756_driver = {
        .id_table       = amd756_ids,
        .probe          = amd756_probe,
        .remove         = __devexit_p(amd756_remove),
-       .dynids.use_driver_data = 1,
 };
 
 static int __init amd756_init(void)
index 8164de1f4d72aba3a411f88f5d187e6d0c137f16..228f75723063968c4e77fbb374e5421e5c87e393 100644 (file)
@@ -423,7 +423,6 @@ static const struct i2c_adapter cpm_ops = {
        .owner          = THIS_MODULE,
        .name           = "i2c-cpm",
        .algo           = &cpm_i2c_algo,
-       .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
 };
 
 static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm)
index 7f38c01fb3a06ce83753f4d411cde7f907f91086..0ed3ccb81b63f74f04a24589a5c3c26ad5fa1ed8 100644 (file)
@@ -104,7 +104,8 @@ static int pcf_isa_getclock(void *data)
        return (clock);
 }
 
-static void pcf_isa_waitforpin(void) {
+static void pcf_isa_waitforpin(void *data)
+{
        DEFINE_WAIT(wait);
        int timeout = 2;
        unsigned long flags;
index 1098f21ace133225901e65d13f9cb63a99c6359d..648aa7baff83b0001faf3f36337d9cd7704a3364 100644 (file)
@@ -123,7 +123,7 @@ static int __devinit hydra_probe(struct pci_dev *dev,
                                hydra_adap.name))
                return -EBUSY;
 
-       hydra_bit_data.data = ioremap(base, pci_resource_len(dev, 0));
+       hydra_bit_data.data = pci_ioremap_bar(dev, 0);
        if (hydra_bit_data.data == NULL) {
                release_mem_region(base+offsetof(struct Hydra, CachePD), 4);
                return -ENODEV;
index dc7ea32b69a8f64c3a09725cd54748fb8c95b9c8..5123eb69a971b22e267d5de0213276c93eee3a1c 100644 (file)
@@ -41,6 +41,7 @@
   Tolapai               0x5032     32     hard     yes     yes     yes
   ICH10                 0x3a30     32     hard     yes     yes     yes
   ICH10                 0x3a60     32     hard     yes     yes     yes
+  PCH                   0x3b30     32     hard     yes     yes     yes
 
   Features supported by this driver:
   Software PEC                     no
@@ -576,6 +577,7 @@ static struct pci_device_id i801_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TOLAPAI_1) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PCH_SMBUS) },
        { 0, }
 };
 
@@ -599,6 +601,7 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
        case PCI_DEVICE_ID_INTEL_TOLAPAI_1:
        case PCI_DEVICE_ID_INTEL_ICH10_4:
        case PCI_DEVICE_ID_INTEL_ICH10_5:
+       case PCI_DEVICE_ID_INTEL_PCH_SMBUS:
                i801_features |= FEATURE_I2C_BLOCK_READ;
                /* fall through */
        case PCI_DEVICE_ID_INTEL_82801DB_3:
index 73dc52e114eb00009d2b87e43250ce03d233ac17..9f194d9efd91b1d39e1cdd7ed874ed871d81d7d5 100644 (file)
@@ -332,10 +332,6 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
        unsigned char temp;
        int error = -ENODEV;
 
-       /* driver_data might come from user-space, so check it */
-       if (id->driver_data & 1 || id->driver_data > 0xff)
-               return -EINVAL;
-
        /* Determine the address of the SMBus areas */
        if (force_addr) {
                vt596_smba = force_addr & 0xfff0;
@@ -483,7 +479,6 @@ static struct pci_driver vt596_driver = {
        .name           = "vt596_smbus",
        .id_table       = vt596_ids,
        .probe          = vt596_probe,
-       .dynids.use_driver_data = 1,
 };
 
 static int __init i2c_vt596_init(void)
index 17356827b93d6ad571f08ca75d58bc6b9dec5426..4c35702830ce5921013e6733e292d23c0b904e4f 100644 (file)
@@ -1,6 +1,8 @@
 #
 # Miscellaneous I2C chip drivers configuration
 #
+# *** DEPRECATED! Do not add new entries! See Makefile ***
+#
 
 menu "Miscellaneous I2C Chip support"
 
index ca520fa143d696dd849e80792213ce796e0266a4..23d2a31b0a644bc610429653d7da70520b86e567 100644 (file)
@@ -1,7 +1,8 @@
 #
 # Makefile for miscellaneous I2C chip drivers.
 #
-# Think twice before you add a new driver to this directory.
+# Do not add new drivers to this directory! It is DEPRECATED.
+#
 # Device drivers are better grouped according to the functionality they
 # implement rather than to the bus they are connected to. In particular:
 # * Hardware monitoring chip drivers go to drivers/hwmon
index 42e852d79ffaa5b001dda2c44219cad064a537e7..5a485c22660a9cc97d5d72d1e6ccad38e5b0658e 100644 (file)
@@ -266,6 +266,9 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
 
        client->dev.platform_data = info->platform_data;
 
+       if (info->archdata)
+               client->dev.archdata = *info->archdata;
+
        client->flags = info->flags;
        client->addr = info->addr;
        client->irq = info->irq;
index 74a369a6116fc7fbeb7bea0c68c629ec4cfb1102..a820ca6fc32770a94410b24a3a126a6f68564432 100644 (file)
@@ -84,21 +84,40 @@ config BLK_DEV_IDE_SATA
 
          If unsure, say N.
 
-config BLK_DEV_IDEDISK
-       tristate "Include IDE/ATA-2 DISK support"
-       ---help---
-         This will include enhanced support for MFM/RLL/IDE hard disks.  If
-         you have a MFM/RLL/IDE disk, and there is no special reason to use
-         the old hard disk driver instead, say Y.  If you have an SCSI-only
-         system, you can say N here.
+config IDE_GD
+       tristate "generic ATA/ATAPI disk support"
+       default y
+       help
+         Support for ATA/ATAPI disks (including ATAPI floppy drives).
 
-         To compile this driver as a module, choose M here: the
-         module will be called ide-disk.
-         Do not compile this driver as a module if your root file system
-         (the one containing the directory /) is located on the IDE disk.
+         To compile this driver as a module, choose M here.
+         The module will be called ide-gd_mod.
+
+         If unsure, say Y.
+
+config IDE_GD_ATA
+       bool "ATA disk support"
+       depends on IDE_GD
+       default y
+       help
+         This will include support for ATA hard disks.
 
          If unsure, say Y.
 
+config IDE_GD_ATAPI
+       bool "ATAPI floppy support"
+       depends on IDE_GD
+       select IDE_ATAPI
+       help
+         This will include support for ATAPI floppy drives
+         (i.e. Iomega ZIP or MKE LS-120).
+
+         For information about jumper settings and the question
+         of when a ZIP drive uses a partition table, see
+         <http://www.win.tue.nl/~aeb/linux/zip/zip-1.html>.
+
+         If unsure, say N.
+
 config BLK_DEV_IDECS
        tristate "PCMCIA IDE support"
        depends on PCMCIA
@@ -163,29 +182,6 @@ config BLK_DEV_IDETAPE
          To compile this driver as a module, choose M here: the
          module will be called ide-tape.
 
-config BLK_DEV_IDEFLOPPY
-       tristate "Include IDE/ATAPI FLOPPY support"
-       select IDE_ATAPI
-       ---help---
-         If you have an IDE floppy drive which uses the ATAPI protocol,
-         answer Y.  ATAPI is a newer protocol used by IDE CD-ROM/tape/floppy
-         drives, similar to the SCSI protocol.
-
-         The LS-120 and the IDE/ATAPI Iomega ZIP drive are also supported by
-         this driver. For information about jumper settings and the question
-         of when a ZIP drive uses a partition table, see
-         <http://www.win.tue.nl/~aeb/linux/zip/zip-1.html>.
-         (ATAPI PD-CD/CDR drives are not supported by this driver; support
-         for PD-CD/CDR drives is available if you answer Y to
-         "SCSI emulation support", below).
-
-         If you say Y here, the FLOPPY drive will be identified along with
-         other IDE devices, as "hdb" or "hdc", or something similar (check
-         the boot messages with dmesg).
-
-         To compile this driver as a module, choose M here: the
-         module will be called ide-floppy.
-
 config BLK_DEV_IDESCSI
        tristate "SCSI emulation support (DEPRECATED)"
        depends on SCSI
@@ -332,7 +328,7 @@ config IDEPCI_PCIBUS_ORDER
 # TODO: split it on per host driver config options (or module parameters)
 config BLK_DEV_OFFBOARD
        bool "Boot off-board chipsets first support (DEPRECATED)"
-       depends on BLK_DEV_IDEPCI && (BLK_DEV_AEC62XX || BLK_DEV_GENERIC || BLK_DEV_HPT34X || BLK_DEV_HPT366 || BLK_DEV_PDC202XX_NEW || BLK_DEV_PDC202XX_OLD || BLK_DEV_TC86C001)
+       depends on BLK_DEV_IDEPCI && (BLK_DEV_AEC62XX || BLK_DEV_GENERIC || BLK_DEV_HPT366 || BLK_DEV_PDC202XX_NEW || BLK_DEV_PDC202XX_OLD || BLK_DEV_TC86C001)
        help
          Normally, IDE controllers built into the motherboard (on-board
          controllers) are assigned to ide0 and ide1 while those on add-in PCI
@@ -482,28 +478,6 @@ config BLK_DEV_CS5535
 
          It is safe to say Y to this question.
 
-config BLK_DEV_HPT34X
-       tristate "HPT34X chipset support"
-       depends on BROKEN
-       select BLK_DEV_IDEDMA_PCI
-       help
-         This driver adds up to 4 more EIDE devices sharing a single
-         interrupt. The HPT343 chipset in its current form is a non-bootable
-         controller; the HPT345/HPT363 chipset is a bootable (needs BIOS FIX)
-         PCI UDMA controllers. This driver requires dynamic tuning of the
-         chipset during the ide-probe at boot time. It is reported to support
-         DVD II drives, by the manufacturer.
-
-config HPT34X_AUTODMA
-       bool "HPT34X AUTODMA support (EXPERIMENTAL)"
-       depends on BLK_DEV_HPT34X && EXPERIMENTAL
-       help
-         This is a dangerous thing to attempt currently! Please read the
-         comments at the top of <file:drivers/ide/pci/hpt34x.c>.  If you say Y
-         here, then say Y to "Use DMA by default when available" as well.
-
-         If unsure, say N.
-
 config BLK_DEV_HPT366
        tristate "HPT36X/37X chipset support"
        select BLK_DEV_IDEDMA_PCI
index ceaf779054eac07246702bf789b0ffbc6a97b7b3..9cf92ac939d20508076a4ee3587e8ba2bf2881ad 100644 (file)
@@ -18,47 +18,96 @@ ide-core-$(CONFIG_BLK_DEV_IDEACPI)  += ide-acpi.o
 
 obj-$(CONFIG_IDE)                      += ide-core.o
 
-ifeq ($(CONFIG_IDE_ARM), y)
-       ide-arm-core-y += arm/ide_arm.o
-       obj-y += ide-arm-core.o
-endif
+obj-$(CONFIG_IDE_ARM)                  += ide_arm.o
+
+obj-$(CONFIG_BLK_DEV_ALI14XX)          += ali14xx.o
+obj-$(CONFIG_BLK_DEV_UMC8672)          += umc8672.o
+obj-$(CONFIG_BLK_DEV_DTC2278)          += dtc2278.o
+obj-$(CONFIG_BLK_DEV_HT6560B)          += ht6560b.o
+obj-$(CONFIG_BLK_DEV_QD65XX)           += qd65xx.o
+obj-$(CONFIG_BLK_DEV_4DRIVES)          += ide-4drives.o
+
+obj-$(CONFIG_BLK_DEV_GAYLE)            += gayle.o
+obj-$(CONFIG_BLK_DEV_FALCON_IDE)       += falconide.o
+obj-$(CONFIG_BLK_DEV_MAC_IDE)          += macide.o
+obj-$(CONFIG_BLK_DEV_Q40IDE)           += q40ide.o
+obj-$(CONFIG_BLK_DEV_BUDDHA)           += buddha.o
+
+obj-$(CONFIG_BLK_DEV_AEC62XX)          += aec62xx.o
+obj-$(CONFIG_BLK_DEV_ALI15X3)          += alim15x3.o
+obj-$(CONFIG_BLK_DEV_AMD74XX)          += amd74xx.o
+obj-$(CONFIG_BLK_DEV_ATIIXP)           += atiixp.o
+obj-$(CONFIG_BLK_DEV_CELLEB)           += scc_pata.o
+obj-$(CONFIG_BLK_DEV_CMD64X)           += cmd64x.o
+obj-$(CONFIG_BLK_DEV_CS5520)           += cs5520.o
+obj-$(CONFIG_BLK_DEV_CS5530)           += cs5530.o
+obj-$(CONFIG_BLK_DEV_CS5535)           += cs5535.o
+obj-$(CONFIG_BLK_DEV_SC1200)           += sc1200.o
+obj-$(CONFIG_BLK_DEV_CY82C693)         += cy82c693.o
+obj-$(CONFIG_BLK_DEV_DELKIN)           += delkin_cb.o
+obj-$(CONFIG_BLK_DEV_HPT366)           += hpt366.o
+obj-$(CONFIG_BLK_DEV_IT8213)           += it8213.o
+obj-$(CONFIG_BLK_DEV_IT821X)           += it821x.o
+obj-$(CONFIG_BLK_DEV_JMICRON)          += jmicron.o
+obj-$(CONFIG_BLK_DEV_NS87415)          += ns87415.o
+obj-$(CONFIG_BLK_DEV_OPTI621)          += opti621.o
+obj-$(CONFIG_BLK_DEV_PDC202XX_OLD)     += pdc202xx_old.o
+obj-$(CONFIG_BLK_DEV_PDC202XX_NEW)     += pdc202xx_new.o
+obj-$(CONFIG_BLK_DEV_PIIX)             += piix.o
+obj-$(CONFIG_BLK_DEV_RZ1000)           += rz1000.o
+obj-$(CONFIG_BLK_DEV_SVWKS)            += serverworks.o
+obj-$(CONFIG_BLK_DEV_SGIIOC4)          += sgiioc4.o
+obj-$(CONFIG_BLK_DEV_SIIMAGE)          += siimage.o
+obj-$(CONFIG_BLK_DEV_SIS5513)          += sis5513.o
+obj-$(CONFIG_BLK_DEV_SL82C105)         += sl82c105.o
+obj-$(CONFIG_BLK_DEV_SLC90E66)         += slc90e66.o
+obj-$(CONFIG_BLK_DEV_TC86C001)         += tc86c001.o
+obj-$(CONFIG_BLK_DEV_TRIFLEX)          += triflex.o
+obj-$(CONFIG_BLK_DEV_TRM290)           += trm290.o
+obj-$(CONFIG_BLK_DEV_VIA82CXXX)                += via82cxxx.o
 
-obj-$(CONFIG_IDE)                      += legacy/ pci/
+# Must appear at the end of the block
+obj-$(CONFIG_BLK_DEV_GENERIC)          += ide-pci-generic.o
+ide-pci-generic-y                      += generic.o
 
 obj-$(CONFIG_IDEPCI_PCIBUS_ORDER)      += ide-scan-pci.o
 
-ifeq ($(CONFIG_BLK_DEV_CMD640), y)
-       cmd640-core-y += pci/cmd640.o
-       obj-y += cmd640-core.o
-endif
+obj-$(CONFIG_BLK_DEV_CMD640)           += cmd640.o
+
+obj-$(CONFIG_BLK_DEV_IDE_PMAC)         += pmac.o
+
+obj-$(CONFIG_IDE_H8300)                        += ide-h8300.o
 
-obj-$(CONFIG_IDE)                      += ppc/
-obj-$(CONFIG_IDE_H8300)                        += h8300/
 obj-$(CONFIG_IDE_GENERIC)              += ide-generic.o
 obj-$(CONFIG_BLK_DEV_IDEPNP)           += ide-pnp.o
 
-ide-disk_mod-y += ide-disk.o ide-disk_ioctl.o
+ide-gd_mod-y += ide-gd.o
 ide-cd_mod-y += ide-cd.o ide-cd_ioctl.o ide-cd_verbose.o
-ide-floppy_mod-y += ide-floppy.o ide-floppy_ioctl.o
 
+ifeq ($(CONFIG_IDE_GD_ATA), y)
+       ide-gd_mod-y += ide-disk.o ide-disk_ioctl.o
 ifeq ($(CONFIG_IDE_PROC_FS), y)
-       ide-disk_mod-y += ide-disk_proc.o
-       ide-floppy_mod-y += ide-floppy_proc.o
+       ide-gd_mod-y += ide-disk_proc.o
+endif
 endif
 
-obj-$(CONFIG_BLK_DEV_IDEDISK)          += ide-disk_mod.o
+ifeq ($(CONFIG_IDE_GD_ATAPI), y)
+       ide-gd_mod-y += ide-floppy.o ide-floppy_ioctl.o
+ifeq ($(CONFIG_IDE_PROC_FS), y)
+       ide-gd_mod-y += ide-floppy_proc.o
+endif
+endif
+
+obj-$(CONFIG_IDE_GD)                   += ide-gd_mod.o
 obj-$(CONFIG_BLK_DEV_IDECD)            += ide-cd_mod.o
-obj-$(CONFIG_BLK_DEV_IDEFLOPPY)                += ide-floppy_mod.o
 obj-$(CONFIG_BLK_DEV_IDETAPE)          += ide-tape.o
 
-ifeq ($(CONFIG_BLK_DEV_IDECS), y)
-       ide-cs-core-y += legacy/ide-cs.o
-       obj-y += ide-cs-core.o
-endif
+obj-$(CONFIG_BLK_DEV_IDECS)            += ide-cs.o
 
-ifeq ($(CONFIG_BLK_DEV_PLATFORM), y)
-       ide-platform-core-y += legacy/ide_platform.o
-       obj-y += ide-platform-core.o
-endif
+obj-$(CONFIG_BLK_DEV_PLATFORM)         += ide_platform.o
+
+obj-$(CONFIG_BLK_DEV_IDE_ICSIDE)       += icside.o
+obj-$(CONFIG_BLK_DEV_IDE_RAPIDE)       += rapide.o
+obj-$(CONFIG_BLK_DEV_PALMCHIP_BK3710)  += palm_bk3710.o
 
-obj-$(CONFIG_IDE)                      += arm/ mips/
+obj-$(CONFIG_BLK_DEV_IDE_AU1XXX)       += au1xxx-ide.o
diff --git a/drivers/ide/arm/Makefile b/drivers/ide/arm/Makefile
deleted file mode 100644 (file)
index 5bc2605..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-
-obj-$(CONFIG_BLK_DEV_IDE_ICSIDE)       += icside.o
-obj-$(CONFIG_BLK_DEV_IDE_RAPIDE)       += rapide.o
-obj-$(CONFIG_BLK_DEV_PALMCHIP_BK3710)  += palm_bk3710.o
-
-ifeq ($(CONFIG_IDE_ARM), m)
-       obj-m += ide_arm.o
-endif
-
-EXTRA_CFLAGS   := -Idrivers/ide
similarity index 81%
rename from drivers/ide/pci/delkin_cb.c
rename to drivers/ide/delkin_cb.c
index 8689a706f537186e46549d2253b51c5c66c3b3a6..8f1b2d9f05138631c541d71c2cb195987de726a5 100644 (file)
@@ -46,10 +46,27 @@ static const struct ide_port_ops delkin_cb_port_ops = {
        .quirkproc              = ide_undecoded_slave,
 };
 
+static unsigned int delkin_cb_init_chipset(struct pci_dev *dev)
+{
+       unsigned long base = pci_resource_start(dev, 0);
+       int i;
+
+       outb(0x02, base + 0x1e);        /* set nIEN to block interrupts */
+       inb(base + 0x17);               /* read status to clear interrupts */
+
+       for (i = 0; i < sizeof(setup); ++i) {
+               if (setup[i])
+                       outb(setup[i], base + i);
+       }
+
+       return 0;
+}
+
 static const struct ide_port_info delkin_cb_port_info = {
        .port_ops               = &delkin_cb_port_ops,
        .host_flags             = IDE_HFLAG_IO_32BIT | IDE_HFLAG_UNMASK_IRQS |
                                  IDE_HFLAG_NO_DMA,
+       .init_chipset           = delkin_cb_init_chipset,
 };
 
 static int __devinit
@@ -57,7 +74,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
 {
        struct ide_host *host;
        unsigned long base;
-       int i, rc;
+       int rc;
        hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
        rc = pci_enable_device(dev);
@@ -72,12 +89,8 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
                return rc;
        }
        base = pci_resource_start(dev, 0);
-       outb(0x02, base + 0x1e);        /* set nIEN to block interrupts */
-       inb(base + 0x17);               /* read status to clear interrupts */
-       for (i = 0; i < sizeof(setup); ++i) {
-               if (setup[i])
-                       outb(setup[i], base + i);
-       }
+
+       delkin_cb_init_chipset(dev);
 
        memset(&hw, 0, sizeof(hw));
        ide_std_init_ports(&hw, base + 0x10, base + 0x1e);
@@ -110,6 +123,40 @@ delkin_cb_remove (struct pci_dev *dev)
        pci_disable_device(dev);
 }
 
+#ifdef CONFIG_PM
+static int delkin_cb_suspend(struct pci_dev *dev, pm_message_t state)
+{
+       pci_save_state(dev);
+       pci_disable_device(dev);
+       pci_set_power_state(dev, pci_choose_state(dev, state));
+
+       return 0;
+}
+
+static int delkin_cb_resume(struct pci_dev *dev)
+{
+       struct ide_host *host = pci_get_drvdata(dev);
+       int rc;
+
+       pci_set_power_state(dev, PCI_D0);
+
+       rc = pci_enable_device(dev);
+       if (rc)
+               return rc;
+
+       pci_restore_state(dev);
+       pci_set_master(dev);
+
+       if (host->init_chipset)
+               host->init_chipset(dev);
+
+       return 0;
+}
+#else
+#define delkin_cb_suspend NULL
+#define delkin_cb_resume NULL
+#endif
+
 static struct pci_device_id delkin_cb_pci_tbl[] __devinitdata = {
        { 0x1145, 0xf021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        { 0x1145, 0xf024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
@@ -122,6 +169,8 @@ static struct pci_driver delkin_cb_pci_driver = {
        .id_table       = delkin_cb_pci_tbl,
        .probe          = delkin_cb_probe,
        .remove         = delkin_cb_remove,
+       .suspend        = delkin_cb_suspend,
+       .resume         = delkin_cb_resume,
 };
 
 static int __init delkin_cb_init(void)
diff --git a/drivers/ide/h8300/Makefile b/drivers/ide/h8300/Makefile
deleted file mode 100644 (file)
index 5eba16f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-
-obj-$(CONFIG_IDE_H8300)                        += ide-h8300.o
similarity index 98%
rename from drivers/ide/pci/hpt366.c
rename to drivers/ide/hpt366.c
index 9cf171cb9376b5265e07f87dfe88cb3a346bdc3f..a7909e9c720e5741d402ceeee78b1d83322dabbe 100644 (file)
@@ -3,7 +3,7 @@
  * Portions Copyright (C) 2001         Sun Microsystems, Inc.
  * Portions Copyright (C) 2003         Red Hat Inc
  * Portions Copyright (C) 2007         Bartlomiej Zolnierkiewicz
- * Portions Copyright (C) 2005-2007    MontaVista Software, Inc.
+ * Portions Copyright (C) 2005-2008    MontaVista Software, Inc.
  *
  * Thanks to HighPoint Technologies for their assistance, and hardware.
  * Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his
@@ -748,26 +748,24 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
        struct pci_dev  *dev    = to_pci_dev(hwif->dev);
        struct hpt_info *info   = hpt3xx_get_info(hwif->dev);
 
-       if (drive->quirk_list) {
-               if (info->chip_type >= HPT370) {
-                       u8 scr1 = 0;
-
-                       pci_read_config_byte(dev, 0x5a, &scr1);
-                       if (((scr1 & 0x10) >> 4) != mask) {
-                               if (mask)
-                                       scr1 |=  0x10;
-                               else
-                                       scr1 &= ~0x10;
-                               pci_write_config_byte(dev, 0x5a, scr1);
-                       }
-               } else {
+       if (drive->quirk_list == 0)
+               return;
+
+       if (info->chip_type >= HPT370) {
+               u8 scr1 = 0;
+
+               pci_read_config_byte(dev, 0x5a, &scr1);
+               if (((scr1 & 0x10) >> 4) != mask) {
                        if (mask)
-                               disable_irq(hwif->irq);
+                               scr1 |=  0x10;
                        else
-                               enable_irq (hwif->irq);
+                               scr1 &= ~0x10;
+                       pci_write_config_byte(dev, 0x5a, scr1);
                }
-       } else
-               outb(ATA_DEVCTL_OBS | (mask ? 2 : 0), hwif->io_ports.ctl_addr);
+       } else if (mask)
+               disable_irq(hwif->irq);
+       else
+               enable_irq(hwif->irq);
 }
 
 /*
@@ -1289,7 +1287,6 @@ static u8 hpt3xx_cable_detect(ide_hwif_t *hwif)
 
 static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
 {
-       struct pci_dev *dev     = to_pci_dev(hwif->dev);
        struct hpt_info *info   = hpt3xx_get_info(hwif->dev);
        int serialize           = HPT_SERIALIZE_IO;
        u8  chip_type           = info->chip_type;
index 2e305714c209e8d9573a2aee1f490ece032b2580..4e58b9e7a58a01592eb3e130aee781a41e4891d1 100644 (file)
@@ -191,7 +191,7 @@ int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on)
 {
        struct ide_atapi_pc pc;
 
-       if (drive->atapi_flags & IDE_AFLAG_NO_DOORLOCK)
+       if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0)
                return 0;
 
        ide_init_pc(&pc);
index 3308b1cd3a335de2cf4da4867ec7ca2597649f5a..133afd09843ca7b1cecb19b6718a125f771c2064 100644 (file)
@@ -99,7 +99,7 @@ static void ide_cd_put(struct cdrom_info *cd)
 /* Mark that we've seen a media change and invalidate our internal buffers. */
 static void cdrom_saw_media_change(ide_drive_t *drive)
 {
-       drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED;
+       drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
        drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID;
 }
 
@@ -340,8 +340,8 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
        }
 
        ide_debug_log(IDE_DBG_RQ, "%s: stat: 0x%x, good_stat: 0x%x, "
-                     "rq->cmd_type: 0x%x, err: 0x%x\n", __func__, stat,
-                     good_stat, rq->cmd_type, err);
+                     "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x, err: 0x%x\n",
+                     __func__, stat, good_stat, rq->cmd[0], rq->cmd_type, err);
 
        if (blk_sense_request(rq)) {
                /*
@@ -843,13 +843,10 @@ static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq)
        rq->q->prep_rq_fn(rq->q, rq);
 }
 
-/*
- * All other packet commands.
- */
 static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq)
 {
-
-       ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+       ide_debug_log(IDE_DBG_FUNC, "Call %s, rq->cmd[0]: 0x%x\n",
+                     __func__, rq->cmd[0]);
 
        /*
         * Some of the trailing request sense fields are optional,
@@ -876,7 +873,7 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
        if (!sense)
                sense = &local_sense;
 
-       ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x, "
+       ide_debug_log(IDE_DBG_PC, "Call %s, cmd[0]: 0x%x, write: 0x%x, "
                      "timeout: %d, cmd_flags: 0x%x\n", __func__, cmd[0], write,
                      timeout, cmd_flags);
 
@@ -1177,8 +1174,9 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
        unsigned short sectors_per_frame =
                queue_hardsect_size(drive->queue) >> SECTOR_BITS;
 
-       ide_debug_log(IDE_DBG_RQ, "Call %s, write: 0x%x, secs_per_frame: %u\n",
-                     __func__, write, sectors_per_frame);
+       ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x, "
+                     "secs_per_frame: %u\n",
+                     __func__, rq->cmd[0], write, sectors_per_frame);
 
        if (write) {
                /* disk has become write protected */
@@ -1221,7 +1219,8 @@ static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive)
 static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
 {
 
-       ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd_type: 0x%x\n", __func__,
+       ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, "
+                     "rq->cmd_type: 0x%x\n", __func__, rq->cmd[0],
                      rq->cmd_type);
 
        if (blk_pc_request(rq))
@@ -1257,9 +1256,6 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
        }
 }
 
-/*
- * cdrom driver request routine.
- */
 static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
                                        sector_t block)
 {
@@ -1267,8 +1263,10 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
        ide_handler_t *fn;
        int xferlen;
 
-       ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd_type: 0x%x, block: %llu\n",
-                     __func__, rq->cmd_type, (unsigned long long)block);
+       ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, "
+                     "rq->cmd_type: 0x%x, block: %llu\n",
+                     __func__, rq->cmd[0], rq->cmd_type,
+                     (unsigned long long)block);
 
        if (blk_fs_request(rq)) {
                if (drive->atapi_flags & IDE_AFLAG_SEEKING) {
@@ -1412,6 +1410,10 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
 
        *capacity = 1 + be32_to_cpu(capbuf.lba);
        *sectors_per_frame = blocklen >> SECTOR_BITS;
+
+       ide_debug_log(IDE_DBG_PROBE, "%s: cap: %lu, sectors_per_frame: %lu\n",
+                     __func__, *capacity, *sectors_per_frame);
+
        return 0;
 }
 
@@ -1643,6 +1645,9 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
                maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]);
        }
 
+       ide_debug_log(IDE_DBG_PROBE, "%s: curspeed: %u, maxspeed: %u\n",
+                     __func__, curspeed, maxspeed);
+
        cd->current_speed = (curspeed + (176/2)) / 176;
        cd->max_speed = (maxspeed + (176/2)) / 176;
 }
@@ -1732,7 +1737,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
                return 0;
 
        if ((buf[8 + 6] & 0x01) == 0)
-               drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK;
+               drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
        if (buf[8 + 6] & 0x08)
                drive->atapi_flags &= ~IDE_AFLAG_NO_EJECT;
        if (buf[8 + 3] & 0x01)
@@ -1777,7 +1782,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
        if ((cdi->mask & CDC_DVD_R) == 0 || (cdi->mask & CDC_DVD_RAM) == 0)
                printk(KERN_CONT " DVD%s%s",
                                 (cdi->mask & CDC_DVD_R) ? "" : "-R",
-                                (cdi->mask & CDC_DVD_RAM) ? "" : "-RAM");
+                                (cdi->mask & CDC_DVD_RAM) ? "" : "/RAM");
 
        if ((cdi->mask & CDC_CD_R) == 0 || (cdi->mask & CDC_CD_RW) == 0)
                printk(KERN_CONT " CD%s%s",
@@ -1908,6 +1913,16 @@ static const struct ide_proc_devset idecd_settings[] = {
        IDE_PROC_DEVSET(dsc_overlap, 0, 1),
        { 0 },
 };
+
+static ide_proc_entry_t *ide_cd_proc_entries(ide_drive_t *drive)
+{
+       return idecd_proc;
+}
+
+static const struct ide_proc_devset *ide_cd_proc_devsets(ide_drive_t *drive)
+{
+       return idecd_settings;
+}
 #endif
 
 static const struct cd_list_entry ide_cd_quirks_list[] = {
@@ -1986,8 +2001,8 @@ static int ide_cdrom_setup(ide_drive_t *drive)
        if (!drive->queue->unplug_delay)
                drive->queue->unplug_delay = 1;
 
-       drive->atapi_flags = IDE_AFLAG_MEDIA_CHANGED | IDE_AFLAG_NO_EJECT |
-                      ide_cd_flags(id);
+       drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
+       drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id);
 
        if ((drive->atapi_flags & IDE_AFLAG_VERTOS_300_SSD) &&
            fw_rev[4] == '1' && fw_rev[6] <= '2')
@@ -2069,22 +2084,20 @@ static ide_driver_t ide_cdrom_driver = {
        .end_request            = ide_end_request,
        .error                  = __ide_error,
 #ifdef CONFIG_IDE_PROC_FS
-       .proc                   = idecd_proc,
-       .settings               = idecd_settings,
+       .proc_entries           = ide_cd_proc_entries,
+       .proc_devsets           = ide_cd_proc_devsets,
 #endif
 };
 
-static int idecd_open(struct inode *inode, struct file *file)
+static int idecd_open(struct block_device *bdev, fmode_t mode)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct cdrom_info *info;
+       struct cdrom_info *info = ide_cd_get(bdev->bd_disk);
        int rc = -ENOMEM;
 
-       info = ide_cd_get(disk);
        if (!info)
                return -ENXIO;
 
-       rc = cdrom_open(&info->devinfo, inode, file);
+       rc = cdrom_open(&info->devinfo, bdev, mode);
 
        if (rc < 0)
                ide_cd_put(info);
@@ -2092,12 +2105,11 @@ static int idecd_open(struct inode *inode, struct file *file)
        return rc;
 }
 
-static int idecd_release(struct inode *inode, struct file *file)
+static int idecd_release(struct gendisk *disk, fmode_t mode)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
        struct cdrom_info *info = ide_drv_g(disk, cdrom_info);
 
-       cdrom_release(&info->devinfo, file);
+       cdrom_release(&info->devinfo, mode);
 
        ide_cd_put(info);
 
@@ -2143,10 +2155,9 @@ static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg)
        return 0;
 }
 
-static int idecd_ioctl(struct inode *inode, struct file *file,
+static int idecd_ioctl(struct block_device *bdev, fmode_t mode,
                        unsigned int cmd, unsigned long arg)
 {
-       struct block_device *bdev = inode->i_bdev;
        struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info);
        int err;
 
@@ -2159,9 +2170,9 @@ static int idecd_ioctl(struct inode *inode, struct file *file,
                break;
        }
 
-       err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg);
+       err = generic_ide_ioctl(info->drive, bdev, cmd, arg);
        if (err == -EINVAL)
-               err = cdrom_ioctl(file, &info->devinfo, inode, cmd, arg);
+               err = cdrom_ioctl(&info->devinfo, bdev, mode, cmd, arg);
 
        return err;
 }
@@ -2186,7 +2197,7 @@ static struct block_device_operations idecd_ops = {
        .owner                  = THIS_MODULE,
        .open                   = idecd_open,
        .release                = idecd_release,
-       .ioctl                  = idecd_ioctl,
+       .locked_ioctl           = idecd_ioctl,
        .media_changed          = idecd_media_changed,
        .revalidate_disk        = idecd_revalidate_disk
 };
index 74231b41f611b5c63a2e60198ab9b742405deb33..df3df0041eb61b8b0050703bbeb5585500bbc8fd 100644 (file)
@@ -86,8 +86,8 @@ int ide_cdrom_check_media_change_real(struct cdrom_device_info *cdi,
 
        if (slot_nr == CDSL_CURRENT) {
                (void) cdrom_check_status(drive, NULL);
-               retval = (drive->atapi_flags & IDE_AFLAG_MEDIA_CHANGED) ? 1 : 0;
-               drive->atapi_flags &= ~IDE_AFLAG_MEDIA_CHANGED;
+               retval = (drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED) ? 1 : 0;
+               drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
                return retval;
        } else {
                return -EINVAL;
@@ -136,7 +136,7 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag,
                sense = &my_sense;
 
        /* If the drive cannot lock the door, just pretend. */
-       if (drive->atapi_flags & IDE_AFLAG_NO_DOORLOCK) {
+       if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) {
                stat = 0;
        } else {
                unsigned char cmd[BLK_MAX_CDB];
@@ -157,7 +157,7 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag,
            (sense->asc == 0x24 || sense->asc == 0x20)) {
                printk(KERN_ERR "%s: door locking not supported\n",
                        drive->name);
-               drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK;
+               drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
                stat = 0;
        }
 
index 3853bde8eedc3c291b8b676529563afccdcc2f0d..223750c1b5a6a170bccfcd0b6171b022df0c5caa 100644 (file)
@@ -14,9 +14,6 @@
  * This is the IDE/ATA disk driver, as evolved from hd.c and ide.c.
  */
 
-#define IDEDISK_VERSION        "1.18"
-
-#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <asm/io.h>
 #include <asm/div64.h>
 
-#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
-#define IDE_DISK_MINORS                (1 << PARTN_BITS)
-#else
-#define IDE_DISK_MINORS                0
-#endif
-
 #include "ide-disk.h"
 
-static DEFINE_MUTEX(idedisk_ref_mutex);
-
-#define to_ide_disk(obj) container_of(obj, struct ide_disk_obj, kref)
-
-static void ide_disk_release(struct kref *);
-
-static struct ide_disk_obj *ide_disk_get(struct gendisk *disk)
-{
-       struct ide_disk_obj *idkp = NULL;
-
-       mutex_lock(&idedisk_ref_mutex);
-       idkp = ide_disk_g(disk);
-       if (idkp) {
-               if (ide_device_get(idkp->drive))
-                       idkp = NULL;
-               else
-                       kref_get(&idkp->kref);
-       }
-       mutex_unlock(&idedisk_ref_mutex);
-       return idkp;
-}
-
-static void ide_disk_put(struct ide_disk_obj *idkp)
-{
-       ide_drive_t *drive = idkp->drive;
-
-       mutex_lock(&idedisk_ref_mutex);
-       kref_put(&idkp->kref, ide_disk_release);
-       ide_device_put(drive);
-       mutex_unlock(&idedisk_ref_mutex);
-}
-
 static const u8 ide_rw_cmds[] = {
        ATA_CMD_READ_MULTI,
        ATA_CMD_WRITE_MULTI,
@@ -374,7 +333,7 @@ static void idedisk_check_hpa(ide_drive_t *drive)
        }
 }
 
-static void init_idedisk_capacity(ide_drive_t *drive)
+static int ide_disk_get_capacity(ide_drive_t *drive)
 {
        u16 *id = drive->id;
        int lba;
@@ -403,11 +362,28 @@ static void init_idedisk_capacity(ide_drive_t *drive)
                if (ata_id_hpa_enabled(id))
                        idedisk_check_hpa(drive);
        }
-}
 
-sector_t ide_disk_capacity(ide_drive_t *drive)
-{
-       return drive->capacity64;
+       /* limit drive capacity to 137GB if LBA48 cannot be used */
+       if ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 &&
+           drive->capacity64 > 1ULL << 28) {
+               printk(KERN_WARNING "%s: cannot use LBA48 - full capacity "
+                      "%llu sectors (%llu MB)\n",
+                      drive->name, (unsigned long long)drive->capacity64,
+                      sectors_to_MB(drive->capacity64));
+               drive->capacity64 = 1ULL << 28;
+       }
+
+       if ((drive->hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) &&
+           (drive->dev_flags & IDE_DFLAG_LBA48)) {
+               if (drive->capacity64 > 1ULL << 28) {
+                       printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode"
+                                        " will be used for accessing sectors "
+                                        "> %u\n", drive->name, 1 << 28);
+               } else
+                       drive->dev_flags &= ~IDE_DFLAG_LBA48;
+       }
+
+       return 0;
 }
 
 static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
@@ -508,7 +484,7 @@ static void update_ordered(ide_drive_t *drive)
                 * time we have trimmed the drive capacity if LBA48 is
                 * not available so we don't need to recheck that.
                 */
-               capacity = ide_disk_capacity(drive);
+               capacity = ide_gd_capacity(drive);
                barrier = ata_id_flush_enabled(id) &&
                        (drive->dev_flags & IDE_DFLAG_NOFLUSH) == 0 &&
                        ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 ||
@@ -616,7 +592,12 @@ ide_ext_devset_rw(wcache, wcache);
 
 ide_ext_devset_rw_sync(nowerr, nowerr);
 
-static void idedisk_setup(ide_drive_t *drive)
+static int ide_disk_check(ide_drive_t *drive, const char *s)
+{
+       return 1;
+}
+
+static void ide_disk_setup(ide_drive_t *drive)
 {
        struct ide_disk_obj *idkp = drive->driver_data;
        ide_hwif_t *hwif = drive->hwif;
@@ -652,33 +633,13 @@ static void idedisk_setup(ide_drive_t *drive)
                         drive->queue->max_sectors / 2);
 
        /* calculate drive capacity, and select LBA if possible */
-       init_idedisk_capacity(drive);
-
-       /* limit drive capacity to 137GB if LBA48 cannot be used */
-       if ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 &&
-           drive->capacity64 > 1ULL << 28) {
-               printk(KERN_WARNING "%s: cannot use LBA48 - full capacity "
-                      "%llu sectors (%llu MB)\n",
-                      drive->name, (unsigned long long)drive->capacity64,
-                      sectors_to_MB(drive->capacity64));
-               drive->capacity64 = 1ULL << 28;
-       }
-
-       if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) &&
-           (drive->dev_flags & IDE_DFLAG_LBA48)) {
-               if (drive->capacity64 > 1ULL << 28) {
-                       printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode"
-                                        " will be used for accessing sectors "
-                                        "> %u\n", drive->name, 1 << 28);
-               } else
-                       drive->dev_flags &= ~IDE_DFLAG_LBA48;
-       }
+       ide_disk_get_capacity(drive);
 
        /*
         * if possible, give fdisk access to more of the drive,
         * by correcting bios_cyls:
         */
-       capacity = ide_disk_capacity(drive);
+       capacity = ide_gd_capacity(drive);
 
        if ((drive->dev_flags & IDE_DFLAG_FORCED_GEOM) == 0) {
                if (ata_id_lba48_enabled(drive->id)) {
@@ -718,9 +679,17 @@ static void idedisk_setup(ide_drive_t *drive)
                drive->dev_flags |= IDE_DFLAG_WCACHE;
 
        set_wcache(drive, 1);
+
+       if ((drive->dev_flags & IDE_DFLAG_LBA) == 0 &&
+           (drive->head == 0 || drive->head > 16)) {
+               printk(KERN_ERR "%s: invalid geometry: %d physical heads?\n",
+                       drive->name, drive->head);
+               drive->dev_flags &= ~IDE_DFLAG_ATTACH;
+       } else
+               drive->dev_flags |= IDE_DFLAG_ATTACH;
 }
 
-static void ide_cacheflush_p(ide_drive_t *drive)
+static void ide_disk_flush(ide_drive_t *drive)
 {
        if (ata_id_flush_enabled(drive->id) == 0 ||
            (drive->dev_flags & IDE_DFLAG_WCACHE) == 0)
@@ -730,267 +699,40 @@ static void ide_cacheflush_p(ide_drive_t *drive)
                printk(KERN_INFO "%s: wcache flush failed!\n", drive->name);
 }
 
-static void ide_disk_remove(ide_drive_t *drive)
-{
-       struct ide_disk_obj *idkp = drive->driver_data;
-       struct gendisk *g = idkp->disk;
-
-       ide_proc_unregister_driver(drive, idkp->driver);
-
-       del_gendisk(g);
-
-       ide_cacheflush_p(drive);
-
-       ide_disk_put(idkp);
-}
-
-static void ide_disk_release(struct kref *kref)
-{
-       struct ide_disk_obj *idkp = to_ide_disk(kref);
-       ide_drive_t *drive = idkp->drive;
-       struct gendisk *g = idkp->disk;
-
-       drive->driver_data = NULL;
-       g->private_data = NULL;
-       put_disk(g);
-       kfree(idkp);
-}
-
-static int ide_disk_probe(ide_drive_t *drive);
-
-/*
- * On HPA drives the capacity needs to be
- * reinitilized on resume otherwise the disk
- * can not be used and a hard reset is required
- */
-static void ide_disk_resume(ide_drive_t *drive)
+static int ide_disk_init_media(ide_drive_t *drive, struct gendisk *disk)
 {
-       if (ata_id_hpa_enabled(drive->id))
-               init_idedisk_capacity(drive);
-}
-
-static void ide_device_shutdown(ide_drive_t *drive)
-{
-#ifdef CONFIG_ALPHA
-       /* On Alpha, halt(8) doesn't actually turn the machine off,
-          it puts you into the sort of firmware monitor. Typically,
-          it's used to boot another kernel image, so it's not much
-          different from reboot(8). Therefore, we don't need to
-          spin down the disk in this case, especially since Alpha
-          firmware doesn't handle disks in standby mode properly.
-          On the other hand, it's reasonably safe to turn the power
-          off when the shutdown process reaches the firmware prompt,
-          as the firmware initialization takes rather long time -
-          at least 10 seconds, which should be sufficient for
-          the disk to expire its write cache. */
-       if (system_state != SYSTEM_POWER_OFF) {
-#else
-       if (system_state == SYSTEM_RESTART) {
-#endif
-               ide_cacheflush_p(drive);
-               return;
-       }
-
-       printk(KERN_INFO "Shutdown: %s\n", drive->name);
-
-       drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND);
+       return 0;
 }
 
-static ide_driver_t idedisk_driver = {
-       .gen_driver = {
-               .owner          = THIS_MODULE,
-               .name           = "ide-disk",
-               .bus            = &ide_bus_type,
-       },
-       .probe                  = ide_disk_probe,
-       .remove                 = ide_disk_remove,
-       .resume                 = ide_disk_resume,
-       .shutdown               = ide_device_shutdown,
-       .version                = IDEDISK_VERSION,
-       .do_request             = ide_do_rw_disk,
-       .end_request            = ide_end_request,
-       .error                  = __ide_error,
-#ifdef CONFIG_IDE_PROC_FS
-       .proc                   = ide_disk_proc,
-       .settings               = ide_disk_settings,
-#endif
-};
-
-static int idedisk_set_doorlock(ide_drive_t *drive, int on)
+static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk,
+                                int on)
 {
        ide_task_t task;
+       int ret;
+
+       if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0)
+               return 0;
 
        memset(&task, 0, sizeof(task));
        task.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK;
        task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
 
-       return ide_no_data_taskfile(drive, &task);
-}
-
-static int idedisk_open(struct inode *inode, struct file *filp)
-{
-       struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct ide_disk_obj *idkp;
-       ide_drive_t *drive;
-
-       idkp = ide_disk_get(disk);
-       if (idkp == NULL)
-               return -ENXIO;
-
-       drive = idkp->drive;
-
-       idkp->openers++;
-
-       if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
-               check_disk_change(inode->i_bdev);
-               /*
-                * Ignore the return code from door_lock,
-                * since the open() has already succeeded,
-                * and the door_lock is irrelevant at this point.
-                */
-               if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) &&
-                   idedisk_set_doorlock(drive, 1))
-                       drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
-       }
-       return 0;
-}
-
-static int idedisk_release(struct inode *inode, struct file *filp)
-{
-       struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct ide_disk_obj *idkp = ide_disk_g(disk);
-       ide_drive_t *drive = idkp->drive;
-
-       if (idkp->openers == 1)
-               ide_cacheflush_p(drive);
-
-       if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
-               if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) &&
-                   idedisk_set_doorlock(drive, 0))
-                       drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
-       }
+       ret = ide_no_data_taskfile(drive, &task);
 
-       idkp->openers--;
+       if (ret)
+               drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
 
-       ide_disk_put(idkp);
-
-       return 0;
-}
-
-static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
-{
-       struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk);
-       ide_drive_t *drive = idkp->drive;
-
-       geo->heads = drive->bios_head;
-       geo->sectors = drive->bios_sect;
-       geo->cylinders = (u16)drive->bios_cyl; /* truncate */
-       return 0;
+       return ret;
 }
 
-static int idedisk_media_changed(struct gendisk *disk)
-{
-       struct ide_disk_obj *idkp = ide_disk_g(disk);
-       ide_drive_t *drive = idkp->drive;
-
-       /* do not scan partitions twice if this is a removable device */
-       if (drive->dev_flags & IDE_DFLAG_ATTACH) {
-               drive->dev_flags &= ~IDE_DFLAG_ATTACH;
-               return 0;
-       }
-
-       /* if removable, always assume it was changed */
-       return !!(drive->dev_flags & IDE_DFLAG_REMOVABLE);
-}
-
-static int idedisk_revalidate_disk(struct gendisk *disk)
-{
-       struct ide_disk_obj *idkp = ide_disk_g(disk);
-       set_capacity(disk, ide_disk_capacity(idkp->drive));
-       return 0;
-}
-
-static struct block_device_operations idedisk_ops = {
-       .owner                  = THIS_MODULE,
-       .open                   = idedisk_open,
-       .release                = idedisk_release,
-       .ioctl                  = ide_disk_ioctl,
-       .getgeo                 = idedisk_getgeo,
-       .media_changed          = idedisk_media_changed,
-       .revalidate_disk        = idedisk_revalidate_disk
+const struct ide_disk_ops ide_ata_disk_ops = {
+       .check          = ide_disk_check,
+       .get_capacity   = ide_disk_get_capacity,
+       .setup          = ide_disk_setup,
+       .flush          = ide_disk_flush,
+       .init_media     = ide_disk_init_media,
+       .set_doorlock   = ide_disk_set_doorlock,
+       .do_request     = ide_do_rw_disk,
+       .end_request    = ide_end_request,
+       .ioctl          = ide_disk_ioctl,
 };
-
-MODULE_DESCRIPTION("ATA DISK Driver");
-
-static int ide_disk_probe(ide_drive_t *drive)
-{
-       struct ide_disk_obj *idkp;
-       struct gendisk *g;
-
-       /* strstr("foo", "") is non-NULL */
-       if (!strstr("ide-disk", drive->driver_req))
-               goto failed;
-
-       if (drive->media != ide_disk)
-               goto failed;
-
-       idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
-       if (!idkp)
-               goto failed;
-
-       g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif));
-       if (!g)
-               goto out_free_idkp;
-
-       ide_init_disk(g, drive);
-
-       kref_init(&idkp->kref);
-
-       idkp->drive = drive;
-       idkp->driver = &idedisk_driver;
-       idkp->disk = g;
-
-       g->private_data = &idkp->driver;
-
-       drive->driver_data = idkp;
-
-       idedisk_setup(drive);
-       if ((drive->dev_flags & IDE_DFLAG_LBA) == 0 &&
-           (drive->head == 0 || drive->head > 16)) {
-               printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n",
-                       drive->name, drive->head);
-               drive->dev_flags &= ~IDE_DFLAG_ATTACH;
-       } else
-               drive->dev_flags |= IDE_DFLAG_ATTACH;
-
-       g->minors = IDE_DISK_MINORS;
-       g->driverfs_dev = &drive->gendev;
-       g->flags |= GENHD_FL_EXT_DEVT;
-       if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
-               g->flags = GENHD_FL_REMOVABLE;
-       set_capacity(g, ide_disk_capacity(drive));
-       g->fops = &idedisk_ops;
-       add_disk(g);
-       return 0;
-
-out_free_idkp:
-       kfree(idkp);
-failed:
-       return -ENODEV;
-}
-
-static void __exit idedisk_exit(void)
-{
-       driver_unregister(&idedisk_driver.gen_driver);
-}
-
-static int __init idedisk_init(void)
-{
-       return driver_register(&idedisk_driver.gen_driver);
-}
-
-MODULE_ALIAS("ide:*m-disk*");
-MODULE_ALIAS("ide-disk");
-module_init(idedisk_init);
-module_exit(idedisk_exit);
-MODULE_LICENSE("GPL");
index a82fa4355665caed6710050a9bc8c64af0b33684..d511dab7c4aacfafce1da38a1409b9d9dcfa54a1 100644 (file)
@@ -1,19 +1,11 @@
 #ifndef __IDE_DISK_H
 #define __IDE_DISK_H
 
-struct ide_disk_obj {
-       ide_drive_t     *drive;
-       ide_driver_t    *driver;
-       struct gendisk  *disk;
-       struct kref     kref;
-       unsigned int    openers;        /* protected by BKL for now */
-};
-
-#define ide_disk_g(disk) \
-       container_of((disk)->private_data, struct ide_disk_obj, driver)
+#include "ide-gd.h"
 
+#ifdef CONFIG_IDE_GD_ATA
 /* ide-disk.c */
-sector_t ide_disk_capacity(ide_drive_t *);
+extern const struct ide_disk_ops ide_ata_disk_ops;
 ide_decl_devset(address);
 ide_decl_devset(multcount);
 ide_decl_devset(nowerr);
@@ -21,12 +13,17 @@ ide_decl_devset(wcache);
 ide_decl_devset(acoustic);
 
 /* ide-disk_ioctl.c */
-int ide_disk_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+int ide_disk_ioctl(ide_drive_t *, struct block_device *, fmode_t, unsigned int,
+                  unsigned long);
 
 #ifdef CONFIG_IDE_PROC_FS
 /* ide-disk_proc.c */
 extern ide_proc_entry_t ide_disk_proc[];
 extern const struct ide_proc_devset ide_disk_settings[];
 #endif
+#else
+#define ide_disk_proc          NULL
+#define ide_disk_settings      NULL
+#endif
 
 #endif /* __IDE_DISK_H */
index a6cf1a03a806e9ca1ac607777ea35eefc7512dc0..7b783dd7c0bec4bea0da3d1517ff0c3b18f3738f 100644 (file)
@@ -13,17 +13,14 @@ static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = {
 { 0 }
 };
 
-int ide_disk_ioctl(struct inode *inode, struct file *file,
+int ide_disk_ioctl(ide_drive_t *drive, struct block_device *bdev, fmode_t mode,
                   unsigned int cmd, unsigned long arg)
 {
-       struct block_device *bdev = inode->i_bdev;
-       struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk);
-       ide_drive_t *drive = idkp->drive;
        int err;
 
        err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings);
        if (err != -EOPNOTSUPP)
                return err;
 
-       return generic_ide_ioctl(drive, file, bdev, cmd, arg);
+       return generic_ide_ioctl(drive, bdev, cmd, arg);
 }
index 4724976afe716f68d11383018632650fd746582a..1146f4204c6e4499ac93f75bfc409d14642c25a1 100644 (file)
@@ -56,7 +56,7 @@ static int proc_idedisk_read_capacity
        ide_drive_t*drive = (ide_drive_t *)data;
        int len;
 
-       len = sprintf(page, "%llu\n", (long long)ide_disk_capacity(drive));
+       len = sprintf(page, "%llu\n", (long long)ide_gd_capacity(drive));
 
        PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
 }
index 0903782689e9753db304ea9d63fc6be61a386cc3..cac431f0df1769eda7e4f2d7fe28d7f8914602db 100644 (file)
@@ -130,7 +130,7 @@ int ide_build_dmatable(ide_drive_t *drive, struct request *rq)
                        xcount = bcount & 0xffff;
                        if (is_trm290)
                                xcount = ((xcount >> 2) - 1) << 16;
-                       if (xcount == 0x0000) {
+                       else if (xcount == 0x0000) {
                                if (count++ >= PRD_ENTRIES)
                                        goto use_pio_instead;
                                *table++ = cpu_to_le32(0x8000);
index cf0aa25470ee87368291dbf8614d2b67020315e9..aeb1ad782f54e5fbc9d39d3cda3e6eeabfc1bef4 100644 (file)
  * Documentation/ide/ChangeLog.ide-floppy.1996-2002
  */
 
-#define DRV_NAME "ide-floppy"
-#define PFX DRV_NAME ": "
-
-#define IDEFLOPPY_VERSION "1.00"
-
-#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
 
 #include "ide-floppy.h"
 
-/* module parameters */
-static unsigned long debug_mask;
-module_param(debug_mask, ulong, 0644);
-
-/* define to see debug info */
-#define IDEFLOPPY_DEBUG_LOG    0
-
-#if IDEFLOPPY_DEBUG_LOG
-#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)
-#else
-#define ide_debug_log(lvl, fmt, args...) do {} while (0)
-#endif
-
 /*
  * After each failed packet command we issue a request sense command and retry
  * the packet command IDEFLOPPY_MAX_PC_RETRIES times.
@@ -83,43 +64,13 @@ module_param(debug_mask, ulong, 0644);
 /* Error code returned in rq->errors to the higher part of the driver. */
 #define        IDEFLOPPY_ERROR_GENERAL         101
 
-static DEFINE_MUTEX(idefloppy_ref_mutex);
-
-static void idefloppy_cleanup_obj(struct kref *);
-
-static struct ide_floppy_obj *ide_floppy_get(struct gendisk *disk)
-{
-       struct ide_floppy_obj *floppy = NULL;
-
-       mutex_lock(&idefloppy_ref_mutex);
-       floppy = ide_drv_g(disk, ide_floppy_obj);
-       if (floppy) {
-               if (ide_device_get(floppy->drive))
-                       floppy = NULL;
-               else
-                       kref_get(&floppy->kref);
-       }
-       mutex_unlock(&idefloppy_ref_mutex);
-       return floppy;
-}
-
-static void ide_floppy_put(struct ide_floppy_obj *floppy)
-{
-       ide_drive_t *drive = floppy->drive;
-
-       mutex_lock(&idefloppy_ref_mutex);
-       kref_put(&floppy->kref, idefloppy_cleanup_obj);
-       ide_device_put(drive);
-       mutex_unlock(&idefloppy_ref_mutex);
-}
-
 /*
  * Used to finish servicing a request. For read/write requests, we will call
  * ide_end_request to pass to the next buffer.
  */
-static int idefloppy_end_request(ide_drive_t *drive, int uptodate, int nsecs)
+static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs)
 {
-       idefloppy_floppy_t *floppy = drive->driver_data;
+       struct ide_disk_obj *floppy = drive->driver_data;
        struct request *rq = HWGROUP(drive)->rq;
        int error;
 
@@ -161,12 +112,12 @@ static void idefloppy_update_buffers(ide_drive_t *drive,
        struct bio *bio = rq->bio;
 
        while ((bio = rq->bio) != NULL)
-               idefloppy_end_request(drive, 1, 0);
+               ide_floppy_end_request(drive, 1, 0);
 }
 
 static void ide_floppy_callback(ide_drive_t *drive, int dsc)
 {
-       idefloppy_floppy_t *floppy = drive->driver_data;
+       struct ide_disk_obj *floppy = drive->driver_data;
        struct ide_atapi_pc *pc = drive->pc;
        int uptodate = pc->error ? 0 : 1;
 
@@ -200,10 +151,10 @@ static void ide_floppy_callback(ide_drive_t *drive, int dsc)
                               "Aborting request!\n");
        }
 
-       idefloppy_end_request(drive, uptodate, 0);
+       ide_floppy_end_request(drive, uptodate, 0);
 }
 
-static void ide_floppy_report_error(idefloppy_floppy_t *floppy,
+static void ide_floppy_report_error(struct ide_disk_obj *floppy,
                                    struct ide_atapi_pc *pc)
 {
        /* supress error messages resulting from Medium not present */
@@ -222,7 +173,7 @@ static void ide_floppy_report_error(idefloppy_floppy_t *floppy,
 static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
                struct ide_atapi_pc *pc)
 {
-       idefloppy_floppy_t *floppy = drive->driver_data;
+       struct ide_disk_obj *floppy = drive->driver_data;
 
        if (floppy->failed_pc == NULL &&
            pc->c[0] != GPCMD_REQUEST_SENSE)
@@ -286,7 +237,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
                                    struct ide_atapi_pc *pc, struct request *rq,
                                    unsigned long sector)
 {
-       idefloppy_floppy_t *floppy = drive->driver_data;
+       struct ide_disk_obj *floppy = drive->driver_data;
        int block = sector / floppy->bs_factor;
        int blocks = rq->nr_sectors / floppy->bs_factor;
        int cmd = rq_data_dir(rq);
@@ -310,7 +261,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
        pc->flags |= PC_FLAG_DMA_OK;
 }
 
-static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy,
+static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy,
                struct ide_atapi_pc *pc, struct request *rq)
 {
        ide_init_pc(pc);
@@ -329,13 +280,12 @@ static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy,
        pc->req_xfer = pc->buf_size = rq->data_len;
 }
 
-static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
-               struct request *rq, sector_t block_s)
+static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
+                                            struct request *rq, sector_t block)
 {
-       idefloppy_floppy_t *floppy = drive->driver_data;
+       struct ide_disk_obj *floppy = drive->driver_data;
        ide_hwif_t *hwif = drive->hwif;
        struct ide_atapi_pc *pc;
-       unsigned long block = (unsigned long)block_s;
 
        ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, "
                      "errors: %d\n",
@@ -353,7 +303,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
                else
                        printk(KERN_ERR PFX "%s: I/O error\n", drive->name);
 
-               idefloppy_end_request(drive, 0, 0);
+               ide_floppy_end_request(drive, 0, 0);
                return ide_stopped;
        }
        if (blk_fs_request(rq)) {
@@ -361,11 +311,11 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
                    (rq->nr_sectors % floppy->bs_factor)) {
                        printk(KERN_ERR PFX "%s: unsupported r/w rq size\n",
                                drive->name);
-                       idefloppy_end_request(drive, 0, 0);
+                       ide_floppy_end_request(drive, 0, 0);
                        return ide_stopped;
                }
                pc = &floppy->queued_pc;
-               idefloppy_create_rw_cmd(drive, pc, rq, block);
+               idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block);
        } else if (blk_special_request(rq)) {
                pc = (struct ide_atapi_pc *) rq->buffer;
        } else if (blk_pc_request(rq)) {
@@ -373,7 +323,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
                idefloppy_blockpc_cmd(floppy, pc, rq);
        } else {
                blk_dump_rq_flags(rq, PFX "unsupported command in queue");
-               idefloppy_end_request(drive, 0, 0);
+               ide_floppy_end_request(drive, 0, 0);
                return ide_stopped;
        }
 
@@ -394,7 +344,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
  */
 static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)
 {
-       idefloppy_floppy_t *floppy = drive->driver_data;
+       struct ide_disk_obj *floppy = drive->driver_data;
        struct gendisk *disk = floppy->disk;
        struct ide_atapi_pc pc;
        u8 *page;
@@ -410,11 +360,11 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)
        }
 
        if (pc.buf[3] & 0x80)
-               drive->atapi_flags |= IDE_AFLAG_WP;
+               drive->dev_flags |= IDE_DFLAG_WP;
        else
-               drive->atapi_flags &= ~IDE_AFLAG_WP;
+               drive->dev_flags &= ~IDE_DFLAG_WP;
 
-       set_disk_ro(disk, !!(drive->atapi_flags & IDE_AFLAG_WP));
+       set_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP));
 
        page = &pc.buf[8];
 
@@ -445,7 +395,9 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)
                        drive->name, lba_capacity, capacity);
                floppy->blocks = floppy->block_size ?
                        capacity / floppy->block_size : 0;
+               drive->capacity64 = floppy->blocks * floppy->bs_factor;
        }
+
        return 0;
 }
 
@@ -455,7 +407,7 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)
  */
 static int ide_floppy_get_capacity(ide_drive_t *drive)
 {
-       idefloppy_floppy_t *floppy = drive->driver_data;
+       struct ide_disk_obj *floppy = drive->driver_data;
        struct gendisk *disk = floppy->disk;
        struct ide_atapi_pc pc;
        u8 *cap_desc;
@@ -466,7 +418,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
        drive->bios_head = drive->bios_sect = 0;
        floppy->blocks = 0;
        floppy->bs_factor = 1;
-       set_capacity(floppy->disk, 0);
+       drive->capacity64 = 0;
 
        ide_floppy_create_read_capacity_cmd(&pc);
        if (ide_queue_pc_tail(drive, disk, &pc)) {
@@ -523,6 +475,8 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
                                               "non 512 bytes block size not "
                                               "fully supported\n",
                                               drive->name);
+                               drive->capacity64 =
+                                       floppy->blocks * floppy->bs_factor;
                                rc = 0;
                        }
                        break;
@@ -547,21 +501,12 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
        if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE))
                (void) ide_floppy_get_flexible_disk_page(drive);
 
-       set_capacity(disk, floppy->blocks * floppy->bs_factor);
-
        return rc;
 }
 
-sector_t ide_floppy_capacity(ide_drive_t *drive)
-{
-       idefloppy_floppy_t *floppy = drive->driver_data;
-       unsigned long capacity = floppy->blocks * floppy->bs_factor;
-
-       return capacity;
-}
-
-static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy)
+static void ide_floppy_setup(ide_drive_t *drive)
 {
+       struct ide_disk_obj *floppy = drive->driver_data;
        u16 *id = drive->id;
 
        drive->pc_callback       = ide_floppy_callback;
@@ -592,252 +537,42 @@ static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy)
                blk_queue_max_sectors(drive->queue, 64);
                drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE;
                /* IOMEGA Clik! drives do not support lock/unlock commands */
-               drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK;
+               drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
        }
 
        (void) ide_floppy_get_capacity(drive);
 
        ide_proc_register_driver(drive, floppy->driver);
-}
 
-static void ide_floppy_remove(ide_drive_t *drive)
-{
-       idefloppy_floppy_t *floppy = drive->driver_data;
-       struct gendisk *g = floppy->disk;
-
-       ide_proc_unregister_driver(drive, floppy->driver);
-
-       del_gendisk(g);
-
-       ide_floppy_put(floppy);
+       drive->dev_flags |= IDE_DFLAG_ATTACH;
 }
 
-static void idefloppy_cleanup_obj(struct kref *kref)
+static void ide_floppy_flush(ide_drive_t *drive)
 {
-       struct ide_floppy_obj *floppy = to_ide_drv(kref, ide_floppy_obj);
-       ide_drive_t *drive = floppy->drive;
-       struct gendisk *g = floppy->disk;
-
-       drive->driver_data = NULL;
-       g->private_data = NULL;
-       put_disk(g);
-       kfree(floppy);
 }
 
-static int ide_floppy_probe(ide_drive_t *);
-
-static ide_driver_t idefloppy_driver = {
-       .gen_driver = {
-               .owner          = THIS_MODULE,
-               .name           = "ide-floppy",
-               .bus            = &ide_bus_type,
-       },
-       .probe                  = ide_floppy_probe,
-       .remove                 = ide_floppy_remove,
-       .version                = IDEFLOPPY_VERSION,
-       .do_request             = idefloppy_do_request,
-       .end_request            = idefloppy_end_request,
-       .error                  = __ide_error,
-#ifdef CONFIG_IDE_PROC_FS
-       .proc                   = ide_floppy_proc,
-       .settings               = ide_floppy_settings,
-#endif
-};
-
-static int idefloppy_open(struct inode *inode, struct file *filp)
+static int ide_floppy_init_media(ide_drive_t *drive, struct gendisk *disk)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct ide_floppy_obj *floppy;
-       ide_drive_t *drive;
        int ret = 0;
 
-       floppy = ide_floppy_get(disk);
-       if (!floppy)
-               return -ENXIO;
-
-       drive = floppy->drive;
-
-       ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
-
-       floppy->openers++;
-
-       if (floppy->openers == 1) {
-               drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
-               /* Just in case */
-
-               if (ide_do_test_unit_ready(drive, disk))
-                       ide_do_start_stop(drive, disk, 1);
-
-               if (ide_floppy_get_capacity(drive)
-                  && (filp->f_flags & O_NDELAY) == 0
-                   /*
-                    * Allow O_NDELAY to open a drive without a disk, or with an
-                    * unreadable disk, so that we can get the format capacity
-                    * of the drive or begin the format - Sam
-                    */
-                   ) {
-                       ret = -EIO;
-                       goto out_put_floppy;
-               }
-
-               if ((drive->atapi_flags & IDE_AFLAG_WP) && (filp->f_mode & 2)) {
-                       ret = -EROFS;
-                       goto out_put_floppy;
-               }
-
-               drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED;
-               ide_set_media_lock(drive, disk, 1);
-               check_disk_change(inode->i_bdev);
-       } else if (drive->atapi_flags & IDE_AFLAG_FORMAT_IN_PROGRESS) {
-               ret = -EBUSY;
-               goto out_put_floppy;
-       }
-       return 0;
-
-out_put_floppy:
-       floppy->openers--;
-       ide_floppy_put(floppy);
-       return ret;
-}
-
-static int idefloppy_release(struct inode *inode, struct file *filp)
-{
-       struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj);
-       ide_drive_t *drive = floppy->drive;
-
-       ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
-
-       if (floppy->openers == 1) {
-               ide_set_media_lock(drive, disk, 0);
-               drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
-       }
-
-       floppy->openers--;
-
-       ide_floppy_put(floppy);
-
-       return 0;
-}
-
-static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)
-{
-       struct ide_floppy_obj *floppy = ide_drv_g(bdev->bd_disk,
-                                                    ide_floppy_obj);
-       ide_drive_t *drive = floppy->drive;
+       if (ide_do_test_unit_ready(drive, disk))
+               ide_do_start_stop(drive, disk, 1);
 
-       geo->heads = drive->bios_head;
-       geo->sectors = drive->bios_sect;
-       geo->cylinders = (u16)drive->bios_cyl; /* truncate */
-       return 0;
-}
+       ret = ide_floppy_get_capacity(drive);
 
-static int idefloppy_media_changed(struct gendisk *disk)
-{
-       struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj);
-       ide_drive_t *drive = floppy->drive;
-       int ret;
+       set_capacity(disk, ide_gd_capacity(drive));
 
-       /* do not scan partitions twice if this is a removable device */
-       if (drive->dev_flags & IDE_DFLAG_ATTACH) {
-               drive->dev_flags &= ~IDE_DFLAG_ATTACH;
-               return 0;
-       }
-       ret = !!(drive->atapi_flags & IDE_AFLAG_MEDIA_CHANGED);
-       drive->atapi_flags &= ~IDE_AFLAG_MEDIA_CHANGED;
        return ret;
 }
 
-static int idefloppy_revalidate_disk(struct gendisk *disk)
-{
-       struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj);
-       set_capacity(disk, ide_floppy_capacity(floppy->drive));
-       return 0;
-}
-
-static struct block_device_operations idefloppy_ops = {
-       .owner                  = THIS_MODULE,
-       .open                   = idefloppy_open,
-       .release                = idefloppy_release,
-       .ioctl                  = ide_floppy_ioctl,
-       .getgeo                 = idefloppy_getgeo,
-       .media_changed          = idefloppy_media_changed,
-       .revalidate_disk        = idefloppy_revalidate_disk
+const struct ide_disk_ops ide_atapi_disk_ops = {
+       .check          = ide_check_atapi_device,
+       .get_capacity   = ide_floppy_get_capacity,
+       .setup          = ide_floppy_setup,
+       .flush          = ide_floppy_flush,
+       .init_media     = ide_floppy_init_media,
+       .set_doorlock   = ide_set_media_lock,
+       .do_request     = ide_floppy_do_request,
+       .end_request    = ide_floppy_end_request,
+       .ioctl          = ide_floppy_ioctl,
 };
-
-static int ide_floppy_probe(ide_drive_t *drive)
-{
-       idefloppy_floppy_t *floppy;
-       struct gendisk *g;
-
-       if (!strstr("ide-floppy", drive->driver_req))
-               goto failed;
-
-       if (drive->media != ide_floppy)
-               goto failed;
-
-       if (!ide_check_atapi_device(drive, DRV_NAME)) {
-               printk(KERN_ERR PFX "%s: not supported by this version of "
-                      DRV_NAME "\n", drive->name);
-               goto failed;
-       }
-       floppy = kzalloc(sizeof(idefloppy_floppy_t), GFP_KERNEL);
-       if (!floppy) {
-               printk(KERN_ERR PFX "%s: Can't allocate a floppy structure\n",
-                      drive->name);
-               goto failed;
-       }
-
-       g = alloc_disk(1 << PARTN_BITS);
-       if (!g)
-               goto out_free_floppy;
-
-       ide_init_disk(g, drive);
-
-       kref_init(&floppy->kref);
-
-       floppy->drive = drive;
-       floppy->driver = &idefloppy_driver;
-       floppy->disk = g;
-
-       g->private_data = &floppy->driver;
-
-       drive->driver_data = floppy;
-
-       drive->debug_mask = debug_mask;
-
-       idefloppy_setup(drive, floppy);
-       drive->dev_flags |= IDE_DFLAG_ATTACH;
-
-       g->minors = 1 << PARTN_BITS;
-       g->driverfs_dev = &drive->gendev;
-       if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
-               g->flags = GENHD_FL_REMOVABLE;
-       g->fops = &idefloppy_ops;
-       add_disk(g);
-       return 0;
-
-out_free_floppy:
-       kfree(floppy);
-failed:
-       return -ENODEV;
-}
-
-static void __exit idefloppy_exit(void)
-{
-       driver_unregister(&idefloppy_driver.gen_driver);
-}
-
-static int __init idefloppy_init(void)
-{
-       printk(KERN_INFO DRV_NAME " driver " IDEFLOPPY_VERSION "\n");
-       return driver_register(&idefloppy_driver.gen_driver);
-}
-
-MODULE_ALIAS("ide:*m-floppy*");
-MODULE_ALIAS("ide-floppy");
-module_init(idefloppy_init);
-module_exit(idefloppy_exit);
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("ATAPI FLOPPY Driver");
-
index 17cf865e583d28edd7890b3e874bcd0cdec561ce..6dd2beb4843492586c78d9e117d82f5676e3cc5e 100644 (file)
@@ -1,37 +1,9 @@
 #ifndef __IDE_FLOPPY_H
 #define __IDE_FLOPPY_H
 
-/*
- * Most of our global data which we need to save even as we leave the driver
- * due to an interrupt or a timer event is stored in a variable of type
- * idefloppy_floppy_t, defined below.
- */
-typedef struct ide_floppy_obj {
-       ide_drive_t     *drive;
-       ide_driver_t    *driver;
-       struct gendisk  *disk;
-       struct kref     kref;
-       unsigned int    openers;        /* protected by BKL for now */
-
-       /* Last failed packet command */
-       struct ide_atapi_pc *failed_pc;
-       /* used for blk_{fs,pc}_request() requests */
-       struct ide_atapi_pc queued_pc;
-
-       /* Last error information */
-       u8 sense_key, asc, ascq;
-
-       int progress_indication;
-
-       /* Device information */
-       /* Current format */
-       int blocks, block_size, bs_factor;
-       /* Last format capacity descriptor */
-       u8 cap_desc[8];
-       /* Copy of the flexible disk page */
-       u8 flexible_disk_page[32];
-} idefloppy_floppy_t;
+#include "ide-gd.h"
 
+#ifdef CONFIG_IDE_GD_ATAPI
 /*
  * Pages of the SELECT SENSE / MODE SENSE packet commands.
  * See SFF-8070i spec.
@@ -46,17 +18,22 @@ typedef struct ide_floppy_obj {
 #define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS    0x4603
 
 /* ide-floppy.c */
+extern const struct ide_disk_ops ide_atapi_disk_ops;
 void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *, u8);
 void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *);
-sector_t ide_floppy_capacity(ide_drive_t *);
 
 /* ide-floppy_ioctl.c */
-int ide_floppy_ioctl(struct inode *, struct file *, unsigned, unsigned long);
+int ide_floppy_ioctl(ide_drive_t *, struct block_device *, fmode_t,
+                    unsigned int, unsigned long);
 
 #ifdef CONFIG_IDE_PROC_FS
 /* ide-floppy_proc.c */
 extern ide_proc_entry_t ide_floppy_proc[];
 extern const struct ide_proc_devset ide_floppy_settings[];
 #endif
+#else
+#define ide_floppy_proc                NULL
+#define ide_floppy_settings    NULL
+#endif
 
 #endif /*__IDE_FLOPPY_H */
index a3a7a0809e2bdf5edba01c3c93c0f2b6cd467d8a..2bc51ff73fee35b3863aea03b7dc6e6bf09bfc9c 100644 (file)
@@ -33,7 +33,7 @@
 
 static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg)
 {
-       struct ide_floppy_obj *floppy = drive->driver_data;
+       struct ide_disk_obj *floppy = drive->driver_data;
        struct ide_atapi_pc pc;
        u8 header_len, desc_cnt;
        int i, blocks, length, u_array_size, u_index;
@@ -113,7 +113,7 @@ static void ide_floppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b,
 
 static int ide_floppy_get_sfrp_bit(ide_drive_t *drive)
 {
-       idefloppy_floppy_t *floppy = drive->driver_data;
+       struct ide_disk_obj *floppy = drive->driver_data;
        struct ide_atapi_pc pc;
 
        drive->atapi_flags &= ~IDE_AFLAG_SRFP;
@@ -132,17 +132,17 @@ static int ide_floppy_get_sfrp_bit(ide_drive_t *drive)
 
 static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg)
 {
-       idefloppy_floppy_t *floppy = drive->driver_data;
+       struct ide_disk_obj *floppy = drive->driver_data;
        struct ide_atapi_pc pc;
        int blocks, length, flags, err = 0;
 
        if (floppy->openers > 1) {
                /* Don't format if someone is using the disk */
-               drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
+               drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
                return -EBUSY;
        }
 
-       drive->atapi_flags |= IDE_AFLAG_FORMAT_IN_PROGRESS;
+       drive->dev_flags |= IDE_DFLAG_FORMAT_IN_PROGRESS;
 
        /*
         * Send ATAPI_FORMAT_UNIT to the drive.
@@ -174,7 +174,7 @@ static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg)
 
 out:
        if (err)
-               drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
+               drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
        return err;
 }
 
@@ -190,7 +190,7 @@ out:
 
 static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg)
 {
-       idefloppy_floppy_t *floppy = drive->driver_data;
+       struct ide_disk_obj *floppy = drive->driver_data;
        struct ide_atapi_pc pc;
        int progress_indication = 0x10000;
 
@@ -226,7 +226,7 @@ static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg)
 static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc,
                               unsigned long arg, unsigned int cmd)
 {
-       idefloppy_floppy_t *floppy = drive->driver_data;
+       struct ide_disk_obj *floppy = drive->driver_data;
        struct gendisk *disk = floppy->disk;
        int prevent = (arg && cmd != CDROMEJECT) ? 1 : 0;
 
@@ -241,7 +241,7 @@ static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc,
        return 0;
 }
 
-static int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file,
+static int ide_floppy_format_ioctl(ide_drive_t *drive, fmode_t mode,
                                   unsigned int cmd, void __user *argp)
 {
        switch (cmd) {
@@ -250,7 +250,7 @@ static int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file,
        case IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY:
                return ide_floppy_get_format_capacities(drive, argp);
        case IDEFLOPPY_IOCTL_FORMAT_START:
-               if (!(file->f_mode & 2))
+               if (!(mode & FMODE_WRITE))
                        return -EPERM;
                return ide_floppy_format_unit(drive, (int __user *)argp);
        case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS:
@@ -260,13 +260,9 @@ static int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file,
        }
 }
 
-int ide_floppy_ioctl(struct inode *inode, struct file *file,
-                   unsigned int cmd, unsigned long arg)
+int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev,
+                    fmode_t mode, unsigned int cmd, unsigned long arg)
 {
-       struct block_device *bdev = inode->i_bdev;
-       struct ide_floppy_obj *floppy = ide_drv_g(bdev->bd_disk,
-                                                    ide_floppy_obj);
-       ide_drive_t *drive = floppy->drive;
        struct ide_atapi_pc pc;
        void __user *argp = (void __user *)arg;
        int err;
@@ -274,7 +270,7 @@ int ide_floppy_ioctl(struct inode *inode, struct file *file,
        if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR)
                return ide_floppy_lockdoor(drive, &pc, arg, cmd);
 
-       err = ide_floppy_format_ioctl(drive, file, cmd, argp);
+       err = ide_floppy_format_ioctl(drive, mode, cmd, argp);
        if (err != -ENOTTY)
                return err;
 
@@ -283,11 +279,11 @@ int ide_floppy_ioctl(struct inode *inode, struct file *file,
         * and CDROM_SEND_PACKET (legacy) ioctls
         */
        if (cmd != CDROM_SEND_PACKET && cmd != SCSI_IOCTL_SEND_COMMAND)
-               err = scsi_cmd_ioctl(file, bdev->bd_disk->queue,
-                                       bdev->bd_disk, cmd, argp);
+               err = scsi_cmd_ioctl(bdev->bd_disk->queue, bdev->bd_disk,
+                               mode, cmd, argp);
 
        if (err == -ENOTTY)
-               err = generic_ide_ioctl(drive, file, bdev, cmd, arg);
+               err = generic_ide_ioctl(drive, bdev, cmd, arg);
 
        return err;
 }
index 76f0c6c4eca3c4652e69dde32c77059220663294..3ec762cb60abfcceae5e0f5ede250adbc2ec2f7c 100644 (file)
@@ -9,7 +9,7 @@ static int proc_idefloppy_read_capacity(char *page, char **start, off_t off,
        ide_drive_t*drive = (ide_drive_t *)data;
        int len;
 
-       len = sprintf(page, "%llu\n", (long long)ide_floppy_capacity(drive));
+       len = sprintf(page, "%llu\n", (long long)ide_gd_capacity(drive));
        PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
 }
 
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c
new file mode 100644 (file)
index 0000000..7b66628
--- /dev/null
@@ -0,0 +1,396 @@
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/genhd.h>
+#include <linux/mutex.h>
+#include <linux/ide.h>
+#include <linux/hdreg.h>
+
+#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
+#define IDE_DISK_MINORS                (1 << PARTN_BITS)
+#else
+#define IDE_DISK_MINORS                0
+#endif
+
+#include "ide-disk.h"
+#include "ide-floppy.h"
+
+#define IDE_GD_VERSION "1.18"
+
+/* module parameters */
+static unsigned long debug_mask;
+module_param(debug_mask, ulong, 0644);
+
+static DEFINE_MUTEX(ide_disk_ref_mutex);
+
+static void ide_disk_release(struct kref *);
+
+static struct ide_disk_obj *ide_disk_get(struct gendisk *disk)
+{
+       struct ide_disk_obj *idkp = NULL;
+
+       mutex_lock(&ide_disk_ref_mutex);
+       idkp = ide_drv_g(disk, ide_disk_obj);
+       if (idkp) {
+               if (ide_device_get(idkp->drive))
+                       idkp = NULL;
+               else
+                       kref_get(&idkp->kref);
+       }
+       mutex_unlock(&ide_disk_ref_mutex);
+       return idkp;
+}
+
+static void ide_disk_put(struct ide_disk_obj *idkp)
+{
+       ide_drive_t *drive = idkp->drive;
+
+       mutex_lock(&ide_disk_ref_mutex);
+       kref_put(&idkp->kref, ide_disk_release);
+       ide_device_put(drive);
+       mutex_unlock(&ide_disk_ref_mutex);
+}
+
+sector_t ide_gd_capacity(ide_drive_t *drive)
+{
+       return drive->capacity64;
+}
+
+static int ide_gd_probe(ide_drive_t *);
+
+static void ide_gd_remove(ide_drive_t *drive)
+{
+       struct ide_disk_obj *idkp = drive->driver_data;
+       struct gendisk *g = idkp->disk;
+
+       ide_proc_unregister_driver(drive, idkp->driver);
+
+       del_gendisk(g);
+
+       drive->disk_ops->flush(drive);
+
+       ide_disk_put(idkp);
+}
+
+static void ide_disk_release(struct kref *kref)
+{
+       struct ide_disk_obj *idkp = to_ide_drv(kref, ide_disk_obj);
+       ide_drive_t *drive = idkp->drive;
+       struct gendisk *g = idkp->disk;
+
+       drive->disk_ops = NULL;
+       drive->driver_data = NULL;
+       g->private_data = NULL;
+       put_disk(g);
+       kfree(idkp);
+}
+
+/*
+ * On HPA drives the capacity needs to be
+ * reinitilized on resume otherwise the disk
+ * can not be used and a hard reset is required
+ */
+static void ide_gd_resume(ide_drive_t *drive)
+{
+       if (ata_id_hpa_enabled(drive->id))
+               (void)drive->disk_ops->get_capacity(drive);
+}
+
+static void ide_gd_shutdown(ide_drive_t *drive)
+{
+#ifdef CONFIG_ALPHA
+       /* On Alpha, halt(8) doesn't actually turn the machine off,
+          it puts you into the sort of firmware monitor. Typically,
+          it's used to boot another kernel image, so it's not much
+          different from reboot(8). Therefore, we don't need to
+          spin down the disk in this case, especially since Alpha
+          firmware doesn't handle disks in standby mode properly.
+          On the other hand, it's reasonably safe to turn the power
+          off when the shutdown process reaches the firmware prompt,
+          as the firmware initialization takes rather long time -
+          at least 10 seconds, which should be sufficient for
+          the disk to expire its write cache. */
+       if (system_state != SYSTEM_POWER_OFF) {
+#else
+       if (system_state == SYSTEM_RESTART) {
+#endif
+               drive->disk_ops->flush(drive);
+               return;
+       }
+
+       printk(KERN_INFO "Shutdown: %s\n", drive->name);
+
+       drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND);
+}
+
+#ifdef CONFIG_IDE_PROC_FS
+static ide_proc_entry_t *ide_disk_proc_entries(ide_drive_t *drive)
+{
+       return (drive->media == ide_disk) ? ide_disk_proc : ide_floppy_proc;
+}
+
+static const struct ide_proc_devset *ide_disk_proc_devsets(ide_drive_t *drive)
+{
+       return (drive->media == ide_disk) ? ide_disk_settings
+                                         : ide_floppy_settings;
+}
+#endif
+
+static ide_startstop_t ide_gd_do_request(ide_drive_t *drive,
+                                        struct request *rq, sector_t sector)
+{
+       return drive->disk_ops->do_request(drive, rq, sector);
+}
+
+static int ide_gd_end_request(ide_drive_t *drive, int uptodate, int nrsecs)
+{
+       return drive->disk_ops->end_request(drive, uptodate, nrsecs);
+}
+
+static ide_driver_t ide_gd_driver = {
+       .gen_driver = {
+               .owner          = THIS_MODULE,
+               .name           = "ide-gd",
+               .bus            = &ide_bus_type,
+       },
+       .probe                  = ide_gd_probe,
+       .remove                 = ide_gd_remove,
+       .resume                 = ide_gd_resume,
+       .shutdown               = ide_gd_shutdown,
+       .version                = IDE_GD_VERSION,
+       .do_request             = ide_gd_do_request,
+       .end_request            = ide_gd_end_request,
+       .error                  = __ide_error,
+#ifdef CONFIG_IDE_PROC_FS
+       .proc_entries           = ide_disk_proc_entries,
+       .proc_devsets           = ide_disk_proc_devsets,
+#endif
+};
+
+static int ide_gd_open(struct block_device *bdev, fmode_t mode)
+{
+       struct gendisk *disk = bdev->bd_disk;
+       struct ide_disk_obj *idkp;
+       ide_drive_t *drive;
+       int ret = 0;
+
+       idkp = ide_disk_get(disk);
+       if (idkp == NULL)
+               return -ENXIO;
+
+       drive = idkp->drive;
+
+       ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+
+       idkp->openers++;
+
+       if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
+               drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
+               /* Just in case */
+
+               ret = drive->disk_ops->init_media(drive, disk);
+
+               /*
+                * Allow O_NDELAY to open a drive without a disk, or with an
+                * unreadable disk, so that we can get the format capacity
+                * of the drive or begin the format - Sam
+                */
+               if (ret && (mode & FMODE_NDELAY) == 0) {
+                       ret = -EIO;
+                       goto out_put_idkp;
+               }
+
+               if ((drive->dev_flags & IDE_DFLAG_WP) && (mode & FMODE_WRITE)) {
+                       ret = -EROFS;
+                       goto out_put_idkp;
+               }
+
+               /*
+                * Ignore the return code from door_lock,
+                * since the open() has already succeeded,
+                * and the door_lock is irrelevant at this point.
+                */
+               drive->disk_ops->set_doorlock(drive, disk, 1);
+               drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
+               check_disk_change(bdev);
+       } else if (drive->dev_flags & IDE_DFLAG_FORMAT_IN_PROGRESS) {
+               ret = -EBUSY;
+               goto out_put_idkp;
+       }
+       return 0;
+
+out_put_idkp:
+       idkp->openers--;
+       ide_disk_put(idkp);
+       return ret;
+}
+
+static int ide_gd_release(struct gendisk *disk, fmode_t mode)
+{
+       struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
+       ide_drive_t *drive = idkp->drive;
+
+       ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+
+       if (idkp->openers == 1)
+               drive->disk_ops->flush(drive);
+
+       if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
+               drive->disk_ops->set_doorlock(drive, disk, 0);
+               drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
+       }
+
+       idkp->openers--;
+
+       ide_disk_put(idkp);
+
+       return 0;
+}
+
+static int ide_gd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+       struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj);
+       ide_drive_t *drive = idkp->drive;
+
+       geo->heads = drive->bios_head;
+       geo->sectors = drive->bios_sect;
+       geo->cylinders = (u16)drive->bios_cyl; /* truncate */
+       return 0;
+}
+
+static int ide_gd_media_changed(struct gendisk *disk)
+{
+       struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
+       ide_drive_t *drive = idkp->drive;
+       int ret;
+
+       /* do not scan partitions twice if this is a removable device */
+       if (drive->dev_flags & IDE_DFLAG_ATTACH) {
+               drive->dev_flags &= ~IDE_DFLAG_ATTACH;
+               return 0;
+       }
+
+       ret = !!(drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED);
+       drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
+
+       return ret;
+}
+
+static int ide_gd_revalidate_disk(struct gendisk *disk)
+{
+       struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
+       set_capacity(disk, ide_gd_capacity(idkp->drive));
+       return 0;
+}
+
+static int ide_gd_ioctl(struct block_device *bdev, fmode_t mode,
+                            unsigned int cmd, unsigned long arg)
+{
+       struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj);
+       ide_drive_t *drive = idkp->drive;
+
+       return drive->disk_ops->ioctl(drive, bdev, mode, cmd, arg);
+}
+
+static struct block_device_operations ide_gd_ops = {
+       .owner                  = THIS_MODULE,
+       .open                   = ide_gd_open,
+       .release                = ide_gd_release,
+       .locked_ioctl           = ide_gd_ioctl,
+       .getgeo                 = ide_gd_getgeo,
+       .media_changed          = ide_gd_media_changed,
+       .revalidate_disk        = ide_gd_revalidate_disk
+};
+
+static int ide_gd_probe(ide_drive_t *drive)
+{
+       const struct ide_disk_ops *disk_ops = NULL;
+       struct ide_disk_obj *idkp;
+       struct gendisk *g;
+
+       /* strstr("foo", "") is non-NULL */
+       if (!strstr("ide-gd", drive->driver_req))
+               goto failed;
+
+#ifdef CONFIG_IDE_GD_ATA
+       if (drive->media == ide_disk)
+               disk_ops = &ide_ata_disk_ops;
+#endif
+#ifdef CONFIG_IDE_GD_ATAPI
+       if (drive->media == ide_floppy)
+               disk_ops = &ide_atapi_disk_ops;
+#endif
+       if (disk_ops == NULL)
+               goto failed;
+
+       if (disk_ops->check(drive, DRV_NAME) == 0) {
+               printk(KERN_ERR PFX "%s: not supported by this driver\n",
+                       drive->name);
+               goto failed;
+       }
+
+       idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
+       if (!idkp) {
+               printk(KERN_ERR PFX "%s: can't allocate a disk structure\n",
+                       drive->name);
+               goto failed;
+       }
+
+       g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif));
+       if (!g)
+               goto out_free_idkp;
+
+       ide_init_disk(g, drive);
+
+       kref_init(&idkp->kref);
+
+       idkp->drive = drive;
+       idkp->driver = &ide_gd_driver;
+       idkp->disk = g;
+
+       g->private_data = &idkp->driver;
+
+       drive->driver_data = idkp;
+       drive->debug_mask = debug_mask;
+       drive->disk_ops = disk_ops;
+
+       disk_ops->setup(drive);
+
+       set_capacity(g, ide_gd_capacity(drive));
+
+       g->minors = IDE_DISK_MINORS;
+       g->driverfs_dev = &drive->gendev;
+       g->flags |= GENHD_FL_EXT_DEVT;
+       if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
+               g->flags = GENHD_FL_REMOVABLE;
+       g->fops = &ide_gd_ops;
+       add_disk(g);
+       return 0;
+
+out_free_idkp:
+       kfree(idkp);
+failed:
+       return -ENODEV;
+}
+
+static int __init ide_gd_init(void)
+{
+       printk(KERN_INFO DRV_NAME " driver " IDE_GD_VERSION "\n");
+       return driver_register(&ide_gd_driver.gen_driver);
+}
+
+static void __exit ide_gd_exit(void)
+{
+       driver_unregister(&ide_gd_driver.gen_driver);
+}
+
+MODULE_ALIAS("ide:*m-disk*");
+MODULE_ALIAS("ide-disk");
+MODULE_ALIAS("ide:*m-floppy*");
+MODULE_ALIAS("ide-floppy");
+module_init(ide_gd_init);
+module_exit(ide_gd_exit);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("generic ATA/ATAPI disk driver");
diff --git a/drivers/ide/ide-gd.h b/drivers/ide/ide-gd.h
new file mode 100644 (file)
index 0000000..7d3d101
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef __IDE_GD_H
+#define __IDE_GD_H
+
+#define DRV_NAME "ide-gd"
+#define PFX DRV_NAME ": "
+
+/* define to see debug info */
+#define IDE_GD_DEBUG_LOG       0
+
+#if IDE_GD_DEBUG_LOG
+#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)
+#else
+#define ide_debug_log(lvl, fmt, args...) do {} while (0)
+#endif
+
+struct ide_disk_obj {
+       ide_drive_t     *drive;
+       ide_driver_t    *driver;
+       struct gendisk  *disk;
+       struct kref     kref;
+       unsigned int    openers;        /* protected by BKL for now */
+
+       /* Last failed packet command */
+       struct ide_atapi_pc *failed_pc;
+       /* used for blk_{fs,pc}_request() requests */
+       struct ide_atapi_pc queued_pc;
+
+       /* Last error information */
+       u8 sense_key, asc, ascq;
+
+       int progress_indication;
+
+       /* Device information */
+       /* Current format */
+       int blocks, block_size, bs_factor;
+       /* Last format capacity descriptor */
+       u8 cap_desc[8];
+       /* Copy of the flexible disk page */
+       u8 flexible_disk_page[32];
+};
+
+sector_t ide_gd_capacity(ide_drive_t *);
+
+#endif /* __IDE_GD_H */
index a90945f4979287ca8d260d65c4fab2e144a846af..fcde16bb53a71498ab6000626b49a2581e9df591 100644 (file)
@@ -240,8 +240,7 @@ static int generic_drive_reset(ide_drive_t *drive)
        return ret;
 }
 
-int generic_ide_ioctl(ide_drive_t *drive, struct file *file,
-                     struct block_device *bdev,
+int generic_ide_ioctl(ide_drive_t *drive, struct block_device *bdev,
                      unsigned int cmd, unsigned long arg)
 {
        int err;
index b762deb2dacb34f408ff55d0104581593f117e5d..bb7a1ed8094e399b1860113ecbaee3ced4b5c96a 100644 (file)
@@ -755,7 +755,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
         
        udelay(1);
        SELECT_DRIVE(drive);
-       SELECT_MASK(drive, 0);
+       SELECT_MASK(drive, 1);
        udelay(1);
        tp_ops->set_irq(hwif, 0);
 
index 19f8c7770a25d7449486b3df07b56cf536ee5b76..1649ea54f76ce7c194f7ec8f5016f132aec79d0f 100644 (file)
@@ -208,6 +208,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
                drive->ready_stat = 0;
                if (ata_id_cdb_intr(id))
                        drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT;
+               drive->dev_flags |= IDE_DFLAG_DOORLOCKING;
                /* we don't do head unloading on ATAPI devices */
                drive->dev_flags |= IDE_DFLAG_NO_UNLOAD;
                return;
index b26926487cc03f907e8e1798cdf6f0323027391e..c31d0dd7a5322aa56355462db58a213c3a3d9a63 100644 (file)
@@ -567,10 +567,10 @@ static void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t
 void ide_proc_register_driver(ide_drive_t *drive, ide_driver_t *driver)
 {
        mutex_lock(&ide_setting_mtx);
-       drive->settings = driver->settings;
+       drive->settings = driver->proc_devsets(drive);
        mutex_unlock(&ide_setting_mtx);
 
-       ide_add_proc_entries(drive->proc, driver->proc, drive);
+       ide_add_proc_entries(drive->proc, driver->proc_entries(drive), drive);
 }
 
 EXPORT_SYMBOL(ide_proc_register_driver);
@@ -591,7 +591,7 @@ void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver)
 {
        unsigned long flags;
 
-       ide_remove_proc_entries(drive->proc, driver->proc);
+       ide_remove_proc_entries(drive->proc, driver->proc_entries(drive));
 
        mutex_lock(&ide_setting_mtx);
        spin_lock_irqsave(&ide_lock, flags);
index d879c7797cde3a6ab961088f65ac17ca441f4120..a2d470eb2b55eed6d66c713ee51c00dd9f806d02 100644 (file)
@@ -2108,7 +2108,7 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive)
 
        /* device lacks locking support according to capabilities page */
        if ((caps[6] & 1) == 0)
-               drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK;
+               drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
 
        if (caps[7] & 0x02)
                tape->blk_size = 512;
@@ -2298,6 +2298,16 @@ static ide_proc_entry_t idetape_proc[] = {
        { "name",       S_IFREG|S_IRUGO,        proc_idetape_read_name, NULL },
        { NULL, 0, NULL, NULL }
 };
+
+static ide_proc_entry_t *ide_tape_proc_entries(ide_drive_t *drive)
+{
+       return idetape_proc;
+}
+
+static const struct ide_proc_devset *ide_tape_proc_devsets(ide_drive_t *drive)
+{
+       return idetape_settings;
+}
 #endif
 
 static int ide_tape_probe(ide_drive_t *);
@@ -2315,8 +2325,8 @@ static ide_driver_t idetape_driver = {
        .end_request            = idetape_end_request,
        .error                  = __ide_error,
 #ifdef CONFIG_IDE_PROC_FS
-       .proc                   = idetape_proc,
-       .settings               = idetape_settings,
+       .proc_entries           = ide_tape_proc_entries,
+       .proc_devsets           = ide_tape_proc_devsets,
 #endif
 };
 
@@ -2330,35 +2340,30 @@ static const struct file_operations idetape_fops = {
        .release        = idetape_chrdev_release,
 };
 
-static int idetape_open(struct inode *inode, struct file *filp)
+static int idetape_open(struct block_device *bdev, fmode_t mode)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct ide_tape_obj *tape;
+       struct ide_tape_obj *tape = ide_tape_get(bdev->bd_disk);
 
-       tape = ide_tape_get(disk);
        if (!tape)
                return -ENXIO;
 
        return 0;
 }
 
-static int idetape_release(struct inode *inode, struct file *filp)
+static int idetape_release(struct gendisk *disk, fmode_t mode)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
        struct ide_tape_obj *tape = ide_drv_g(disk, ide_tape_obj);
 
        ide_tape_put(tape);
-
        return 0;
 }
 
-static int idetape_ioctl(struct inode *inode, struct file *file,
+static int idetape_ioctl(struct block_device *bdev, fmode_t mode,
                        unsigned int cmd, unsigned long arg)
 {
-       struct block_device *bdev = inode->i_bdev;
        struct ide_tape_obj *tape = ide_drv_g(bdev->bd_disk, ide_tape_obj);
        ide_drive_t *drive = tape->drive;
-       int err = generic_ide_ioctl(drive, file, bdev, cmd, arg);
+       int err = generic_ide_ioctl(drive, bdev, cmd, arg);
        if (err == -EINVAL)
                err = idetape_blkdev_ioctl(drive, cmd, arg);
        return err;
@@ -2368,7 +2373,7 @@ static struct block_device_operations idetape_block_ops = {
        .owner          = THIS_MODULE,
        .open           = idetape_open,
        .release        = idetape_release,
-       .ioctl          = idetape_ioctl,
+       .locked_ioctl   = idetape_ioctl,
 };
 
 static int ide_tape_probe(ide_drive_t *drive)
diff --git a/drivers/ide/legacy/Makefile b/drivers/ide/legacy/Makefile
deleted file mode 100644 (file)
index 6939329..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-
-# link order is important here
-
-obj-$(CONFIG_BLK_DEV_ALI14XX)          += ali14xx.o
-obj-$(CONFIG_BLK_DEV_UMC8672)          += umc8672.o
-obj-$(CONFIG_BLK_DEV_DTC2278)          += dtc2278.o
-obj-$(CONFIG_BLK_DEV_HT6560B)          += ht6560b.o
-obj-$(CONFIG_BLK_DEV_QD65XX)           += qd65xx.o
-obj-$(CONFIG_BLK_DEV_4DRIVES)          += ide-4drives.o
-
-obj-$(CONFIG_BLK_DEV_GAYLE)            += gayle.o
-obj-$(CONFIG_BLK_DEV_FALCON_IDE)       += falconide.o
-obj-$(CONFIG_BLK_DEV_MAC_IDE)          += macide.o
-obj-$(CONFIG_BLK_DEV_Q40IDE)           += q40ide.o
-obj-$(CONFIG_BLK_DEV_BUDDHA)           += buddha.o
-
-ifeq ($(CONFIG_BLK_DEV_IDECS), m)
-       obj-m += ide-cs.o
-endif
-
-ifeq ($(CONFIG_BLK_DEV_PLATFORM), m)
-       obj-m += ide_platform.o
-endif
-
-EXTRA_CFLAGS   := -Idrivers/ide
diff --git a/drivers/ide/mips/Makefile b/drivers/ide/mips/Makefile
deleted file mode 100644 (file)
index 5873fa0..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_BLK_DEV_IDE_AU1XXX)       += au1xxx-ide.o
-
-EXTRA_CFLAGS    := -Idrivers/ide
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile
deleted file mode 100644 (file)
index 02e6ee7..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-
-obj-$(CONFIG_BLK_DEV_AEC62XX)          += aec62xx.o
-obj-$(CONFIG_BLK_DEV_ALI15X3)          += alim15x3.o
-obj-$(CONFIG_BLK_DEV_AMD74XX)          += amd74xx.o
-obj-$(CONFIG_BLK_DEV_ATIIXP)           += atiixp.o
-obj-$(CONFIG_BLK_DEV_CELLEB)           += scc_pata.o
-obj-$(CONFIG_BLK_DEV_CMD64X)           += cmd64x.o
-obj-$(CONFIG_BLK_DEV_CS5520)           += cs5520.o
-obj-$(CONFIG_BLK_DEV_CS5530)           += cs5530.o
-obj-$(CONFIG_BLK_DEV_CS5535)           += cs5535.o
-obj-$(CONFIG_BLK_DEV_SC1200)           += sc1200.o
-obj-$(CONFIG_BLK_DEV_CY82C693)         += cy82c693.o
-obj-$(CONFIG_BLK_DEV_DELKIN)           += delkin_cb.o
-obj-$(CONFIG_BLK_DEV_HPT34X)           += hpt34x.o
-obj-$(CONFIG_BLK_DEV_HPT366)           += hpt366.o
-obj-$(CONFIG_BLK_DEV_IT8213)           += it8213.o
-obj-$(CONFIG_BLK_DEV_IT821X)           += it821x.o
-obj-$(CONFIG_BLK_DEV_JMICRON)          += jmicron.o
-obj-$(CONFIG_BLK_DEV_NS87415)          += ns87415.o
-obj-$(CONFIG_BLK_DEV_OPTI621)          += opti621.o
-obj-$(CONFIG_BLK_DEV_PDC202XX_OLD)     += pdc202xx_old.o
-obj-$(CONFIG_BLK_DEV_PDC202XX_NEW)     += pdc202xx_new.o
-obj-$(CONFIG_BLK_DEV_PIIX)             += piix.o
-obj-$(CONFIG_BLK_DEV_RZ1000)           += rz1000.o
-obj-$(CONFIG_BLK_DEV_SVWKS)            += serverworks.o
-obj-$(CONFIG_BLK_DEV_SGIIOC4)          += sgiioc4.o
-obj-$(CONFIG_BLK_DEV_SIIMAGE)          += siimage.o
-obj-$(CONFIG_BLK_DEV_SIS5513)          += sis5513.o
-obj-$(CONFIG_BLK_DEV_SL82C105)         += sl82c105.o
-obj-$(CONFIG_BLK_DEV_SLC90E66)         += slc90e66.o
-obj-$(CONFIG_BLK_DEV_TC86C001)         += tc86c001.o
-obj-$(CONFIG_BLK_DEV_TRIFLEX)          += triflex.o
-obj-$(CONFIG_BLK_DEV_TRM290)           += trm290.o
-obj-$(CONFIG_BLK_DEV_VIA82CXXX)                += via82cxxx.o
-
-# Must appear at the end of the block
-obj-$(CONFIG_BLK_DEV_GENERIC)          += ide-pci-generic.o
-ide-pci-generic-y                      += generic.o
-
-ifeq ($(CONFIG_BLK_DEV_CMD640), m)
-       obj-m += cmd640.o
-endif
-
-EXTRA_CFLAGS   := -Idrivers/ide
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c
deleted file mode 100644 (file)
index fb1a3aa..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 1998-2000     Andre Hedrick <andre@linux-ide.org>
- *
- * May be copied or modified under the terms of the GNU General Public License
- *
- *
- * 00:12.0 Unknown mass storage controller:
- * Triones Technologies, Inc.
- * Unknown device 0003 (rev 01)
- *
- * hde: UDMA 2 (0x0000 0x0002) (0x0000 0x0010)
- * hdf: UDMA 2 (0x0002 0x0012) (0x0010 0x0030)
- * hde: DMA 2  (0x0000 0x0002) (0x0000 0x0010)
- * hdf: DMA 2  (0x0002 0x0012) (0x0010 0x0030)
- * hdg: DMA 1  (0x0012 0x0052) (0x0030 0x0070)
- * hdh: DMA 1  (0x0052 0x0252) (0x0070 0x00f0)
- *
- * ide-pci.c reference
- *
- * Since there are two cards that report almost identically,
- * the only discernable difference is the values reported in pcicmd.
- * Booting-BIOS card or HPT363 :: pcicmd == 0x07
- * Non-bootable card or HPT343 :: pcicmd == 0x05
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/ide.h>
-
-#define DRV_NAME "hpt34x"
-
-#define HPT343_DEBUG_DRIVE_INFO                0
-
-static void hpt34x_set_mode(ide_drive_t *drive, const u8 speed)
-{
-       struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
-       u32 reg1= 0, tmp1 = 0, reg2 = 0, tmp2 = 0;
-       u8                      hi_speed, lo_speed;
-
-       hi_speed = speed >> 4;
-       lo_speed = speed & 0x0f;
-
-       if (hi_speed & 7) {
-               hi_speed = (hi_speed & 4) ? 0x01 : 0x10;
-       } else {
-               lo_speed <<= 5;
-               lo_speed >>= 5;
-       }
-
-       pci_read_config_dword(dev, 0x44, &reg1);
-       pci_read_config_dword(dev, 0x48, &reg2);
-       tmp1 = ((lo_speed << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn))));
-       tmp2 = ((hi_speed << drive->dn) | (reg2 & ~(0x11 << drive->dn)));
-       pci_write_config_dword(dev, 0x44, tmp1);
-       pci_write_config_dword(dev, 0x48, tmp2);
-
-#if HPT343_DEBUG_DRIVE_INFO
-       printk("%s: %s drive%d (0x%04x 0x%04x) (0x%04x 0x%04x)" \
-               " (0x%02x 0x%02x)\n",
-               drive->name, ide_xfer_verbose(speed),
-               drive->dn, reg1, tmp1, reg2, tmp2,
-               hi_speed, lo_speed);
-#endif /* HPT343_DEBUG_DRIVE_INFO */
-}
-
-static void hpt34x_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
-       hpt34x_set_mode(drive, XFER_PIO_0 + pio);
-}
-
-/*
- * If the BIOS does not set the IO base addaress to XX00, 343 will fail.
- */
-#define        HPT34X_PCI_INIT_REG             0x80
-
-static unsigned int init_chipset_hpt34x(struct pci_dev *dev)
-{
-       int i = 0;
-       unsigned long hpt34xIoBase = pci_resource_start(dev, 4);
-       unsigned long hpt_addr[4] = { 0x20, 0x34, 0x28, 0x3c };
-       unsigned long hpt_addr_len[4] = { 7, 3, 7, 3 };
-       u16 cmd;
-       unsigned long flags;
-
-       local_irq_save(flags);
-
-       pci_write_config_byte(dev, HPT34X_PCI_INIT_REG, 0x00);
-       pci_read_config_word(dev, PCI_COMMAND, &cmd);
-
-       if (cmd & PCI_COMMAND_MEMORY)
-               pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0);
-       else
-               pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
-
-       /*
-        * Since 20-23 can be assigned and are R/W, we correct them.
-        */
-       pci_write_config_word(dev, PCI_COMMAND, cmd & ~PCI_COMMAND_IO);
-       for(i=0; i<4; i++) {
-               dev->resource[i].start = (hpt34xIoBase + hpt_addr[i]);
-               dev->resource[i].end = dev->resource[i].start + hpt_addr_len[i];
-               dev->resource[i].flags = IORESOURCE_IO;
-               pci_write_config_dword(dev,
-                               (PCI_BASE_ADDRESS_0 + (i * 4)),
-                               dev->resource[i].start);
-       }
-       pci_write_config_word(dev, PCI_COMMAND, cmd);
-
-       local_irq_restore(flags);
-
-       return dev->irq;
-}
-
-static const struct ide_port_ops hpt34x_port_ops = {
-       .set_pio_mode           = hpt34x_set_pio_mode,
-       .set_dma_mode           = hpt34x_set_mode,
-};
-
-#define IDE_HFLAGS_HPT34X \
-       (IDE_HFLAG_NO_ATAPI_DMA | \
-        IDE_HFLAG_NO_DSC | \
-        IDE_HFLAG_NO_AUTODMA)
-
-static const struct ide_port_info hpt34x_chipsets[] __devinitdata = {
-       { /* 0: HPT343 */
-               .name           = DRV_NAME,
-               .init_chipset   = init_chipset_hpt34x,
-               .port_ops       = &hpt34x_port_ops,
-               .host_flags     = IDE_HFLAGS_HPT34X | IDE_HFLAG_NON_BOOTABLE,
-               .pio_mask       = ATA_PIO5,
-       },
-       { /* 1: HPT345 */
-               .name           = DRV_NAME,
-               .init_chipset   = init_chipset_hpt34x,
-               .port_ops       = &hpt34x_port_ops,
-               .host_flags     = IDE_HFLAGS_HPT34X | IDE_HFLAG_OFF_BOARD,
-               .pio_mask       = ATA_PIO5,
-#ifdef CONFIG_HPT34X_AUTODMA
-               .swdma_mask     = ATA_SWDMA2,
-               .mwdma_mask     = ATA_MWDMA2,
-               .udma_mask      = ATA_UDMA2,
-#endif
-       }
-};
-
-static int __devinit hpt34x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
-{
-       const struct ide_port_info *d;
-       u16 pcicmd = 0;
-
-       pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
-
-       d = &hpt34x_chipsets[(pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0];
-
-       return ide_pci_init_one(dev, d, NULL);
-}
-
-static const struct pci_device_id hpt34x_pci_tbl[] = {
-       { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT343), 0 },
-       { 0, },
-};
-MODULE_DEVICE_TABLE(pci, hpt34x_pci_tbl);
-
-static struct pci_driver hpt34x_pci_driver = {
-       .name           = "HPT34x_IDE",
-       .id_table       = hpt34x_pci_tbl,
-       .probe          = hpt34x_init_one,
-       .remove         = ide_pci_remove,
-       .suspend        = ide_pci_suspend,
-       .resume         = ide_pci_resume,
-};
-
-static int __init hpt34x_ide_init(void)
-{
-       return ide_pci_register_driver(&hpt34x_pci_driver);
-}
-
-static void __exit hpt34x_ide_exit(void)
-{
-       pci_unregister_driver(&hpt34x_pci_driver);
-}
-
-module_init(hpt34x_ide_init);
-module_exit(hpt34x_ide_exit);
-
-MODULE_AUTHOR("Andre Hedrick");
-MODULE_DESCRIPTION("PCI driver module for Highpoint 34x IDE");
-MODULE_LICENSE("GPL");
similarity index 100%
rename from drivers/ide/pci/piix.c
rename to drivers/ide/piix.c
similarity index 100%
rename from drivers/ide/ppc/pmac.c
rename to drivers/ide/pmac.c
diff --git a/drivers/ide/ppc/Makefile b/drivers/ide/ppc/Makefile
deleted file mode 100644 (file)
index 74e52ad..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-
-obj-$(CONFIG_BLK_DEV_IDE_PMAC)         += pmac.o
similarity index 99%
rename from drivers/ide/pci/scc_pata.c
rename to drivers/ide/scc_pata.c
index 9ce1d8059921932de41938cc874412088b75b4ee..49f163aa51e3197773c0ac626ad094cca96d6630 100644 (file)
@@ -617,7 +617,6 @@ static int __devinit init_setup_scc(struct pci_dev *dev,
        unsigned long intmask_port;
        unsigned long mode_port;
        unsigned long ecmode_port;
-       unsigned long dma_status_port;
        u32 reg = 0;
        struct scc_ports *ports;
        int rc;
@@ -637,7 +636,6 @@ static int __devinit init_setup_scc(struct pci_dev *dev,
        intmask_port = dma_base + 0x010;
        mode_port = ctl_base + 0x024;
        ecmode_port = ctl_base + 0xf00;
-       dma_status_port = dma_base + 0x004;
 
        /* controller initialization */
        reg = 0;
@@ -843,8 +841,6 @@ static u8 scc_cable_detect(ide_hwif_t *hwif)
 
 static void __devinit init_hwif_scc(ide_hwif_t *hwif)
 {
-       struct scc_ports *ports = ide_get_hwifdata(hwif);
-
        /* PTERADD */
        out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma);
 
similarity index 93%
rename from drivers/ide/pci/sgiioc4.c
rename to drivers/ide/sgiioc4.c
index dd634541ce361a62a4789484cdf89fe6a85584f3..8af9b23499fdd59d481e1dc03d0d9c44a2525606 100644 (file)
@@ -101,18 +101,8 @@ sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port,
        for (i = 0; i <= 7; i++)
                hw->io_ports_array[i] = reg + i * 4;
 
-       if (ctrl_port)
-               hw->io_ports.ctl_addr = ctrl_port;
-
-       if (irq_port)
-               hw->io_ports.irq_addr = irq_port;
-}
-
-static void
-sgiioc4_maskproc(ide_drive_t * drive, int mask)
-{
-       writeb(ATA_DEVCTL_OBS | (mask ? 2 : 0),
-              (void __iomem *)drive->hwif->io_ports.ctl_addr);
+       hw->io_ports.ctl_addr = ctrl_port;
+       hw->io_ports.irq_addr = irq_port;
 }
 
 static int
@@ -310,16 +300,14 @@ static u8 sgiioc4_read_status(ide_hwif_t *hwif)
        unsigned long port = hwif->io_ports.status_addr;
        u8 reg = (u8) readb((void __iomem *) port);
 
-       if ((port & 0xFFF) == 0x11C) {  /* Status register of IOC4 */
-               if (!(reg & ATA_BUSY)) { /* Not busy... check for interrupt */
-                       unsigned long other_ir = port - 0x110;
-                       unsigned int intr_reg = (u32) readl((void __iomem *) other_ir);
+       if (!(reg & ATA_BUSY)) {        /* Not busy... check for interrupt */
+               unsigned long other_ir = port - 0x110;
+               unsigned int intr_reg = (u32) readl((void __iomem *) other_ir);
 
-                       /* Clear the Interrupt, Error bits on the IOC4 */
-                       if (intr_reg & 0x03) {
-                               writel(0x03, (void __iomem *) other_ir);
-                               intr_reg = (u32) readl((void __iomem *) other_ir);
-                       }
+               /* Clear the Interrupt, Error bits on the IOC4 */
+               if (intr_reg & 0x03) {
+                       writel(0x03, (void __iomem *) other_ir);
+                       intr_reg = (u32) readl((void __iomem *) other_ir);
                }
        }
 
@@ -332,13 +320,9 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d)
 {
        struct pci_dev *dev = to_pci_dev(hwif->dev);
        unsigned long dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET;
-       void __iomem *virt_dma_base;
        int num_ports = sizeof (ioc4_dma_regs_t);
        void *pad;
 
-       if (dma_base == 0)
-               return -1;
-
        printk(KERN_INFO "    %s: MMIO-DMA\n", hwif->name);
 
        if (request_mem_region(dma_base, num_ports, hwif->name) == NULL) {
@@ -348,14 +332,8 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d)
                return -1;
        }
 
-       virt_dma_base = ioremap(dma_base, num_ports);
-       if (virt_dma_base == NULL) {
-               printk(KERN_ERR "%s(%s) -- ERROR: unable to map addresses "
-                      "0x%lx to 0x%lx\n", __func__, hwif->name,
-                      dma_base, dma_base + num_ports - 1);
-               goto dma_remap_failure;
-       }
-       hwif->dma_base = (unsigned long) virt_dma_base;
+       hwif->dma_base = (unsigned long)hwif->io_ports.irq_addr +
+                        IOC4_DMA_OFFSET;
 
        hwif->sg_max_nents = IOC4_PRD_ENTRIES;
 
@@ -379,9 +357,6 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d)
        printk(KERN_INFO "%s: changing from DMA to PIO mode", hwif->name);
 
 dma_pci_alloc_failure:
-       iounmap(virt_dma_base);
-
-dma_remap_failure:
        release_mem_region(dma_base, num_ports);
 
        return -1;
@@ -563,8 +538,6 @@ static const struct ide_port_ops sgiioc4_port_ops = {
        .set_dma_mode           = sgiioc4_set_dma_mode,
        /* reset DMA engine, clear IRQs */
        .resetproc              = sgiioc4_resetproc,
-       /* mask on/off NIEN register */
-       .maskproc               = sgiioc4_maskproc,
 };
 
 static const struct ide_dma_ops sgiioc4_dma_ops = {
diff --git a/drivers/idle/Kconfig b/drivers/idle/Kconfig
new file mode 100644 (file)
index 0000000..f5b26dd
--- /dev/null
@@ -0,0 +1,16 @@
+
+menu "Memory power savings"
+
+config I7300_IDLE_IOAT_CHANNEL
+       bool
+
+config I7300_IDLE
+       tristate "Intel chipset idle power saving driver"
+       select I7300_IDLE_IOAT_CHANNEL
+       depends on X86_64
+       help
+         Enable idle power savings with certain Intel server chipsets.
+         The chipset must have I/O AT support, such as the Intel 7300.
+         The power savings depends on the type and quantity of DRAM devices.
+
+endmenu
diff --git a/drivers/idle/Makefile b/drivers/idle/Makefile
new file mode 100644 (file)
index 0000000..5f68fc3
--- /dev/null
@@ -0,0 +1,2 @@
+obj-$(CONFIG_I7300_IDLE)                       += i7300_idle.o
+
diff --git a/drivers/idle/i7300_idle.c b/drivers/idle/i7300_idle.c
new file mode 100644 (file)
index 0000000..59d1bbc
--- /dev/null
@@ -0,0 +1,674 @@
+/*
+ * (C) Copyright 2008 Intel Corporation
+ * Authors:
+ * Andy Henroid <andrew.d.henroid@intel.com>
+ * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ */
+
+/*
+ * Save DIMM power on Intel 7300-based platforms when all CPUs/cores
+ * are idle, using the DIMM thermal throttling capability.
+ *
+ * This driver depends on the Intel integrated DMA controller (I/O AT).
+ * If the driver for I/O AT (drivers/dma/ioatdma*) is also enabled,
+ * this driver should work cooperatively.
+ */
+
+/* #define DEBUG */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/notifier.h>
+#include <linux/cpumask.h>
+#include <linux/ktime.h>
+#include <linux/delay.h>
+#include <linux/debugfs.h>
+#include <linux/stop_machine.h>
+
+#include <asm/idle.h>
+
+#include "../dma/ioatdma_hw.h"
+#include "../dma/ioatdma_registers.h"
+
+#define I7300_IDLE_DRIVER_VERSION      "1.55"
+#define I7300_PRINT                    "i7300_idle:"
+
+static int debug;
+module_param_named(debug, debug, uint, 0644);
+MODULE_PARM_DESC(debug, "Enable debug printks in this driver");
+
+#define dprintk(fmt, arg...) \
+       do { if (debug) printk(KERN_INFO I7300_PRINT fmt, ##arg); } while (0)
+
+/*
+ * Value to set THRTLOW to when initiating throttling
+ *  0 = No throttling
+ *  1 = Throttle when > 4 activations per eval window (Maximum throttling)
+ *  2 = Throttle when > 8 activations
+ *  168 = Throttle when > 168 activations (Minimum throttling)
+ */
+#define MAX_THRTLWLIMIT                168
+static uint i7300_idle_thrtlowlm = 1;
+module_param_named(thrtlwlimit, i7300_idle_thrtlowlm, uint, 0644);
+MODULE_PARM_DESC(thrtlwlimit,
+               "Value for THRTLOWLM activation field "
+               "(0 = disable throttle, 1 = Max throttle, 168 = Min throttle)");
+
+/*
+ * simple invocation and duration statistics
+ */
+static unsigned long total_starts;
+static unsigned long total_us;
+
+#ifdef DEBUG
+static unsigned long past_skip;
+#endif
+
+static struct pci_dev *fbd_dev;
+
+static spinlock_t i7300_idle_lock;
+static int i7300_idle_active;
+
+static u8 i7300_idle_thrtctl_saved;
+static u8 i7300_idle_thrtlow_saved;
+static u32 i7300_idle_mc_saved;
+
+static cpumask_t idle_cpumask;
+static ktime_t start_ktime;
+static unsigned long avg_idle_us;
+
+static struct dentry *debugfs_dir;
+
+/* Begin: I/O AT Helper routines */
+
+#define IOAT_CHANBASE(ioat_ctl, chan) (ioat_ctl + 0x80 + 0x80 * chan)
+/* Snoop control (disable snoops when coherency is not important) */
+#define IOAT_DESC_SADDR_SNP_CTL (1UL << 1)
+#define IOAT_DESC_DADDR_SNP_CTL (1UL << 2)
+
+static struct pci_dev *ioat_dev;
+static struct ioat_dma_descriptor *ioat_desc; /* I/O AT desc & data (1 page) */
+static unsigned long ioat_desc_phys;
+static u8 *ioat_iomap; /* I/O AT memory-mapped control regs (aka CB_BAR) */
+static u8 *ioat_chanbase;
+
+/* Start I/O AT memory copy */
+static int i7300_idle_ioat_start(void)
+{
+       u32 err;
+       /* Clear error (due to circular descriptor pointer) */
+       err = readl(ioat_chanbase + IOAT_CHANERR_OFFSET);
+       if (err)
+               writel(err, ioat_chanbase + IOAT_CHANERR_OFFSET);
+
+       writeb(IOAT_CHANCMD_START, ioat_chanbase + IOAT1_CHANCMD_OFFSET);
+       return 0;
+}
+
+/* Stop I/O AT memory copy */
+static void i7300_idle_ioat_stop(void)
+{
+       int i;
+       u8 sts;
+
+       for (i = 0; i < 5; i++) {
+               writeb(IOAT_CHANCMD_RESET,
+                       ioat_chanbase + IOAT1_CHANCMD_OFFSET);
+
+               udelay(10);
+
+               sts = readq(ioat_chanbase + IOAT1_CHANSTS_OFFSET) &
+                       IOAT_CHANSTS_DMA_TRANSFER_STATUS;
+
+               if (sts != IOAT_CHANSTS_DMA_TRANSFER_STATUS_ACTIVE)
+                       break;
+
+       }
+
+       if (i == 5)
+               dprintk("failed to suspend+reset I/O AT after 5 retries\n");
+
+}
+
+/* Test I/O AT by copying 1024 byte from 2k to 1k */
+static int __init i7300_idle_ioat_selftest(u8 *ctl,
+               struct ioat_dma_descriptor *desc, unsigned long desc_phys)
+{
+       u64 chan_sts;
+
+       memset(desc, 0, 2048);
+       memset((u8 *) desc + 2048, 0xab, 1024);
+
+       desc[0].size = 1024;
+       desc[0].ctl = 0;
+       desc[0].src_addr = desc_phys + 2048;
+       desc[0].dst_addr = desc_phys + 1024;
+       desc[0].next = 0;
+
+       writeb(IOAT_CHANCMD_RESET, ioat_chanbase + IOAT1_CHANCMD_OFFSET);
+       writeb(IOAT_CHANCMD_START, ioat_chanbase + IOAT1_CHANCMD_OFFSET);
+
+       udelay(1000);
+
+       chan_sts = readq(ioat_chanbase + IOAT1_CHANSTS_OFFSET) &
+                       IOAT_CHANSTS_DMA_TRANSFER_STATUS;
+
+       if (chan_sts != IOAT_CHANSTS_DMA_TRANSFER_STATUS_DONE) {
+               /* Not complete, reset the channel */
+               writeb(IOAT_CHANCMD_RESET,
+                      ioat_chanbase + IOAT1_CHANCMD_OFFSET);
+               return -1;
+       }
+
+       if (*(u32 *) ((u8 *) desc + 3068) != 0xabababab ||
+           *(u32 *) ((u8 *) desc + 2044) != 0xabababab) {
+               dprintk("Data values src 0x%x, dest 0x%x, memset 0x%x\n",
+                       *(u32 *) ((u8 *) desc + 2048),
+                       *(u32 *) ((u8 *) desc + 1024),
+                       *(u32 *) ((u8 *) desc + 3072));
+               return -1;
+       }
+       return 0;
+}
+
+static struct device dummy_dma_dev = {
+       .bus_id = "fallback device",
+       .coherent_dma_mask = DMA_64BIT_MASK,
+       .dma_mask = &dummy_dma_dev.coherent_dma_mask,
+};
+
+/* Setup and initialize I/O AT */
+/* This driver needs I/O AT as the throttling takes effect only when there is
+ * some memory activity. We use I/O AT to set up a dummy copy, while all CPUs
+ * go idle and memory is throttled.
+ */
+static int __init i7300_idle_ioat_init(void)
+{
+       u8 ver, chan_count, ioat_chan;
+       u16 chan_ctl;
+
+       ioat_iomap = (u8 *) ioremap_nocache(pci_resource_start(ioat_dev, 0),
+                                           pci_resource_len(ioat_dev, 0));
+
+       if (!ioat_iomap) {
+               printk(KERN_ERR I7300_PRINT "failed to map I/O AT registers\n");
+               goto err_ret;
+       }
+
+       ver = readb(ioat_iomap + IOAT_VER_OFFSET);
+       if (ver != IOAT_VER_1_2) {
+               printk(KERN_ERR I7300_PRINT "unknown I/O AT version (%u.%u)\n",
+                       ver >> 4, ver & 0xf);
+               goto err_unmap;
+       }
+
+       chan_count = readb(ioat_iomap + IOAT_CHANCNT_OFFSET);
+       if (!chan_count) {
+               printk(KERN_ERR I7300_PRINT "unexpected # of I/O AT channels "
+                       "(%u)\n",
+                       chan_count);
+               goto err_unmap;
+       }
+
+       ioat_chan = chan_count - 1;
+       ioat_chanbase = IOAT_CHANBASE(ioat_iomap, ioat_chan);
+
+       chan_ctl = readw(ioat_chanbase + IOAT_CHANCTRL_OFFSET);
+       if (chan_ctl & IOAT_CHANCTRL_CHANNEL_IN_USE) {
+               printk(KERN_ERR I7300_PRINT "channel %d in use\n", ioat_chan);
+               goto err_unmap;
+       }
+
+       writew(IOAT_CHANCTRL_CHANNEL_IN_USE,
+               ioat_chanbase + IOAT_CHANCTRL_OFFSET);
+
+       ioat_desc = (struct ioat_dma_descriptor *)dma_alloc_coherent(
+                       &dummy_dma_dev, 4096,
+                       (dma_addr_t *)&ioat_desc_phys, GFP_KERNEL);
+       if (!ioat_desc) {
+               printk(KERN_ERR I7300_PRINT "failed to allocate I/O AT desc\n");
+               goto err_mark_unused;
+       }
+
+       writel(ioat_desc_phys & 0xffffffffUL,
+              ioat_chanbase + IOAT1_CHAINADDR_OFFSET_LOW);
+       writel(ioat_desc_phys >> 32,
+              ioat_chanbase + IOAT1_CHAINADDR_OFFSET_HIGH);
+
+       if (i7300_idle_ioat_selftest(ioat_iomap, ioat_desc, ioat_desc_phys)) {
+               printk(KERN_ERR I7300_PRINT "I/O AT self-test failed\n");
+               goto err_free;
+       }
+
+       /* Setup circular I/O AT descriptor chain */
+       ioat_desc[0].ctl = IOAT_DESC_SADDR_SNP_CTL | IOAT_DESC_DADDR_SNP_CTL;
+       ioat_desc[0].src_addr = ioat_desc_phys + 2048;
+       ioat_desc[0].dst_addr = ioat_desc_phys + 3072;
+       ioat_desc[0].size = 128;
+       ioat_desc[0].next = ioat_desc_phys + sizeof(struct ioat_dma_descriptor);
+
+       ioat_desc[1].ctl = ioat_desc[0].ctl;
+       ioat_desc[1].src_addr = ioat_desc[0].src_addr;
+       ioat_desc[1].dst_addr = ioat_desc[0].dst_addr;
+       ioat_desc[1].size = ioat_desc[0].size;
+       ioat_desc[1].next = ioat_desc_phys;
+
+       return 0;
+
+err_free:
+       dma_free_coherent(&dummy_dma_dev, 4096, (void *)ioat_desc, 0);
+err_mark_unused:
+       writew(0, ioat_chanbase + IOAT_CHANCTRL_OFFSET);
+err_unmap:
+       iounmap(ioat_iomap);
+err_ret:
+       return -ENODEV;
+}
+
+/* Cleanup I/O AT */
+static void __exit i7300_idle_ioat_exit(void)
+{
+       int i;
+       u64 chan_sts;
+
+       i7300_idle_ioat_stop();
+
+       /* Wait for a while for the channel to halt before releasing */
+       for (i = 0; i < 10; i++) {
+               writeb(IOAT_CHANCMD_RESET,
+                      ioat_chanbase + IOAT1_CHANCMD_OFFSET);
+
+               chan_sts = readq(ioat_chanbase + IOAT1_CHANSTS_OFFSET) &
+                       IOAT_CHANSTS_DMA_TRANSFER_STATUS;
+
+               if (chan_sts != IOAT_CHANSTS_DMA_TRANSFER_STATUS_ACTIVE) {
+                       writew(0, ioat_chanbase + IOAT_CHANCTRL_OFFSET);
+                       break;
+               }
+               udelay(1000);
+       }
+
+       chan_sts = readq(ioat_chanbase + IOAT1_CHANSTS_OFFSET) &
+                       IOAT_CHANSTS_DMA_TRANSFER_STATUS;
+
+       /*
+        * We tried to reset multiple times. If IO A/T channel is still active
+        * flag an error and return without cleanup. Memory leak is better
+        * than random corruption in that extreme error situation.
+        */
+       if (chan_sts == IOAT_CHANSTS_DMA_TRANSFER_STATUS_ACTIVE) {
+               printk(KERN_ERR I7300_PRINT "Unable to stop IO A/T channels."
+                       " Not freeing resources\n");
+               return;
+       }
+
+       dma_free_coherent(&dummy_dma_dev, 4096, (void *)ioat_desc, 0);
+       iounmap(ioat_iomap);
+}
+
+/* End: I/O AT Helper routines */
+
+#define DIMM_THRTLOW 0x64
+#define DIMM_THRTCTL 0x67
+#define DIMM_THRTCTL_THRMHUNT (1UL << 0)
+#define DIMM_MC 0x40
+#define DIMM_GTW_MODE (1UL << 17)
+#define DIMM_GBLACT 0x60
+
+/*
+ * Keep track of an exponential-decaying average of recent idle durations.
+ * The latest duration gets DURATION_WEIGHT_PCT percentage weight
+ * in this average, with the old average getting the remaining weight.
+ *
+ * High weights emphasize recent history, low weights include long history.
+ */
+#define DURATION_WEIGHT_PCT 55
+
+/*
+ * When the decaying average of recent durations or the predicted duration
+ * of the next timer interrupt is shorter than duration_threshold, the
+ * driver will decline to throttle.
+ */
+#define DURATION_THRESHOLD_US 100
+
+
+/* Store DIMM thermal throttle configuration */
+static int i7300_idle_thrt_save(void)
+{
+       u32 new_mc_val;
+       u8 gblactlm;
+
+       pci_read_config_byte(fbd_dev, DIMM_THRTCTL, &i7300_idle_thrtctl_saved);
+       pci_read_config_byte(fbd_dev, DIMM_THRTLOW, &i7300_idle_thrtlow_saved);
+       pci_read_config_dword(fbd_dev, DIMM_MC, &i7300_idle_mc_saved);
+       /*
+        * Make sure we have Global Throttling Window Mode set to have a
+        * "short" window. This (mostly) works around an issue where
+        * throttling persists until the end of the global throttling window
+        * size. On the tested system, this was resulting in a maximum of
+        * 64 ms to exit throttling (average 32 ms). The actual numbers
+        * depends on system frequencies. Setting the short window reduces
+        * this by a factor of 4096.
+        *
+        * We will only do this only if the system is set for
+        * unlimited-activations while in open-loop throttling (i.e., when
+        * Global Activation Throttle Limit is zero).
+        */
+       pci_read_config_byte(fbd_dev, DIMM_GBLACT, &gblactlm);
+       dprintk("thrtctl_saved = 0x%02x, thrtlow_saved = 0x%02x\n",
+               i7300_idle_thrtctl_saved,
+               i7300_idle_thrtlow_saved);
+       dprintk("mc_saved = 0x%08x, gblactlm = 0x%02x\n",
+               i7300_idle_mc_saved,
+               gblactlm);
+       if (gblactlm == 0) {
+               new_mc_val = i7300_idle_mc_saved | DIMM_GTW_MODE;
+               pci_write_config_dword(fbd_dev, DIMM_MC, new_mc_val);
+               return 0;
+       } else {
+               dprintk("could not set GTW_MODE = 1 (OLTT enabled)\n");
+               return -ENODEV;
+       }
+}
+
+/* Restore DIMM thermal throttle configuration */
+static void i7300_idle_thrt_restore(void)
+{
+       pci_write_config_dword(fbd_dev, DIMM_MC, i7300_idle_mc_saved);
+       pci_write_config_byte(fbd_dev, DIMM_THRTLOW, i7300_idle_thrtlow_saved);
+       pci_write_config_byte(fbd_dev, DIMM_THRTCTL, i7300_idle_thrtctl_saved);
+}
+
+/* Enable DIMM thermal throttling */
+static void i7300_idle_start(void)
+{
+       u8 new_ctl;
+       u8 limit;
+
+       new_ctl = i7300_idle_thrtctl_saved & ~DIMM_THRTCTL_THRMHUNT;
+       pci_write_config_byte(fbd_dev, DIMM_THRTCTL, new_ctl);
+
+       limit = i7300_idle_thrtlowlm;
+       if (unlikely(limit > MAX_THRTLWLIMIT))
+               limit = MAX_THRTLWLIMIT;
+
+       pci_write_config_byte(fbd_dev, DIMM_THRTLOW, limit);
+
+       new_ctl = i7300_idle_thrtctl_saved | DIMM_THRTCTL_THRMHUNT;
+       pci_write_config_byte(fbd_dev, DIMM_THRTCTL, new_ctl);
+}
+
+/* Disable DIMM thermal throttling */
+static void i7300_idle_stop(void)
+{
+       u8 new_ctl;
+       u8 got_ctl;
+
+       new_ctl = i7300_idle_thrtctl_saved & ~DIMM_THRTCTL_THRMHUNT;
+       pci_write_config_byte(fbd_dev, DIMM_THRTCTL, new_ctl);
+
+       pci_write_config_byte(fbd_dev, DIMM_THRTLOW, i7300_idle_thrtlow_saved);
+       pci_write_config_byte(fbd_dev, DIMM_THRTCTL, i7300_idle_thrtctl_saved);
+       pci_read_config_byte(fbd_dev, DIMM_THRTCTL, &got_ctl);
+       WARN_ON_ONCE(got_ctl != i7300_idle_thrtctl_saved);
+}
+
+
+/*
+ * i7300_avg_duration_check()
+ * return 0 if the decaying average of recent idle durations is
+ * more than DURATION_THRESHOLD_US
+ */
+static int i7300_avg_duration_check(void)
+{
+       if (avg_idle_us >= DURATION_THRESHOLD_US)
+               return 0;
+
+#ifdef DEBUG
+       past_skip++;
+#endif
+       return 1;
+}
+
+/* Idle notifier to look at idle CPUs */
+static int i7300_idle_notifier(struct notifier_block *nb, unsigned long val,
+                               void *data)
+{
+       unsigned long flags;
+       ktime_t now_ktime;
+       static ktime_t idle_begin_time;
+       static int time_init = 1;
+
+       if (!i7300_idle_thrtlowlm)
+               return 0;
+
+       if (unlikely(time_init)) {
+               time_init = 0;
+               idle_begin_time = ktime_get();
+       }
+
+       spin_lock_irqsave(&i7300_idle_lock, flags);
+       if (val == IDLE_START) {
+
+               cpu_set(smp_processor_id(), idle_cpumask);
+
+               if (cpus_weight(idle_cpumask) != num_online_cpus())
+                       goto end;
+
+               now_ktime = ktime_get();
+               idle_begin_time = now_ktime;
+
+               if (i7300_avg_duration_check())
+                       goto end;
+
+               i7300_idle_active = 1;
+               total_starts++;
+               start_ktime = now_ktime;
+
+               i7300_idle_start();
+               i7300_idle_ioat_start();
+
+       } else if (val == IDLE_END) {
+               cpu_clear(smp_processor_id(), idle_cpumask);
+               if (cpus_weight(idle_cpumask) == (num_online_cpus() - 1)) {
+                       /* First CPU coming out of idle */
+                       u64 idle_duration_us;
+
+                       now_ktime = ktime_get();
+
+                       idle_duration_us = ktime_to_us(ktime_sub
+                                               (now_ktime, idle_begin_time));
+
+                       avg_idle_us =
+                               ((100 - DURATION_WEIGHT_PCT) * avg_idle_us +
+                                DURATION_WEIGHT_PCT * idle_duration_us) / 100;
+
+                       if (i7300_idle_active) {
+                               ktime_t idle_ktime;
+
+                               idle_ktime = ktime_sub(now_ktime, start_ktime);
+                               total_us += ktime_to_us(idle_ktime);
+
+                               i7300_idle_ioat_stop();
+                               i7300_idle_stop();
+                               i7300_idle_active = 0;
+                       }
+               }
+       }
+end:
+       spin_unlock_irqrestore(&i7300_idle_lock, flags);
+       return 0;
+}
+
+static struct notifier_block i7300_idle_nb = {
+       .notifier_call = i7300_idle_notifier,
+};
+
+/*
+ * I/O AT controls (PCI bus 0 device 8 function 0)
+ * DIMM controls (PCI bus 0 device 16 function 1)
+ */
+#define IOAT_BUS 0
+#define IOAT_DEVFN PCI_DEVFN(8, 0)
+#define MEMCTL_BUS 0
+#define MEMCTL_DEVFN PCI_DEVFN(16, 1)
+
+struct fbd_ioat {
+       unsigned int vendor;
+       unsigned int ioat_dev;
+};
+
+/*
+ * The i5000 chip-set has the same hooks as the i7300
+ * but support is disabled by default because this driver
+ * has not been validated on that platform.
+ */
+#define SUPPORT_I5000 0
+
+static const struct fbd_ioat fbd_ioat_list[] = {
+       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_CNB},
+#if SUPPORT_I5000
+       {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT},
+#endif
+       {0, 0}
+};
+
+/* table of devices that work with this driver */
+static const struct pci_device_id pci_tbl[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_FBD_CNB) },
+#if SUPPORT_I5000
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) },
+#endif
+       { } /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(pci, pci_tbl);
+
+/* Check for known platforms with I/O-AT */
+static int __init i7300_idle_platform_probe(void)
+{
+       int i;
+
+       fbd_dev = pci_get_bus_and_slot(MEMCTL_BUS, MEMCTL_DEVFN);
+       if (!fbd_dev)
+               return -ENODEV;
+
+       for (i = 0; pci_tbl[i].vendor != 0; i++) {
+               if (fbd_dev->vendor == pci_tbl[i].vendor &&
+                   fbd_dev->device == pci_tbl[i].device) {
+                       break;
+               }
+       }
+       if (pci_tbl[i].vendor == 0)
+               return -ENODEV;
+
+       ioat_dev = pci_get_bus_and_slot(IOAT_BUS, IOAT_DEVFN);
+       if (!ioat_dev)
+               return -ENODEV;
+
+       for (i = 0; fbd_ioat_list[i].vendor != 0; i++) {
+               if (ioat_dev->vendor == fbd_ioat_list[i].vendor &&
+                   ioat_dev->device == fbd_ioat_list[i].ioat_dev) {
+                       return 0;
+               }
+       }
+       return -ENODEV;
+}
+
+int stats_open_generic(struct inode *inode, struct file *fp)
+{
+       fp->private_data = inode->i_private;
+       return 0;
+}
+
+static ssize_t stats_read_ul(struct file *fp, char __user *ubuf, size_t count,
+                               loff_t *off)
+{
+       unsigned long *p = fp->private_data;
+       char buf[32];
+       int len;
+
+       len = snprintf(buf, 32, "%lu\n", *p);
+       return simple_read_from_buffer(ubuf, count, off, buf, len);
+}
+
+static const struct file_operations idle_fops = {
+       .open   = stats_open_generic,
+       .read   = stats_read_ul,
+};
+
+struct debugfs_file_info {
+       void *ptr;
+       char name[32];
+       struct dentry *file;
+} debugfs_file_list[] = {
+                               {&total_starts, "total_starts", NULL},
+                               {&total_us, "total_us", NULL},
+#ifdef DEBUG
+                               {&past_skip, "past_skip", NULL},
+#endif
+                               {NULL, "", NULL}
+                       };
+
+static int __init i7300_idle_init(void)
+{
+       spin_lock_init(&i7300_idle_lock);
+       cpus_clear(idle_cpumask);
+       total_us = 0;
+
+       if (i7300_idle_platform_probe())
+               return -ENODEV;
+
+       if (i7300_idle_thrt_save())
+               return -ENODEV;
+
+       if (i7300_idle_ioat_init())
+               return -ENODEV;
+
+       debugfs_dir = debugfs_create_dir("i7300_idle", NULL);
+       if (debugfs_dir) {
+               int i = 0;
+
+               while (debugfs_file_list[i].ptr != NULL) {
+                       debugfs_file_list[i].file = debugfs_create_file(
+                                       debugfs_file_list[i].name,
+                                       S_IRUSR,
+                                       debugfs_dir,
+                                       debugfs_file_list[i].ptr,
+                                       &idle_fops);
+                       i++;
+               }
+       }
+
+       idle_notifier_register(&i7300_idle_nb);
+
+       printk(KERN_INFO "i7300_idle: loaded v%s\n", I7300_IDLE_DRIVER_VERSION);
+       return 0;
+}
+
+static void __exit i7300_idle_exit(void)
+{
+       idle_notifier_unregister(&i7300_idle_nb);
+
+       if (debugfs_dir) {
+               int i = 0;
+
+               while (debugfs_file_list[i].file != NULL) {
+                       debugfs_remove(debugfs_file_list[i].file);
+                       i++;
+               }
+
+               debugfs_remove(debugfs_dir);
+       }
+       i7300_idle_thrt_restore();
+       i7300_idle_ioat_exit();
+}
+
+module_init(i7300_idle_init);
+module_exit(i7300_idle_exit);
+
+MODULE_AUTHOR("Andy Henroid <andrew.d.henroid@intel.com>");
+MODULE_DESCRIPTION("Intel Chipset DIMM Idle Power Saving Driver v"
+                       I7300_IDLE_DRIVER_VERSION);
+MODULE_LICENSE("GPL");
index 49c45feccd5b4148d2e73afff3c846185b9ed75b..5c54fc2350be4f6fede141ef78575166b9c2495f 100644 (file)
@@ -406,19 +406,15 @@ static int register_snoop_agent(struct ib_mad_qp_info *qp_info,
 
        if (i == qp_info->snoop_table_size) {
                /* Grow table. */
-               new_snoop_table = kmalloc(sizeof mad_snoop_priv *
-                                         qp_info->snoop_table_size + 1,
-                                         GFP_ATOMIC);
+               new_snoop_table = krealloc(qp_info->snoop_table,
+                                          sizeof mad_snoop_priv *
+                                          (qp_info->snoop_table_size + 1),
+                                          GFP_ATOMIC);
                if (!new_snoop_table) {
                        i = -ENOMEM;
                        goto out;
                }
-               if (qp_info->snoop_table) {
-                       memcpy(new_snoop_table, qp_info->snoop_table,
-                              sizeof mad_snoop_priv *
-                              qp_info->snoop_table_size);
-                       kfree(qp_info->snoop_table);
-               }
+
                qp_info->snoop_table = new_snoop_table;
                qp_info->snoop_table_size++;
        }
index 3ddacf39b7ba50e1d9de4378ca2544b7637488fc..4346a24568fb74746a74a12b2b1f534f23f1731f 100644 (file)
@@ -904,8 +904,8 @@ static ssize_t ucma_join_multicast(struct ucma_file *file,
 
        mutex_lock(&file->mut);
        mc = ucma_alloc_multicast(ctx);
-       if (IS_ERR(mc)) {
-               ret = PTR_ERR(mc);
+       if (!mc) {
+               ret = -ENOMEM;
                goto err1;
        }
 
index c325c44807e8226b1744796a7463e6aab384e950..44e936e48a313d023964459ce36b0cf7c4b668d9 100644 (file)
@@ -1942,6 +1942,7 @@ fail4:
 fail3:
        cxgb3_free_atid(ep->com.tdev, ep->atid);
 fail2:
+       cm_id->rem_ref(cm_id);
        put_ep(&ep->com);
 out:
        return err;
index 5d7b7855afb9d2c8fe9178e11d9dcf60cc41096d..4df887af66a527156a4ad9688e319bb308f36ebc 100644 (file)
@@ -128,6 +128,8 @@ struct ehca_shca {
        /* MR pgsize: bit 0-3 means 4K, 64K, 1M, 16M respectively */
        u32 hca_cap_mr_pgsize;
        int max_mtu;
+       int max_num_qps;
+       int max_num_cqs;
        atomic_t num_cqs;
        atomic_t num_qps;
 };
index 33647a95eb9a03f1ff5a47c760fb6d3fc5c2d483..2f4c28a30271694f0d62c5add9b625716e027e4c 100644 (file)
@@ -132,9 +132,9 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
        if (cqe >= 0xFFFFFFFF - 64 - additional_cqe)
                return ERR_PTR(-EINVAL);
 
-       if (!atomic_add_unless(&shca->num_cqs, 1, ehca_max_cq)) {
+       if (!atomic_add_unless(&shca->num_cqs, 1, shca->max_num_cqs)) {
                ehca_err(device, "Unable to create CQ, max number of %i "
-                       "CQs reached.", ehca_max_cq);
+                       "CQs reached.", shca->max_num_cqs);
                ehca_err(device, "To increase the maximum number of CQs "
                        "use the number_of_cqs module parameter.\n");
                return ERR_PTR(-ENOSPC);
index 598844d2edc93131a0cd1c9264035e1651f2097a..bb02a86aa5269d7b3c22a85aa23d1caaf0411e7e 100644 (file)
@@ -44,6 +44,8 @@
 #include <linux/slab.h>
 #endif
 
+#include <linux/notifier.h>
+#include <linux/memory.h>
 #include "ehca_classes.h"
 #include "ehca_iverbs.h"
 #include "ehca_mrmw.h"
@@ -366,22 +368,23 @@ static int ehca_sense_attributes(struct ehca_shca *shca)
                        shca->hca_cap_mr_pgsize |= pgsize_map[i + 1];
 
        /* Set maximum number of CQs and QPs to calculate EQ size */
-       if (ehca_max_qp == -1)
-               ehca_max_qp = min_t(int, rblock->max_qp, EHCA_MAX_NUM_QUEUES);
-       else if (ehca_max_qp < 1 || ehca_max_qp > rblock->max_qp) {
-               ehca_gen_err("Requested number of QPs is out of range (1 - %i) "
-                       "specified by HW", rblock->max_qp);
-               ret = -EINVAL;
-               goto sense_attributes1;
+       if (shca->max_num_qps == -1)
+               shca->max_num_qps = min_t(int, rblock->max_qp,
+                                         EHCA_MAX_NUM_QUEUES);
+       else if (shca->max_num_qps < 1 || shca->max_num_qps > rblock->max_qp) {
+               ehca_gen_warn("The requested number of QPs is out of range "
+                             "(1 - %i) specified by HW. Value is set to %i",
+                             rblock->max_qp, rblock->max_qp);
+               shca->max_num_qps = rblock->max_qp;
        }
 
-       if (ehca_max_cq == -1)
-               ehca_max_cq = min_t(int, rblock->max_cq, EHCA_MAX_NUM_QUEUES);
-       else if (ehca_max_cq < 1 || ehca_max_cq > rblock->max_cq) {
-               ehca_gen_err("Requested number of CQs is out of range (1 - %i) "
-                       "specified by HW", rblock->max_cq);
-               ret = -EINVAL;
-               goto sense_attributes1;
+       if (shca->max_num_cqs == -1)
+               shca->max_num_cqs = min_t(int, rblock->max_cq,
+                                         EHCA_MAX_NUM_QUEUES);
+       else if (shca->max_num_cqs < 1 || shca->max_num_cqs > rblock->max_cq) {
+               ehca_gen_warn("The requested number of CQs is out of range "
+                             "(1 - %i) specified by HW. Value is set to %i",
+                             rblock->max_cq, rblock->max_cq);
        }
 
        /* query max MTU from first port -- it's the same for all ports */
@@ -733,9 +736,13 @@ static int __devinit ehca_probe(struct of_device *dev,
                ehca_gen_err("Cannot allocate shca memory.");
                return -ENOMEM;
        }
+
        mutex_init(&shca->modify_mutex);
        atomic_set(&shca->num_cqs, 0);
        atomic_set(&shca->num_qps, 0);
+       shca->max_num_qps = ehca_max_qp;
+       shca->max_num_cqs = ehca_max_cq;
+
        for (i = 0; i < ARRAY_SIZE(shca->sport); i++)
                spin_lock_init(&shca->sport[i].mod_sqp_lock);
 
@@ -755,7 +762,7 @@ static int __devinit ehca_probe(struct of_device *dev,
                goto probe1;
        }
 
-       eq_size = 2 * ehca_max_cq + 4 * ehca_max_qp;
+       eq_size = 2 * shca->max_num_cqs + 4 * shca->max_num_qps;
        /* create event queues */
        ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, eq_size);
        if (ret) {
@@ -964,6 +971,41 @@ void ehca_poll_eqs(unsigned long data)
        spin_unlock(&shca_list_lock);
 }
 
+static int ehca_mem_notifier(struct notifier_block *nb,
+                            unsigned long action, void *data)
+{
+       static unsigned long ehca_dmem_warn_time;
+
+       switch (action) {
+       case MEM_CANCEL_OFFLINE:
+       case MEM_CANCEL_ONLINE:
+       case MEM_ONLINE:
+       case MEM_OFFLINE:
+               return NOTIFY_OK;
+       case MEM_GOING_ONLINE:
+       case MEM_GOING_OFFLINE:
+               /* only ok if no hca is attached to the lpar */
+               spin_lock(&shca_list_lock);
+               if (list_empty(&shca_list)) {
+                       spin_unlock(&shca_list_lock);
+                       return NOTIFY_OK;
+               } else {
+                       spin_unlock(&shca_list_lock);
+                       if (printk_timed_ratelimit(&ehca_dmem_warn_time,
+                                                  30 * 1000))
+                               ehca_gen_err("DMEM operations are not allowed"
+                                            "as long as an ehca adapter is"
+                                            "attached to the LPAR");
+                       return NOTIFY_BAD;
+               }
+       }
+       return NOTIFY_OK;
+}
+
+static struct notifier_block ehca_mem_nb = {
+       .notifier_call = ehca_mem_notifier,
+};
+
 static int __init ehca_module_init(void)
 {
        int ret;
@@ -991,6 +1033,12 @@ static int __init ehca_module_init(void)
                goto module_init2;
        }
 
+       ret = register_memory_notifier(&ehca_mem_nb);
+       if (ret) {
+               ehca_gen_err("Failed registering memory add/remove notifier");
+               goto module_init3;
+       }
+
        if (ehca_poll_all_eqs != 1) {
                ehca_gen_err("WARNING!!!");
                ehca_gen_err("It is possible to lose interrupts.");
@@ -1003,6 +1051,9 @@ static int __init ehca_module_init(void)
 
        return 0;
 
+module_init3:
+       ibmebus_unregister_driver(&ehca_driver);
+
 module_init2:
        ehca_destroy_slab_caches();
 
@@ -1018,6 +1069,8 @@ static void __exit ehca_module_exit(void)
 
        ibmebus_unregister_driver(&ehca_driver);
 
+       unregister_memory_notifier(&ehca_mem_nb);
+
        ehca_destroy_slab_caches();
 
        ehca_destroy_comp_pool();
index 4dbe2870e0145fac40e3e31e3d8a01298fa10f17..4d54b9f6456789cb17fa07e93481cebb322b2d81 100644 (file)
@@ -465,9 +465,9 @@ static struct ehca_qp *internal_create_qp(
        u32 swqe_size = 0, rwqe_size = 0, ib_qp_num;
        unsigned long flags;
 
-       if (!atomic_add_unless(&shca->num_qps, 1, ehca_max_qp)) {
+       if (!atomic_add_unless(&shca->num_qps, 1, shca->max_num_qps)) {
                ehca_err(pd->device, "Unable to create QP, max number of %i "
-                        "QPs reached.", ehca_max_qp);
+                        "QPs reached.", shca->max_num_qps);
                ehca_err(pd->device, "To increase the maximum number of QPs "
                         "use the number_of_qps module parameter.\n");
                return ERR_PTR(-ENOSPC);
@@ -502,6 +502,12 @@ static struct ehca_qp *internal_create_qp(
        if (init_attr->srq) {
                my_srq = container_of(init_attr->srq, struct ehca_qp, ib_srq);
 
+               if (qp_type == IB_QPT_UC) {
+                       ehca_err(pd->device, "UC with SRQ not supported");
+                       atomic_dec(&shca->num_qps);
+                       return ERR_PTR(-EINVAL);
+               }
+
                has_srq = 1;
                parms.ext_type = EQPT_SRQBASE;
                parms.srq_qpn = my_srq->real_qp_num;
index cdca3a511e1c793dd6056ac3956e2e6ca9dc09d1..606f1e2ef28419178bda9407dacccf94752860e0 100644 (file)
@@ -298,7 +298,7 @@ int mlx4_ib_mad_init(struct mlx4_ib_dev *dev)
        int p, q;
        int ret;
 
-       for (p = 0; p < dev->dev->caps.num_ports; ++p)
+       for (p = 0; p < dev->num_ports; ++p)
                for (q = 0; q <= 1; ++q) {
                        agent = ib_register_mad_agent(&dev->ib_dev, p + 1,
                                                      q ? IB_QPT_GSI : IB_QPT_SMI,
@@ -314,7 +314,7 @@ int mlx4_ib_mad_init(struct mlx4_ib_dev *dev)
        return 0;
 
 err:
-       for (p = 0; p < dev->dev->caps.num_ports; ++p)
+       for (p = 0; p < dev->num_ports; ++p)
                for (q = 0; q <= 1; ++q)
                        if (dev->send_agent[p][q])
                                ib_unregister_mad_agent(dev->send_agent[p][q]);
@@ -327,7 +327,7 @@ void mlx4_ib_mad_cleanup(struct mlx4_ib_dev *dev)
        struct ib_mad_agent *agent;
        int p, q;
 
-       for (p = 0; p < dev->dev->caps.num_ports; ++p) {
+       for (p = 0; p < dev->num_ports; ++p) {
                for (q = 0; q <= 1; ++q) {
                        agent = dev->send_agent[p][q];
                        dev->send_agent[p][q] = NULL;
index a3c2851c0545dcaf44eab62e9e7e4ed0bf4674e4..2e80f8f47b02ad1fbc0fc1d3fe9ae3bf24313f5a 100644 (file)
@@ -574,7 +574,10 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
        ibdev->ib_dev.owner             = THIS_MODULE;
        ibdev->ib_dev.node_type         = RDMA_NODE_IB_CA;
        ibdev->ib_dev.local_dma_lkey    = dev->caps.reserved_lkey;
-       ibdev->ib_dev.phys_port_cnt     = dev->caps.num_ports;
+       ibdev->num_ports = 0;
+       mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB)
+               ibdev->num_ports++;
+       ibdev->ib_dev.phys_port_cnt     = ibdev->num_ports;
        ibdev->ib_dev.num_comp_vectors  = 1;
        ibdev->ib_dev.dma_device        = &dev->pdev->dev;
 
@@ -691,7 +694,7 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr)
        struct mlx4_ib_dev *ibdev = ibdev_ptr;
        int p;
 
-       for (p = 1; p <= dev->caps.num_ports; ++p)
+       for (p = 1; p <= ibdev->num_ports; ++p)
                mlx4_CLOSE_PORT(dev, p);
 
        mlx4_ib_mad_cleanup(ibdev);
@@ -706,6 +709,10 @@ static void mlx4_ib_event(struct mlx4_dev *dev, void *ibdev_ptr,
                          enum mlx4_dev_event event, int port)
 {
        struct ib_event ibev;
+       struct mlx4_ib_dev *ibdev = to_mdev((struct ib_device *) ibdev_ptr);
+
+       if (port > ibdev->num_ports)
+               return;
 
        switch (event) {
        case MLX4_DEV_EVENT_PORT_UP:
index 6e2b0dc21b614dd2b89171c1de04bc6cb133de90..9974e886b8dec23e7789be0889cbbc658e97c51b 100644 (file)
@@ -162,6 +162,7 @@ struct mlx4_ib_ah {
 struct mlx4_ib_dev {
        struct ib_device        ib_dev;
        struct mlx4_dev        *dev;
+       int                     num_ports;
        void __iomem           *uar_map;
 
        struct mlx4_uar         priv_uar;
index baa01deb2436eb5e453a7784c867a3c7105f97d7..39167a797f99f554b7a54ef94f989663811152e7 100644 (file)
@@ -451,6 +451,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
                            struct ib_qp_init_attr *init_attr,
                            struct ib_udata *udata, int sqpn, struct mlx4_ib_qp *qp)
 {
+       int qpn;
        int err;
 
        mutex_init(&qp->mutex);
@@ -545,9 +546,17 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
                }
        }
 
-       err = mlx4_qp_alloc(dev->dev, sqpn, &qp->mqp);
+       if (sqpn) {
+               qpn = sqpn;
+       } else {
+               err = mlx4_qp_reserve_range(dev->dev, 1, 1, &qpn);
+               if (err)
+                       goto err_wrid;
+       }
+
+       err = mlx4_qp_alloc(dev->dev, qpn, &qp->mqp);
        if (err)
-               goto err_wrid;
+               goto err_qpn;
 
        /*
         * Hardware wants QPN written in big-endian order (after
@@ -560,6 +569,10 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
 
        return 0;
 
+err_qpn:
+       if (!sqpn)
+               mlx4_qp_release_range(dev->dev, qpn, 1);
+
 err_wrid:
        if (pd->uobject) {
                if (!init_attr->srq)
@@ -655,6 +668,10 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp,
        mlx4_ib_unlock_cqs(send_cq, recv_cq);
 
        mlx4_qp_free(dev->dev, &qp->mqp);
+
+       if (!is_sqp(dev, qp))
+               mlx4_qp_release_range(dev->dev, qp->mqp.qpn, 1);
+
        mlx4_mtt_cleanup(dev->dev, &qp->mtt);
 
        if (is_user) {
index 68ba5c3482e47097b50998db96dc8941b37363d2..e0c7dfabf2b4e6d6f13abab65ffcc4d11dffefcb 100644 (file)
@@ -507,6 +507,7 @@ int ipoib_pkey_dev_delay_open(struct net_device *dev);
 void ipoib_drain_cq(struct net_device *dev);
 
 void ipoib_set_ethtool_ops(struct net_device *dev);
+int ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca);
 
 #ifdef CONFIG_INFINIBAND_IPOIB_CM
 
index 66af5c1a76e525ec059fd5313bf772c2da8b0a0b..e9795f60e5d684d12afd707d8b07c46ad28260a1 100644 (file)
@@ -42,6 +42,13 @@ static void ipoib_get_drvinfo(struct net_device *netdev,
        strncpy(drvinfo->driver, "ipoib", sizeof(drvinfo->driver) - 1);
 }
 
+static u32 ipoib_get_rx_csum(struct net_device *dev)
+{
+       struct ipoib_dev_priv *priv = netdev_priv(dev);
+       return test_bit(IPOIB_FLAG_CSUM, &priv->flags) &&
+               !test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
+}
+
 static int ipoib_get_coalesce(struct net_device *dev,
                              struct ethtool_coalesce *coal)
 {
@@ -129,7 +136,7 @@ static void ipoib_get_ethtool_stats(struct net_device *dev,
 
 static const struct ethtool_ops ipoib_ethtool_ops = {
        .get_drvinfo            = ipoib_get_drvinfo,
-       .get_tso                = ethtool_op_get_tso,
+       .get_rx_csum            = ipoib_get_rx_csum,
        .get_coalesce           = ipoib_get_coalesce,
        .set_coalesce           = ipoib_set_coalesce,
        .get_flags              = ethtool_op_get_flags,
index 0e748aeeae99fe830eb3c9e1c1e8bd96461ba30a..28eb6f03c588987c1c417377205e53b34b2f5058 100644 (file)
@@ -685,10 +685,6 @@ int ipoib_ib_dev_open(struct net_device *dev)
        queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task,
                           round_jiffies_relative(HZ));
 
-       init_timer(&priv->poll_timer);
-       priv->poll_timer.function = ipoib_ib_tx_timer_func;
-       priv->poll_timer.data = (unsigned long)dev;
-
        set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
 
        return 0;
@@ -906,6 +902,9 @@ int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
                return -ENODEV;
        }
 
+       setup_timer(&priv->poll_timer, ipoib_ib_tx_timer_func,
+                   (unsigned long) dev);
+
        if (dev->flags & IFF_UP) {
                if (ipoib_ib_dev_open(dev)) {
                        ipoib_transport_dev_cleanup(dev);
index c0ee514396dfa7a18842d0503d2c01641661d261..fddded7900d1c3df5589f9090d238238e92ad72c 100644 (file)
@@ -1173,11 +1173,48 @@ int ipoib_add_pkey_attr(struct net_device *dev)
        return device_create_file(&dev->dev, &dev_attr_pkey);
 }
 
+int ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca)
+{
+       struct ib_device_attr *device_attr;
+       int result = -ENOMEM;
+
+       device_attr = kmalloc(sizeof *device_attr, GFP_KERNEL);
+       if (!device_attr) {
+               printk(KERN_WARNING "%s: allocation of %zu bytes failed\n",
+                      hca->name, sizeof *device_attr);
+               return result;
+       }
+
+       result = ib_query_device(hca, device_attr);
+       if (result) {
+               printk(KERN_WARNING "%s: ib_query_device failed (ret = %d)\n",
+                      hca->name, result);
+               kfree(device_attr);
+               return result;
+       }
+       priv->hca_caps = device_attr->device_cap_flags;
+
+       kfree(device_attr);
+
+       if (priv->hca_caps & IB_DEVICE_UD_IP_CSUM) {
+               set_bit(IPOIB_FLAG_CSUM, &priv->flags);
+               priv->dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+       }
+
+       if (lro)
+               priv->dev->features |= NETIF_F_LRO;
+
+       if (priv->dev->features & NETIF_F_SG && priv->hca_caps & IB_DEVICE_UD_TSO)
+               priv->dev->features |= NETIF_F_TSO;
+
+       return 0;
+}
+
+
 static struct net_device *ipoib_add_port(const char *format,
                                         struct ib_device *hca, u8 port)
 {
        struct ipoib_dev_priv *priv;
-       struct ib_device_attr *device_attr;
        struct ib_port_attr attr;
        int result = -ENOMEM;
 
@@ -1206,31 +1243,8 @@ static struct net_device *ipoib_add_port(const char *format,
                goto device_init_failed;
        }
 
-       device_attr = kmalloc(sizeof *device_attr, GFP_KERNEL);
-       if (!device_attr) {
-               printk(KERN_WARNING "%s: allocation of %zu bytes failed\n",
-                      hca->name, sizeof *device_attr);
+       if (ipoib_set_dev_features(priv, hca))
                goto device_init_failed;
-       }
-
-       result = ib_query_device(hca, device_attr);
-       if (result) {
-               printk(KERN_WARNING "%s: ib_query_device failed (ret = %d)\n",
-                      hca->name, result);
-               kfree(device_attr);
-               goto device_init_failed;
-       }
-       priv->hca_caps = device_attr->device_cap_flags;
-
-       kfree(device_attr);
-
-       if (priv->hca_caps & IB_DEVICE_UD_IP_CSUM) {
-               set_bit(IPOIB_FLAG_CSUM, &priv->flags);
-               priv->dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-       }
-
-       if (lro)
-               priv->dev->features |= NETIF_F_LRO;
 
        /*
         * Set the full membership bit, so that we join the right
@@ -1266,9 +1280,6 @@ static struct net_device *ipoib_add_port(const char *format,
                goto event_failed;
        }
 
-       if (priv->dev->features & NETIF_F_SG && priv->hca_caps & IB_DEVICE_UD_TSO)
-               priv->dev->features |= NETIF_F_TSO;
-
        result = register_netdev(priv->dev);
        if (result) {
                printk(KERN_WARNING "%s: couldn't register ipoib port %d; error %d\n",
index b08eb56196d301eb9ecd34797286339669f47890..2cf1a40887180dec32e63a38bf173c0116646790 100644 (file)
@@ -93,6 +93,10 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
        priv->mcast_mtu  = priv->admin_mtu = priv->dev->mtu;
        set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags);
 
+       result = ipoib_set_dev_features(priv, ppriv->ca);
+       if (result)
+               goto device_init_failed;
+
        priv->pkey = pkey;
 
        memcpy(priv->dev->dev_addr, ppriv->dev->dev_addr, INFINIBAND_ALEN);
index 8317fdef1691c0bb4c564116c8b27c75e24b561e..3d1ab8fa9accb88e341f4d66748c7cf0b09db3f0 100644 (file)
@@ -42,8 +42,9 @@ config TOUCHSCREEN_BITSY
          module will be called h3600_ts_input.
 
 config TOUCHSCREEN_CORGI
-       tristate "SharpSL (Corgi and Spitz series) touchscreen driver"
+       tristate "SharpSL (Corgi and Spitz series) touchscreen driver (DEPRECATED)"
        depends on PXA_SHARPSL
+       select CORGI_SSP_DEPRECATED
        default y
        help
          Say Y here to enable the driver for the touchscreen on the
@@ -54,6 +55,9 @@ config TOUCHSCREEN_CORGI
          To compile this driver as a module, choose M here: the
          module will be called corgi_ts.
 
+         NOTE: this driver is deprecated, try enable SPI and generic
+         ADS7846-based touchscreen driver.
+
 config TOUCHSCREEN_FUJITSU
        tristate "Fujitsu serial touchscreen"
        select SERIO
index 33ff1cbeebd9d2abca58db89913ac3ae7841fe72..e7fb7d2fcbfc4792abc91993337620a562a3323c 100644 (file)
@@ -187,7 +187,7 @@ config LEDS_TRIGGER_TIMER
 
 config LEDS_TRIGGER_IDE_DISK
        bool "LED IDE Disk Trigger"
-       depends on LEDS_TRIGGERS && BLK_DEV_IDEDISK
+       depends on LEDS_TRIGGERS && IDE_GD_ATA
        help
          This allows LEDs to be controlled by IDE disk activity.
          If unsure, say Y.
index f1ef33dfd8cf42bafc5debb9b53464107245f202..1c615804ea76180f5bf2b32c07d7e62bc96d8c67 100644 (file)
@@ -34,7 +34,7 @@ obj-$(CONFIG_DM_CRYPT)                += dm-crypt.o
 obj-$(CONFIG_DM_DELAY)         += dm-delay.o
 obj-$(CONFIG_DM_MULTIPATH)     += dm-multipath.o dm-round-robin.o
 obj-$(CONFIG_DM_SNAPSHOT)      += dm-snapshot.o
-obj-$(CONFIG_DM_MIRROR)                += dm-mirror.o dm-log.o
+obj-$(CONFIG_DM_MIRROR)                += dm-mirror.o dm-log.o dm-region-hash.o
 obj-$(CONFIG_DM_ZERO)          += dm-zero.o
 
 quiet_cmd_unroll = UNROLL  $@
index 682ef9e6acd3344d5bf8a19f4550de90331f37d3..ce26c84af064339f196a0a2eb62b0c55866408b2 100644 (file)
@@ -23,7 +23,7 @@
 #include <asm/page.h>
 #include <asm/unaligned.h>
 
-#include "dm.h"
+#include <linux/device-mapper.h>
 
 #define DM_MSG_PREFIX "crypt"
 #define MESG_STR(x) x, sizeof(x)
@@ -56,6 +56,7 @@ struct dm_crypt_io {
        atomic_t pending;
        int error;
        sector_t sector;
+       struct dm_crypt_io *base_io;
 };
 
 struct dm_crypt_request {
@@ -93,7 +94,6 @@ struct crypt_config {
 
        struct workqueue_struct *io_queue;
        struct workqueue_struct *crypt_queue;
-       wait_queue_head_t writeq;
 
        /*
         * crypto related data
@@ -534,6 +534,7 @@ static struct dm_crypt_io *crypt_io_alloc(struct dm_target *ti,
        io->base_bio = bio;
        io->sector = sector;
        io->error = 0;
+       io->base_io = NULL;
        atomic_set(&io->pending, 0);
 
        return io;
@@ -547,6 +548,7 @@ static void crypt_inc_pending(struct dm_crypt_io *io)
 /*
  * One of the bios was finished. Check for completion of
  * the whole request and correctly clean up the buffer.
+ * If base_io is set, wait for the last fragment to complete.
  */
 static void crypt_dec_pending(struct dm_crypt_io *io)
 {
@@ -555,7 +557,14 @@ static void crypt_dec_pending(struct dm_crypt_io *io)
        if (!atomic_dec_and_test(&io->pending))
                return;
 
-       bio_endio(io->base_bio, io->error);
+       if (likely(!io->base_io))
+               bio_endio(io->base_bio, io->error);
+       else {
+               if (io->error && !io->base_io->error)
+                       io->base_io->error = io->error;
+               crypt_dec_pending(io->base_io);
+       }
+
        mempool_free(io, cc->io_pool);
 }
 
@@ -646,10 +655,7 @@ static void kcryptd_io_read(struct dm_crypt_io *io)
 static void kcryptd_io_write(struct dm_crypt_io *io)
 {
        struct bio *clone = io->ctx.bio_out;
-       struct crypt_config *cc = io->target->private;
-
        generic_make_request(clone);
-       wake_up(&cc->writeq);
 }
 
 static void kcryptd_io(struct work_struct *work)
@@ -688,7 +694,6 @@ static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io,
        BUG_ON(io->ctx.idx_out < clone->bi_vcnt);
 
        clone->bi_sector = cc->start + io->sector;
-       io->sector += bio_sectors(clone);
 
        if (async)
                kcryptd_queue_io(io);
@@ -700,16 +705,18 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
 {
        struct crypt_config *cc = io->target->private;
        struct bio *clone;
+       struct dm_crypt_io *new_io;
        int crypt_finished;
        unsigned out_of_pages = 0;
        unsigned remaining = io->base_bio->bi_size;
+       sector_t sector = io->sector;
        int r;
 
        /*
         * Prevent io from disappearing until this function completes.
         */
        crypt_inc_pending(io);
-       crypt_convert_init(cc, &io->ctx, NULL, io->base_bio, io->sector);
+       crypt_convert_init(cc, &io->ctx, NULL, io->base_bio, sector);
 
        /*
         * The allocated buffers can be smaller than the whole bio,
@@ -726,6 +733,7 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
                io->ctx.idx_out = 0;
 
                remaining -= clone->bi_size;
+               sector += bio_sectors(clone);
 
                crypt_inc_pending(io);
                r = crypt_convert(cc, &io->ctx);
@@ -741,6 +749,8 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
                         */
                        if (unlikely(r < 0))
                                break;
+
+                       io->sector = sector;
                }
 
                /*
@@ -750,8 +760,33 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
                if (unlikely(out_of_pages))
                        congestion_wait(WRITE, HZ/100);
 
-               if (unlikely(remaining))
-                       wait_event(cc->writeq, !atomic_read(&io->ctx.pending));
+               /*
+                * With async crypto it is unsafe to share the crypto context
+                * between fragments, so switch to a new dm_crypt_io structure.
+                */
+               if (unlikely(!crypt_finished && remaining)) {
+                       new_io = crypt_io_alloc(io->target, io->base_bio,
+                                               sector);
+                       crypt_inc_pending(new_io);
+                       crypt_convert_init(cc, &new_io->ctx, NULL,
+                                          io->base_bio, sector);
+                       new_io->ctx.idx_in = io->ctx.idx_in;
+                       new_io->ctx.offset_in = io->ctx.offset_in;
+
+                       /*
+                        * Fragments after the first use the base_io
+                        * pending count.
+                        */
+                       if (!io->base_io)
+                               new_io->base_io = io;
+                       else {
+                               new_io->base_io = io->base_io;
+                               crypt_inc_pending(io->base_io);
+                               crypt_dec_pending(io);
+                       }
+
+                       io = new_io;
+               }
        }
 
        crypt_dec_pending(io);
@@ -1078,7 +1113,6 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
                goto bad_crypt_queue;
        }
 
-       init_waitqueue_head(&cc->writeq);
        ti->private = cc;
        return 0;
 
index bdd37f881c42ab757cb381514db10d4d232b854e..848b381f11732c626161ecc8f8c06e5d82927a07 100644 (file)
@@ -13,7 +13,8 @@
 #include <linux/bio.h>
 #include <linux/slab.h>
 
-#include "dm.h"
+#include <linux/device-mapper.h>
+
 #include "dm-bio-list.h"
 
 #define DM_MSG_PREFIX "delay"
index 769ab677f8e05a4b3887093be5e98e0cf9cd4125..01590f3e00093ffd25e9fe0aa6e70d1472e607f4 100644 (file)
@@ -7,7 +7,6 @@
  * This file is released under the GPL.
  */
 
-#include "dm.h"
 #include "dm-snap.h"
 
 #include <linux/mm.h>
@@ -104,6 +103,11 @@ struct pstore {
         */
        void *area;
 
+       /*
+        * An area of zeros used to clear the next area.
+        */
+       void *zero_area;
+
        /*
         * Used to keep track of which metadata area the data in
         * 'chunk' refers to.
@@ -149,6 +153,13 @@ static int alloc_area(struct pstore *ps)
        if (!ps->area)
                return r;
 
+       ps->zero_area = vmalloc(len);
+       if (!ps->zero_area) {
+               vfree(ps->area);
+               return r;
+       }
+       memset(ps->zero_area, 0, len);
+
        return 0;
 }
 
@@ -156,6 +167,8 @@ static void free_area(struct pstore *ps)
 {
        vfree(ps->area);
        ps->area = NULL;
+       vfree(ps->zero_area);
+       ps->zero_area = NULL;
 }
 
 struct mdata_req {
@@ -220,25 +233,41 @@ static chunk_t area_location(struct pstore *ps, chunk_t area)
  * Read or write a metadata area.  Remembering to skip the first
  * chunk which holds the header.
  */
-static int area_io(struct pstore *ps, chunk_t area, int rw)
+static int area_io(struct pstore *ps, int rw)
 {
        int r;
        chunk_t chunk;
 
-       chunk = area_location(ps, area);
+       chunk = area_location(ps, ps->current_area);
 
        r = chunk_io(ps, chunk, rw, 0);
        if (r)
                return r;
 
-       ps->current_area = area;
        return 0;
 }
 
-static int zero_area(struct pstore *ps, chunk_t area)
+static void zero_memory_area(struct pstore *ps)
 {
        memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT);
-       return area_io(ps, area, WRITE);
+}
+
+static int zero_disk_area(struct pstore *ps, chunk_t area)
+{
+       struct dm_io_region where = {
+               .bdev = ps->snap->cow->bdev,
+               .sector = ps->snap->chunk_size * area_location(ps, area),
+               .count = ps->snap->chunk_size,
+       };
+       struct dm_io_request io_req = {
+               .bi_rw = WRITE,
+               .mem.type = DM_IO_VMA,
+               .mem.ptr.vma = ps->zero_area,
+               .client = ps->io_client,
+               .notify.fn = NULL,
+       };
+
+       return dm_io(&io_req, 1, &where, NULL);
 }
 
 static int read_header(struct pstore *ps, int *new_snapshot)
@@ -411,15 +440,14 @@ static int insert_exceptions(struct pstore *ps, int *full)
 
 static int read_exceptions(struct pstore *ps)
 {
-       chunk_t area;
        int r, full = 1;
 
        /*
         * Keeping reading chunks and inserting exceptions until
         * we find a partially full area.
         */
-       for (area = 0; full; area++) {
-               r = area_io(ps, area, READ);
+       for (ps->current_area = 0; full; ps->current_area++) {
+               r = area_io(ps, READ);
                if (r)
                        return r;
 
@@ -428,6 +456,8 @@ static int read_exceptions(struct pstore *ps)
                        return r;
        }
 
+       ps->current_area--;
+
        return 0;
 }
 
@@ -486,12 +516,13 @@ static int persistent_read_metadata(struct exception_store *store)
                        return r;
                }
 
-               r = zero_area(ps, 0);
+               ps->current_area = 0;
+               zero_memory_area(ps);
+               r = zero_disk_area(ps, 0);
                if (r) {
-                       DMWARN("zero_area(0) failed");
+                       DMWARN("zero_disk_area(0) failed");
                        return r;
                }
-
        } else {
                /*
                 * Sanity checks.
@@ -551,7 +582,6 @@ static void persistent_commit(struct exception_store *store,
                              void (*callback) (void *, int success),
                              void *callback_context)
 {
-       int r;
        unsigned int i;
        struct pstore *ps = get_info(store);
        struct disk_exception de;
@@ -572,33 +602,41 @@ static void persistent_commit(struct exception_store *store,
        cb->context = callback_context;
 
        /*
-        * If there are no more exceptions in flight, or we have
-        * filled this metadata area we commit the exceptions to
-        * disk.
+        * If there are exceptions in flight and we have not yet
+        * filled this metadata area there's nothing more to do.
         */
-       if (atomic_dec_and_test(&ps->pending_count) ||
-           (ps->current_committed == ps->exceptions_per_area)) {
-               r = area_io(ps, ps->current_area, WRITE);
-               if (r)
-                       ps->valid = 0;
+       if (!atomic_dec_and_test(&ps->pending_count) &&
+           (ps->current_committed != ps->exceptions_per_area))
+               return;
 
-               /*
-                * Have we completely filled the current area ?
-                */
-               if (ps->current_committed == ps->exceptions_per_area) {
-                       ps->current_committed = 0;
-                       r = zero_area(ps, ps->current_area + 1);
-                       if (r)
-                               ps->valid = 0;
-               }
+       /*
+        * If we completely filled the current area, then wipe the next one.
+        */
+       if ((ps->current_committed == ps->exceptions_per_area) &&
+            zero_disk_area(ps, ps->current_area + 1))
+               ps->valid = 0;
 
-               for (i = 0; i < ps->callback_count; i++) {
-                       cb = ps->callbacks + i;
-                       cb->callback(cb->context, r == 0 ? 1 : 0);
-               }
+       /*
+        * Commit exceptions to disk.
+        */
+       if (ps->valid && area_io(ps, WRITE))
+               ps->valid = 0;
 
-               ps->callback_count = 0;
+       /*
+        * Advance to the next area if this one is full.
+        */
+       if (ps->current_committed == ps->exceptions_per_area) {
+               ps->current_committed = 0;
+               ps->current_area++;
+               zero_memory_area(ps);
        }
+
+       for (i = 0; i < ps->callback_count; i++) {
+               cb = ps->callbacks + i;
+               cb->callback(cb->context, ps->valid);
+       }
+
+       ps->callback_count = 0;
 }
 
 static void persistent_drop(struct exception_store *store)
index 4789c42d9a3ac503d53ba6ea77fe7fadbee21682..2fd6d4450637943963d88c948080cf4f0ed73a92 100644 (file)
@@ -5,7 +5,7 @@
  * This file is released under the GPL.
  */
 
-#include "dm.h"
+#include <linux/device-mapper.h>
 
 #include <linux/bio.h>
 #include <linux/mempool.h>
index dca401dc70a0ec3f24c0392851a002a8a125fd21..777c948180f9ae9b956f803eb92c659cb12b2937 100644 (file)
@@ -988,9 +988,9 @@ static int dev_wait(struct dm_ioctl *param, size_t param_size)
        return r;
 }
 
-static inline int get_mode(struct dm_ioctl *param)
+static inline fmode_t get_mode(struct dm_ioctl *param)
 {
-       int mode = FMODE_READ | FMODE_WRITE;
+       fmode_t mode = FMODE_READ | FMODE_WRITE;
 
        if (param->flags & DM_READONLY_FLAG)
                mode = FMODE_READ;
index 996802b8a4522e50126365d070f21458f9b68be2..3073618269ea3030e468541ea2af6f05dd2aac65 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/vmalloc.h>
 #include <linux/workqueue.h>
 #include <linux/mutex.h>
+#include <linux/device-mapper.h>
 #include <linux/dm-kcopyd.h>
 
 #include "dm.h"
@@ -268,6 +269,17 @@ static void push(struct list_head *jobs, struct kcopyd_job *job)
        spin_unlock_irqrestore(&kc->job_lock, flags);
 }
 
+
+static void push_head(struct list_head *jobs, struct kcopyd_job *job)
+{
+       unsigned long flags;
+       struct dm_kcopyd_client *kc = job->kc;
+
+       spin_lock_irqsave(&kc->job_lock, flags);
+       list_add(&job->list, jobs);
+       spin_unlock_irqrestore(&kc->job_lock, flags);
+}
+
 /*
  * These three functions process 1 item from the corresponding
  * job list.
@@ -398,7 +410,7 @@ static int process_jobs(struct list_head *jobs, struct dm_kcopyd_client *kc,
                         * We couldn't service this job ATM, so
                         * push this job back onto the list.
                         */
-                       push(jobs, job);
+                       push_head(jobs, job);
                        break;
                }
 
index 6449bcdf84ca47465673223fa3a27f88c44684ce..44042becad8adea2e53af2af8bdf2589f070d91e 100644 (file)
@@ -5,12 +5,12 @@
  */
 
 #include "dm.h"
-
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/bio.h>
 #include <linux/slab.h>
+#include <linux/device-mapper.h>
 
 #define DM_MSG_PREFIX "linear"
 
@@ -110,20 +110,11 @@ static int linear_status(struct dm_target *ti, status_type_t type,
        return 0;
 }
 
-static int linear_ioctl(struct dm_target *ti, struct inode *inode,
-                       struct file *filp, unsigned int cmd,
+static int linear_ioctl(struct dm_target *ti, unsigned int cmd,
                        unsigned long arg)
 {
        struct linear_c *lc = (struct linear_c *) ti->private;
-       struct block_device *bdev = lc->dev->bdev;
-       struct file fake_file = {};
-       struct dentry fake_dentry = {};
-
-       fake_file.f_mode = lc->dev->mode;
-       fake_file.f_path.dentry = &fake_dentry;
-       fake_dentry.d_inode = bdev->bd_inode;
-
-       return blkdev_driver_ioctl(bdev->bd_inode, &fake_file, bdev->bd_disk, cmd, arg);
+       return __blkdev_driver_ioctl(lc->dev->bdev, lc->dev->mode, cmd, arg);
 }
 
 static int linear_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
index 5b48478c79f53037474579edf1930b4d103b160c..a8c0fc79ca78c18d52631bb3e27176ee68c4712f 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/dm-io.h>
 #include <linux/dm-dirty-log.h>
 
-#include "dm.h"
+#include <linux/device-mapper.h>
 
 #define DM_MSG_PREFIX "dirty region log"
 
index 9bf3460c5540b9fdbefbacaed15788f7a6868fb0..4840733cd9032c48a1253a8fae8ebdea2d4c09cd 100644 (file)
@@ -5,7 +5,8 @@
  * This file is released under the GPL.
  */
 
-#include "dm.h"
+#include <linux/device-mapper.h>
+
 #include "dm-path-selector.h"
 #include "dm-bio-list.h"
 #include "dm-bio-record.h"
@@ -1395,19 +1396,15 @@ error:
        return -EINVAL;
 }
 
-static int multipath_ioctl(struct dm_target *ti, struct inode *inode,
-                          struct file *filp, unsigned int cmd,
+static int multipath_ioctl(struct dm_target *ti, unsigned int cmd,
                           unsigned long arg)
 {
        struct multipath *m = (struct multipath *) ti->private;
        struct block_device *bdev = NULL;
+       fmode_t mode = 0;
        unsigned long flags;
-       struct file fake_file = {};
-       struct dentry fake_dentry = {};
        int r = 0;
 
-       fake_file.f_path.dentry = &fake_dentry;
-
        spin_lock_irqsave(&m->lock, flags);
 
        if (!m->current_pgpath)
@@ -1415,8 +1412,7 @@ static int multipath_ioctl(struct dm_target *ti, struct inode *inode,
 
        if (m->current_pgpath) {
                bdev = m->current_pgpath->path.dev->bdev;
-               fake_dentry.d_inode = bdev->bd_inode;
-               fake_file.f_mode = m->current_pgpath->path.dev->mode;
+               mode = m->current_pgpath->path.dev->mode;
        }
 
        if (m->queue_io)
@@ -1426,8 +1422,7 @@ static int multipath_ioctl(struct dm_target *ti, struct inode *inode,
 
        spin_unlock_irqrestore(&m->lock, flags);
 
-       return r ? : blkdev_driver_ioctl(bdev->bd_inode, &fake_file,
-                                        bdev->bd_disk, cmd, arg);
+       return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg);
 }
 
 /*-----------------------------------------------------------------
index ca1bb636a3e4ba808ae63d88dfbb62bc4ee28a04..96ea226155b10e3dbb560b3faa8c2211ec11f41f 100644 (file)
@@ -9,7 +9,8 @@
  * Path selector registration.
  */
 
-#include "dm.h"
+#include <linux/device-mapper.h>
+
 #include "dm-path-selector.h"
 
 #include <linux/slab.h>
index 29913e42c4ab436da84fc7fdf6e42da4fe051e49..92dcc06832a462a3210fbd521c323abce9b43cd0 100644 (file)
 /*
  * Copyright (C) 2003 Sistina Software Limited.
+ * Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
  *
  * This file is released under the GPL.
  */
 
-#include "dm.h"
 #include "dm-bio-list.h"
 #include "dm-bio-record.h"
 
-#include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/mempool.h>
 #include <linux/module.h>
 #include <linux/pagemap.h>
 #include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/vmalloc.h>
 #include <linux/workqueue.h>
-#include <linux/log2.h>
-#include <linux/hardirq.h>
+#include <linux/device-mapper.h>
 #include <linux/dm-io.h>
 #include <linux/dm-dirty-log.h>
 #include <linux/dm-kcopyd.h>
+#include <linux/dm-region-hash.h>
 
 #define DM_MSG_PREFIX "raid1"
+
+#define MAX_RECOVERY 1 /* Maximum number of regions recovered in parallel. */
 #define DM_IO_PAGES 64
+#define DM_KCOPYD_PAGES 64
 
 #define DM_RAID1_HANDLE_ERRORS 0x01
 #define errors_handled(p)      ((p)->features & DM_RAID1_HANDLE_ERRORS)
 
 static DECLARE_WAIT_QUEUE_HEAD(_kmirrord_recovery_stopped);
 
-/*-----------------------------------------------------------------
- * Region hash
- *
- * The mirror splits itself up into discrete regions.  Each
- * region can be in one of three states: clean, dirty,
- * nosync.  There is no need to put clean regions in the hash.
- *
- * In addition to being present in the hash table a region _may_
- * be present on one of three lists.
- *
- *   clean_regions: Regions on this list have no io pending to
- *   them, they are in sync, we are no longer interested in them,
- *   they are dull.  rh_update_states() will remove them from the
- *   hash table.
- *
- *   quiesced_regions: These regions have been spun down, ready
- *   for recovery.  rh_recovery_start() will remove regions from
- *   this list and hand them to kmirrord, which will schedule the
- *   recovery io with kcopyd.
- *
- *   recovered_regions: Regions that kcopyd has successfully
- *   recovered.  rh_update_states() will now schedule any delayed
- *   io, up the recovery_count, and remove the region from the
- *   hash.
- *
- * There are 2 locks:
- *   A rw spin lock 'hash_lock' protects just the hash table,
- *   this is never held in write mode from interrupt context,
- *   which I believe means that we only have to disable irqs when
- *   doing a write lock.
- *
- *   An ordinary spin lock 'region_lock' that protects the three
- *   lists in the region_hash, with the 'state', 'list' and
- *   'bhs_delayed' fields of the regions.  This is used from irq
- *   context, so all other uses will have to suspend local irqs.
- *---------------------------------------------------------------*/
-struct mirror_set;
-struct region_hash {
-       struct mirror_set *ms;
-       uint32_t region_size;
-       unsigned region_shift;
-
-       /* holds persistent region state */
-       struct dm_dirty_log *log;
-
-       /* hash table */
-       rwlock_t hash_lock;
-       mempool_t *region_pool;
-       unsigned int mask;
-       unsigned int nr_buckets;
-       struct list_head *buckets;
-
-       spinlock_t region_lock;
-       atomic_t recovery_in_flight;
-       struct semaphore recovery_count;
-       struct list_head clean_regions;
-       struct list_head quiesced_regions;
-       struct list_head recovered_regions;
-       struct list_head failed_recovered_regions;
-};
-
-enum {
-       RH_CLEAN,
-       RH_DIRTY,
-       RH_NOSYNC,
-       RH_RECOVERING
-};
-
-struct region {
-       struct region_hash *rh; /* FIXME: can we get rid of this ? */
-       region_t key;
-       int state;
-
-       struct list_head hash_list;
-       struct list_head list;
-
-       atomic_t pending;
-       struct bio_list delayed_bios;
-};
-
-
 /*-----------------------------------------------------------------
  * Mirror set structures.
  *---------------------------------------------------------------*/
@@ -132,8 +51,7 @@ struct mirror {
 struct mirror_set {
        struct dm_target *ti;
        struct list_head list;
-       struct region_hash rh;
-       struct dm_kcopyd_client *kcopyd_client;
+
        uint64_t features;
 
        spinlock_t lock;        /* protects the lists */
@@ -141,6 +59,8 @@ struct mirror_set {
        struct bio_list writes;
        struct bio_list failures;
 
+       struct dm_region_hash *rh;
+       struct dm_kcopyd_client *kcopyd_client;
        struct dm_io_client *io_client;
        mempool_t *read_record_pool;
 
@@ -159,25 +79,14 @@ struct mirror_set {
 
        struct work_struct trigger_event;
 
-       unsigned int nr_mirrors;
+       unsigned nr_mirrors;
        struct mirror mirror[0];
 };
 
-/*
- * Conversion fns
- */
-static inline region_t bio_to_region(struct region_hash *rh, struct bio *bio)
-{
-       return (bio->bi_sector - rh->ms->ti->begin) >> rh->region_shift;
-}
-
-static inline sector_t region_to_sector(struct region_hash *rh, region_t region)
+static void wakeup_mirrord(void *context)
 {
-       return region << rh->region_shift;
-}
+       struct mirror_set *ms = context;
 
-static void wake(struct mirror_set *ms)
-{
        queue_work(ms->kmirrord_wq, &ms->kmirrord_work);
 }
 
@@ -186,7 +95,7 @@ static void delayed_wake_fn(unsigned long data)
        struct mirror_set *ms = (struct mirror_set *) data;
 
        clear_bit(0, &ms->timer_pending);
-       wake(ms);
+       wakeup_mirrord(ms);
 }
 
 static void delayed_wake(struct mirror_set *ms)
@@ -200,473 +109,34 @@ static void delayed_wake(struct mirror_set *ms)
        add_timer(&ms->timer);
 }
 
-/* FIXME move this */
-static void queue_bio(struct mirror_set *ms, struct bio *bio, int rw);
-
-#define MIN_REGIONS 64
-#define MAX_RECOVERY 1
-static int rh_init(struct region_hash *rh, struct mirror_set *ms,
-                  struct dm_dirty_log *log, uint32_t region_size,
-                  region_t nr_regions)
+static void wakeup_all_recovery_waiters(void *context)
 {
-       unsigned int nr_buckets, max_buckets;
-       size_t i;
-
-       /*
-        * Calculate a suitable number of buckets for our hash
-        * table.
-        */
-       max_buckets = nr_regions >> 6;
-       for (nr_buckets = 128u; nr_buckets < max_buckets; nr_buckets <<= 1)
-               ;
-       nr_buckets >>= 1;
-
-       rh->ms = ms;
-       rh->log = log;
-       rh->region_size = region_size;
-       rh->region_shift = ffs(region_size) - 1;
-       rwlock_init(&rh->hash_lock);
-       rh->mask = nr_buckets - 1;
-       rh->nr_buckets = nr_buckets;
-
-       rh->buckets = vmalloc(nr_buckets * sizeof(*rh->buckets));
-       if (!rh->buckets) {
-               DMERR("unable to allocate region hash memory");
-               return -ENOMEM;
-       }
-
-       for (i = 0; i < nr_buckets; i++)
-               INIT_LIST_HEAD(rh->buckets + i);
-
-       spin_lock_init(&rh->region_lock);
-       sema_init(&rh->recovery_count, 0);
-       atomic_set(&rh->recovery_in_flight, 0);
-       INIT_LIST_HEAD(&rh->clean_regions);
-       INIT_LIST_HEAD(&rh->quiesced_regions);
-       INIT_LIST_HEAD(&rh->recovered_regions);
-       INIT_LIST_HEAD(&rh->failed_recovered_regions);
-
-       rh->region_pool = mempool_create_kmalloc_pool(MIN_REGIONS,
-                                                     sizeof(struct region));
-       if (!rh->region_pool) {
-               vfree(rh->buckets);
-               rh->buckets = NULL;
-               return -ENOMEM;
-       }
-
-       return 0;
+       wake_up_all(&_kmirrord_recovery_stopped);
 }
 
-static void rh_exit(struct region_hash *rh)
-{
-       unsigned int h;
-       struct region *reg, *nreg;
-
-       BUG_ON(!list_empty(&rh->quiesced_regions));
-       for (h = 0; h < rh->nr_buckets; h++) {
-               list_for_each_entry_safe(reg, nreg, rh->buckets + h, hash_list) {
-                       BUG_ON(atomic_read(&reg->pending));
-                       mempool_free(reg, rh->region_pool);
-               }
-       }
-
-       if (rh->log)
-               dm_dirty_log_destroy(rh->log);
-       if (rh->region_pool)
-               mempool_destroy(rh->region_pool);
-       vfree(rh->buckets);
-}
-
-#define RH_HASH_MULT 2654435387U
-
-static inline unsigned int rh_hash(struct region_hash *rh, region_t region)
-{
-       return (unsigned int) ((region * RH_HASH_MULT) >> 12) & rh->mask;
-}
-
-static struct region *__rh_lookup(struct region_hash *rh, region_t region)
-{
-       struct region *reg;
-
-       list_for_each_entry (reg, rh->buckets + rh_hash(rh, region), hash_list)
-               if (reg->key == region)
-                       return reg;
-
-       return NULL;
-}
-
-static void __rh_insert(struct region_hash *rh, struct region *reg)
-{
-       unsigned int h = rh_hash(rh, reg->key);
-       list_add(&reg->hash_list, rh->buckets + h);
-}
-
-static struct region *__rh_alloc(struct region_hash *rh, region_t region)
-{
-       struct region *reg, *nreg;
-
-       read_unlock(&rh->hash_lock);
-       nreg = mempool_alloc(rh->region_pool, GFP_ATOMIC);
-       if (unlikely(!nreg))
-               nreg = kmalloc(sizeof(struct region), GFP_NOIO);
-       nreg->state = rh->log->type->in_sync(rh->log, region, 1) ?
-               RH_CLEAN : RH_NOSYNC;
-       nreg->rh = rh;
-       nreg->key = region;
-
-       INIT_LIST_HEAD(&nreg->list);
-
-       atomic_set(&nreg->pending, 0);
-       bio_list_init(&nreg->delayed_bios);
-       write_lock_irq(&rh->hash_lock);
-
-       reg = __rh_lookup(rh, region);
-       if (reg)
-               /* we lost the race */
-               mempool_free(nreg, rh->region_pool);
-
-       else {
-               __rh_insert(rh, nreg);
-               if (nreg->state == RH_CLEAN) {
-                       spin_lock(&rh->region_lock);
-                       list_add(&nreg->list, &rh->clean_regions);
-                       spin_unlock(&rh->region_lock);
-               }
-               reg = nreg;
-       }
-       write_unlock_irq(&rh->hash_lock);
-       read_lock(&rh->hash_lock);
-
-       return reg;
-}
-
-static inline struct region *__rh_find(struct region_hash *rh, region_t region)
-{
-       struct region *reg;
-
-       reg = __rh_lookup(rh, region);
-       if (!reg)
-               reg = __rh_alloc(rh, region);
-
-       return reg;
-}
-
-static int rh_state(struct region_hash *rh, region_t region, int may_block)
-{
-       int r;
-       struct region *reg;
-
-       read_lock(&rh->hash_lock);
-       reg = __rh_lookup(rh, region);
-       read_unlock(&rh->hash_lock);
-
-       if (reg)
-               return reg->state;
-
-       /*
-        * The region wasn't in the hash, so we fall back to the
-        * dirty log.
-        */
-       r = rh->log->type->in_sync(rh->log, region, may_block);
-
-       /*
-        * Any error from the dirty log (eg. -EWOULDBLOCK) gets
-        * taken as a RH_NOSYNC
-        */
-       return r == 1 ? RH_CLEAN : RH_NOSYNC;
-}
-
-static inline int rh_in_sync(struct region_hash *rh,
-                            region_t region, int may_block)
-{
-       int state = rh_state(rh, region, may_block);
-       return state == RH_CLEAN || state == RH_DIRTY;
-}
-
-static void dispatch_bios(struct mirror_set *ms, struct bio_list *bio_list)
-{
-       struct bio *bio;
-
-       while ((bio = bio_list_pop(bio_list))) {
-               queue_bio(ms, bio, WRITE);
-       }
-}
-
-static void complete_resync_work(struct region *reg, int success)
-{
-       struct region_hash *rh = reg->rh;
-
-       rh->log->type->set_region_sync(rh->log, reg->key, success);
-
-       /*
-        * Dispatch the bios before we call 'wake_up_all'.
-        * This is important because if we are suspending,
-        * we want to know that recovery is complete and
-        * the work queue is flushed.  If we wake_up_all
-        * before we dispatch_bios (queue bios and call wake()),
-        * then we risk suspending before the work queue
-        * has been properly flushed.
-        */
-       dispatch_bios(rh->ms, &reg->delayed_bios);
-       if (atomic_dec_and_test(&rh->recovery_in_flight))
-               wake_up_all(&_kmirrord_recovery_stopped);
-       up(&rh->recovery_count);
-}
-
-static void rh_update_states(struct region_hash *rh)
-{
-       struct region *reg, *next;
-
-       LIST_HEAD(clean);
-       LIST_HEAD(recovered);
-       LIST_HEAD(failed_recovered);
-
-       /*
-        * Quickly grab the lists.
-        */
-       write_lock_irq(&rh->hash_lock);
-       spin_lock(&rh->region_lock);
-       if (!list_empty(&rh->clean_regions)) {
-               list_splice_init(&rh->clean_regions, &clean);
-
-               list_for_each_entry(reg, &clean, list)
-                       list_del(&reg->hash_list);
-       }
-
-       if (!list_empty(&rh->recovered_regions)) {
-               list_splice_init(&rh->recovered_regions, &recovered);
-
-               list_for_each_entry (reg, &recovered, list)
-                       list_del(&reg->hash_list);
-       }
-
-       if (!list_empty(&rh->failed_recovered_regions)) {
-               list_splice_init(&rh->failed_recovered_regions,
-                                &failed_recovered);
-
-               list_for_each_entry(reg, &failed_recovered, list)
-                       list_del(&reg->hash_list);
-       }
-
-       spin_unlock(&rh->region_lock);
-       write_unlock_irq(&rh->hash_lock);
-
-       /*
-        * All the regions on the recovered and clean lists have
-        * now been pulled out of the system, so no need to do
-        * any more locking.
-        */
-       list_for_each_entry_safe (reg, next, &recovered, list) {
-               rh->log->type->clear_region(rh->log, reg->key);
-               complete_resync_work(reg, 1);
-               mempool_free(reg, rh->region_pool);
-       }
-
-       list_for_each_entry_safe(reg, next, &failed_recovered, list) {
-               complete_resync_work(reg, errors_handled(rh->ms) ? 0 : 1);
-               mempool_free(reg, rh->region_pool);
-       }
-
-       list_for_each_entry_safe(reg, next, &clean, list) {
-               rh->log->type->clear_region(rh->log, reg->key);
-               mempool_free(reg, rh->region_pool);
-       }
-
-       rh->log->type->flush(rh->log);
-}
-
-static void rh_inc(struct region_hash *rh, region_t region)
-{
-       struct region *reg;
-
-       read_lock(&rh->hash_lock);
-       reg = __rh_find(rh, region);
-
-       spin_lock_irq(&rh->region_lock);
-       atomic_inc(&reg->pending);
-
-       if (reg->state == RH_CLEAN) {
-               reg->state = RH_DIRTY;
-               list_del_init(&reg->list);      /* take off the clean list */
-               spin_unlock_irq(&rh->region_lock);
-
-               rh->log->type->mark_region(rh->log, reg->key);
-       } else
-               spin_unlock_irq(&rh->region_lock);
-
-
-       read_unlock(&rh->hash_lock);
-}
-
-static void rh_inc_pending(struct region_hash *rh, struct bio_list *bios)
-{
-       struct bio *bio;
-
-       for (bio = bios->head; bio; bio = bio->bi_next)
-               rh_inc(rh, bio_to_region(rh, bio));
-}
-
-static void rh_dec(struct region_hash *rh, region_t region)
+static void queue_bio(struct mirror_set *ms, struct bio *bio, int rw)
 {
        unsigned long flags;
-       struct region *reg;
        int should_wake = 0;
+       struct bio_list *bl;
 
-       read_lock(&rh->hash_lock);
-       reg = __rh_lookup(rh, region);
-       read_unlock(&rh->hash_lock);
-
-       spin_lock_irqsave(&rh->region_lock, flags);
-       if (atomic_dec_and_test(&reg->pending)) {
-               /*
-                * There is no pending I/O for this region.
-                * We can move the region to corresponding list for next action.
-                * At this point, the region is not yet connected to any list.
-                *
-                * If the state is RH_NOSYNC, the region should be kept off
-                * from clean list.
-                * The hash entry for RH_NOSYNC will remain in memory
-                * until the region is recovered or the map is reloaded.
-                */
-
-               /* do nothing for RH_NOSYNC */
-               if (reg->state == RH_RECOVERING) {
-                       list_add_tail(&reg->list, &rh->quiesced_regions);
-               } else if (reg->state == RH_DIRTY) {
-                       reg->state = RH_CLEAN;
-                       list_add(&reg->list, &rh->clean_regions);
-               }
-               should_wake = 1;
-       }
-       spin_unlock_irqrestore(&rh->region_lock, flags);
+       bl = (rw == WRITE) ? &ms->writes : &ms->reads;
+       spin_lock_irqsave(&ms->lock, flags);
+       should_wake = !(bl->head);
+       bio_list_add(bl, bio);
+       spin_unlock_irqrestore(&ms->lock, flags);
 
        if (should_wake)
-               wake(rh->ms);
-}
-
-/*
- * Starts quiescing a region in preparation for recovery.
- */
-static int __rh_recovery_prepare(struct region_hash *rh)
-{
-       int r;
-       struct region *reg;
-       region_t region;
-
-       /*
-        * Ask the dirty log what's next.
-        */
-       r = rh->log->type->get_resync_work(rh->log, &region);
-       if (r <= 0)
-               return r;
-
-       /*
-        * Get this region, and start it quiescing by setting the
-        * recovering flag.
-        */
-       read_lock(&rh->hash_lock);
-       reg = __rh_find(rh, region);
-       read_unlock(&rh->hash_lock);
-
-       spin_lock_irq(&rh->region_lock);
-       reg->state = RH_RECOVERING;
-
-       /* Already quiesced ? */
-       if (atomic_read(&reg->pending))
-               list_del_init(&reg->list);
-       else
-               list_move(&reg->list, &rh->quiesced_regions);
-
-       spin_unlock_irq(&rh->region_lock);
-
-       return 1;
-}
-
-static void rh_recovery_prepare(struct region_hash *rh)
-{
-       /* Extra reference to avoid race with rh_stop_recovery */
-       atomic_inc(&rh->recovery_in_flight);
-
-       while (!down_trylock(&rh->recovery_count)) {
-               atomic_inc(&rh->recovery_in_flight);
-               if (__rh_recovery_prepare(rh) <= 0) {
-                       atomic_dec(&rh->recovery_in_flight);
-                       up(&rh->recovery_count);
-                       break;
-               }
-       }
-
-       /* Drop the extra reference */
-       if (atomic_dec_and_test(&rh->recovery_in_flight))
-               wake_up_all(&_kmirrord_recovery_stopped);
-}
-
-/*
- * Returns any quiesced regions.
- */
-static struct region *rh_recovery_start(struct region_hash *rh)
-{
-       struct region *reg = NULL;
-
-       spin_lock_irq(&rh->region_lock);
-       if (!list_empty(&rh->quiesced_regions)) {
-               reg = list_entry(rh->quiesced_regions.next,
-                                struct region, list);
-               list_del_init(&reg->list);      /* remove from the quiesced list */
-       }
-       spin_unlock_irq(&rh->region_lock);
-
-       return reg;
-}
-
-static void rh_recovery_end(struct region *reg, int success)
-{
-       struct region_hash *rh = reg->rh;
-
-       spin_lock_irq(&rh->region_lock);
-       if (success)
-               list_add(&reg->list, &reg->rh->recovered_regions);
-       else {
-               reg->state = RH_NOSYNC;
-               list_add(&reg->list, &reg->rh->failed_recovered_regions);
-       }
-       spin_unlock_irq(&rh->region_lock);
-
-       wake(rh->ms);
+               wakeup_mirrord(ms);
 }
 
-static int rh_flush(struct region_hash *rh)
+static void dispatch_bios(void *context, struct bio_list *bio_list)
 {
-       return rh->log->type->flush(rh->log);
-}
-
-static void rh_delay(struct region_hash *rh, struct bio *bio)
-{
-       struct region *reg;
-
-       read_lock(&rh->hash_lock);
-       reg = __rh_find(rh, bio_to_region(rh, bio));
-       bio_list_add(&reg->delayed_bios, bio);
-       read_unlock(&rh->hash_lock);
-}
-
-static void rh_stop_recovery(struct region_hash *rh)
-{
-       int i;
-
-       /* wait for any recovering regions */
-       for (i = 0; i < MAX_RECOVERY; i++)
-               down(&rh->recovery_count);
-}
-
-static void rh_start_recovery(struct region_hash *rh)
-{
-       int i;
-
-       for (i = 0; i < MAX_RECOVERY; i++)
-               up(&rh->recovery_count);
+       struct mirror_set *ms = context;
+       struct bio *bio;
 
-       wake(rh->ms);
+       while ((bio = bio_list_pop(bio_list)))
+               queue_bio(ms, bio, WRITE);
 }
 
 #define MIN_READ_RECORDS 20
@@ -776,8 +246,8 @@ out:
 static void recovery_complete(int read_err, unsigned long write_err,
                              void *context)
 {
-       struct region *reg = (struct region *)context;
-       struct mirror_set *ms = reg->rh->ms;
+       struct dm_region *reg = context;
+       struct mirror_set *ms = dm_rh_region_context(reg);
        int m, bit = 0;
 
        if (read_err) {
@@ -803,31 +273,33 @@ static void recovery_complete(int read_err, unsigned long write_err,
                }
        }
 
-       rh_recovery_end(reg, !(read_err || write_err));
+       dm_rh_recovery_end(reg, !(read_err || write_err));
 }
 
-static int recover(struct mirror_set *ms, struct region *reg)
+static int recover(struct mirror_set *ms, struct dm_region *reg)
 {
        int r;
-       unsigned int i;
+       unsigned i;
        struct dm_io_region from, to[DM_KCOPYD_MAX_REGIONS], *dest;
        struct mirror *m;
        unsigned long flags = 0;
+       region_t key = dm_rh_get_region_key(reg);
+       sector_t region_size = dm_rh_get_region_size(ms->rh);
 
        /* fill in the source */
        m = get_default_mirror(ms);
        from.bdev = m->dev->bdev;
-       from.sector = m->offset + region_to_sector(reg->rh, reg->key);
-       if (reg->key == (ms->nr_regions - 1)) {
+       from.sector = m->offset + dm_rh_region_to_sector(ms->rh, key);
+       if (key == (ms->nr_regions - 1)) {
                /*
                 * The final region may be smaller than
                 * region_size.
                 */
-               from.count = ms->ti->len & (reg->rh->region_size - 1);
+               from.count = ms->ti->len & (region_size - 1);
                if (!from.count)
-                       from.count = reg->rh->region_size;
+                       from.count = region_size;
        } else
-               from.count = reg->rh->region_size;
+               from.count = region_size;
 
        /* fill in the destinations */
        for (i = 0, dest = to; i < ms->nr_mirrors; i++) {
@@ -836,7 +308,7 @@ static int recover(struct mirror_set *ms, struct region *reg)
 
                m = ms->mirror + i;
                dest->bdev = m->dev->bdev;
-               dest->sector = m->offset + region_to_sector(reg->rh, reg->key);
+               dest->sector = m->offset + dm_rh_region_to_sector(ms->rh, key);
                dest->count = from.count;
                dest++;
        }
@@ -853,22 +325,22 @@ static int recover(struct mirror_set *ms, struct region *reg)
 
 static void do_recovery(struct mirror_set *ms)
 {
+       struct dm_region *reg;
+       struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
        int r;
-       struct region *reg;
-       struct dm_dirty_log *log = ms->rh.log;
 
        /*
         * Start quiescing some regions.
         */
-       rh_recovery_prepare(&ms->rh);
+       dm_rh_recovery_prepare(ms->rh);
 
        /*
         * Copy any already quiesced regions.
         */
-       while ((reg = rh_recovery_start(&ms->rh))) {
+       while ((reg = dm_rh_recovery_start(ms->rh))) {
                r = recover(ms, reg);
                if (r)
-                       rh_recovery_end(reg, 0);
+                       dm_rh_recovery_end(reg, 0);
        }
 
        /*
@@ -909,9 +381,10 @@ static int default_ok(struct mirror *m)
 
 static int mirror_available(struct mirror_set *ms, struct bio *bio)
 {
-       region_t region = bio_to_region(&ms->rh, bio);
+       struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
+       region_t region = dm_rh_bio_to_region(ms->rh, bio);
 
-       if (ms->rh.log->type->in_sync(ms->rh.log, region, 0))
+       if (log->type->in_sync(log, region, 0))
                return choose_mirror(ms,  bio->bi_sector) ? 1 : 0;
 
        return 0;
@@ -985,7 +458,14 @@ static void read_async_bio(struct mirror *m, struct bio *bio)
 
        map_region(&io, m, bio);
        bio_set_m(bio, m);
-       (void) dm_io(&io_req, 1, &io, NULL);
+       BUG_ON(dm_io(&io_req, 1, &io, NULL));
+}
+
+static inline int region_in_sync(struct mirror_set *ms, region_t region,
+                                int may_block)
+{
+       int state = dm_rh_get_state(ms->rh, region, may_block);
+       return state == DM_RH_CLEAN || state == DM_RH_DIRTY;
 }
 
 static void do_reads(struct mirror_set *ms, struct bio_list *reads)
@@ -995,13 +475,13 @@ static void do_reads(struct mirror_set *ms, struct bio_list *reads)
        struct mirror *m;
 
        while ((bio = bio_list_pop(reads))) {
-               region = bio_to_region(&ms->rh, bio);
+               region = dm_rh_bio_to_region(ms->rh, bio);
                m = get_default_mirror(ms);
 
                /*
                 * We can only read balance if the region is in sync.
                 */
-               if (likely(rh_in_sync(&ms->rh, region, 1)))
+               if (likely(region_in_sync(ms, region, 1)))
                        m = choose_mirror(ms, bio->bi_sector);
                else if (m && atomic_read(&m->error_count))
                        m = NULL;
@@ -1024,57 +504,6 @@ static void do_reads(struct mirror_set *ms, struct bio_list *reads)
  * NOSYNC:     increment pending, just write to the default mirror
  *---------------------------------------------------------------*/
 
-/* __bio_mark_nosync
- * @ms
- * @bio
- * @done
- * @error
- *
- * The bio was written on some mirror(s) but failed on other mirror(s).
- * We can successfully endio the bio but should avoid the region being
- * marked clean by setting the state RH_NOSYNC.
- *
- * This function is _not_ safe in interrupt context!
- */
-static void __bio_mark_nosync(struct mirror_set *ms,
-                             struct bio *bio, unsigned done, int error)
-{
-       unsigned long flags;
-       struct region_hash *rh = &ms->rh;
-       struct dm_dirty_log *log = ms->rh.log;
-       struct region *reg;
-       region_t region = bio_to_region(rh, bio);
-       int recovering = 0;
-
-       /* We must inform the log that the sync count has changed. */
-       log->type->set_region_sync(log, region, 0);
-       ms->in_sync = 0;
-
-       read_lock(&rh->hash_lock);
-       reg = __rh_find(rh, region);
-       read_unlock(&rh->hash_lock);
-
-       /* region hash entry should exist because write was in-flight */
-       BUG_ON(!reg);
-       BUG_ON(!list_empty(&reg->list));
-
-       spin_lock_irqsave(&rh->region_lock, flags);
-       /*
-        * Possible cases:
-        *   1) RH_DIRTY
-        *   2) RH_NOSYNC: was dirty, other preceeding writes failed
-        *   3) RH_RECOVERING: flushing pending writes
-        * Either case, the region should have not been connected to list.
-        */
-       recovering = (reg->state == RH_RECOVERING);
-       reg->state = RH_NOSYNC;
-       BUG_ON(!list_empty(&reg->list));
-       spin_unlock_irqrestore(&rh->region_lock, flags);
-
-       bio_endio(bio, error);
-       if (recovering)
-               complete_resync_work(reg, 0);
-}
 
 static void write_callback(unsigned long error, void *context)
 {
@@ -1119,7 +548,7 @@ static void write_callback(unsigned long error, void *context)
                bio_list_add(&ms->failures, bio);
                spin_unlock_irqrestore(&ms->lock, flags);
                if (should_wake)
-                       wake(ms);
+                       wakeup_mirrord(ms);
                return;
        }
 out:
@@ -1149,7 +578,7 @@ static void do_write(struct mirror_set *ms, struct bio *bio)
         */
        bio_set_m(bio, get_default_mirror(ms));
 
-       (void) dm_io(&io_req, ms->nr_mirrors, io, NULL);
+       BUG_ON(dm_io(&io_req, ms->nr_mirrors, io, NULL));
 }
 
 static void do_writes(struct mirror_set *ms, struct bio_list *writes)
@@ -1169,18 +598,19 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
        bio_list_init(&recover);
 
        while ((bio = bio_list_pop(writes))) {
-               state = rh_state(&ms->rh, bio_to_region(&ms->rh, bio), 1);
+               state = dm_rh_get_state(ms->rh,
+                                       dm_rh_bio_to_region(ms->rh, bio), 1);
                switch (state) {
-               case RH_CLEAN:
-               case RH_DIRTY:
+               case DM_RH_CLEAN:
+               case DM_RH_DIRTY:
                        this_list = &sync;
                        break;
 
-               case RH_NOSYNC:
+               case DM_RH_NOSYNC:
                        this_list = &nosync;
                        break;
 
-               case RH_RECOVERING:
+               case DM_RH_RECOVERING:
                        this_list = &recover;
                        break;
                }
@@ -1193,9 +623,9 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
         * be written to (writes to recover regions are going to
         * be delayed).
         */
-       rh_inc_pending(&ms->rh, &sync);
-       rh_inc_pending(&ms->rh, &nosync);
-       ms->log_failure = rh_flush(&ms->rh) ? 1 : 0;
+       dm_rh_inc_pending(ms->rh, &sync);
+       dm_rh_inc_pending(ms->rh, &nosync);
+       ms->log_failure = dm_rh_flush(ms->rh) ? 1 : 0;
 
        /*
         * Dispatch io.
@@ -1204,13 +634,13 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
                spin_lock_irq(&ms->lock);
                bio_list_merge(&ms->failures, &sync);
                spin_unlock_irq(&ms->lock);
-               wake(ms);
+               wakeup_mirrord(ms);
        } else
                while ((bio = bio_list_pop(&sync)))
                        do_write(ms, bio);
 
        while ((bio = bio_list_pop(&recover)))
-               rh_delay(&ms->rh, bio);
+               dm_rh_delay(ms->rh, bio);
 
        while ((bio = bio_list_pop(&nosync))) {
                map_bio(get_default_mirror(ms), bio);
@@ -1227,7 +657,8 @@ static void do_failures(struct mirror_set *ms, struct bio_list *failures)
 
        if (!ms->log_failure) {
                while ((bio = bio_list_pop(failures)))
-                       __bio_mark_nosync(ms, bio, bio->bi_size, 0);
+                       ms->in_sync = 0;
+                       dm_rh_mark_nosync(ms->rh, bio, bio->bi_size, 0);
                return;
        }
 
@@ -1280,8 +711,8 @@ static void trigger_event(struct work_struct *work)
  *---------------------------------------------------------------*/
 static void do_mirror(struct work_struct *work)
 {
-       struct mirror_set *ms =container_of(work, struct mirror_set,
-                                           kmirrord_work);
+       struct mirror_set *ms = container_of(work, struct mirror_set,
+                                            kmirrord_work);
        struct bio_list reads, writes, failures;
        unsigned long flags;
 
@@ -1294,7 +725,7 @@ static void do_mirror(struct work_struct *work)
        bio_list_init(&ms->failures);
        spin_unlock_irqrestore(&ms->lock, flags);
 
-       rh_update_states(&ms->rh);
+       dm_rh_update_states(ms->rh, errors_handled(ms));
        do_recovery(ms);
        do_reads(ms, &reads);
        do_writes(ms, &writes);
@@ -1303,7 +734,6 @@ static void do_mirror(struct work_struct *work)
        dm_table_unplug_all(ms->ti->table);
 }
 
-
 /*-----------------------------------------------------------------
  * Target functions
  *---------------------------------------------------------------*/
@@ -1315,9 +745,6 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors,
        size_t len;
        struct mirror_set *ms = NULL;
 
-       if (array_too_big(sizeof(*ms), sizeof(ms->mirror[0]), nr_mirrors))
-               return NULL;
-
        len = sizeof(*ms) + (sizeof(ms->mirror[0]) * nr_mirrors);
 
        ms = kzalloc(len, GFP_KERNEL);
@@ -1353,7 +780,11 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors,
                return NULL;
        }
 
-       if (rh_init(&ms->rh, ms, dl, region_size, ms->nr_regions)) {
+       ms->rh = dm_region_hash_create(ms, dispatch_bios, wakeup_mirrord,
+                                      wakeup_all_recovery_waiters,
+                                      ms->ti->begin, MAX_RECOVERY,
+                                      dl, region_size, ms->nr_regions);
+       if (IS_ERR(ms->rh)) {
                ti->error = "Error creating dirty region hash";
                dm_io_client_destroy(ms->io_client);
                mempool_destroy(ms->read_record_pool);
@@ -1371,7 +802,7 @@ static void free_context(struct mirror_set *ms, struct dm_target *ti,
                dm_put_device(ti, ms->mirror[m].dev);
 
        dm_io_client_destroy(ms->io_client);
-       rh_exit(&ms->rh);
+       dm_region_hash_destroy(ms->rh);
        mempool_destroy(ms->read_record_pool);
        kfree(ms);
 }
@@ -1411,10 +842,10 @@ static int get_mirror(struct mirror_set *ms, struct dm_target *ti,
  * Create dirty log: log_type #log_params <log_params>
  */
 static struct dm_dirty_log *create_dirty_log(struct dm_target *ti,
-                                         unsigned int argc, char **argv,
-                                         unsigned int *args_used)
+                                            unsigned argc, char **argv,
+                                            unsigned *args_used)
 {
-       unsigned int param_count;
+       unsigned param_count;
        struct dm_dirty_log *dl;
 
        if (argc < 2) {
@@ -1545,7 +976,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        }
 
        ti->private = ms;
-       ti->split_io = ms->rh.region_size;
+       ti->split_io = dm_rh_get_region_size(ms->rh);
 
        ms->kmirrord_wq = create_singlethread_workqueue("kmirrord");
        if (!ms->kmirrord_wq) {
@@ -1580,11 +1011,11 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
                goto err_destroy_wq;
        }
 
-       r = dm_kcopyd_client_create(DM_IO_PAGES, &ms->kcopyd_client);
+       r = dm_kcopyd_client_create(DM_KCOPYD_PAGES, &ms->kcopyd_client);
        if (r)
                goto err_destroy_wq;
 
-       wake(ms);
+       wakeup_mirrord(ms);
        return 0;
 
 err_destroy_wq:
@@ -1605,22 +1036,6 @@ static void mirror_dtr(struct dm_target *ti)
        free_context(ms, ti, ms->nr_mirrors);
 }
 
-static void queue_bio(struct mirror_set *ms, struct bio *bio, int rw)
-{
-       unsigned long flags;
-       int should_wake = 0;
-       struct bio_list *bl;
-
-       bl = (rw == WRITE) ? &ms->writes : &ms->reads;
-       spin_lock_irqsave(&ms->lock, flags);
-       should_wake = !(bl->head);
-       bio_list_add(bl, bio);
-       spin_unlock_irqrestore(&ms->lock, flags);
-
-       if (should_wake)
-               wake(ms);
-}
-
 /*
  * Mirror mapping function
  */
@@ -1631,16 +1046,16 @@ static int mirror_map(struct dm_target *ti, struct bio *bio,
        struct mirror *m;
        struct mirror_set *ms = ti->private;
        struct dm_raid1_read_record *read_record = NULL;
+       struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
 
        if (rw == WRITE) {
                /* Save region for mirror_end_io() handler */
-               map_context->ll = bio_to_region(&ms->rh, bio);
+               map_context->ll = dm_rh_bio_to_region(ms->rh, bio);
                queue_bio(ms, bio, rw);
                return DM_MAPIO_SUBMITTED;
        }
 
-       r = ms->rh.log->type->in_sync(ms->rh.log,
-                                     bio_to_region(&ms->rh, bio), 0);
+       r = log->type->in_sync(log, dm_rh_bio_to_region(ms->rh, bio), 0);
        if (r < 0 && r != -EWOULDBLOCK)
                return r;
 
@@ -1688,7 +1103,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio,
         * We need to dec pending if this was a write.
         */
        if (rw == WRITE) {
-               rh_dec(&ms->rh, map_context->ll);
+               dm_rh_dec(ms->rh, map_context->ll);
                return error;
        }
 
@@ -1744,7 +1159,7 @@ out:
 static void mirror_presuspend(struct dm_target *ti)
 {
        struct mirror_set *ms = (struct mirror_set *) ti->private;
-       struct dm_dirty_log *log = ms->rh.log;
+       struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
 
        atomic_set(&ms->suspend, 1);
 
@@ -1752,10 +1167,10 @@ static void mirror_presuspend(struct dm_target *ti)
         * We must finish up all the work that we've
         * generated (i.e. recovery work).
         */
-       rh_stop_recovery(&ms->rh);
+       dm_rh_stop_recovery(ms->rh);
 
        wait_event(_kmirrord_recovery_stopped,
-                  !atomic_read(&ms->rh.recovery_in_flight));
+                  !dm_rh_recovery_in_flight(ms->rh));
 
        if (log->type->presuspend && log->type->presuspend(log))
                /* FIXME: need better error handling */
@@ -1773,7 +1188,7 @@ static void mirror_presuspend(struct dm_target *ti)
 static void mirror_postsuspend(struct dm_target *ti)
 {
        struct mirror_set *ms = ti->private;
-       struct dm_dirty_log *log = ms->rh.log;
+       struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
 
        if (log->type->postsuspend && log->type->postsuspend(log))
                /* FIXME: need better error handling */
@@ -1783,13 +1198,13 @@ static void mirror_postsuspend(struct dm_target *ti)
 static void mirror_resume(struct dm_target *ti)
 {
        struct mirror_set *ms = ti->private;
-       struct dm_dirty_log *log = ms->rh.log;
+       struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
 
        atomic_set(&ms->suspend, 0);
        if (log->type->resume && log->type->resume(log))
                /* FIXME: need better error handling */
                DMWARN("log resume failed");
-       rh_start_recovery(&ms->rh);
+       dm_rh_start_recovery(ms->rh);
 }
 
 /*
@@ -1821,7 +1236,7 @@ static int mirror_status(struct dm_target *ti, status_type_t type,
 {
        unsigned int m, sz = 0;
        struct mirror_set *ms = (struct mirror_set *) ti->private;
-       struct dm_dirty_log *log = ms->rh.log;
+       struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
        char buffer[ms->nr_mirrors + 1];
 
        switch (type) {
@@ -1834,15 +1249,15 @@ static int mirror_status(struct dm_target *ti, status_type_t type,
                buffer[m] = '\0';
 
                DMEMIT("%llu/%llu 1 %s ",
-                     (unsigned long long)log->type->get_sync_count(ms->rh.log),
+                     (unsigned long long)log->type->get_sync_count(log),
                      (unsigned long long)ms->nr_regions, buffer);
 
-               sz += log->type->status(ms->rh.log, type, result+sz, maxlen-sz);
+               sz += log->type->status(log, type, result+sz, maxlen-sz);
 
                break;
 
        case STATUSTYPE_TABLE:
-               sz = log->type->status(ms->rh.log, type, result, maxlen);
+               sz = log->type->status(log, type, result, maxlen);
 
                DMEMIT("%d", ms->nr_mirrors);
                for (m = 0; m < ms->nr_mirrors; m++)
diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c
new file mode 100644 (file)
index 0000000..59f8d9d
--- /dev/null
@@ -0,0 +1,704 @@
+/*
+ * Copyright (C) 2003 Sistina Software Limited.
+ * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+
+#include <linux/dm-dirty-log.h>
+#include <linux/dm-region-hash.h>
+
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+
+#include "dm.h"
+#include "dm-bio-list.h"
+
+#define        DM_MSG_PREFIX   "region hash"
+
+/*-----------------------------------------------------------------
+ * Region hash
+ *
+ * The mirror splits itself up into discrete regions.  Each
+ * region can be in one of three states: clean, dirty,
+ * nosync.  There is no need to put clean regions in the hash.
+ *
+ * In addition to being present in the hash table a region _may_
+ * be present on one of three lists.
+ *
+ *   clean_regions: Regions on this list have no io pending to
+ *   them, they are in sync, we are no longer interested in them,
+ *   they are dull.  dm_rh_update_states() will remove them from the
+ *   hash table.
+ *
+ *   quiesced_regions: These regions have been spun down, ready
+ *   for recovery.  rh_recovery_start() will remove regions from
+ *   this list and hand them to kmirrord, which will schedule the
+ *   recovery io with kcopyd.
+ *
+ *   recovered_regions: Regions that kcopyd has successfully
+ *   recovered.  dm_rh_update_states() will now schedule any delayed
+ *   io, up the recovery_count, and remove the region from the
+ *   hash.
+ *
+ * There are 2 locks:
+ *   A rw spin lock 'hash_lock' protects just the hash table,
+ *   this is never held in write mode from interrupt context,
+ *   which I believe means that we only have to disable irqs when
+ *   doing a write lock.
+ *
+ *   An ordinary spin lock 'region_lock' that protects the three
+ *   lists in the region_hash, with the 'state', 'list' and
+ *   'delayed_bios' fields of the regions.  This is used from irq
+ *   context, so all other uses will have to suspend local irqs.
+ *---------------------------------------------------------------*/
+struct dm_region_hash {
+       uint32_t region_size;
+       unsigned region_shift;
+
+       /* holds persistent region state */
+       struct dm_dirty_log *log;
+
+       /* hash table */
+       rwlock_t hash_lock;
+       mempool_t *region_pool;
+       unsigned mask;
+       unsigned nr_buckets;
+       unsigned prime;
+       unsigned shift;
+       struct list_head *buckets;
+
+       unsigned max_recovery; /* Max # of regions to recover in parallel */
+
+       spinlock_t region_lock;
+       atomic_t recovery_in_flight;
+       struct semaphore recovery_count;
+       struct list_head clean_regions;
+       struct list_head quiesced_regions;
+       struct list_head recovered_regions;
+       struct list_head failed_recovered_regions;
+
+       void *context;
+       sector_t target_begin;
+
+       /* Callback function to schedule bios writes */
+       void (*dispatch_bios)(void *context, struct bio_list *bios);
+
+       /* Callback function to wakeup callers worker thread. */
+       void (*wakeup_workers)(void *context);
+
+       /* Callback function to wakeup callers recovery waiters. */
+       void (*wakeup_all_recovery_waiters)(void *context);
+};
+
+struct dm_region {
+       struct dm_region_hash *rh;      /* FIXME: can we get rid of this ? */
+       region_t key;
+       int state;
+
+       struct list_head hash_list;
+       struct list_head list;
+
+       atomic_t pending;
+       struct bio_list delayed_bios;
+};
+
+/*
+ * Conversion fns
+ */
+static region_t dm_rh_sector_to_region(struct dm_region_hash *rh, sector_t sector)
+{
+       return sector >> rh->region_shift;
+}
+
+sector_t dm_rh_region_to_sector(struct dm_region_hash *rh, region_t region)
+{
+       return region << rh->region_shift;
+}
+EXPORT_SYMBOL_GPL(dm_rh_region_to_sector);
+
+region_t dm_rh_bio_to_region(struct dm_region_hash *rh, struct bio *bio)
+{
+       return dm_rh_sector_to_region(rh, bio->bi_sector - rh->target_begin);
+}
+EXPORT_SYMBOL_GPL(dm_rh_bio_to_region);
+
+void *dm_rh_region_context(struct dm_region *reg)
+{
+       return reg->rh->context;
+}
+EXPORT_SYMBOL_GPL(dm_rh_region_context);
+
+region_t dm_rh_get_region_key(struct dm_region *reg)
+{
+       return reg->key;
+}
+EXPORT_SYMBOL_GPL(dm_rh_get_region_key);
+
+sector_t dm_rh_get_region_size(struct dm_region_hash *rh)
+{
+       return rh->region_size;
+}
+EXPORT_SYMBOL_GPL(dm_rh_get_region_size);
+
+/*
+ * FIXME: shall we pass in a structure instead of all these args to
+ * dm_region_hash_create()????
+ */
+#define RH_HASH_MULT 2654435387U
+#define RH_HASH_SHIFT 12
+
+#define MIN_REGIONS 64
+struct dm_region_hash *dm_region_hash_create(
+               void *context, void (*dispatch_bios)(void *context,
+                                                    struct bio_list *bios),
+               void (*wakeup_workers)(void *context),
+               void (*wakeup_all_recovery_waiters)(void *context),
+               sector_t target_begin, unsigned max_recovery,
+               struct dm_dirty_log *log, uint32_t region_size,
+               region_t nr_regions)
+{
+       struct dm_region_hash *rh;
+       unsigned nr_buckets, max_buckets;
+       size_t i;
+
+       /*
+        * Calculate a suitable number of buckets for our hash
+        * table.
+        */
+       max_buckets = nr_regions >> 6;
+       for (nr_buckets = 128u; nr_buckets < max_buckets; nr_buckets <<= 1)
+               ;
+       nr_buckets >>= 1;
+
+       rh = kmalloc(sizeof(*rh), GFP_KERNEL);
+       if (!rh) {
+               DMERR("unable to allocate region hash memory");
+               return ERR_PTR(-ENOMEM);
+       }
+
+       rh->context = context;
+       rh->dispatch_bios = dispatch_bios;
+       rh->wakeup_workers = wakeup_workers;
+       rh->wakeup_all_recovery_waiters = wakeup_all_recovery_waiters;
+       rh->target_begin = target_begin;
+       rh->max_recovery = max_recovery;
+       rh->log = log;
+       rh->region_size = region_size;
+       rh->region_shift = ffs(region_size) - 1;
+       rwlock_init(&rh->hash_lock);
+       rh->mask = nr_buckets - 1;
+       rh->nr_buckets = nr_buckets;
+
+       rh->shift = RH_HASH_SHIFT;
+       rh->prime = RH_HASH_MULT;
+
+       rh->buckets = vmalloc(nr_buckets * sizeof(*rh->buckets));
+       if (!rh->buckets) {
+               DMERR("unable to allocate region hash bucket memory");
+               kfree(rh);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       for (i = 0; i < nr_buckets; i++)
+               INIT_LIST_HEAD(rh->buckets + i);
+
+       spin_lock_init(&rh->region_lock);
+       sema_init(&rh->recovery_count, 0);
+       atomic_set(&rh->recovery_in_flight, 0);
+       INIT_LIST_HEAD(&rh->clean_regions);
+       INIT_LIST_HEAD(&rh->quiesced_regions);
+       INIT_LIST_HEAD(&rh->recovered_regions);
+       INIT_LIST_HEAD(&rh->failed_recovered_regions);
+
+       rh->region_pool = mempool_create_kmalloc_pool(MIN_REGIONS,
+                                                     sizeof(struct dm_region));
+       if (!rh->region_pool) {
+               vfree(rh->buckets);
+               kfree(rh);
+               rh = ERR_PTR(-ENOMEM);
+       }
+
+       return rh;
+}
+EXPORT_SYMBOL_GPL(dm_region_hash_create);
+
+void dm_region_hash_destroy(struct dm_region_hash *rh)
+{
+       unsigned h;
+       struct dm_region *reg, *nreg;
+
+       BUG_ON(!list_empty(&rh->quiesced_regions));
+       for (h = 0; h < rh->nr_buckets; h++) {
+               list_for_each_entry_safe(reg, nreg, rh->buckets + h,
+                                        hash_list) {
+                       BUG_ON(atomic_read(&reg->pending));
+                       mempool_free(reg, rh->region_pool);
+               }
+       }
+
+       if (rh->log)
+               dm_dirty_log_destroy(rh->log);
+
+       if (rh->region_pool)
+               mempool_destroy(rh->region_pool);
+
+       vfree(rh->buckets);
+       kfree(rh);
+}
+EXPORT_SYMBOL_GPL(dm_region_hash_destroy);
+
+struct dm_dirty_log *dm_rh_dirty_log(struct dm_region_hash *rh)
+{
+       return rh->log;
+}
+EXPORT_SYMBOL_GPL(dm_rh_dirty_log);
+
+static unsigned rh_hash(struct dm_region_hash *rh, region_t region)
+{
+       return (unsigned) ((region * rh->prime) >> rh->shift) & rh->mask;
+}
+
+static struct dm_region *__rh_lookup(struct dm_region_hash *rh, region_t region)
+{
+       struct dm_region *reg;
+       struct list_head *bucket = rh->buckets + rh_hash(rh, region);
+
+       list_for_each_entry(reg, bucket, hash_list)
+               if (reg->key == region)
+                       return reg;
+
+       return NULL;
+}
+
+static void __rh_insert(struct dm_region_hash *rh, struct dm_region *reg)
+{
+       list_add(&reg->hash_list, rh->buckets + rh_hash(rh, reg->key));
+}
+
+static struct dm_region *__rh_alloc(struct dm_region_hash *rh, region_t region)
+{
+       struct dm_region *reg, *nreg;
+
+       nreg = mempool_alloc(rh->region_pool, GFP_ATOMIC);
+       if (unlikely(!nreg))
+               nreg = kmalloc(sizeof(*nreg), GFP_NOIO);
+
+       nreg->state = rh->log->type->in_sync(rh->log, region, 1) ?
+                     DM_RH_CLEAN : DM_RH_NOSYNC;
+       nreg->rh = rh;
+       nreg->key = region;
+       INIT_LIST_HEAD(&nreg->list);
+       atomic_set(&nreg->pending, 0);
+       bio_list_init(&nreg->delayed_bios);
+
+       write_lock_irq(&rh->hash_lock);
+       reg = __rh_lookup(rh, region);
+       if (reg)
+               /* We lost the race. */
+               mempool_free(nreg, rh->region_pool);
+       else {
+               __rh_insert(rh, nreg);
+               if (nreg->state == DM_RH_CLEAN) {
+                       spin_lock(&rh->region_lock);
+                       list_add(&nreg->list, &rh->clean_regions);
+                       spin_unlock(&rh->region_lock);
+               }
+
+               reg = nreg;
+       }
+       write_unlock_irq(&rh->hash_lock);
+
+       return reg;
+}
+
+static struct dm_region *__rh_find(struct dm_region_hash *rh, region_t region)
+{
+       struct dm_region *reg;
+
+       reg = __rh_lookup(rh, region);
+       if (!reg) {
+               read_unlock(&rh->hash_lock);
+               reg = __rh_alloc(rh, region);
+               read_lock(&rh->hash_lock);
+       }
+
+       return reg;
+}
+
+int dm_rh_get_state(struct dm_region_hash *rh, region_t region, int may_block)
+{
+       int r;
+       struct dm_region *reg;
+
+       read_lock(&rh->hash_lock);
+       reg = __rh_lookup(rh, region);
+       read_unlock(&rh->hash_lock);
+
+       if (reg)
+               return reg->state;
+
+       /*
+        * The region wasn't in the hash, so we fall back to the
+        * dirty log.
+        */
+       r = rh->log->type->in_sync(rh->log, region, may_block);
+
+       /*
+        * Any error from the dirty log (eg. -EWOULDBLOCK) gets
+        * taken as a DM_RH_NOSYNC
+        */
+       return r == 1 ? DM_RH_CLEAN : DM_RH_NOSYNC;
+}
+EXPORT_SYMBOL_GPL(dm_rh_get_state);
+
+static void complete_resync_work(struct dm_region *reg, int success)
+{
+       struct dm_region_hash *rh = reg->rh;
+
+       rh->log->type->set_region_sync(rh->log, reg->key, success);
+
+       /*
+        * Dispatch the bios before we call 'wake_up_all'.
+        * This is important because if we are suspending,
+        * we want to know that recovery is complete and
+        * the work queue is flushed.  If we wake_up_all
+        * before we dispatch_bios (queue bios and call wake()),
+        * then we risk suspending before the work queue
+        * has been properly flushed.
+        */
+       rh->dispatch_bios(rh->context, &reg->delayed_bios);
+       if (atomic_dec_and_test(&rh->recovery_in_flight))
+               rh->wakeup_all_recovery_waiters(rh->context);
+       up(&rh->recovery_count);
+}
+
+/* dm_rh_mark_nosync
+ * @ms
+ * @bio
+ * @done
+ * @error
+ *
+ * The bio was written on some mirror(s) but failed on other mirror(s).
+ * We can successfully endio the bio but should avoid the region being
+ * marked clean by setting the state DM_RH_NOSYNC.
+ *
+ * This function is _not_ safe in interrupt context!
+ */
+void dm_rh_mark_nosync(struct dm_region_hash *rh,
+                      struct bio *bio, unsigned done, int error)
+{
+       unsigned long flags;
+       struct dm_dirty_log *log = rh->log;
+       struct dm_region *reg;
+       region_t region = dm_rh_bio_to_region(rh, bio);
+       int recovering = 0;
+
+       /* We must inform the log that the sync count has changed. */
+       log->type->set_region_sync(log, region, 0);
+
+       read_lock(&rh->hash_lock);
+       reg = __rh_find(rh, region);
+       read_unlock(&rh->hash_lock);
+
+       /* region hash entry should exist because write was in-flight */
+       BUG_ON(!reg);
+       BUG_ON(!list_empty(&reg->list));
+
+       spin_lock_irqsave(&rh->region_lock, flags);
+       /*
+        * Possible cases:
+        *   1) DM_RH_DIRTY
+        *   2) DM_RH_NOSYNC: was dirty, other preceeding writes failed
+        *   3) DM_RH_RECOVERING: flushing pending writes
+        * Either case, the region should have not been connected to list.
+        */
+       recovering = (reg->state == DM_RH_RECOVERING);
+       reg->state = DM_RH_NOSYNC;
+       BUG_ON(!list_empty(&reg->list));
+       spin_unlock_irqrestore(&rh->region_lock, flags);
+
+       bio_endio(bio, error);
+       if (recovering)
+               complete_resync_work(reg, 0);
+}
+EXPORT_SYMBOL_GPL(dm_rh_mark_nosync);
+
+void dm_rh_update_states(struct dm_region_hash *rh, int errors_handled)
+{
+       struct dm_region *reg, *next;
+
+       LIST_HEAD(clean);
+       LIST_HEAD(recovered);
+       LIST_HEAD(failed_recovered);
+
+       /*
+        * Quickly grab the lists.
+        */
+       write_lock_irq(&rh->hash_lock);
+       spin_lock(&rh->region_lock);
+       if (!list_empty(&rh->clean_regions)) {
+               list_splice_init(&rh->clean_regions, &clean);
+
+               list_for_each_entry(reg, &clean, list)
+                       list_del(&reg->hash_list);
+       }
+
+       if (!list_empty(&rh->recovered_regions)) {
+               list_splice_init(&rh->recovered_regions, &recovered);
+
+               list_for_each_entry(reg, &recovered, list)
+                       list_del(&reg->hash_list);
+       }
+
+       if (!list_empty(&rh->failed_recovered_regions)) {
+               list_splice_init(&rh->failed_recovered_regions,
+                                &failed_recovered);
+
+               list_for_each_entry(reg, &failed_recovered, list)
+                       list_del(&reg->hash_list);
+       }
+
+       spin_unlock(&rh->region_lock);
+       write_unlock_irq(&rh->hash_lock);
+
+       /*
+        * All the regions on the recovered and clean lists have
+        * now been pulled out of the system, so no need to do
+        * any more locking.
+        */
+       list_for_each_entry_safe(reg, next, &recovered, list) {
+               rh->log->type->clear_region(rh->log, reg->key);
+               complete_resync_work(reg, 1);
+               mempool_free(reg, rh->region_pool);
+       }
+
+       list_for_each_entry_safe(reg, next, &failed_recovered, list) {
+               complete_resync_work(reg, errors_handled ? 0 : 1);
+               mempool_free(reg, rh->region_pool);
+       }
+
+       list_for_each_entry_safe(reg, next, &clean, list) {
+               rh->log->type->clear_region(rh->log, reg->key);
+               mempool_free(reg, rh->region_pool);
+       }
+
+       rh->log->type->flush(rh->log);
+}
+EXPORT_SYMBOL_GPL(dm_rh_update_states);
+
+static void rh_inc(struct dm_region_hash *rh, region_t region)
+{
+       struct dm_region *reg;
+
+       read_lock(&rh->hash_lock);
+       reg = __rh_find(rh, region);
+
+       spin_lock_irq(&rh->region_lock);
+       atomic_inc(&reg->pending);
+
+       if (reg->state == DM_RH_CLEAN) {
+               reg->state = DM_RH_DIRTY;
+               list_del_init(&reg->list);      /* take off the clean list */
+               spin_unlock_irq(&rh->region_lock);
+
+               rh->log->type->mark_region(rh->log, reg->key);
+       } else
+               spin_unlock_irq(&rh->region_lock);
+
+
+       read_unlock(&rh->hash_lock);
+}
+
+void dm_rh_inc_pending(struct dm_region_hash *rh, struct bio_list *bios)
+{
+       struct bio *bio;
+
+       for (bio = bios->head; bio; bio = bio->bi_next)
+               rh_inc(rh, dm_rh_bio_to_region(rh, bio));
+}
+EXPORT_SYMBOL_GPL(dm_rh_inc_pending);
+
+void dm_rh_dec(struct dm_region_hash *rh, region_t region)
+{
+       unsigned long flags;
+       struct dm_region *reg;
+       int should_wake = 0;
+
+       read_lock(&rh->hash_lock);
+       reg = __rh_lookup(rh, region);
+       read_unlock(&rh->hash_lock);
+
+       spin_lock_irqsave(&rh->region_lock, flags);
+       if (atomic_dec_and_test(&reg->pending)) {
+               /*
+                * There is no pending I/O for this region.
+                * We can move the region to corresponding list for next action.
+                * At this point, the region is not yet connected to any list.
+                *
+                * If the state is DM_RH_NOSYNC, the region should be kept off
+                * from clean list.
+                * The hash entry for DM_RH_NOSYNC will remain in memory
+                * until the region is recovered or the map is reloaded.
+                */
+
+               /* do nothing for DM_RH_NOSYNC */
+               if (reg->state == DM_RH_RECOVERING) {
+                       list_add_tail(&reg->list, &rh->quiesced_regions);
+               } else if (reg->state == DM_RH_DIRTY) {
+                       reg->state = DM_RH_CLEAN;
+                       list_add(&reg->list, &rh->clean_regions);
+               }
+               should_wake = 1;
+       }
+       spin_unlock_irqrestore(&rh->region_lock, flags);
+
+       if (should_wake)
+               rh->wakeup_workers(rh->context);
+}
+EXPORT_SYMBOL_GPL(dm_rh_dec);
+
+/*
+ * Starts quiescing a region in preparation for recovery.
+ */
+static int __rh_recovery_prepare(struct dm_region_hash *rh)
+{
+       int r;
+       region_t region;
+       struct dm_region *reg;
+
+       /*
+        * Ask the dirty log what's next.
+        */
+       r = rh->log->type->get_resync_work(rh->log, &region);
+       if (r <= 0)
+               return r;
+
+       /*
+        * Get this region, and start it quiescing by setting the
+        * recovering flag.
+        */
+       read_lock(&rh->hash_lock);
+       reg = __rh_find(rh, region);
+       read_unlock(&rh->hash_lock);
+
+       spin_lock_irq(&rh->region_lock);
+       reg->state = DM_RH_RECOVERING;
+
+       /* Already quiesced ? */
+       if (atomic_read(&reg->pending))
+               list_del_init(&reg->list);
+       else
+               list_move(&reg->list, &rh->quiesced_regions);
+
+       spin_unlock_irq(&rh->region_lock);
+
+       return 1;
+}
+
+void dm_rh_recovery_prepare(struct dm_region_hash *rh)
+{
+       /* Extra reference to avoid race with dm_rh_stop_recovery */
+       atomic_inc(&rh->recovery_in_flight);
+
+       while (!down_trylock(&rh->recovery_count)) {
+               atomic_inc(&rh->recovery_in_flight);
+               if (__rh_recovery_prepare(rh) <= 0) {
+                       atomic_dec(&rh->recovery_in_flight);
+                       up(&rh->recovery_count);
+                       break;
+               }
+       }
+
+       /* Drop the extra reference */
+       if (atomic_dec_and_test(&rh->recovery_in_flight))
+               rh->wakeup_all_recovery_waiters(rh->context);
+}
+EXPORT_SYMBOL_GPL(dm_rh_recovery_prepare);
+
+/*
+ * Returns any quiesced regions.
+ */
+struct dm_region *dm_rh_recovery_start(struct dm_region_hash *rh)
+{
+       struct dm_region *reg = NULL;
+
+       spin_lock_irq(&rh->region_lock);
+       if (!list_empty(&rh->quiesced_regions)) {
+               reg = list_entry(rh->quiesced_regions.next,
+                                struct dm_region, list);
+               list_del_init(&reg->list);  /* remove from the quiesced list */
+       }
+       spin_unlock_irq(&rh->region_lock);
+
+       return reg;
+}
+EXPORT_SYMBOL_GPL(dm_rh_recovery_start);
+
+void dm_rh_recovery_end(struct dm_region *reg, int success)
+{
+       struct dm_region_hash *rh = reg->rh;
+
+       spin_lock_irq(&rh->region_lock);
+       if (success)
+               list_add(&reg->list, &reg->rh->recovered_regions);
+       else {
+               reg->state = DM_RH_NOSYNC;
+               list_add(&reg->list, &reg->rh->failed_recovered_regions);
+       }
+       spin_unlock_irq(&rh->region_lock);
+
+       rh->wakeup_workers(rh->context);
+}
+EXPORT_SYMBOL_GPL(dm_rh_recovery_end);
+
+/* Return recovery in flight count. */
+int dm_rh_recovery_in_flight(struct dm_region_hash *rh)
+{
+       return atomic_read(&rh->recovery_in_flight);
+}
+EXPORT_SYMBOL_GPL(dm_rh_recovery_in_flight);
+
+int dm_rh_flush(struct dm_region_hash *rh)
+{
+       return rh->log->type->flush(rh->log);
+}
+EXPORT_SYMBOL_GPL(dm_rh_flush);
+
+void dm_rh_delay(struct dm_region_hash *rh, struct bio *bio)
+{
+       struct dm_region *reg;
+
+       read_lock(&rh->hash_lock);
+       reg = __rh_find(rh, dm_rh_bio_to_region(rh, bio));
+       bio_list_add(&reg->delayed_bios, bio);
+       read_unlock(&rh->hash_lock);
+}
+EXPORT_SYMBOL_GPL(dm_rh_delay);
+
+void dm_rh_stop_recovery(struct dm_region_hash *rh)
+{
+       int i;
+
+       /* wait for any recovering regions */
+       for (i = 0; i < rh->max_recovery; i++)
+               down(&rh->recovery_count);
+}
+EXPORT_SYMBOL_GPL(dm_rh_stop_recovery);
+
+void dm_rh_start_recovery(struct dm_region_hash *rh)
+{
+       int i;
+
+       for (i = 0; i < rh->max_recovery; i++)
+               up(&rh->recovery_count);
+
+       rh->wakeup_workers(rh->context);
+}
+EXPORT_SYMBOL_GPL(dm_rh_start_recovery);
+
+MODULE_DESCRIPTION(DM_NAME " region hash");
+MODULE_AUTHOR("Joe Thornber/Heinz Mauelshagen <dm-devel@redhat.com>");
+MODULE_LICENSE("GPL");
index 391dfa2ad4347a690d8bc4636515ebfff39a5f08..cdfbf65b28cb0fb5d4af95d9e6718d80d69be760 100644 (file)
@@ -9,7 +9,8 @@
  * Round-robin path selector.
  */
 
-#include "dm.h"
+#include <linux/device-mapper.h>
+
 #include "dm-path-selector.h"
 
 #include <linux/slab.h>
index 6e5528aecc98c38698a6d2a07a18e1e84164a7ab..b2d9d1ac28adb4554537fd3568ae4fe52e748a41 100644 (file)
@@ -600,7 +600,6 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 
        s->valid = 1;
        s->active = 0;
-       s->last_percent = 0;
        init_rwsem(&s->lock);
        spin_lock_init(&s->pe_lock);
        s->ti = ti;
@@ -824,8 +823,10 @@ static struct bio *put_pending_exception(struct dm_snap_pending_exception *pe)
         * the bios for the original write to the origin.
         */
        if (primary_pe &&
-           atomic_dec_and_test(&primary_pe->ref_count))
+           atomic_dec_and_test(&primary_pe->ref_count)) {
                origin_bios = bio_list_get(&primary_pe->origin_bios);
+               free_pending_exception(primary_pe);
+       }
 
        /*
         * Free the pe if it's not linked to an origin write or if
@@ -834,12 +835,6 @@ static struct bio *put_pending_exception(struct dm_snap_pending_exception *pe)
        if (!primary_pe || primary_pe != pe)
                free_pending_exception(pe);
 
-       /*
-        * Free the primary pe if nothing references it.
-        */
-       if (primary_pe && !atomic_read(&primary_pe->ref_count))
-               free_pending_exception(primary_pe);
-
        return origin_bios;
 }
 
index 292c15609ae362fc344a9c46811285319a3f1bec..f07315fe23621e706bae67ab240d2bb8d89c42d3 100644 (file)
@@ -9,7 +9,7 @@
 #ifndef DM_SNAPSHOT_H
 #define DM_SNAPSHOT_H
 
-#include "dm.h"
+#include <linux/device-mapper.h>
 #include "dm-bio-list.h"
 #include <linux/blkdev.h>
 #include <linux/workqueue.h>
@@ -158,9 +158,6 @@ struct dm_snapshot {
        /* Used for display of table */
        char type;
 
-       /* The last percentage we notified */
-       int last_percent;
-
        mempool_t *pending_pool;
 
        struct exception_table pending;
index b745d8ac625b5ffd6730f585e95fec2081cf8429..a2d068dbe9e2669dc25290a09e8918b4b5c2f28f 100644 (file)
@@ -4,7 +4,7 @@
  * This file is released under the GPL.
  */
 
-#include "dm.h"
+#include <linux/device-mapper.h>
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -60,8 +60,8 @@ static inline struct stripe_c *alloc_context(unsigned int stripes)
 {
        size_t len;
 
-       if (array_too_big(sizeof(struct stripe_c), sizeof(struct stripe),
-                         stripes))
+       if (dm_array_too_big(sizeof(struct stripe_c), sizeof(struct stripe),
+                            stripes))
                return NULL;
 
        len = sizeof(struct stripe_c) + (sizeof(struct stripe) * stripes);
index a740a6950f598ce44eb7ee285b48f057ef19cd83..a63161aec48750ef51feb6e6e506c7ff83044dc0 100644 (file)
@@ -43,7 +43,7 @@ struct dm_table {
         * device.  This should be a combination of FMODE_READ
         * and FMODE_WRITE.
         */
-       int mode;
+       fmode_t mode;
 
        /* a list of devices used by this table */
        struct list_head devices;
@@ -217,7 +217,7 @@ static int alloc_targets(struct dm_table *t, unsigned int num)
        return 0;
 }
 
-int dm_table_create(struct dm_table **result, int mode,
+int dm_table_create(struct dm_table **result, fmode_t mode,
                    unsigned num_targets, struct mapped_device *md)
 {
        struct dm_table *t = kzalloc(sizeof(*t), GFP_KERNEL);
@@ -312,19 +312,6 @@ static inline int check_space(struct dm_table *t)
        return 0;
 }
 
-/*
- * Convert a device path to a dev_t.
- */
-static int lookup_device(const char *path, dev_t *dev)
-{
-       struct block_device *bdev = lookup_bdev(path);
-       if (IS_ERR(bdev))
-               return PTR_ERR(bdev);
-       *dev = bdev->bd_dev;
-       bdput(bdev);
-       return 0;
-}
-
 /*
  * See if we've already got a device in the list.
  */
@@ -357,7 +344,7 @@ static int open_dev(struct dm_dev_internal *d, dev_t dev,
                return PTR_ERR(bdev);
        r = bd_claim_by_disk(bdev, _claim_ptr, dm_disk(md));
        if (r)
-               blkdev_put(bdev);
+               blkdev_put(bdev, d->dm_dev.mode);
        else
                d->dm_dev.bdev = bdev;
        return r;
@@ -372,7 +359,7 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md)
                return;
 
        bd_release_from_disk(d->dm_dev.bdev, dm_disk(md));
-       blkdev_put(d->dm_dev.bdev);
+       blkdev_put(d->dm_dev.bdev, d->dm_dev.mode);
        d->dm_dev.bdev = NULL;
 }
 
@@ -395,7 +382,7 @@ static int check_device_area(struct dm_dev_internal *dd, sector_t start,
  * careful to leave things as they were if we fail to reopen the
  * device.
  */
-static int upgrade_mode(struct dm_dev_internal *dd, int new_mode,
+static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode,
                        struct mapped_device *md)
 {
        int r;
@@ -421,7 +408,7 @@ static int upgrade_mode(struct dm_dev_internal *dd, int new_mode,
  */
 static int __table_get_device(struct dm_table *t, struct dm_target *ti,
                              const char *path, sector_t start, sector_t len,
-                             int mode, struct dm_dev **result)
+                             fmode_t mode, struct dm_dev **result)
 {
        int r;
        dev_t uninitialized_var(dev);
@@ -437,8 +424,12 @@ static int __table_get_device(struct dm_table *t, struct dm_target *ti,
                        return -EOVERFLOW;
        } else {
                /* convert the path to a device */
-               if ((r = lookup_device(path, &dev)))
-                       return r;
+               struct block_device *bdev = lookup_bdev(path);
+
+               if (IS_ERR(bdev))
+                       return PTR_ERR(bdev);
+               dev = bdev->bd_dev;
+               bdput(bdev);
        }
 
        dd = find_device(&t->devices, dev);
@@ -537,7 +528,7 @@ void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev)
 EXPORT_SYMBOL_GPL(dm_set_device_limits);
 
 int dm_get_device(struct dm_target *ti, const char *path, sector_t start,
-                 sector_t len, int mode, struct dm_dev **result)
+                 sector_t len, fmode_t mode, struct dm_dev **result)
 {
        int r = __table_get_device(ti->table, ti, path,
                                   start, len, mode, result);
@@ -887,7 +878,7 @@ struct list_head *dm_table_get_devices(struct dm_table *t)
        return &t->devices;
 }
 
-int dm_table_get_mode(struct dm_table *t)
+fmode_t dm_table_get_mode(struct dm_table *t)
 {
        return t->mode;
 }
index bdec206c404bcbbe70db8ce82546072dd8ea9ee0..cdbf126ec10651f6632bfed0401598e3ced361d5 100644 (file)
@@ -4,7 +4,7 @@
  * This file is released under the GPL.
  */
 
-#include "dm.h"
+#include <linux/device-mapper.h>
 
 #include <linux/module.h>
 #include <linux/init.h>
index 327de03a5bdfed7f11b0904abb72f3eac65fc92d..6963ad1484082bf5d0f8009c60aa1db18eb980c1 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/idr.h>
 #include <linux/hdreg.h>
 #include <linux/blktrace_api.h>
-#include <linux/smp_lock.h>
 
 #define DM_MSG_PREFIX "core"
 
@@ -76,7 +75,6 @@ union map_info *dm_get_mapinfo(struct bio *bio)
  */
 struct dm_wq_req {
        enum {
-               DM_WQ_FLUSH_ALL,
                DM_WQ_FLUSH_DEFERRED,
        } type;
        struct work_struct work;
@@ -151,40 +149,40 @@ static struct kmem_cache *_tio_cache;
 
 static int __init local_init(void)
 {
-       int r;
+       int r = -ENOMEM;
 
        /* allocate a slab for the dm_ios */
        _io_cache = KMEM_CACHE(dm_io, 0);
        if (!_io_cache)
-               return -ENOMEM;
+               return r;
 
        /* allocate a slab for the target ios */
        _tio_cache = KMEM_CACHE(dm_target_io, 0);
-       if (!_tio_cache) {
-               kmem_cache_destroy(_io_cache);
-               return -ENOMEM;
-       }
+       if (!_tio_cache)
+               goto out_free_io_cache;
 
        r = dm_uevent_init();
-       if (r) {
-               kmem_cache_destroy(_tio_cache);
-               kmem_cache_destroy(_io_cache);
-               return r;
-       }
+       if (r)
+               goto out_free_tio_cache;
 
        _major = major;
        r = register_blkdev(_major, _name);
-       if (r < 0) {
-               kmem_cache_destroy(_tio_cache);
-               kmem_cache_destroy(_io_cache);
-               dm_uevent_exit();
-               return r;
-       }
+       if (r < 0)
+               goto out_uevent_exit;
 
        if (!_major)
                _major = r;
 
        return 0;
+
+out_uevent_exit:
+       dm_uevent_exit();
+out_free_tio_cache:
+       kmem_cache_destroy(_tio_cache);
+out_free_io_cache:
+       kmem_cache_destroy(_io_cache);
+
+       return r;
 }
 
 static void local_exit(void)
@@ -249,13 +247,13 @@ static void __exit dm_exit(void)
 /*
  * Block device functions
  */
-static int dm_blk_open(struct inode *inode, struct file *file)
+static int dm_blk_open(struct block_device *bdev, fmode_t mode)
 {
        struct mapped_device *md;
 
        spin_lock(&_minor_lock);
 
-       md = inode->i_bdev->bd_disk->private_data;
+       md = bdev->bd_disk->private_data;
        if (!md)
                goto out;
 
@@ -274,11 +272,9 @@ out:
        return md ? 0 : -ENXIO;
 }
 
-static int dm_blk_close(struct inode *inode, struct file *file)
+static int dm_blk_close(struct gendisk *disk, fmode_t mode)
 {
-       struct mapped_device *md;
-
-       md = inode->i_bdev->bd_disk->private_data;
+       struct mapped_device *md = disk->private_data;
        atomic_dec(&md->open_count);
        dm_put(md);
        return 0;
@@ -315,21 +311,14 @@ static int dm_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
        return dm_get_geometry(md, geo);
 }
 
-static int dm_blk_ioctl(struct inode *inode, struct file *file,
+static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode,
                        unsigned int cmd, unsigned long arg)
 {
-       struct mapped_device *md;
-       struct dm_table *map;
+       struct mapped_device *md = bdev->bd_disk->private_data;
+       struct dm_table *map = dm_get_table(md);
        struct dm_target *tgt;
        int r = -ENOTTY;
 
-       /* We don't really need this lock, but we do need 'inode'. */
-       unlock_kernel();
-
-       md = inode->i_bdev->bd_disk->private_data;
-
-       map = dm_get_table(md);
-
        if (!map || !dm_table_get_size(map))
                goto out;
 
@@ -345,12 +334,11 @@ static int dm_blk_ioctl(struct inode *inode, struct file *file,
        }
 
        if (tgt->type->ioctl)
-               r = tgt->type->ioctl(tgt, inode, file, cmd, arg);
+               r = tgt->type->ioctl(tgt, cmd, arg);
 
 out:
        dm_table_put(map);
 
-       lock_kernel();
        return r;
 }
 
@@ -669,6 +657,7 @@ static struct bio *split_bvec(struct bio *bio, sector_t sector,
        clone->bi_size = to_bytes(len);
        clone->bi_io_vec->bv_offset = offset;
        clone->bi_io_vec->bv_len = clone->bi_size;
+       clone->bi_flags |= 1 << BIO_CLONED;
 
        return clone;
 }
@@ -1394,9 +1383,6 @@ static void dm_wq_work(struct work_struct *work)
 
        down_write(&md->io_lock);
        switch (req->type) {
-       case DM_WQ_FLUSH_ALL:
-               __merge_pushback_list(md);
-               /* pass through */
        case DM_WQ_FLUSH_DEFERRED:
                __flush_deferred_io(md);
                break;
@@ -1526,7 +1512,7 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
                if (!md->suspended_bdev) {
                        DMWARN("bdget failed in dm_suspend");
                        r = -ENOMEM;
-                       goto flush_and_out;
+                       goto out;
                }
 
                /*
@@ -1577,14 +1563,6 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
 
        set_bit(DMF_SUSPENDED, &md->flags);
 
-flush_and_out:
-       if (r && noflush)
-               /*
-                * Because there may be already I/Os in the pushback list,
-                * flush them before return.
-                */
-               dm_queue_flush(md, DM_WQ_FLUSH_ALL, NULL);
-
 out:
        if (r && md->suspended_bdev) {
                bdput(md->suspended_bdev);
index cd189da2b2fa1fbad7293f152f0744b7bdbb8c35..0ade60cdef42dd062bf8f11210ee27b65dd651d2 100644 (file)
@@ -62,15 +62,6 @@ void dm_put_target_type(struct target_type *t);
 int dm_target_iterate(void (*iter_func)(struct target_type *tt,
                                        void *param), void *param);
 
-/*-----------------------------------------------------------------
- * Useful inlines.
- *---------------------------------------------------------------*/
-static inline int array_too_big(unsigned long fixed, unsigned long obj,
-                               unsigned long num)
-{
-       return (num > (ULONG_MAX - fixed) / obj);
-}
-
 int dm_split_args(int *argc, char ***argvp, char *input);
 
 /*
index aaa3d465de4ece202bd3a18c1c605248ebd40ad7..c1a837ca193c26c4c74af8c975b76201005c2533 100644 (file)
@@ -1520,7 +1520,7 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev, int shared)
        if (err) {
                printk(KERN_ERR "md: could not bd_claim %s.\n",
                        bdevname(bdev, b));
-               blkdev_put(bdev);
+               blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
                return err;
        }
        if (!shared)
@@ -1536,7 +1536,7 @@ static void unlock_rdev(mdk_rdev_t *rdev)
        if (!bdev)
                MD_BUG();
        bd_release(bdev);
-       blkdev_put(bdev);
+       blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
 }
 
 void md_autodetect_dev(dev_t dev);
@@ -4785,7 +4785,7 @@ static int md_getgeo(struct block_device *bdev, struct hd_geometry *geo)
        return 0;
 }
 
-static int md_ioctl(struct inode *inode, struct file *file,
+static int md_ioctl(struct block_device *bdev, fmode_t mode,
                        unsigned int cmd, unsigned long arg)
 {
        int err = 0;
@@ -4823,7 +4823,7 @@ static int md_ioctl(struct inode *inode, struct file *file,
         * Commands creating/starting a new array:
         */
 
-       mddev = inode->i_bdev->bd_disk->private_data;
+       mddev = bdev->bd_disk->private_data;
 
        if (!mddev) {
                BUG();
@@ -4996,13 +4996,13 @@ abort:
        return err;
 }
 
-static int md_open(struct inode *inode, struct file *file)
+static int md_open(struct block_device *bdev, fmode_t mode)
 {
        /*
         * Succeed if we can lock the mddev, which confirms that
         * it isn't being stopped right now.
         */
-       mddev_t *mddev = inode->i_bdev->bd_disk->private_data;
+       mddev_t *mddev = bdev->bd_disk->private_data;
        int err;
 
        if ((err = mutex_lock_interruptible_nested(&mddev->reconfig_mutex, 1)))
@@ -5013,14 +5013,14 @@ static int md_open(struct inode *inode, struct file *file)
        atomic_inc(&mddev->openers);
        mddev_unlock(mddev);
 
-       check_disk_change(inode->i_bdev);
+       check_disk_change(bdev);
  out:
        return err;
 }
 
-static int md_release(struct inode *inode, struct file * file)
+static int md_release(struct gendisk *disk, fmode_t mode)
 {
-       mddev_t *mddev = inode->i_bdev->bd_disk->private_data;
+       mddev_t *mddev = disk->private_data;
 
        BUG_ON(!mddev);
        atomic_dec(&mddev->openers);
@@ -5048,7 +5048,7 @@ static struct block_device_operations md_fops =
        .owner          = THIS_MODULE,
        .open           = md_open,
        .release        = md_release,
-       .ioctl          = md_ioctl,
+       .locked_ioctl   = md_ioctl,
        .getgeo         = md_getgeo,
        .media_changed  = md_media_changed,
        .revalidate_disk= md_revalidate,
index 5b34c134aa25147dc118a3cc44a3ba49365166f6..127b0526a727f15ac9bf6f570e05ac0f352c08a7 100644 (file)
@@ -545,11 +545,11 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
        if( VFL_TYPE_GRABBER == type ) {
                vv->video_minor = vfd->minor;
                INFO(("%s: registered device video%d [v4l2]\n",
-                       dev->name, vfd->minor & 0x1f));
+                       dev->name, vfd->num));
        } else {
                vv->vbi_minor = vfd->minor;
                INFO(("%s: registered device vbi%d [v4l2]\n",
-                       dev->name, vfd->minor & 0x1f));
+                       dev->name, vfd->num));
        }
 
        *vid = vfd;
index 99be9e5c85f78c5221a4107ff06233e70a36e242..fe0bd55977e32a1c1858597ffcbf53314eec2071 100644 (file)
@@ -834,7 +834,7 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
  * copying is done already, arg is a kernel pointer.
  */
 
-int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg)
+static int __saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 {
        struct saa7146_fh *fh  = file->private_data;
        struct saa7146_dev *dev = fh->dev;
@@ -1215,12 +1215,18 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
        }
 #endif
        default:
-               return v4l_compat_translate_ioctl(inode,file,cmd,arg,
-                                                 saa7146_video_do_ioctl);
+               return v4l_compat_translate_ioctl(file, cmd, arg,
+                                                 __saa7146_video_do_ioctl);
        }
        return 0;
 }
 
+int saa7146_video_do_ioctl(struct inode *inode, struct file *file,
+                                   unsigned int cmd, void *arg)
+{
+       return __saa7146_video_do_ioctl(file, cmd, arg);
+}
+
 /*********************************************************************************/
 /* buffer handling functions                                                  */
 
index 2febfb5a846bc0922e31d75daf779c7cb0fe5ed3..40644aacffcb218dbbee77ee8a8b80e15b2b0164 100644 (file)
@@ -38,6 +38,7 @@ struct s5h1411_state {
        struct dvb_frontend frontend;
 
        fe_modulation_t current_modulation;
+       unsigned int first_tune:1;
 
        u32 current_frequency;
        int if_freq;
@@ -62,7 +63,7 @@ static struct init_tab {
        { S5H1411_I2C_TOP_ADDR, 0x08, 0x0047, },
        { S5H1411_I2C_TOP_ADDR, 0x1c, 0x0400, },
        { S5H1411_I2C_TOP_ADDR, 0x1e, 0x0370, },
-       { S5H1411_I2C_TOP_ADDR, 0x1f, 0x342a, },
+       { S5H1411_I2C_TOP_ADDR, 0x1f, 0x342c, },
        { S5H1411_I2C_TOP_ADDR, 0x24, 0x0231, },
        { S5H1411_I2C_TOP_ADDR, 0x25, 0x1011, },
        { S5H1411_I2C_TOP_ADDR, 0x26, 0x0f07, },
@@ -100,7 +101,6 @@ static struct init_tab {
        { S5H1411_I2C_TOP_ADDR, 0x78, 0x3141, },
        { S5H1411_I2C_TOP_ADDR, 0x7a, 0x3141, },
        { S5H1411_I2C_TOP_ADDR, 0xb3, 0x8003, },
-       { S5H1411_I2C_TOP_ADDR, 0xb5, 0xafbb, },
        { S5H1411_I2C_TOP_ADDR, 0xb5, 0xa6bb, },
        { S5H1411_I2C_TOP_ADDR, 0xb6, 0x0609, },
        { S5H1411_I2C_TOP_ADDR, 0xb7, 0x2f06, },
@@ -393,7 +393,7 @@ static int s5h1411_set_if_freq(struct dvb_frontend *fe, int KHz)
 
        switch (KHz) {
        case 3250:
-               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x10d9);
+               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x10d5);
                s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x5342);
                s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x10d9);
                break;
@@ -464,13 +464,25 @@ static int s5h1411_set_spectralinversion(struct dvb_frontend *fe, int inversion)
 
        if (inversion == 1)
                val |= 0x1000; /* Inverted */
-       else
-               val |= 0x0000;
 
        state->inversion = inversion;
        return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x24, val);
 }
 
+static int s5h1411_set_serialmode(struct dvb_frontend *fe, int serial)
+{
+       struct s5h1411_state *state = fe->demodulator_priv;
+       u16 val;
+
+       dprintk("%s(%d)\n", __func__, serial);
+       val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xbd) & ~0x100;
+
+       if (serial == 1)
+               val |= 0x100;
+
+       return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, val);
+}
+
 static int s5h1411_enable_modulation(struct dvb_frontend *fe,
                                     fe_modulation_t m)
 {
@@ -478,6 +490,12 @@ static int s5h1411_enable_modulation(struct dvb_frontend *fe,
 
        dprintk("%s(0x%08x)\n", __func__, m);
 
+       if ((state->first_tune == 0) && (m == state->current_modulation)) {
+               dprintk("%s() Already at desired modulation.  Skipping...\n",
+                       __func__);
+               return 0;
+       }
+
        switch (m) {
        case VSB_8:
                dprintk("%s() VSB_8\n", __func__);
@@ -502,6 +520,7 @@ static int s5h1411_enable_modulation(struct dvb_frontend *fe,
        }
 
        state->current_modulation = m;
+       state->first_tune = 0;
        s5h1411_softreset(fe);
 
        return 0;
@@ -535,7 +554,7 @@ static int s5h1411_set_gpio(struct dvb_frontend *fe, int enable)
                return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0, val);
 }
 
-static int s5h1411_sleep(struct dvb_frontend *fe, int enable)
+static int s5h1411_set_powerstate(struct dvb_frontend *fe, int enable)
 {
        struct s5h1411_state *state = fe->demodulator_priv;
 
@@ -551,6 +570,11 @@ static int s5h1411_sleep(struct dvb_frontend *fe, int enable)
        return 0;
 }
 
+static int s5h1411_sleep(struct dvb_frontend *fe)
+{
+       return s5h1411_set_powerstate(fe, 1);
+}
+
 static int s5h1411_register_reset(struct dvb_frontend *fe)
 {
        struct s5h1411_state *state = fe->demodulator_priv;
@@ -574,9 +598,6 @@ static int s5h1411_set_frontend(struct dvb_frontend *fe,
 
        s5h1411_enable_modulation(fe, p->u.vsb.modulation);
 
-       /* Allow the demod to settle */
-       msleep(100);
-
        if (fe->ops.tuner_ops.set_params) {
                if (fe->ops.i2c_gate_ctrl)
                        fe->ops.i2c_gate_ctrl(fe, 1);
@@ -587,6 +608,10 @@ static int s5h1411_set_frontend(struct dvb_frontend *fe,
                        fe->ops.i2c_gate_ctrl(fe, 0);
        }
 
+       /* Issue a reset to the demod so it knows to resync against the
+          newly tuned frequency */
+       s5h1411_softreset(fe);
+
        return 0;
 }
 
@@ -599,7 +624,7 @@ static int s5h1411_init(struct dvb_frontend *fe)
 
        dprintk("%s()\n", __func__);
 
-       s5h1411_sleep(fe, 0);
+       s5h1411_set_powerstate(fe, 0);
        s5h1411_register_reset(fe);
 
        for (i = 0; i < ARRAY_SIZE(init_tab); i++)
@@ -610,12 +635,17 @@ static int s5h1411_init(struct dvb_frontend *fe)
        /* The datasheet says that after initialisation, VSB is default */
        state->current_modulation = VSB_8;
 
+       /* Although the datasheet says it's in VSB, empirical evidence
+          shows problems getting lock on the first tuning request.  Make
+          sure we call enable_modulation the first time around */
+       state->first_tune = 1;
+
        if (state->config->output_mode == S5H1411_SERIAL_OUTPUT)
                /* Serial */
-               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, 0x1101);
+               s5h1411_set_serialmode(fe, 1);
        else
                /* Parallel */
-               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, 0x1001);
+               s5h1411_set_serialmode(fe, 0);
 
        s5h1411_set_spectralinversion(fe, state->config->inversion);
        s5h1411_set_if_freq(fe, state->config->vsb_if);
@@ -637,28 +667,29 @@ static int s5h1411_read_status(struct dvb_frontend *fe, fe_status_t *status)
 
        *status = 0;
 
-       /* Get the demodulator status */
-       reg = (s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf2) >> 15)
-               & 0x0001;
-       if (reg)
-               *status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_SIGNAL;
+       /* Register F2 bit 15 = Master Lock, removed */
 
        switch (state->current_modulation) {
        case QAM_64:
        case QAM_256:
                reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf0);
-               if (reg & 0x100)
-                       *status |= FE_HAS_VITERBI;
-               if (reg & 0x10)
-                       *status |= FE_HAS_SYNC;
+               if (reg & 0x10) /* QAM FEC Lock */
+                       *status |= FE_HAS_SYNC | FE_HAS_LOCK;
+               if (reg & 0x100) /* QAM EQ Lock */
+                       *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL;
+
                break;
        case VSB_8:
-               reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x5e);
-               if (reg & 0x0001)
-                       *status |= FE_HAS_SYNC;
                reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf2);
-               if (reg & 0x1000)
-                       *status |= FE_HAS_VITERBI;
+               if (reg & 0x1000) /* FEC Lock */
+                       *status |= FE_HAS_SYNC | FE_HAS_LOCK;
+               if (reg & 0x2000) /* EQ Lock */
+                       *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL;
+
+               reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x53);
+               if (reg & 0x1) /* AFC Lock */
+                       *status |= FE_HAS_SIGNAL;
+
                break;
        default:
                return -EINVAL;
@@ -863,6 +894,7 @@ static struct dvb_frontend_ops s5h1411_ops = {
        },
 
        .init                 = s5h1411_init,
+       .sleep                = s5h1411_sleep,
        .i2c_gate_ctrl        = s5h1411_i2c_gate_ctrl,
        .set_frontend         = s5h1411_set_frontend,
        .get_frontend         = s5h1411_get_frontend,
index 7d542bc00c487e9ad9c27e92d2c2f12e9e3d9642..45ec0f82989c46f29ee628318afade0853bb6f57 100644 (file)
@@ -47,7 +47,7 @@ struct s5h1411_config {
        u16 mpeg_timing;
 
        /* IF Freq for QAM and VSB in KHz */
-#define S5H1411_IF_2500  2500
+#define S5H1411_IF_3250  3250
 #define S5H1411_IF_3500  3500
 #define S5H1411_IF_4000  4000
 #define S5H1411_IF_5380  5380
index 78f56944e640f53b53e37273f436ac3490e045db..a5ca176a7b083a80ef5201d2ac57d1a3475bbbbb 100644 (file)
@@ -171,11 +171,11 @@ static int dsbr100_start(struct dsbr100_device *radio)
        if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
                        USB_REQ_GET_STATUS,
                        USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
-                       0x00, 0xC7, radio->transfer_buffer, 8, 300)<0 ||
+                       0x00, 0xC7, radio->transfer_buffer, 8, 300) < 0 ||
        usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
                        DSB100_ONOFF,
                        USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
-                       0x01, 0x00, radio->transfer_buffer, 8, 300)<0)
+                       0x01, 0x00, radio->transfer_buffer, 8, 300) < 0)
                return -1;
        radio->muted=0;
        return (radio->transfer_buffer)[0];
@@ -188,11 +188,11 @@ static int dsbr100_stop(struct dsbr100_device *radio)
        if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
                        USB_REQ_GET_STATUS,
                        USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
-                       0x16, 0x1C, radio->transfer_buffer, 8, 300)<0 ||
+                       0x16, 0x1C, radio->transfer_buffer, 8, 300) < 0 ||
        usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
                        DSB100_ONOFF,
                        USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
-                       0x00, 0x00, radio->transfer_buffer, 8, 300)<0)
+                       0x00, 0x00, radio->transfer_buffer, 8, 300) < 0)
                return -1;
        radio->muted=1;
        return (radio->transfer_buffer)[0];
@@ -201,24 +201,24 @@ static int dsbr100_stop(struct dsbr100_device *radio)
 /* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
 static int dsbr100_setfreq(struct dsbr100_device *radio, int freq)
 {
-       freq = (freq/16*80)/1000+856;
+       freq = (freq / 16 * 80) / 1000 + 856;
        if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
                        DSB100_TUNE,
                        USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
-                       (freq>>8)&0x00ff, freq&0xff,
-                       radio->transfer_buffer, 8, 300)<0 ||
+                       (freq >> 8) & 0x00ff, freq & 0xff,
+                       radio->transfer_buffer, 8, 300) < 0 ||
           usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
                        USB_REQ_GET_STATUS,
                        USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
-                       0x96, 0xB7, radio->transfer_buffer, 8, 300)<0 ||
+                       0x96, 0xB7, radio->transfer_buffer, 8, 300) < 0 ||
        usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
                        USB_REQ_GET_STATUS,
                        USB_TYPE_VENDOR | USB_RECIP_DEVICE |  USB_DIR_IN,
-                       0x00, 0x24, radio->transfer_buffer, 8, 300)<0) {
+                       0x00, 0x24, radio->transfer_buffer, 8, 300) < 0) {
                radio->stereo = -1;
                return -1;
        }
-       radio->stereo = ! ((radio->transfer_buffer)[0]&0x01);
+       radio->stereo = !((radio->transfer_buffer)[0] & 0x01);
        return (radio->transfer_buffer)[0];
 }
 
@@ -229,10 +229,10 @@ static void dsbr100_getstat(struct dsbr100_device *radio)
        if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
                USB_REQ_GET_STATUS,
                USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
-               0x00 , 0x24, radio->transfer_buffer, 8, 300)<0)
+               0x00 , 0x24, radio->transfer_buffer, 8, 300) < 0)
                radio->stereo = -1;
        else
-               radio->stereo = ! (radio->transfer_buffer[0]&0x01);
+               radio->stereo = !(radio->transfer_buffer[0] & 0x01);
 }
 
 
@@ -265,7 +265,7 @@ static int vidioc_querycap(struct file *file, void *priv,
 {
        strlcpy(v->driver, "dsbr100", sizeof(v->driver));
        strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof(v->card));
-       sprintf(v->bus_info, "ISA");
+       sprintf(v->bus_info, "USB");
        v->version = RADIO_VERSION;
        v->capabilities = V4L2_CAP_TUNER;
        return 0;
@@ -282,9 +282,9 @@ static int vidioc_g_tuner(struct file *file, void *priv,
        dsbr100_getstat(radio);
        strcpy(v->name, "FM");
        v->type = V4L2_TUNER_RADIO;
-       v->rangelow = FREQ_MIN*FREQ_MUL;
-       v->rangehigh = FREQ_MAX*FREQ_MUL;
-       v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+       v->rangelow = FREQ_MIN * FREQ_MUL;
+       v->rangehigh = FREQ_MAX * FREQ_MUL;
+       v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
        v->capability = V4L2_TUNER_CAP_LOW;
        if(radio->stereo)
                v->audmode = V4L2_TUNER_MODE_STEREO;
@@ -309,7 +309,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
        struct dsbr100_device *radio = video_drvdata(file);
 
        radio->curfreq = f->frequency;
-       if (dsbr100_setfreq(radio, radio->curfreq)==-1)
+       if (dsbr100_setfreq(radio, radio->curfreq) == -1)
                dev_warn(&radio->usbdev->dev, "Set frequency failed\n");
        return 0;
 }
@@ -331,8 +331,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
 
        for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
                if (qc->id && qc->id == radio_qctrl[i].id) {
-                       memcpy(qc, &(radio_qctrl[i]),
-                                               sizeof(*qc));
+                       memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
                        return 0;
                }
        }
@@ -412,19 +411,25 @@ static int vidioc_s_audio(struct file *file, void *priv,
 static int usb_dsbr100_open(struct inode *inode, struct file *file)
 {
        struct dsbr100_device *radio = video_drvdata(file);
+       int retval;
 
        lock_kernel();
        radio->users = 1;
        radio->muted = 1;
 
-       if (dsbr100_start(radio)<0) {
+       if (dsbr100_start(radio) < 0) {
                dev_warn(&radio->usbdev->dev,
                         "Radio did not start up properly\n");
                radio->users = 0;
                unlock_kernel();
                return -EIO;
        }
-       dsbr100_setfreq(radio, radio->curfreq);
+
+       retval = dsbr100_setfreq(radio, radio->curfreq);
+
+       if (retval == -1)
+               printk(KERN_WARNING KBUILD_MODNAME ": Set frequency failed\n");
+
        unlock_kernel();
        return 0;
 }
@@ -485,13 +490,20 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
 {
        struct dsbr100_device *radio;
 
-       if (!(radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL)))
+       radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL);
+
+       if (!radio)
                return -ENOMEM;
-       if (!(radio->transfer_buffer = kmalloc(TB_LEN, GFP_KERNEL))) {
+
+       radio->transfer_buffer = kmalloc(TB_LEN, GFP_KERNEL);
+
+       if (!(radio->transfer_buffer)) {
                kfree(radio);
                return -ENOMEM;
        }
-       if (!(radio->videodev = video_device_alloc())) {
+       radio->videodev = video_device_alloc();
+
+       if (!(radio->videodev)) {
                kfree(radio->transfer_buffer);
                kfree(radio);
                return -ENOMEM;
@@ -501,7 +513,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
        radio->removed = 0;
        radio->users = 0;
        radio->usbdev = interface_to_usbdev(intf);
-       radio->curfreq = FREQ_MIN*FREQ_MUL;
+       radio->curfreq = FREQ_MIN * FREQ_MUL;
        video_set_drvdata(radio->videodev, radio);
        if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr) < 0) {
                dev_warn(&intf->dev, "Could not register video device\n");
index a33717c48003c8def8a0449e9f9a582732c6a5e9..256cbeffdcb6c274a80657fab1eb23f107e0b976 100644 (file)
@@ -469,16 +469,21 @@ static int usb_amradio_open(struct inode *inode, struct file *file)
 {
        struct amradio_device *radio = video_get_drvdata(video_devdata(file));
 
+       lock_kernel();
+
        radio->users = 1;
        radio->muted = 1;
 
        if (amradio_start(radio) < 0) {
                warn("Radio did not start up properly");
                radio->users = 0;
+               unlock_kernel();
                return -EIO;
        }
        if (amradio_setfreq(radio, radio->curfreq) < 0)
                warn("Set frequency failed");
+
+       unlock_kernel();
        return 0;
 }
 
index 218754b4906a7a4fee61b7840dc4b8ed1db92ad4..e09b006932308b81e3940dd204226538ac88afbc 100644 (file)
@@ -866,7 +866,7 @@ static int __init ar_init(void)
        }
 
        printk("video%d: Found M64278 VGA (IRQ %d, Freq %dMHz).\n",
-               ar->vdev->minor, M32R_IRQ_INT3, freq);
+               ar->vdev->num, M32R_IRQ_INT3, freq);
 
        return 0;
 
index 5858bf5ff41c3da1392bb21d337d13713bf56c45..9ec4cec2e52dada612a8857a1033325f6cb5415a 100644 (file)
@@ -4246,7 +4246,7 @@ static int __devinit bttv_register_video(struct bttv *btv)
                                  video_nr[btv->c.nr]) < 0)
                goto err;
        printk(KERN_INFO "bttv%d: registered device video%d\n",
-              btv->c.nr,btv->video_dev->minor & 0x1f);
+              btv->c.nr, btv->video_dev->num);
        if (device_create_file(&btv->video_dev->dev,
                                     &dev_attr_card)<0) {
                printk(KERN_ERR "bttv%d: device_create_file 'card' "
@@ -4263,7 +4263,7 @@ static int __devinit bttv_register_video(struct bttv *btv)
                                  vbi_nr[btv->c.nr]) < 0)
                goto err;
        printk(KERN_INFO "bttv%d: registered device vbi%d\n",
-              btv->c.nr,btv->vbi_dev->minor & 0x1f);
+              btv->c.nr, btv->vbi_dev->num);
 
        if (!btv->has_radio)
                return 0;
@@ -4275,7 +4275,7 @@ static int __devinit bttv_register_video(struct bttv *btv)
                                  radio_nr[btv->c.nr]) < 0)
                goto err;
        printk(KERN_INFO "bttv%d: registered device radio%d\n",
-              btv->c.nr,btv->radio_dev->minor & 0x1f);
+              btv->c.nr, btv->radio_dev->num);
 
        /* all done */
        return 0;
index 17aa0adb346703938b650c8c8164e3789eab5f88..0f930d35146619fea78c43a0370b6fec6fdaba0f 100644 (file)
@@ -815,7 +815,7 @@ static int init_cqcam(struct parport *port)
        }
 
        printk(KERN_INFO "video%d: Colour QuickCam found on %s\n",
-              qcam->vdev.minor, qcam->pport->name);
+              qcam->vdev.num, qcam->pport->name);
 
        qcams[num_cams++] = qcam;
 
index fc9497bdd322f008c6673ada3c7468be051c3706..a8c068e1de1cb30956e227e9d14a933c0c36735d 100644 (file)
@@ -2059,10 +2059,10 @@ static void cafe_dfs_cam_setup(struct cafe_camera *cam)
 
        if (!cafe_dfs_root)
                return;
-       sprintf(fname, "regs-%d", cam->v4ldev.minor);
+       sprintf(fname, "regs-%d", cam->v4ldev.num);
        cam->dfs_regs = debugfs_create_file(fname, 0444, cafe_dfs_root,
                        cam, &cafe_dfs_reg_ops);
-       sprintf(fname, "cam-%d", cam->v4ldev.minor);
+       sprintf(fname, "cam-%d", cam->v4ldev.num);
        cam->dfs_cam_regs = debugfs_create_file(fname, 0444, cafe_dfs_root,
                        cam, &cafe_dfs_cam_ops);
 }
index 1798b779a25a10993e767a469ee860317016a992..16c094f7785294230cdb5d9e1423fbf248454aa7 100644 (file)
@@ -1347,7 +1347,7 @@ static void create_proc_cpia_cam(struct cam_data *cam)
        if (!cpia_proc_root || !cam)
                return;
 
-       snprintf(name, sizeof(name), "video%d", cam->vdev.minor);
+       snprintf(name, sizeof(name), "video%d", cam->vdev.num);
 
        ent = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, cpia_proc_root);
        if (!ent)
@@ -1372,7 +1372,7 @@ static void destroy_proc_cpia_cam(struct cam_data *cam)
        if (!cam || !cam->proc_entry)
                return;
 
-       snprintf(name, sizeof(name), "video%d", cam->vdev.minor);
+       snprintf(name, sizeof(name), "video%d", cam->vdev.num);
        remove_proc_entry(name, cpia_proc_root);
        cam->proc_entry = NULL;
 }
@@ -4005,7 +4005,7 @@ void cpia_unregister_camera(struct cam_data *cam)
        }
 
 #ifdef CONFIG_PROC_FS
-       DBG("destroying /proc/cpia/video%d\n", cam->vdev.minor);
+       DBG("destroying /proc/cpia/video%d\n", cam->vdev.num);
        destroy_proc_cpia_cam(cam);
 #endif
        if (!cam->open_count) {
index 897e8d1a5c3c0a08cadc5dfa470767c90095573d..1c6bd633f1939a5493bcef8a1e20f51df863aed9 100644 (file)
@@ -1973,7 +1973,7 @@ void cpia2_unregister_camera(struct camera_data *cam)
        } else {
                LOG("/dev/video%d removed while open, "
                    "deferring video_unregister_device\n",
-                   cam->vdev->minor);
+                   cam->vdev->num);
        }
 }
 
index 085121c2b47f3844aa07e60b21f7b5e4843437b6..7a1a7830a6b3fcc49ec0b1ff86c049c816c13b38 100644 (file)
@@ -613,6 +613,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
                                const struct pci_device_id *pci_id)
 {
        int retval = 0;
+       int i;
        int vbi_buf_size;
        u32 devtype;
        struct cx18 *cx;
@@ -698,7 +699,8 @@ static int __devinit cx18_probe(struct pci_dev *dev,
 
        /* active i2c  */
        CX18_DEBUG_INFO("activating i2c...\n");
-       if (init_cx18_i2c(cx)) {
+       retval = init_cx18_i2c(cx);
+       if (retval) {
                CX18_ERR("Could not initialize i2c\n");
                goto free_map;
        }
@@ -836,8 +838,11 @@ err:
        CX18_ERR("Error %d on initialization\n", retval);
        cx18_log_statistics(cx);
 
-       kfree(cx18_cards[cx18_cards_active]);
-       cx18_cards[cx18_cards_active] = NULL;
+       i = cx->num;
+       spin_lock(&cx18_cards_lock);
+       kfree(cx18_cards[i]);
+       cx18_cards[i] = NULL;
+       spin_unlock(&cx18_cards_lock);
        return retval;
 }
 
index 197d4fbd9f9544a8bf1d530adc8a4ee57dbf90cc..287a5e8bf67b8a988c88b4bb0cdb7315c2d3b613 100644 (file)
@@ -39,7 +39,7 @@ static inline void cx18_io_delay(struct cx18 *cx)
 
 /* Statistics gathering */
 static inline
-void cx18_log_write_retries(struct cx18 *cx, int i, const void *addr)
+void cx18_log_write_retries(struct cx18 *cx, int i, const void __iomem *addr)
 {
        if (i > CX18_MAX_MMIO_RETRIES)
                i = CX18_MAX_MMIO_RETRIES;
@@ -48,7 +48,7 @@ void cx18_log_write_retries(struct cx18 *cx, int i, const void *addr)
 }
 
 static inline
-void cx18_log_read_retries(struct cx18 *cx, int i, const void *addr)
+void cx18_log_read_retries(struct cx18 *cx, int i, const void __iomem *addr)
 {
        if (i > CX18_MAX_MMIO_RETRIES)
                i = CX18_MAX_MMIO_RETRIES;
index 0c8e7542cf6044ec86fbe8e0c6eb8931240c8e25..e5ff7705b7a134c8495566b264c1621b65071f32 100644 (file)
@@ -200,16 +200,18 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
 /* Initialize v4l2 variables and register v4l2 devices */
 int cx18_streams_setup(struct cx18 *cx)
 {
-       int type;
+       int type, ret;
 
        /* Setup V4L2 Devices */
        for (type = 0; type < CX18_MAX_STREAMS; type++) {
                /* Prepare device */
-               if (cx18_prep_dev(cx, type))
+               ret = cx18_prep_dev(cx, type);
+               if (ret < 0)
                        break;
 
                /* Allocate Stream */
-               if (cx18_stream_alloc(&cx->streams[type]))
+               ret = cx18_stream_alloc(&cx->streams[type]);
+               if (ret < 0)
                        break;
        }
        if (type == CX18_MAX_STREAMS)
@@ -217,14 +219,14 @@ int cx18_streams_setup(struct cx18 *cx)
 
        /* One or more streams could not be initialized. Clean 'em all up. */
        cx18_streams_cleanup(cx, 0);
-       return -ENOMEM;
+       return ret;
 }
 
 static int cx18_reg_dev(struct cx18 *cx, int type)
 {
        struct cx18_stream *s = &cx->streams[type];
        int vfl_type = cx18_stream_info[type].vfl_type;
-       int num;
+       int num, ret;
 
        /* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something?
         * We need a VFL_TYPE_TS defined.
@@ -233,9 +235,10 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
                /* just return if no DVB is supported */
                if ((cx->card->hw_all & CX18_HW_DVB) == 0)
                        return 0;
-               if (cx18_dvb_register(s) < 0) {
+               ret = cx18_dvb_register(s);
+               if (ret < 0) {
                        CX18_ERR("DVB failed to register\n");
-                       return -EINVAL;
+                       return ret;
                }
        }
 
@@ -252,12 +255,13 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
        }
 
        /* Register device. First try the desired minor, then any free one. */
-       if (video_register_device(s->v4l2dev, vfl_type, num)) {
+       ret = video_register_device(s->v4l2dev, vfl_type, num);
+       if (ret < 0) {
                CX18_ERR("Couldn't register v4l2 device for %s kernel number %d\n",
                        s->name, num);
                video_device_release(s->v4l2dev);
                s->v4l2dev = NULL;
-               return -ENOMEM;
+               return ret;
        }
        num = s->v4l2dev->num;
 
@@ -290,18 +294,22 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
 int cx18_streams_register(struct cx18 *cx)
 {
        int type;
-       int err = 0;
+       int err;
+       int ret = 0;
 
        /* Register V4L2 devices */
-       for (type = 0; type < CX18_MAX_STREAMS; type++)
-               err |= cx18_reg_dev(cx, type);
+       for (type = 0; type < CX18_MAX_STREAMS; type++) {
+               err = cx18_reg_dev(cx, type);
+               if (err && ret == 0)
+                       ret = err;
+       }
 
-       if (err == 0)
+       if (ret == 0)
                return 0;
 
        /* One or more streams could not be initialized. Clean 'em all up. */
        cx18_streams_cleanup(cx, 1);
-       return -ENOMEM;
+       return ret;
 }
 
 /* Unregister v4l2 devices */
index 395c11fa47ceb486206eaf37f44145644762bc31..00831f3ef8f59b7f821d2281737987add37b74aa 100644 (file)
@@ -1815,7 +1815,7 @@ int cx23885_417_register(struct cx23885_dev *dev)
        cx23885_mc417_init(dev);
 
        printk(KERN_INFO "%s: registered device video%d [mpeg]\n",
-              dev->name, dev->v4l_device->minor & 0x1f);
+              dev->name, dev->v4l_device->num);
 
        return 0;
 }
index ab3110d6046ca08ac7fd2488da02fcaa19396bd2..c742a10be5cb2f9a94972b5f20d9eeb5ad355063 100644 (file)
@@ -1543,7 +1543,7 @@ int cx23885_video_register(struct cx23885_dev *dev)
                goto fail_unreg;
        }
        printk(KERN_INFO "%s/0: registered device video%d [v4l2]\n",
-              dev->name, dev->video_dev->minor & 0x1f);
+              dev->name, dev->video_dev->num);
        /* initial device configuration */
        mutex_lock(&dev->lock);
        cx23885_set_tvnorm(dev, dev->tvnorm);
index e71369754305cdfe21cab45990120115079aafa7..078be63195568433e9d673e6becd886415ce21b4 100644 (file)
@@ -1285,7 +1285,7 @@ static int blackbird_register_video(struct cx8802_dev *dev)
                return err;
        }
        printk(KERN_INFO "%s/2: registered device video%d [mpeg]\n",
-              dev->core->name,dev->mpeg_dev->minor & 0x1f);
+              dev->core->name, dev->mpeg_dev->num);
        return 0;
 }
 
index fbc224f46e0eb15ea596e7759cc05a39390f71b9..5bcbb4cc7c2a53e0656d56be53441ad085fb0874 100644 (file)
@@ -3044,8 +3044,8 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
 
        memcpy(&core->board, &cx88_boards[core->boardnr], sizeof(core->board));
 
-       if (!core->board.num_frontends)
-               core->board.num_frontends=1;
+       if (!core->board.num_frontends && (core->board.mpeg & CX88_MPEG_DVB))
+               core->board.num_frontends = 1;
 
        info_printk(core, "subsystem: %04x:%04x, board: %s [card=%d,%s], frontend(s): %d\n",
                pci->subsystem_vendor, pci->subsystem_device, core->board.name,
index 6968ab0181aa6a6ee96672c7e856829c3135b697..cf6c30d4e545e5dcc6d7c02013738b51544a0b9a 100644 (file)
@@ -789,7 +789,7 @@ static int dvb_register(struct cx8802_dev *dev)
                if (fe0->dvb.frontend)
                        fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
                if (attach_xc3028(0x61, dev) < 0)
-                       return -EINVAL;
+                       goto frontend_detach;
                break;
        case CX88_BOARD_PCHDTV_HD3000:
                fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
@@ -1058,7 +1058,6 @@ static int dvb_register(struct cx8802_dev *dev)
                                        goto frontend_detach;
                                core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
                                fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
-
                        }
                }
                break;
@@ -1110,10 +1109,7 @@ static int dvb_register(struct cx8802_dev *dev)
                &dev->pci->dev, adapter_nr, mfe_shared);
 
 frontend_detach:
-       if (fe0->dvb.frontend) {
-               dvb_frontend_detach(fe0->dvb.frontend);
-               fe0->dvb.frontend = NULL;
-       }
+       videobuf_dvb_dealloc_frontends(&dev->frontends);
        return -EINVAL;
 }
 
@@ -1246,8 +1242,11 @@ fail_core:
 
 static int cx8802_dvb_remove(struct cx8802_driver *drv)
 {
+       struct cx88_core *core = drv->core;
        struct cx8802_dev *dev = drv->core->dvbdev;
 
+       dprintk( 1, "%s\n", __func__);
+
        videobuf_dvb_unregister_bus(&dev->frontends);
 
        vp3054_i2c_remove(dev);
index 01de23007095f5d7d1de4b8371df34f26b9d0795..1ab691d2069268dc6d2db42ac0b304eef1f69288 100644 (file)
@@ -116,8 +116,10 @@ static int detach_inform(struct i2c_client *client)
 
 void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
 {
+#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
        struct videobuf_dvb_frontends *f = &core->dvbdev->frontends;
        struct videobuf_dvb_frontend *fe = NULL;
+#endif
        if (0 != core->i2c_rc)
                return;
 
index 6df5cf31418627025e16752fdecbab998040a7ed..a1c435b4b1cd3901f93022d6ecf25f65d16486f8 100644 (file)
@@ -768,8 +768,11 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
 {
        struct cx8802_dev *dev;
        struct cx88_core  *core;
+       int err;
+#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
        struct videobuf_dvb_frontend *demod;
-       int err,i;
+       int i;
+#endif
 
        /* general setup */
        core = cx88_core_get(pci_dev);
@@ -782,11 +785,6 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
        if (!core->board.mpeg)
                goto fail_core;
 
-       if (!core->board.num_frontends) {
-               printk(KERN_ERR "%s() .num_frontends should be non-zero, err = %d\n", __func__, err);
-               goto fail_core;
-       }
-
        err = -ENOMEM;
        dev = kzalloc(sizeof(*dev),GFP_KERNEL);
        if (NULL == dev)
@@ -801,10 +799,12 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
        INIT_LIST_HEAD(&dev->drvlist);
        list_add_tail(&dev->devlist,&cx8802_devlist);
 
+#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
        mutex_init(&dev->frontends.lock);
        INIT_LIST_HEAD(&dev->frontends.felist);
 
-       printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, core->board.num_frontends);
+       if (core->board.num_frontends)
+               printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, core->board.num_frontends);
 
        for (i = 1; i <= core->board.num_frontends; i++) {
                demod = videobuf_dvb_alloc_frontend(&dev->frontends, i);
@@ -814,6 +814,7 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
                        goto fail_free;
                }
        }
+#endif
 
        /* Maintain a reference so cx88-video can query the 8802 device. */
        core->dvbdev = dev;
index 3904b73f52ee2879ebc6058770d8692a80a57700..61265fd04d5603edb4198b7e4e46f3980a222b90 100644 (file)
@@ -1911,7 +1911,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
                goto fail_unreg;
        }
        printk(KERN_INFO "%s/0: registered device video%d [v4l2]\n",
-              core->name,dev->video_dev->minor & 0x1f);
+              core->name, dev->video_dev->num);
 
        dev->vbi_dev = cx88_vdev_init(core,dev->pci,&cx8800_vbi_template,"vbi");
        err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI,
@@ -1922,7 +1922,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
                goto fail_unreg;
        }
        printk(KERN_INFO "%s/0: registered device vbi%d\n",
-              core->name,dev->vbi_dev->minor & 0x1f);
+              core->name, dev->vbi_dev->num);
 
        if (core->board.radio.type == CX88_RADIO) {
                dev->radio_dev = cx88_vdev_init(core,dev->pci,
@@ -1935,7 +1935,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
                        goto fail_unreg;
                }
                printk(KERN_INFO "%s/0: registered device radio%d\n",
-                      core->name,dev->radio_dev->minor & 0x1f);
+                      core->name, dev->radio_dev->num);
        }
 
        /* everything worked */
index c53649e5315b0a815cd09633578dfcea263b41cd..a1ab2ef45578d491ea9951ef1ddfe933b85294fb 100644 (file)
@@ -2042,7 +2042,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
                        goto fail_unreg;
                }
                em28xx_info("Registered radio device as /dev/radio%d\n",
-                           dev->radio_dev->minor & 0x1f);
+                           dev->radio_dev->num);
        }
 
        /* init video dma queues */
index 7a85c41b0eea3b592ccc7554707421a40d70aaa3..9d0ef96c23ff47c6147059ee9b3a2b28b5986067 100644 (file)
@@ -588,7 +588,7 @@ static int et61x251_stream_interrupt(struct et61x251_device* cam)
                cam->state |= DEV_MISCONFIGURED;
                DBG(1, "URB timeout reached. The camera is misconfigured. To "
                       "use it, close and open /dev/video%d again.",
-                   cam->v4ldev->minor);
+                   cam->v4ldev->num);
                return -EIO;
        }
 
@@ -1195,7 +1195,7 @@ static void et61x251_release_resources(struct kref *kref)
 
        cam = container_of(kref, struct et61x251_device, kref);
 
-       DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor);
+       DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->num);
        video_set_drvdata(cam->v4ldev, NULL);
        video_unregister_device(cam->v4ldev);
        usb_put_dev(cam->usbdev);
@@ -1237,7 +1237,7 @@ static int et61x251_open(struct inode* inode, struct file* filp)
 
        if (cam->users) {
                DBG(2, "Device /dev/video%d is already in use",
-                      cam->v4ldev->minor);
+                      cam->v4ldev->num);
                DBG(3, "Simultaneous opens are not supported");
                if ((filp->f_flags & O_NONBLOCK) ||
                    (filp->f_flags & O_NDELAY)) {
@@ -1280,7 +1280,7 @@ static int et61x251_open(struct inode* inode, struct file* filp)
        cam->frame_count = 0;
        et61x251_empty_framequeues(cam);
 
-       DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor);
+       DBG(3, "Video device /dev/video%d is open", cam->v4ldev->num);
 
 out:
        mutex_unlock(&cam->open_mutex);
@@ -1304,7 +1304,7 @@ static int et61x251_release(struct inode* inode, struct file* filp)
        cam->users--;
        wake_up_interruptible_nr(&cam->wait_open, 1);
 
-       DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor);
+       DBG(3, "Video device /dev/video%d closed", cam->v4ldev->num);
 
        kref_put(&cam->kref, et61x251_release_resources);
 
@@ -1845,7 +1845,7 @@ et61x251_vidioc_s_crop(struct et61x251_device* cam, void __user * arg)
                cam->state |= DEV_MISCONFIGURED;
                DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
                       "use the camera, close and open /dev/video%d again.",
-                   cam->v4ldev->minor);
+                   cam->v4ldev->num);
                return -EIO;
        }
 
@@ -1858,7 +1858,7 @@ et61x251_vidioc_s_crop(struct et61x251_device* cam, void __user * arg)
                cam->state |= DEV_MISCONFIGURED;
                DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
                       "use the camera, close and open /dev/video%d again.",
-                   cam->v4ldev->minor);
+                   cam->v4ldev->num);
                return -ENOMEM;
        }
 
@@ -2068,7 +2068,7 @@ et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd,
                cam->state |= DEV_MISCONFIGURED;
                DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
                       "use the camera, close and open /dev/video%d again.",
-                   cam->v4ldev->minor);
+                   cam->v4ldev->num);
                return -EIO;
        }
 
@@ -2080,7 +2080,7 @@ et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd,
                cam->state |= DEV_MISCONFIGURED;
                DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
                       "use the camera, close and open /dev/video%d again.",
-                   cam->v4ldev->minor);
+                   cam->v4ldev->num);
                return -ENOMEM;
        }
 
@@ -2128,7 +2128,7 @@ et61x251_vidioc_s_jpegcomp(struct et61x251_device* cam, void __user * arg)
                cam->state |= DEV_MISCONFIGURED;
                DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
                       "problems. To use the camera, close and open "
-                      "/dev/video%d again.", cam->v4ldev->minor);
+                      "/dev/video%d again.", cam->v4ldev->num);
                return -EIO;
        }
 
@@ -2605,7 +2605,7 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
                goto fail;
        }
 
-       DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor);
+       DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->num);
 
        cam->module_param.force_munmap = force_munmap[dev_nr];
        cam->module_param.frame_timeout = frame_timeout[dev_nr];
@@ -2658,7 +2658,7 @@ static void et61x251_usb_disconnect(struct usb_interface* intf)
        if (cam->users) {
                DBG(2, "Device /dev/video%d is open! Deregistration and "
                       "memory deallocation are deferred.",
-                   cam->v4ldev->minor);
+                   cam->v4ldev->num);
                cam->state |= DEV_MISCONFIGURED;
                et61x251_stop_transfer(cam);
                cam->state |= DEV_DISCONNECTED;
index aeaa13f6cb3639edda26bbc3178e4105fcdb283b..d36485023b68a91b9244af8776c38f028474aaa5 100644 (file)
@@ -1211,6 +1211,10 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
 
        if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
                ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std);
+               /* Turn off the output signal. The mpeg decoder is not yet
+                  active so without this you would get a green image until the
+                  mpeg decoder becomes active. */
+               ivtv_saa7127(itv, VIDIOC_STREAMOFF, NULL);
        }
 
        /* clear interrupt mask, effectively disabling interrupts */
@@ -1330,6 +1334,10 @@ int ivtv_init_on_first_open(struct ivtv *itv)
        ivtv_s_frequency(NULL, &fh, &vf);
 
        if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) {
+               /* Turn on the TV-out: ivtv_init_mpeg_decoder() initializes
+                  the mpeg decoder so now the saa7127 receives a proper
+                  signal. */
+               ivtv_saa7127(itv, VIDIOC_STREAMON, NULL);
                ivtv_init_mpeg_decoder(itv);
        }
        ivtv_s_std(NULL, &fh, &itv->tuner_std);
@@ -1366,6 +1374,10 @@ static void ivtv_remove(struct pci_dev *pci_dev)
 
                /* Stop all decoding */
                IVTV_DEBUG_INFO("Stopping decoding\n");
+
+               /* Turn off the TV-out */
+               if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
+                       ivtv_saa7127(itv, VIDIOC_STREAMOFF, NULL);
                if (atomic_read(&itv->decoding) > 0) {
                        int type;
 
index 24700c211d5264e660696e64cf92373d69e82793..41dbbe9621a1fa34d95379444e60a0f5b01df9c1 100644 (file)
@@ -726,6 +726,7 @@ int ivtv_saa7127(struct ivtv *itv, unsigned int cmd, void *arg)
 {
        return ivtv_call_i2c_client(itv, IVTV_SAA7127_I2C_ADDR, cmd, arg);
 }
+EXPORT_SYMBOL(ivtv_saa7127);
 
 int ivtv_saa717x(struct ivtv *itv, unsigned int cmd, void *arg)
 {
index 208fb54842f2f4a91f8527f280e5023cd8780215..4bae38d21ef6099cd24cc21edfc3d7d3a4a56f44 100644 (file)
@@ -1756,12 +1756,12 @@ static int ivtv_default(struct file *file, void *fh, int cmd, void *arg)
        return 0;
 }
 
-static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct file *filp,
+static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp,
                unsigned int cmd, unsigned long arg)
 {
        struct video_device *vfd = video_devdata(filp);
        struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
-       int ret;
+       long ret;
 
        /* Filter dvb ioctls that cannot be handled by the v4l ioctl framework */
        switch (cmd) {
@@ -1830,20 +1830,19 @@ static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct f
 
        if (ivtv_debug & IVTV_DBGFLG_IOCTL)
                vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
-       ret = video_ioctl2(inode, filp, cmd, arg);
+       ret = __video_ioctl2(filp, cmd, arg);
        vfd->debug = 0;
        return ret;
 }
 
-int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
-                   unsigned long arg)
+long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
        struct ivtv *itv = id->itv;
-       int res;
+       long res;
 
        mutex_lock(&itv->serialize_lock);
-       res = ivtv_serialized_ioctl(itv, inode, filp, cmd, arg);
+       res = ivtv_serialized_ioctl(itv, filp, cmd, arg);
        mutex_unlock(&itv->serialize_lock);
        return res;
 }
index 70188588b4f4f1e07c5916371ef13d5fd3da6da6..58f003412afdd5141a854c41779b80ad38a4884d 100644 (file)
@@ -30,7 +30,6 @@ void ivtv_set_funcs(struct video_device *vdev);
 int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std);
 int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
 int ivtv_s_input(struct file *file, void *fh, unsigned int inp);
-int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
-                   unsigned long arg);
+long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
 
 #endif
index 5bbf31e393048fd6b1cd6740a4c02b9ace8f051b..9b7aa79eb2677d49ddd3da33c1f95fc2f6429283 100644 (file)
@@ -48,7 +48,7 @@ static const struct file_operations ivtv_v4l2_enc_fops = {
        .read = ivtv_v4l2_read,
        .write = ivtv_v4l2_write,
        .open = ivtv_v4l2_open,
-       .ioctl = ivtv_v4l2_ioctl,
+       .unlocked_ioctl = ivtv_v4l2_ioctl,
        .compat_ioctl = v4l_compat_ioctl32,
        .release = ivtv_v4l2_close,
        .poll = ivtv_v4l2_enc_poll,
@@ -59,7 +59,7 @@ static const struct file_operations ivtv_v4l2_dec_fops = {
        .read = ivtv_v4l2_read,
        .write = ivtv_v4l2_write,
        .open = ivtv_v4l2_open,
-       .ioctl = ivtv_v4l2_ioctl,
+       .unlocked_ioctl = ivtv_v4l2_ioctl,
        .compat_ioctl = v4l_compat_ioctl32,
        .release = ivtv_v4l2_close,
        .poll = ivtv_v4l2_dec_poll,
index 8a4a150b12fb1083c787da3fb3ddcbdb9ab9a51c..921e281876f8181168fe60b8fdb3d7823e51a0bf 100644 (file)
@@ -48,6 +48,7 @@
 #endif
 
 #include "ivtv-driver.h"
+#include "ivtv-i2c.h"
 #include "ivtv-udma.h"
 #include "ivtv-mailbox.h"
 
@@ -894,11 +895,16 @@ static int ivtvfb_blank(int blank_mode, struct fb_info *info)
        switch (blank_mode) {
        case FB_BLANK_UNBLANK:
                ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 1);
+               ivtv_saa7127(itv, VIDIOC_STREAMON, NULL);
                break;
        case FB_BLANK_NORMAL:
        case FB_BLANK_HSYNC_SUSPEND:
        case FB_BLANK_VSYNC_SUSPEND:
+               ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
+               ivtv_saa7127(itv, VIDIOC_STREAMON, NULL);
+               break;
        case FB_BLANK_POWERDOWN:
+               ivtv_saa7127(itv, VIDIOC_STREAMOFF, NULL);
                ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
                break;
        }
index a1252d673b411331e36811dac8cdea5d65e052f4..273d2a1aa220f0b8a42ad41ae9722dd3c299de5c 100644 (file)
@@ -402,6 +402,10 @@ static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw)
        ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 0,3,0,0);
        ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4,15,0,0,0);
 
+       /* prevent the PTSs from slowly drifting away in the generated
+          MPEG stream */
+       ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC, 2, 4, 1);
+
        return ret;
 }
 
index 94265bd3d926c1b2a8960ae743a05f962aec75c2..5b81ba469641c89b302a777d9f41f62043609133 100644 (file)
@@ -60,7 +60,6 @@ static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL};
 static DEFINE_MUTEX(pvr2_unit_mtx);
 
 static int ctlchg;
-static int initusbreset = 1;
 static int procreload;
 static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 };
 static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
@@ -71,8 +70,6 @@ module_param(ctlchg, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value");
 module_param(init_pause_msec, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(init_pause_msec, "hardware initialization settling delay");
-module_param(initusbreset, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(initusbreset, "Do USB reset device on probe");
 module_param(procreload, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(procreload,
                 "Attempt init failure recovery with firmware reload");
@@ -1967,9 +1964,6 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
        }
        hdw->fw1_state = FW1_STATE_OK;
 
-       if (initusbreset) {
-               pvr2_hdw_device_reset(hdw);
-       }
        if (!pvr2_hdw_dev_ok(hdw)) return;
 
        for (idx = 0; idx < hdw->hdw_desc->client_modules.cnt; idx++) {
index f048d80b77e58b8e7e5e05ff9c2fec798929e135..97ed95957992ff9d5107ff90b1c754f3f2c6bbdc 100644 (file)
@@ -168,7 +168,7 @@ static const char *get_v4l_name(int v4l_type)
  * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
  *
  */
-static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
+static int __pvr2_v4l2_do_ioctl(struct file *file,
                              unsigned int cmd, void *arg)
 {
        struct pvr2_v4l2_fh *fh = file->private_data;
@@ -863,8 +863,8 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
 #endif
 
        default :
-               ret = v4l_compat_translate_ioctl(inode,file,cmd,
-                                                arg,pvr2_v4l2_do_ioctl);
+               ret = v4l_compat_translate_ioctl(file, cmd,
+                                                arg, __pvr2_v4l2_do_ioctl);
        }
 
        pvr2_hdw_commit_ctl(hdw);
@@ -890,10 +890,15 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
        return ret;
 }
 
+static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
+                             unsigned int cmd, void *arg)
+{
+       return __pvr2_v4l2_do_ioctl(file, cmd, arg);
+}
 
 static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
 {
-       int minor_id = dip->devbase.minor;
+       int num = dip->devbase.num;
        struct pvr2_hdw *hdw = dip->v4lp->channel.mc_head->hdw;
        enum pvr2_config cfg = dip->config;
        int v4l_type = dip->v4l_type;
@@ -909,7 +914,7 @@ static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
        video_unregister_device(&dip->devbase);
 
        printk(KERN_INFO "pvrusb2: unregistered device %s%u [%s]\n",
-              get_v4l_name(v4l_type),minor_id & 0x1f,
+              get_v4l_name(v4l_type), num,
               pvr2_config_get_name(cfg));
 
 }
@@ -1310,7 +1315,7 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
        }
 
        printk(KERN_INFO "pvrusb2: registered device %s%u [%s]\n",
-              get_v4l_name(dip->v4l_type),dip->devbase.minor & 0x1f,
+              get_v4l_name(dip->v4l_type), dip->devbase.num,
               pvr2_config_get_name(dip->config));
 
        pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,
index ab28389b4cdadf17d0e28282dd6c186237c2fe14..f3897a3fdb75b3542de06f693e60e213ed642f1a 100644 (file)
@@ -1795,7 +1795,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
                goto err;
        }
        else {
-               PWC_INFO("Registered as /dev/video%d.\n", pdev->vdev->minor & 0x3F);
+               PWC_INFO("Registered as /dev/video%d.\n", pdev->vdev->num);
        }
 
        /* occupy slot */
index b686bfabbde0defb53a765a8b3bf8978e1f21b0a..24918445294906ce9152c05db70d1748dfc6a9af 100644 (file)
@@ -996,7 +996,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
                goto fail4;
        }
        printk(KERN_INFO "%s: registered device video%d [v4l2]\n",
-              dev->name,dev->video_dev->minor & 0x1f);
+              dev->name, dev->video_dev->num);
 
        dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi");
 
@@ -1005,7 +1005,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
        if (err < 0)
                goto fail4;
        printk(KERN_INFO "%s: registered device vbi%d\n",
-              dev->name,dev->vbi_dev->minor & 0x1f);
+              dev->name, dev->vbi_dev->num);
 
        if (card_has_radio(dev)) {
                dev->radio_dev = vdev_init(dev,&saa7134_radio_template,"radio");
@@ -1014,7 +1014,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
                if (err < 0)
                        goto fail4;
                printk(KERN_INFO "%s: registered device radio%d\n",
-                      dev->name,dev->radio_dev->minor & 0x1f);
+                      dev->name, dev->radio_dev->num);
        }
 
        /* everything worked */
index 9a8766a78a0c31f45ddadeb561d4d837662730ba..7f40511bcc04b9493423d2fc9826d57e2473af98 100644 (file)
@@ -534,7 +534,7 @@ static int empress_init(struct saa7134_dev *dev)
                return err;
        }
        printk(KERN_INFO "%s: registered device video%d [mpeg]\n",
-              dev->name,dev->empress_dev->minor & 0x1f);
+              dev->name, dev->empress_dev->num);
 
        videobuf_queue_sg_init(&dev->empress_tsq, &saa7134_ts_qops,
                            &dev->pci->dev, &dev->slock,
index ae3949180c4ed3ace8801f67b94c24899e0b916f..044a2e94c34dc5e5708d6e3f0c4deb944a8ff263 100644 (file)
@@ -1412,7 +1412,7 @@ static int se401_probe(struct usb_interface *intf,
                return -EIO;
        }
        dev_info(&intf->dev, "registered new video device: video%d\n",
-                se401->vdev.minor);
+                se401->vdev.num);
 
        usb_set_intfdata (intf, se401);
        return 0;
index 20e30bd9364be9eb3d988079e8764029ed8543c9..fcd2b62f92c43506456437fa3b46f7469fc4d25c 100644 (file)
@@ -1008,7 +1008,7 @@ static int sn9c102_stream_interrupt(struct sn9c102_device* cam)
                cam->state |= DEV_MISCONFIGURED;
                DBG(1, "URB timeout reached. The camera is misconfigured. "
                       "To use it, close and open /dev/video%d again.",
-                   cam->v4ldev->minor);
+                   cam->v4ldev->num);
                return -EIO;
        }
 
@@ -1734,7 +1734,7 @@ static void sn9c102_release_resources(struct kref *kref)
 
        cam = container_of(kref, struct sn9c102_device, kref);
 
-       DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor);
+       DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->num);
        video_set_drvdata(cam->v4ldev, NULL);
        video_unregister_device(cam->v4ldev);
        usb_put_dev(cam->usbdev);
@@ -1792,7 +1792,7 @@ static int sn9c102_open(struct inode* inode, struct file* filp)
 
        if (cam->users) {
                DBG(2, "Device /dev/video%d is already in use",
-                      cam->v4ldev->minor);
+                      cam->v4ldev->num);
                DBG(3, "Simultaneous opens are not supported");
                /*
                   open() must follow the open flags and should block
@@ -1845,7 +1845,7 @@ static int sn9c102_open(struct inode* inode, struct file* filp)
        cam->frame_count = 0;
        sn9c102_empty_framequeues(cam);
 
-       DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor);
+       DBG(3, "Video device /dev/video%d is open", cam->v4ldev->num);
 
 out:
        mutex_unlock(&cam->open_mutex);
@@ -1870,7 +1870,7 @@ static int sn9c102_release(struct inode* inode, struct file* filp)
        cam->users--;
        wake_up_interruptible_nr(&cam->wait_open, 1);
 
-       DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor);
+       DBG(3, "Video device /dev/video%d closed", cam->v4ldev->num);
 
        kref_put(&cam->kref, sn9c102_release_resources);
 
@@ -2432,7 +2432,7 @@ sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg)
                cam->state |= DEV_MISCONFIGURED;
                DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
                       "use the camera, close and open /dev/video%d again.",
-                   cam->v4ldev->minor);
+                   cam->v4ldev->num);
                return -EIO;
        }
 
@@ -2445,7 +2445,7 @@ sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg)
                cam->state |= DEV_MISCONFIGURED;
                DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
                       "use the camera, close and open /dev/video%d again.",
-                   cam->v4ldev->minor);
+                   cam->v4ldev->num);
                return -ENOMEM;
        }
 
@@ -2689,7 +2689,7 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
                cam->state |= DEV_MISCONFIGURED;
                DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
                       "use the camera, close and open /dev/video%d again.",
-                   cam->v4ldev->minor);
+                   cam->v4ldev->num);
                return -EIO;
        }
 
@@ -2701,7 +2701,7 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
                cam->state |= DEV_MISCONFIGURED;
                DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
                       "use the camera, close and open /dev/video%d again.",
-                   cam->v4ldev->minor);
+                   cam->v4ldev->num);
                return -ENOMEM;
        }
 
@@ -2748,7 +2748,7 @@ sn9c102_vidioc_s_jpegcomp(struct sn9c102_device* cam, void __user * arg)
                cam->state |= DEV_MISCONFIGURED;
                DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
                       "problems. To use the camera, close and open "
-                      "/dev/video%d again.", cam->v4ldev->minor);
+                      "/dev/video%d again.", cam->v4ldev->num);
                return -EIO;
        }
 
@@ -3348,7 +3348,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
                goto fail;
        }
 
-       DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor);
+       DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->num);
 
        video_set_drvdata(cam->v4ldev, cam);
        cam->module_param.force_munmap = force_munmap[dev_nr];
@@ -3402,7 +3402,7 @@ static void sn9c102_usb_disconnect(struct usb_interface* intf)
        if (cam->users) {
                DBG(2, "Device /dev/video%d is open! Deregistration and "
                       "memory deallocation are deferred.",
-                   cam->v4ldev->minor);
+                   cam->v4ldev->num);
                cam->state |= DEV_MISCONFIGURED;
                sn9c102_stop_transfer(cam);
                cam->state |= DEV_DISCONNECTED;
index edaea4964513ef3027a3673034877ee886d5743d..e9eb6d754d5c85db037e9d41fa398a1e2589830a 100644 (file)
@@ -1331,7 +1331,7 @@ static int stk_register_video_device(struct stk_camera *dev)
                STK_ERROR("v4l registration failed\n");
        else
                STK_INFO("Syntek USB2.0 Camera is now controlling video device"
-                       " /dev/video%d\n", dev->vdev.minor);
+                       " /dev/video%d\n", dev->vdev.num);
        return err;
 }
 
@@ -1426,7 +1426,7 @@ static void stk_camera_disconnect(struct usb_interface *interface)
        stk_remove_sysfs_files(&dev->vdev);
 
        STK_INFO("Syntek USB2.0 Camera release resources "
-               "video device /dev/video%d\n", dev->vdev.minor);
+               "video device /dev/video%d\n", dev->vdev.num);
 
        video_unregister_device(&dev->vdev);
 }
index 9c549d93599426c3d0ad53348b481edeb8decb52..328c41b1517d1a0d0897a17baad51c0fe08c3a40 100644 (file)
@@ -1470,7 +1470,8 @@ static int stv680_probe (struct usb_interface *intf, const struct usb_device_id
                retval = -EIO;
                goto error_vdev;
        }
-       PDEBUG (0, "STV(i): registered new video device: video%d", stv680->vdev->minor);
+       PDEBUG(0, "STV(i): registered new video device: video%d",
+               stv680->vdev->num);
 
        usb_set_intfdata (intf, stv680);
        retval = stv680_create_sysfs_files(stv680->vdev);
index 07cd87d16f69f602dcbd8bf416347200ce79a8d0..7c575bb8184fd6a95c80750f7a3f795afc5f6a24 100644 (file)
@@ -1059,7 +1059,7 @@ int usbvideo_RegisterVideoDevice(struct uvd *uvd)
 
        dev_info(&uvd->dev->dev, "%s on /dev/video%d: canvas=%s videosize=%s\n",
                 (uvd->handle != NULL) ? uvd->handle->drvName : "???",
-                uvd->vdev.minor, tmp2, tmp1);
+                uvd->vdev.num, tmp2, tmp1);
 
        usb_get_dev(uvd->dev);
        return 0;
index 7a127d6bfdee5432770136980b3899afc6f25825..8e2d58bec48120c1991c78fd3f8be963c5095f47 100644 (file)
@@ -877,7 +877,8 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id)
                return -EIO;
        }
 
-       printk(KERN_INFO "ViCam webcam driver now controlling video device %d\n",cam->vdev.minor);
+       printk(KERN_INFO "ViCam webcam driver now controlling video device %d\n",
+                       cam->vdev.num);
 
        usb_set_intfdata (intf, cam);
 
index 92427fdc1459b2b62af94aabe79063a08dc335f3..9907b9aff2b9228bc9aecb92305c7d4418563d8f 100644 (file)
@@ -236,7 +236,7 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
               sizeof(struct i2c_client));
 
        sprintf(usbvision->i2c_adap.name + strlen(usbvision->i2c_adap.name),
-               " #%d", usbvision->vdev->minor & 0x1f);
+               " #%d", usbvision->vdev->num);
        PDEBUG(DBG_I2C,"Adaptername: %s", usbvision->i2c_adap.name);
        usbvision->i2c_adap.dev.parent = &usbvision->dev->dev;
 
index 77aeb39b2750b1a34e660e3a733209e89da792af..d185b57fdcd0eb11108f9e2a482c6e869227f24e 100644 (file)
@@ -1440,7 +1440,7 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision)
        // vbi Device:
        if (usbvision->vbi) {
                PDEBUG(DBG_PROBE, "unregister /dev/vbi%d [v4l2]",
-                      usbvision->vbi->minor & 0x1f);
+                      usbvision->vbi->num);
                if (usbvision->vbi->minor != -1) {
                        video_unregister_device(usbvision->vbi);
                } else {
@@ -1452,7 +1452,7 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision)
        // Radio Device:
        if (usbvision->rdev) {
                PDEBUG(DBG_PROBE, "unregister /dev/radio%d [v4l2]",
-                      usbvision->rdev->minor & 0x1f);
+                      usbvision->rdev->num);
                if (usbvision->rdev->minor != -1) {
                        video_unregister_device(usbvision->rdev);
                } else {
@@ -1464,7 +1464,7 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision)
        // Video Device:
        if (usbvision->vdev) {
                PDEBUG(DBG_PROBE, "unregister /dev/video%d [v4l2]",
-                      usbvision->vdev->minor & 0x1f);
+                      usbvision->vdev->num);
                if (usbvision->vdev->minor != -1) {
                        video_unregister_device(usbvision->vdev);
                } else {
@@ -1490,7 +1490,7 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision)
                goto err_exit;
        }
        printk(KERN_INFO "USBVision[%d]: registered USBVision Video device /dev/video%d [v4l2]\n",
-              usbvision->nr,usbvision->vdev->minor & 0x1f);
+              usbvision->nr, usbvision->vdev->num);
 
        // Radio Device:
        if (usbvision_device_data[usbvision->DevModel].Radio) {
@@ -1507,7 +1507,7 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision)
                        goto err_exit;
                }
                printk(KERN_INFO "USBVision[%d]: registered USBVision Radio device /dev/radio%d [v4l2]\n",
-                      usbvision->nr, usbvision->rdev->minor & 0x1f);
+                      usbvision->nr, usbvision->rdev->num);
        }
        // vbi Device:
        if (usbvision_device_data[usbvision->DevModel].vbi) {
@@ -1523,7 +1523,7 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision)
                        goto err_exit;
                }
                printk(KERN_INFO "USBVision[%d]: registered USBVision VBI device /dev/vbi%d [v4l2] (Not Working Yet!)\n",
-                      usbvision->nr,usbvision->vbi->minor & 0x1f);
+                      usbvision->nr, usbvision->vbi->num);
        }
        // all done
        return 0;
index 78e4c4e09d89cb1c5fae161b7cce07f412712917..758dfefaba8d3854e7b2ad22e57467d40edb68c0 100644 (file)
@@ -464,7 +464,7 @@ static int uvc_v4l2_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static int uvc_v4l2_do_ioctl(struct inode *inode, struct file *file,
+static int __uvc_v4l2_do_ioctl(struct file *file,
                     unsigned int cmd, void *arg)
 {
        struct video_device *vdev = video_devdata(file);
@@ -978,8 +978,8 @@ static int uvc_v4l2_do_ioctl(struct inode *inode, struct file *file,
                return uvc_xu_ctrl_query(video, arg, 1);
 
        default:
-               if ((ret = v4l_compat_translate_ioctl(inode, file, cmd, arg,
-                       uvc_v4l2_do_ioctl)) == -ENOIOCTLCMD)
+               if ((ret = v4l_compat_translate_ioctl(file, cmd, arg,
+                       __uvc_v4l2_do_ioctl)) == -ENOIOCTLCMD)
                        uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n",
                                  cmd);
                return ret;
@@ -988,6 +988,12 @@ static int uvc_v4l2_do_ioctl(struct inode *inode, struct file *file,
        return ret;
 }
 
+static int uvc_v4l2_do_ioctl(struct inode *inode, struct file *file,
+                             unsigned int cmd, void *arg)
+{
+       return __uvc_v4l2_do_ioctl(file, cmd, arg);
+}
+
 static int uvc_v4l2_ioctl(struct inode *inode, struct file *file,
                     unsigned int cmd, unsigned long arg)
 {
index 928cb4037372e963f648c96656a65b9058baf98a..f13c0a9d684fe997dcbe0ab593f04d1c49557c21 100644 (file)
@@ -57,8 +57,7 @@ MODULE_LICENSE("GPL");
  */
 
 static int
-get_v4l_control(struct inode            *inode,
-               struct file             *file,
+get_v4l_control(struct file             *file,
                int                     cid,
                v4l2_kioctl             drv)
 {
@@ -67,12 +66,12 @@ get_v4l_control(struct inode            *inode,
        int                     err;
 
        qctrl2.id = cid;
-       err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2);
+       err = drv(file, VIDIOC_QUERYCTRL, &qctrl2);
        if (err < 0)
                dprintk("VIDIOC_QUERYCTRL: %d\n", err);
        if (err == 0 && !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED)) {
                ctrl2.id = qctrl2.id;
-               err = drv(inode, file, VIDIOC_G_CTRL, &ctrl2);
+               err = drv(file, VIDIOC_G_CTRL, &ctrl2);
                if (err < 0) {
                        dprintk("VIDIOC_G_CTRL: %d\n", err);
                        return 0;
@@ -85,8 +84,7 @@ get_v4l_control(struct inode            *inode,
 }
 
 static int
-set_v4l_control(struct inode            *inode,
-               struct file             *file,
+set_v4l_control(struct file             *file,
                int                     cid,
                int                     value,
                v4l2_kioctl             drv)
@@ -96,7 +94,7 @@ set_v4l_control(struct inode            *inode,
        int                     err;
 
        qctrl2.id = cid;
-       err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2);
+       err = drv(file, VIDIOC_QUERYCTRL, &qctrl2);
        if (err < 0)
                dprintk("VIDIOC_QUERYCTRL: %d\n", err);
        if (err == 0 &&
@@ -114,7 +112,7 @@ set_v4l_control(struct inode            *inode,
                         + 32767)
                        / 65535;
                ctrl2.value += qctrl2.minimum;
-               err = drv(inode, file, VIDIOC_S_CTRL, &ctrl2);
+               err = drv(file, VIDIOC_S_CTRL, &ctrl2);
                if (err < 0)
                        dprintk("VIDIOC_S_CTRL: %d\n", err);
        }
@@ -222,7 +220,6 @@ static int poll_one(struct file *file, struct poll_wqueues *pwq)
 }
 
 static int count_inputs(
-                       struct inode *inode,
                        struct file *file,
                        v4l2_kioctl drv)
 {
@@ -232,14 +229,13 @@ static int count_inputs(
        for (i = 0;; i++) {
                memset(&input2, 0, sizeof(input2));
                input2.index = i;
-               if (0 != drv(inode, file, VIDIOC_ENUMINPUT, &input2))
+               if (0 != drv(file, VIDIOC_ENUMINPUT, &input2))
                        break;
        }
        return i;
 }
 
 static int check_size(
-               struct inode *inode,
                struct file *file,
                v4l2_kioctl drv,
                int *maxw,
@@ -252,14 +248,14 @@ static int check_size(
        memset(&fmt2, 0, sizeof(fmt2));
 
        desc2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       if (0 != drv(inode, file, VIDIOC_ENUM_FMT, &desc2))
+       if (0 != drv(file, VIDIOC_ENUM_FMT, &desc2))
                goto done;
 
        fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        fmt2.fmt.pix.width       = 10000;
        fmt2.fmt.pix.height      = 10000;
        fmt2.fmt.pix.pixelformat = desc2.pixelformat;
-       if (0 != drv(inode, file, VIDIOC_TRY_FMT, &fmt2))
+       if (0 != drv(file, VIDIOC_TRY_FMT, &fmt2))
                goto done;
 
        *maxw = fmt2.fmt.pix.width;
@@ -273,7 +269,6 @@ done:
 
 static noinline int v4l1_compat_get_capabilities(
                                        struct video_capability *cap,
-                                       struct inode *inode,
                                        struct file *file,
                                        v4l2_kioctl drv)
 {
@@ -289,13 +284,13 @@ static noinline int v4l1_compat_get_capabilities(
        memset(cap, 0, sizeof(*cap));
        memset(&fbuf, 0, sizeof(fbuf));
 
-       err = drv(inode, file, VIDIOC_QUERYCAP, cap2);
+       err = drv(file, VIDIOC_QUERYCAP, cap2);
        if (err < 0) {
                dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %d\n", err);
                goto done;
        }
        if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) {
-               err = drv(inode, file, VIDIOC_G_FBUF, &fbuf);
+               err = drv(file, VIDIOC_G_FBUF, &fbuf);
                if (err < 0) {
                        dprintk("VIDIOCGCAP / VIDIOC_G_FBUF: %d\n", err);
                        memset(&fbuf, 0, sizeof(fbuf));
@@ -317,8 +312,8 @@ static noinline int v4l1_compat_get_capabilities(
        if (fbuf.capability & V4L2_FBUF_CAP_LIST_CLIPPING)
                cap->type |= VID_TYPE_CLIPPING;
 
-       cap->channels  = count_inputs(inode, file, drv);
-       check_size(inode, file, drv,
+       cap->channels  = count_inputs(file, drv);
+       check_size(file, drv,
                   &cap->maxwidth, &cap->maxheight);
        cap->audios    =  0; /* FIXME */
        cap->minwidth  = 48; /* FIXME */
@@ -331,7 +326,6 @@ done:
 
 static noinline int v4l1_compat_get_frame_buffer(
                                        struct video_buffer *buffer,
-                                       struct inode *inode,
                                        struct file *file,
                                        v4l2_kioctl drv)
 {
@@ -341,7 +335,7 @@ static noinline int v4l1_compat_get_frame_buffer(
        memset(buffer, 0, sizeof(*buffer));
        memset(&fbuf, 0, sizeof(fbuf));
 
-       err = drv(inode, file, VIDIOC_G_FBUF, &fbuf);
+       err = drv(file, VIDIOC_G_FBUF, &fbuf);
        if (err < 0) {
                dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %d\n", err);
                goto done;
@@ -386,7 +380,6 @@ done:
 
 static noinline int v4l1_compat_set_frame_buffer(
                                        struct video_buffer *buffer,
-                                       struct inode *inode,
                                        struct file *file,
                                        v4l2_kioctl drv)
 {
@@ -415,7 +408,7 @@ static noinline int v4l1_compat_set_frame_buffer(
                break;
        }
        fbuf.fmt.bytesperline = buffer->bytesperline;
-       err = drv(inode, file, VIDIOC_S_FBUF, &fbuf);
+       err = drv(file, VIDIOC_S_FBUF, &fbuf);
        if (err < 0)
                dprintk("VIDIOCSFBUF / VIDIOC_S_FBUF: %d\n", err);
        return err;
@@ -423,7 +416,6 @@ static noinline int v4l1_compat_set_frame_buffer(
 
 static noinline int v4l1_compat_get_win_cap_dimensions(
                                        struct video_window *win,
-                                       struct inode *inode,
                                        struct file *file,
                                        v4l2_kioctl drv)
 {
@@ -438,7 +430,7 @@ static noinline int v4l1_compat_get_win_cap_dimensions(
        memset(win, 0, sizeof(*win));
 
        fmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
-       err = drv(inode, file, VIDIOC_G_FMT, fmt);
+       err = drv(file, VIDIOC_G_FMT, fmt);
        if (err < 0)
                dprintk("VIDIOCGWIN / VIDIOC_G_WIN: %d\n", err);
        if (err == 0) {
@@ -453,7 +445,7 @@ static noinline int v4l1_compat_get_win_cap_dimensions(
        }
 
        fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       err = drv(inode, file, VIDIOC_G_FMT, fmt);
+       err = drv(file, VIDIOC_G_FMT, fmt);
        if (err < 0) {
                dprintk("VIDIOCGWIN / VIDIOC_G_FMT: %d\n", err);
                goto done;
@@ -472,7 +464,6 @@ done:
 
 static noinline int v4l1_compat_set_win_cap_dimensions(
                                        struct video_window *win,
-                                       struct inode *inode,
                                        struct file *file,
                                        v4l2_kioctl drv)
 {
@@ -485,8 +476,8 @@ static noinline int v4l1_compat_set_win_cap_dimensions(
                return err;
        }
        fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       drv(inode, file, VIDIOC_STREAMOFF, &fmt->type);
-       err1 = drv(inode, file, VIDIOC_G_FMT, fmt);
+       drv(file, VIDIOC_STREAMOFF, &fmt->type);
+       err1 = drv(file, VIDIOC_G_FMT, fmt);
        if (err1 < 0)
                dprintk("VIDIOCSWIN / VIDIOC_G_FMT: %d\n", err1);
        if (err1 == 0) {
@@ -494,7 +485,7 @@ static noinline int v4l1_compat_set_win_cap_dimensions(
                fmt->fmt.pix.height = win->height;
                fmt->fmt.pix.field  = V4L2_FIELD_ANY;
                fmt->fmt.pix.bytesperline = 0;
-               err = drv(inode, file, VIDIOC_S_FMT, fmt);
+               err = drv(file, VIDIOC_S_FMT, fmt);
                if (err < 0)
                        dprintk("VIDIOCSWIN / VIDIOC_S_FMT #1: %d\n",
                                err);
@@ -511,7 +502,7 @@ static noinline int v4l1_compat_set_win_cap_dimensions(
        fmt->fmt.win.chromakey = win->chromakey;
        fmt->fmt.win.clips     = (void __user *)win->clips;
        fmt->fmt.win.clipcount = win->clipcount;
-       err2 = drv(inode, file, VIDIOC_S_FMT, fmt);
+       err2 = drv(file, VIDIOC_S_FMT, fmt);
        if (err2 < 0)
                dprintk("VIDIOCSWIN / VIDIOC_S_FMT #2: %d\n", err2);
 
@@ -525,7 +516,6 @@ static noinline int v4l1_compat_set_win_cap_dimensions(
 
 static noinline int v4l1_compat_turn_preview_on_off(
                                        int *on,
-                                       struct inode *inode,
                                        struct file *file,
                                        v4l2_kioctl drv)
 {
@@ -536,9 +526,9 @@ static noinline int v4l1_compat_turn_preview_on_off(
                /* dirty hack time.  But v4l1 has no STREAMOFF
                 * equivalent in the API, and this one at
                 * least comes close ... */
-               drv(inode, file, VIDIOC_STREAMOFF, &captype);
+               drv(file, VIDIOC_STREAMOFF, &captype);
        }
-       err = drv(inode, file, VIDIOC_OVERLAY, on);
+       err = drv(file, VIDIOC_OVERLAY, on);
        if (err < 0)
                dprintk("VIDIOCCAPTURE / VIDIOC_PREVIEW: %d\n", err);
        return err;
@@ -546,7 +536,6 @@ static noinline int v4l1_compat_turn_preview_on_off(
 
 static noinline int v4l1_compat_get_input_info(
                                        struct video_channel *chan,
-                                       struct inode *inode,
                                        struct file *file,
                                        v4l2_kioctl drv)
 {
@@ -556,7 +545,7 @@ static noinline int v4l1_compat_get_input_info(
 
        memset(&input2, 0, sizeof(input2));
        input2.index = chan->channel;
-       err = drv(inode, file, VIDIOC_ENUMINPUT, &input2);
+       err = drv(file, VIDIOC_ENUMINPUT, &input2);
        if (err < 0) {
                dprintk("VIDIOCGCHAN / VIDIOC_ENUMINPUT: "
                        "channel=%d err=%d\n", chan->channel, err);
@@ -578,7 +567,7 @@ static noinline int v4l1_compat_get_input_info(
                break;
        }
        chan->norm = 0;
-       err = drv(inode, file, VIDIOC_G_STD, &sid);
+       err = drv(file, VIDIOC_G_STD, &sid);
        if (err < 0)
                dprintk("VIDIOCGCHAN / VIDIOC_G_STD: %d\n", err);
        if (err == 0) {
@@ -595,14 +584,13 @@ done:
 
 static noinline int v4l1_compat_set_input(
                                        struct video_channel *chan,
-                                       struct inode *inode,
                                        struct file *file,
                                        v4l2_kioctl drv)
 {
        int err;
        v4l2_std_id sid = 0;
 
-       err = drv(inode, file, VIDIOC_S_INPUT, &chan->channel);
+       err = drv(file, VIDIOC_S_INPUT, &chan->channel);
        if (err < 0)
                dprintk("VIDIOCSCHAN / VIDIOC_S_INPUT: %d\n", err);
        switch (chan->norm) {
@@ -617,7 +605,7 @@ static noinline int v4l1_compat_set_input(
                break;
        }
        if (0 != sid) {
-               err = drv(inode, file, VIDIOC_S_STD, &sid);
+               err = drv(file, VIDIOC_S_STD, &sid);
                if (err < 0)
                        dprintk("VIDIOCSCHAN / VIDIOC_S_STD: %d\n", err);
        }
@@ -626,7 +614,6 @@ static noinline int v4l1_compat_set_input(
 
 static noinline int v4l1_compat_get_picture(
                                        struct video_picture *pict,
-                                       struct inode *inode,
                                        struct file *file,
                                        v4l2_kioctl drv)
 {
@@ -639,19 +626,19 @@ static noinline int v4l1_compat_get_picture(
                return err;
        }
 
-       pict->brightness = get_v4l_control(inode, file,
+       pict->brightness = get_v4l_control(file,
                                           V4L2_CID_BRIGHTNESS, drv);
-       pict->hue = get_v4l_control(inode, file,
+       pict->hue = get_v4l_control(file,
                                    V4L2_CID_HUE, drv);
-       pict->contrast = get_v4l_control(inode, file,
+       pict->contrast = get_v4l_control(file,
                                         V4L2_CID_CONTRAST, drv);
-       pict->colour = get_v4l_control(inode, file,
+       pict->colour = get_v4l_control(file,
                                       V4L2_CID_SATURATION, drv);
-       pict->whiteness = get_v4l_control(inode, file,
+       pict->whiteness = get_v4l_control(file,
                                          V4L2_CID_WHITENESS, drv);
 
        fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       err = drv(inode, file, VIDIOC_G_FMT, fmt);
+       err = drv(file, VIDIOC_G_FMT, fmt);
        if (err < 0) {
                dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n", err);
                goto done;
@@ -669,7 +656,6 @@ done:
 
 static noinline int v4l1_compat_set_picture(
                                        struct video_picture *pict,
-                                       struct inode *inode,
                                        struct file *file,
                                        v4l2_kioctl drv)
 {
@@ -685,15 +671,15 @@ static noinline int v4l1_compat_set_picture(
        }
        memset(&fbuf, 0, sizeof(fbuf));
 
-       set_v4l_control(inode, file,
+       set_v4l_control(file,
                        V4L2_CID_BRIGHTNESS, pict->brightness, drv);
-       set_v4l_control(inode, file,
+       set_v4l_control(file,
                        V4L2_CID_HUE, pict->hue, drv);
-       set_v4l_control(inode, file,
+       set_v4l_control(file,
                        V4L2_CID_CONTRAST, pict->contrast, drv);
-       set_v4l_control(inode, file,
+       set_v4l_control(file,
                        V4L2_CID_SATURATION, pict->colour, drv);
-       set_v4l_control(inode, file,
+       set_v4l_control(file,
                        V4L2_CID_WHITENESS, pict->whiteness, drv);
        /*
         * V4L1 uses this ioctl to set both memory capture and overlay
@@ -703,7 +689,7 @@ static noinline int v4l1_compat_set_picture(
         */
 
        fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       err = drv(inode, file, VIDIOC_G_FMT, fmt);
+       err = drv(file, VIDIOC_G_FMT, fmt);
        /* If VIDIOC_G_FMT failed, then the driver likely doesn't
           support memory capture.  Trying to set the memory capture
           parameters would be pointless.  */
@@ -714,13 +700,13 @@ static noinline int v4l1_compat_set_picture(
                 palette_to_pixelformat(pict->palette)) {
                fmt->fmt.pix.pixelformat = palette_to_pixelformat(
                        pict->palette);
-               mem_err = drv(inode, file, VIDIOC_S_FMT, fmt);
+               mem_err = drv(file, VIDIOC_S_FMT, fmt);
                if (mem_err < 0)
                        dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",
                                mem_err);
        }
 
-       err = drv(inode, file, VIDIOC_G_FBUF, &fbuf);
+       err = drv(file, VIDIOC_G_FBUF, &fbuf);
        /* If VIDIOC_G_FBUF failed, then the driver likely doesn't
           support overlay.  Trying to set the overlay parameters
           would be quite pointless.  */
@@ -731,7 +717,7 @@ static noinline int v4l1_compat_set_picture(
                 palette_to_pixelformat(pict->palette)) {
                fbuf.fmt.pixelformat = palette_to_pixelformat(
                        pict->palette);
-               ovl_err = drv(inode, file, VIDIOC_S_FBUF, &fbuf);
+               ovl_err = drv(file, VIDIOC_S_FBUF, &fbuf);
                if (ovl_err < 0)
                        dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",
                                ovl_err);
@@ -752,7 +738,6 @@ static noinline int v4l1_compat_set_picture(
 
 static noinline int v4l1_compat_get_tuner(
                                        struct video_tuner *tun,
-                                       struct inode *inode,
                                        struct file *file,
                                        v4l2_kioctl drv)
 {
@@ -762,7 +747,7 @@ static noinline int v4l1_compat_get_tuner(
        v4l2_std_id             sid;
 
        memset(&tun2, 0, sizeof(tun2));
-       err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
+       err = drv(file, VIDIOC_G_TUNER, &tun2);
        if (err < 0) {
                dprintk("VIDIOCGTUNER / VIDIOC_G_TUNER: %d\n", err);
                goto done;
@@ -778,7 +763,7 @@ static noinline int v4l1_compat_get_tuner(
        for (i = 0; i < 64; i++) {
                memset(&std2, 0, sizeof(std2));
                std2.index = i;
-               if (0 != drv(inode, file, VIDIOC_ENUMSTD, &std2))
+               if (0 != drv(file, VIDIOC_ENUMSTD, &std2))
                        break;
                if (std2.id & V4L2_STD_PAL)
                        tun->flags |= VIDEO_TUNER_PAL;
@@ -788,7 +773,7 @@ static noinline int v4l1_compat_get_tuner(
                        tun->flags |= VIDEO_TUNER_SECAM;
        }
 
-       err = drv(inode, file, VIDIOC_G_STD, &sid);
+       err = drv(file, VIDIOC_G_STD, &sid);
        if (err < 0)
                dprintk("VIDIOCGTUNER / VIDIOC_G_STD: %d\n", err);
        if (err == 0) {
@@ -811,7 +796,6 @@ done:
 
 static noinline int v4l1_compat_select_tuner(
                                        struct video_tuner *tun,
-                                       struct inode *inode,
                                        struct file *file,
                                        v4l2_kioctl drv)
 {
@@ -821,7 +805,7 @@ static noinline int v4l1_compat_select_tuner(
 
        t.index = tun->tuner;
 
-       err = drv(inode, file, VIDIOC_S_INPUT, &t);
+       err = drv(file, VIDIOC_S_INPUT, &t);
        if (err < 0)
                dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %d\n", err);
        return err;
@@ -829,7 +813,6 @@ static noinline int v4l1_compat_select_tuner(
 
 static noinline int v4l1_compat_get_frequency(
                                        unsigned long *freq,
-                                       struct inode *inode,
                                        struct file *file,
                                        v4l2_kioctl drv)
 {
@@ -838,7 +821,7 @@ static noinline int v4l1_compat_get_frequency(
        memset(&freq2, 0, sizeof(freq2));
 
        freq2.tuner = 0;
-       err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
+       err = drv(file, VIDIOC_G_FREQUENCY, &freq2);
        if (err < 0)
                dprintk("VIDIOCGFREQ / VIDIOC_G_FREQUENCY: %d\n", err);
        if (0 == err)
@@ -848,7 +831,6 @@ static noinline int v4l1_compat_get_frequency(
 
 static noinline int v4l1_compat_set_frequency(
                                        unsigned long *freq,
-                                       struct inode *inode,
                                        struct file *file,
                                        v4l2_kioctl drv)
 {
@@ -856,9 +838,9 @@ static noinline int v4l1_compat_set_frequency(
        struct v4l2_frequency   freq2;
        memset(&freq2, 0, sizeof(freq2));
 
-       drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
+       drv(file, VIDIOC_G_FREQUENCY, &freq2);
        freq2.frequency = *freq;
-       err = drv(inode, file, VIDIOC_S_FREQUENCY, &freq2);
+       err = drv(file, VIDIOC_S_FREQUENCY, &freq2);
        if (err < 0)
                dprintk("VIDIOCSFREQ / VIDIOC_S_FREQUENCY: %d\n", err);
        return err;
@@ -866,7 +848,6 @@ static noinline int v4l1_compat_set_frequency(
 
 static noinline int v4l1_compat_get_audio(
                                        struct video_audio *aud,
-                                       struct inode *inode,
                                        struct file *file,
                                        v4l2_kioctl drv)
 {
@@ -876,7 +857,7 @@ static noinline int v4l1_compat_get_audio(
        struct v4l2_tuner       tun2;
        memset(&aud2, 0, sizeof(aud2));
 
-       err = drv(inode, file, VIDIOC_G_AUDIO, &aud2);
+       err = drv(file, VIDIOC_G_AUDIO, &aud2);
        if (err < 0) {
                dprintk("VIDIOCGAUDIO / VIDIOC_G_AUDIO: %d\n", err);
                goto done;
@@ -886,27 +867,27 @@ static noinline int v4l1_compat_get_audio(
        aud->name[sizeof(aud->name) - 1] = 0;
        aud->audio = aud2.index;
        aud->flags = 0;
-       i = get_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME, drv);
+       i = get_v4l_control(file, V4L2_CID_AUDIO_VOLUME, drv);
        if (i >= 0) {
                aud->volume = i;
                aud->flags |= VIDEO_AUDIO_VOLUME;
        }
-       i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BASS, drv);
+       i = get_v4l_control(file, V4L2_CID_AUDIO_BASS, drv);
        if (i >= 0) {
                aud->bass = i;
                aud->flags |= VIDEO_AUDIO_BASS;
        }
-       i = get_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE, drv);
+       i = get_v4l_control(file, V4L2_CID_AUDIO_TREBLE, drv);
        if (i >= 0) {
                aud->treble = i;
                aud->flags |= VIDEO_AUDIO_TREBLE;
        }
-       i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE, drv);
+       i = get_v4l_control(file, V4L2_CID_AUDIO_BALANCE, drv);
        if (i >= 0) {
                aud->balance = i;
                aud->flags |= VIDEO_AUDIO_BALANCE;
        }
-       i = get_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE, drv);
+       i = get_v4l_control(file, V4L2_CID_AUDIO_MUTE, drv);
        if (i >= 0) {
                if (i)
                        aud->flags |= VIDEO_AUDIO_MUTE;
@@ -914,13 +895,13 @@ static noinline int v4l1_compat_get_audio(
        }
        aud->step = 1;
        qctrl2.id = V4L2_CID_AUDIO_VOLUME;
-       if (drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2) == 0 &&
+       if (drv(file, VIDIOC_QUERYCTRL, &qctrl2) == 0 &&
            !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
                aud->step = qctrl2.step;
        aud->mode = 0;
 
        memset(&tun2, 0, sizeof(tun2));
-       err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
+       err = drv(file, VIDIOC_G_TUNER, &tun2);
        if (err < 0) {
                dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %d\n", err);
                err = 0;
@@ -939,7 +920,6 @@ done:
 
 static noinline int v4l1_compat_set_audio(
                                        struct video_audio *aud,
-                                       struct inode *inode,
                                        struct file *file,
                                        v4l2_kioctl drv)
 {
@@ -951,24 +931,24 @@ static noinline int v4l1_compat_set_audio(
        memset(&tun2, 0, sizeof(tun2));
 
        aud2.index = aud->audio;
-       err = drv(inode, file, VIDIOC_S_AUDIO, &aud2);
+       err = drv(file, VIDIOC_S_AUDIO, &aud2);
        if (err < 0) {
                dprintk("VIDIOCSAUDIO / VIDIOC_S_AUDIO: %d\n", err);
                goto done;
        }
 
-       set_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME,
+       set_v4l_control(file, V4L2_CID_AUDIO_VOLUME,
                        aud->volume, drv);
-       set_v4l_control(inode, file, V4L2_CID_AUDIO_BASS,
+       set_v4l_control(file, V4L2_CID_AUDIO_BASS,
                        aud->bass, drv);
-       set_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE,
+       set_v4l_control(file, V4L2_CID_AUDIO_TREBLE,
                        aud->treble, drv);
-       set_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE,
+       set_v4l_control(file, V4L2_CID_AUDIO_BALANCE,
                        aud->balance, drv);
-       set_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE,
+       set_v4l_control(file, V4L2_CID_AUDIO_MUTE,
                        !!(aud->flags & VIDEO_AUDIO_MUTE), drv);
 
-       err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
+       err = drv(file, VIDIOC_G_TUNER, &tun2);
        if (err < 0)
                dprintk("VIDIOCSAUDIO / VIDIOC_G_TUNER: %d\n", err);
        if (err == 0) {
@@ -985,7 +965,7 @@ static noinline int v4l1_compat_set_audio(
                        tun2.audmode = V4L2_TUNER_MODE_LANG2;
                        break;
                }
-               err = drv(inode, file, VIDIOC_S_TUNER, &tun2);
+               err = drv(file, VIDIOC_S_TUNER, &tun2);
                if (err < 0)
                        dprintk("VIDIOCSAUDIO / VIDIOC_S_TUNER: %d\n", err);
        }
@@ -996,7 +976,6 @@ done:
 
 static noinline int v4l1_compat_capture_frame(
                                        struct video_mmap *mm,
-                                       struct inode *inode,
                                        struct file *file,
                                        v4l2_kioctl drv)
 {
@@ -1013,7 +992,7 @@ static noinline int v4l1_compat_capture_frame(
        memset(&buf, 0, sizeof(buf));
 
        fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       err = drv(inode, file, VIDIOC_G_FMT, fmt);
+       err = drv(file, VIDIOC_G_FMT, fmt);
        if (err < 0) {
                dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %d\n", err);
                goto done;
@@ -1029,7 +1008,7 @@ static noinline int v4l1_compat_capture_frame(
                        palette_to_pixelformat(mm->format);
                fmt->fmt.pix.field = V4L2_FIELD_ANY;
                fmt->fmt.pix.bytesperline = 0;
-               err = drv(inode, file, VIDIOC_S_FMT, fmt);
+               err = drv(file, VIDIOC_S_FMT, fmt);
                if (err < 0) {
                        dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %d\n", err);
                        goto done;
@@ -1037,17 +1016,17 @@ static noinline int v4l1_compat_capture_frame(
        }
        buf.index = mm->frame;
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       err = drv(inode, file, VIDIOC_QUERYBUF, &buf);
+       err = drv(file, VIDIOC_QUERYBUF, &buf);
        if (err < 0) {
                dprintk("VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %d\n", err);
                goto done;
        }
-       err = drv(inode, file, VIDIOC_QBUF, &buf);
+       err = drv(file, VIDIOC_QBUF, &buf);
        if (err < 0) {
                dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %d\n", err);
                goto done;
        }
-       err = drv(inode, file, VIDIOC_STREAMON, &captype);
+       err = drv(file, VIDIOC_STREAMON, &captype);
        if (err < 0)
                dprintk("VIDIOCMCAPTURE / VIDIOC_STREAMON: %d\n", err);
 done:
@@ -1057,7 +1036,6 @@ done:
 
 static noinline int v4l1_compat_sync(
                                int *i,
-                               struct inode *inode,
                                struct file *file,
                                v4l2_kioctl drv)
 {
@@ -1069,7 +1047,7 @@ static noinline int v4l1_compat_sync(
        memset(&buf, 0, sizeof(buf));
        buf.index = *i;
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       err = drv(inode, file, VIDIOC_QUERYBUF, &buf);
+       err = drv(file, VIDIOC_QUERYBUF, &buf);
        if (err < 0) {
                /*  No such buffer */
                dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n", err);
@@ -1082,7 +1060,7 @@ static noinline int v4l1_compat_sync(
        }
 
        /* make sure capture actually runs so we don't block forever */
-       err = drv(inode, file, VIDIOC_STREAMON, &captype);
+       err = drv(file, VIDIOC_STREAMON, &captype);
        if (err < 0) {
                dprintk("VIDIOCSYNC / VIDIOC_STREAMON: %d\n", err);
                goto done;
@@ -1096,7 +1074,7 @@ static noinline int v4l1_compat_sync(
                if (err < 0 ||  /* error or sleep was interrupted  */
                    err == 0)   /* timeout? Shouldn't occur.  */
                        break;
-               err = drv(inode, file, VIDIOC_QUERYBUF, &buf);
+               err = drv(file, VIDIOC_QUERYBUF, &buf);
                if (err < 0)
                        dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n", err);
        }
@@ -1104,7 +1082,7 @@ static noinline int v4l1_compat_sync(
        if (!(buf.flags & V4L2_BUF_FLAG_DONE)) /* not done */
                goto done;
        do {
-               err = drv(inode, file, VIDIOC_DQBUF, &buf);
+               err = drv(file, VIDIOC_DQBUF, &buf);
                if (err < 0)
                        dprintk("VIDIOCSYNC / VIDIOC_DQBUF: %d\n", err);
        } while (err == 0 && buf.index != *i);
@@ -1114,7 +1092,6 @@ done:
 
 static noinline int v4l1_compat_get_vbi_format(
                                struct vbi_format *fmt,
-                               struct inode *inode,
                                struct file *file,
                                v4l2_kioctl drv)
 {
@@ -1128,7 +1105,7 @@ static noinline int v4l1_compat_get_vbi_format(
        }
        fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
 
-       err = drv(inode, file, VIDIOC_G_FMT, fmt2);
+       err = drv(file, VIDIOC_G_FMT, fmt2);
        if (err < 0) {
                dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err);
                goto done;
@@ -1153,7 +1130,6 @@ done:
 
 static noinline int v4l1_compat_set_vbi_format(
                                struct vbi_format *fmt,
-                               struct inode *inode,
                                struct file *file,
                                v4l2_kioctl drv)
 {
@@ -1179,7 +1155,7 @@ static noinline int v4l1_compat_set_vbi_format(
        fmt2->fmt.vbi.start[1]         = fmt->start[1];
        fmt2->fmt.vbi.count[1]         = fmt->count[1];
        fmt2->fmt.vbi.flags            = fmt->flags;
-       err = drv(inode, file, VIDIOC_TRY_FMT, fmt2);
+       err = drv(file, VIDIOC_TRY_FMT, fmt2);
        if (err < 0) {
                dprintk("VIDIOCSVBIFMT / VIDIOC_TRY_FMT: %d\n", err);
                goto done;
@@ -1196,7 +1172,7 @@ static noinline int v4l1_compat_set_vbi_format(
                err = -EINVAL;
                goto done;
        }
-       err = drv(inode, file, VIDIOC_S_FMT, fmt2);
+       err = drv(file, VIDIOC_S_FMT, fmt2);
        if (err < 0)
                dprintk("VIDIOCSVBIFMT / VIDIOC_S_FMT: %d\n", err);
 done:
@@ -1208,8 +1184,7 @@ done:
  *     This function is exported.
  */
 int
-v4l_compat_translate_ioctl(struct inode         *inode,
-                          struct file          *file,
+v4l_compat_translate_ioctl(struct file         *file,
                           int                  cmd,
                           void                 *arg,
                           v4l2_kioctl          drv)
@@ -1218,64 +1193,64 @@ v4l_compat_translate_ioctl(struct inode         *inode,
 
        switch (cmd) {
        case VIDIOCGCAP:        /* capability */
-               err = v4l1_compat_get_capabilities(arg, inode, file, drv);
+               err = v4l1_compat_get_capabilities(arg, file, drv);
                break;
        case VIDIOCGFBUF: /*  get frame buffer  */
-               err = v4l1_compat_get_frame_buffer(arg, inode, file, drv);
+               err = v4l1_compat_get_frame_buffer(arg, file, drv);
                break;
        case VIDIOCSFBUF: /*  set frame buffer  */
-               err = v4l1_compat_set_frame_buffer(arg, inode, file, drv);
+               err = v4l1_compat_set_frame_buffer(arg, file, drv);
                break;
        case VIDIOCGWIN: /*  get window or capture dimensions  */
-               err = v4l1_compat_get_win_cap_dimensions(arg, inode, file, drv);
+               err = v4l1_compat_get_win_cap_dimensions(arg, file, drv);
                break;
        case VIDIOCSWIN: /*  set window and/or capture dimensions  */
-               err = v4l1_compat_set_win_cap_dimensions(arg, inode, file, drv);
+               err = v4l1_compat_set_win_cap_dimensions(arg, file, drv);
                break;
        case VIDIOCCAPTURE: /*  turn on/off preview  */
-               err = v4l1_compat_turn_preview_on_off(arg, inode, file, drv);
+               err = v4l1_compat_turn_preview_on_off(arg, file, drv);
                break;
        case VIDIOCGCHAN: /*  get input information  */
-               err = v4l1_compat_get_input_info(arg, inode, file, drv);
+               err = v4l1_compat_get_input_info(arg, file, drv);
                break;
        case VIDIOCSCHAN: /*  set input  */
-               err = v4l1_compat_set_input(arg, inode, file, drv);
+               err = v4l1_compat_set_input(arg, file, drv);
                break;
        case VIDIOCGPICT: /*  get tone controls & partial capture format  */
-               err = v4l1_compat_get_picture(arg, inode, file, drv);
+               err = v4l1_compat_get_picture(arg, file, drv);
                break;
        case VIDIOCSPICT: /*  set tone controls & partial capture format  */
-               err = v4l1_compat_set_picture(arg, inode, file, drv);
+               err = v4l1_compat_set_picture(arg, file, drv);
                break;
        case VIDIOCGTUNER: /*  get tuner information  */
-               err = v4l1_compat_get_tuner(arg, inode, file, drv);
+               err = v4l1_compat_get_tuner(arg, file, drv);
                break;
        case VIDIOCSTUNER: /*  select a tuner input  */
-               err = v4l1_compat_select_tuner(arg, inode, file, drv);
+               err = v4l1_compat_select_tuner(arg, file, drv);
                break;
        case VIDIOCGFREQ: /*  get frequency  */
-               err = v4l1_compat_get_frequency(arg, inode, file, drv);
+               err = v4l1_compat_get_frequency(arg, file, drv);
                break;
        case VIDIOCSFREQ: /*  set frequency  */
-               err = v4l1_compat_set_frequency(arg, inode, file, drv);
+               err = v4l1_compat_set_frequency(arg, file, drv);
                break;
        case VIDIOCGAUDIO: /*  get audio properties/controls  */
-               err = v4l1_compat_get_audio(arg, inode, file, drv);
+               err = v4l1_compat_get_audio(arg, file, drv);
                break;
        case VIDIOCSAUDIO: /*  set audio controls  */
-               err = v4l1_compat_set_audio(arg, inode, file, drv);
+               err = v4l1_compat_set_audio(arg, file, drv);
                break;
        case VIDIOCMCAPTURE: /*  capture a frame  */
-               err = v4l1_compat_capture_frame(arg, inode, file, drv);
+               err = v4l1_compat_capture_frame(arg, file, drv);
                break;
        case VIDIOCSYNC: /*  wait for a frame  */
-               err = v4l1_compat_sync(arg, inode, file, drv);
+               err = v4l1_compat_sync(arg, file, drv);
                break;
        case VIDIOCGVBIFMT: /* query VBI data capture format */
-               err = v4l1_compat_get_vbi_format(arg, inode, file, drv);
+               err = v4l1_compat_get_vbi_format(arg, file, drv);
                break;
        case VIDIOCSVBIFMT:
-               err = v4l1_compat_set_vbi_format(arg, inode, file, drv);
+               err = v4l1_compat_set_vbi_format(arg, file, drv);
                break;
        default:
                err = -ENOIOCTLCMD;
index 0e4549922f26df0bce6ea8a1c3ec4361c97408f5..a935bae538ef26f4455cea5f58e0bf1da2b7c159 100644 (file)
@@ -32,7 +32,7 @@
 static DEFINE_MUTEX(mutex);
 static LIST_HEAD(int_list);
 
-static void v4l2_int_device_try_attach_all(void)
+void v4l2_int_device_try_attach_all(void)
 {
        struct v4l2_int_device *m, *s;
 
@@ -66,6 +66,7 @@ static void v4l2_int_device_try_attach_all(void)
                }
        }
 }
+EXPORT_SYMBOL_GPL(v4l2_int_device_try_attach_all);
 
 static int ioctl_sort_cmp(const void *a, const void *b)
 {
@@ -144,6 +145,7 @@ int v4l2_int_ioctl_0(struct v4l2_int_device *d, int cmd)
                find_ioctl(d->u.slave, cmd,
                           (v4l2_int_ioctl_func *)no_such_ioctl_0))(d);
 }
+EXPORT_SYMBOL_GPL(v4l2_int_ioctl_0);
 
 static int no_such_ioctl_1(struct v4l2_int_device *d, void *arg)
 {
@@ -156,5 +158,6 @@ int v4l2_int_ioctl_1(struct v4l2_int_device *d, int cmd, void *arg)
                find_ioctl(d->u.slave, cmd,
                           (v4l2_int_ioctl_func *)no_such_ioctl_1))(d, arg);
 }
+EXPORT_SYMBOL_GPL(v4l2_int_ioctl_1);
 
 MODULE_LICENSE("GPL");
index 155c9d77a463531d43989b75e2505da632f901b2..710e1a40c422b1f787ce55b677b39ae4f029acff 100644 (file)
@@ -625,13 +625,13 @@ static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type)
        return -EINVAL;
 }
 
-static int __video_do_ioctl(struct inode *inode, struct file *file,
+static int __video_do_ioctl(struct file *file,
                unsigned int cmd, void *arg)
 {
        struct video_device *vfd = video_devdata(file);
        const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
-       void                 *fh = file->private_data;
-       int                  ret = -EINVAL;
+       void *fh = file->private_data;
+       int ret = -EINVAL;
 
        if ((vfd->debug & V4L2_DEBUG_IOCTL) &&
                                !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
@@ -675,7 +675,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
         V4L2 ioctls.
         ********************************************************/
        if (_IOC_TYPE(cmd) == 'v' && _IOC_NR(cmd) < BASE_VIDIOCPRIVATE)
-               return v4l_compat_translate_ioctl(inode, file, cmd, arg,
+               return v4l_compat_translate_ioctl(file, cmd, arg,
                                                __video_do_ioctl);
 #endif
 
@@ -1768,7 +1768,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
        return ret;
 }
 
-int video_ioctl2(struct inode *inode, struct file *file,
+int __video_ioctl2(struct file *file,
               unsigned int cmd, unsigned long arg)
 {
        char    sbuf[128];
@@ -1832,7 +1832,7 @@ int video_ioctl2(struct inode *inode, struct file *file,
        }
 
        /* Handles IOCTL */
-       err = __video_do_ioctl(inode, file, cmd, parg);
+       err = __video_do_ioctl(file, cmd, parg);
        if (err == -ENOIOCTLCMD)
                err = -EINVAL;
        if (is_ext_ctrl) {
@@ -1860,4 +1860,11 @@ out:
        kfree(mbuf);
        return err;
 }
+EXPORT_SYMBOL(__video_ioctl2);
+
+int video_ioctl2(struct inode *inode, struct file *file,
+              unsigned int cmd, unsigned long arg)
+{
+       return __video_ioctl2(file, cmd, arg);
+}
 EXPORT_SYMBOL(video_ioctl2);
index 917277d3660562b670399c3dc8eae25d72777b89..0e7dcba8e4ae08aa902a0a4c06213630d077bb76 100644 (file)
@@ -296,29 +296,7 @@ EXPORT_SYMBOL(videobuf_dvb_register_bus);
 
 void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f)
 {
-       struct list_head *list, *q;
-       struct videobuf_dvb_frontend *fe;
-
-       mutex_lock(&f->lock);
-       list_for_each_safe(list, q, &f->felist) {
-               fe = list_entry(list, struct videobuf_dvb_frontend, felist);
-               if (fe->dvb.net.dvbdev) {
-                       dvb_net_release(&fe->dvb.net);
-                       fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx,
-                               &fe->dvb.fe_mem);
-                       fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx,
-                               &fe->dvb.fe_hw);
-                       dvb_dmxdev_release(&fe->dvb.dmxdev);
-                       dvb_dmx_release(&fe->dvb.demux);
-                       dvb_unregister_frontend(fe->dvb.frontend);
-               }
-               if (fe->dvb.frontend)
-                       /* always allocated, may have been reset */
-                       dvb_frontend_detach(fe->dvb.frontend);
-               list_del(list);
-               kfree(fe);
-       }
-       mutex_unlock(&f->lock);
+       videobuf_dvb_dealloc_frontends(f);
 
        dvb_unregister_adapter(&f->adapter);
 }
@@ -389,3 +367,31 @@ fail_alloc:
        return fe;
 }
 EXPORT_SYMBOL(videobuf_dvb_alloc_frontend);
+
+void videobuf_dvb_dealloc_frontends(struct videobuf_dvb_frontends *f)
+{
+       struct list_head *list, *q;
+       struct videobuf_dvb_frontend *fe;
+
+       mutex_lock(&f->lock);
+       list_for_each_safe(list, q, &f->felist) {
+               fe = list_entry(list, struct videobuf_dvb_frontend, felist);
+               if (fe->dvb.net.dvbdev) {
+                       dvb_net_release(&fe->dvb.net);
+                       fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx,
+                               &fe->dvb.fe_mem);
+                       fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx,
+                               &fe->dvb.fe_hw);
+                       dvb_dmxdev_release(&fe->dvb.dmxdev);
+                       dvb_dmx_release(&fe->dvb.demux);
+                       dvb_unregister_frontend(fe->dvb.frontend);
+               }
+               if (fe->dvb.frontend)
+                       /* always allocated, may have been reset */
+                       dvb_frontend_detach(fe->dvb.frontend);
+               list_del(list); /* remove list entry */
+               kfree(fe);      /* free frontend allocation */
+       }
+       mutex_unlock(&f->lock);
+}
+EXPORT_SYMBOL(videobuf_dvb_dealloc_frontends);
index 7d7e51def461b10d11d0efd7968b3fa21b6abb3d..e15e48f04be7511e788b5022f413952d10d93bc7 100644 (file)
@@ -1163,11 +1163,11 @@ static int vivi_release(void)
 
                if (-1 != dev->vfd->minor) {
                        printk(KERN_INFO "%s: unregistering /dev/video%d\n",
-                               VIVI_MODULE_NAME, dev->vfd->minor);
+                               VIVI_MODULE_NAME, dev->vfd->num);
                        video_unregister_device(dev->vfd);
                } else {
                        printk(KERN_INFO "%s: releasing /dev/video%d\n",
-                               VIVI_MODULE_NAME, dev->vfd->minor);
+                               VIVI_MODULE_NAME, dev->vfd->num);
                        video_device_release(dev->vfd);
                }
 
@@ -1307,7 +1307,7 @@ static int __init vivi_init(void)
 
                dev->vfd = vfd;
                printk(KERN_INFO "%s: V4L2 device registered as /dev/video%d\n",
-                       VIVI_MODULE_NAME, vfd->minor);
+                       VIVI_MODULE_NAME, vfd->num);
        }
 
        if (ret < 0) {
index dcd45dbd82dcfa0424b900f78a495d85f5a3ec9e..4dfb43bd1846b977edfe277d6f8e2d06898bb837 100644 (file)
@@ -2398,7 +2398,7 @@ error:
        cam->sensor = CC_UNKNOWN;
        DBG(1, "Image sensor initialization failed for %s (/dev/video%d). "
               "Try to detach and attach this device again",
-           symbolic(camlist, cam->id), cam->v4ldev->minor)
+           symbolic(camlist, cam->id), cam->v4ldev->num)
        return err;
 }
 
@@ -2644,7 +2644,7 @@ static void w9968cf_release_resources(struct w9968cf_device* cam)
 {
        mutex_lock(&w9968cf_devlist_mutex);
 
-       DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->minor)
+       DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->num)
 
        video_unregister_device(cam->v4ldev);
        list_del(&cam->v4llist);
@@ -2679,7 +2679,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
                DBG(2, "No supported image sensor has been detected by the "
                       "'ovcamchip' module for the %s (/dev/video%d). Make "
                       "sure it is loaded *before* (re)connecting the camera.",
-                   symbolic(camlist, cam->id), cam->v4ldev->minor)
+                   symbolic(camlist, cam->id), cam->v4ldev->num)
                mutex_unlock(&cam->dev_mutex);
                up_read(&w9968cf_disconnect);
                return -ENODEV;
@@ -2687,7 +2687,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
 
        if (cam->users) {
                DBG(2, "%s (/dev/video%d) has been already occupied by '%s'",
-                   symbolic(camlist, cam->id),cam->v4ldev->minor,cam->command)
+                   symbolic(camlist, cam->id), cam->v4ldev->num, cam->command)
                if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) {
                        mutex_unlock(&cam->dev_mutex);
                        up_read(&w9968cf_disconnect);
@@ -2709,7 +2709,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
        }
 
        DBG(5, "Opening '%s', /dev/video%d ...",
-           symbolic(camlist, cam->id), cam->v4ldev->minor)
+           symbolic(camlist, cam->id), cam->v4ldev->num)
 
        cam->streaming = 0;
        cam->misconfigured = 0;
@@ -2947,7 +2947,7 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
                        .minheight = cam->minheight,
                };
                sprintf(cap.name, "W996[87]CF USB Camera #%d",
-                       cam->v4ldev->minor);
+                       cam->v4ldev->num);
                cap.maxwidth = (cam->upscaling && w9968cf_vpp)
                               ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth)
                                 : cam->maxwidth;
@@ -3567,7 +3567,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
                goto fail;
        }
 
-       DBG(2, "V4L device registered as /dev/video%d", cam->v4ldev->minor)
+       DBG(2, "V4L device registered as /dev/video%d", cam->v4ldev->num)
 
        /* Set some basic constants */
        w9968cf_configure_camera(cam, udev, mod_id, dev_nr);
@@ -3618,7 +3618,7 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf)
                        DBG(2, "The device is open (/dev/video%d)! "
                               "Process name: %s. Deregistration and memory "
                               "deallocation are deferred on close.",
-                           cam->v4ldev->minor, cam->command)
+                           cam->v4ldev->num, cam->command)
                        cam->misconfigured = 1;
                        w9968cf_stop_transfer(cam);
                        wake_up_interruptible(&cam->wait_queue);
index 6a0902bcba6bee88a250b0511cee48269d9c57bf..9fc58170763827d241e50c7deb28a4077941e1c4 100644 (file)
@@ -539,7 +539,7 @@ static int zc0301_stream_interrupt(struct zc0301_device* cam)
                cam->state |= DEV_MISCONFIGURED;
                DBG(1, "URB timeout reached. The camera is misconfigured. To "
                       "use it, close and open /dev/video%d again.",
-                   cam->v4ldev->minor);
+                   cam->v4ldev->num);
                return -EIO;
        }
 
@@ -640,7 +640,7 @@ static void zc0301_release_resources(struct kref *kref)
 {
        struct zc0301_device *cam = container_of(kref, struct zc0301_device,
                                                 kref);
-       DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor);
+       DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->num);
        video_set_drvdata(cam->v4ldev, NULL);
        video_unregister_device(cam->v4ldev);
        usb_put_dev(cam->usbdev);
@@ -679,7 +679,7 @@ static int zc0301_open(struct inode* inode, struct file* filp)
        }
 
        if (cam->users) {
-               DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor);
+               DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->num);
                DBG(3, "Simultaneous opens are not supported");
                if ((filp->f_flags & O_NONBLOCK) ||
                    (filp->f_flags & O_NDELAY)) {
@@ -722,7 +722,7 @@ static int zc0301_open(struct inode* inode, struct file* filp)
        cam->frame_count = 0;
        zc0301_empty_framequeues(cam);
 
-       DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor);
+       DBG(3, "Video device /dev/video%d is open", cam->v4ldev->num);
 
 out:
        mutex_unlock(&cam->open_mutex);
@@ -746,7 +746,7 @@ static int zc0301_release(struct inode* inode, struct file* filp)
        cam->users--;
        wake_up_interruptible_nr(&cam->wait_open, 1);
 
-       DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor);
+       DBG(3, "Video device /dev/video%d closed", cam->v4ldev->num);
 
        kref_put(&cam->kref, zc0301_release_resources);
 
@@ -1275,7 +1275,7 @@ zc0301_vidioc_s_crop(struct zc0301_device* cam, void __user * arg)
                cam->state |= DEV_MISCONFIGURED;
                DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
                       "use the camera, close and open /dev/video%d again.",
-                   cam->v4ldev->minor);
+                   cam->v4ldev->num);
                return -EIO;
        }
 
@@ -1288,7 +1288,7 @@ zc0301_vidioc_s_crop(struct zc0301_device* cam, void __user * arg)
                cam->state |= DEV_MISCONFIGURED;
                DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
                       "use the camera, close and open /dev/video%d again.",
-                   cam->v4ldev->minor);
+                   cam->v4ldev->num);
                return -ENOMEM;
        }
 
@@ -1470,7 +1470,7 @@ zc0301_vidioc_try_s_fmt(struct zc0301_device* cam, unsigned int cmd,
                cam->state |= DEV_MISCONFIGURED;
                DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
                       "use the camera, close and open /dev/video%d again.",
-                   cam->v4ldev->minor);
+                   cam->v4ldev->num);
                return -EIO;
        }
 
@@ -1482,7 +1482,7 @@ zc0301_vidioc_try_s_fmt(struct zc0301_device* cam, unsigned int cmd,
                cam->state |= DEV_MISCONFIGURED;
                DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
                       "use the camera, close and open /dev/video%d again.",
-                   cam->v4ldev->minor);
+                   cam->v4ldev->num);
                return -ENOMEM;
        }
 
@@ -1529,7 +1529,7 @@ zc0301_vidioc_s_jpegcomp(struct zc0301_device* cam, void __user * arg)
                cam->state |= DEV_MISCONFIGURED;
                DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
                       "problems. To use the camera, close and open "
-                      "/dev/video%d again.", cam->v4ldev->minor);
+                      "/dev/video%d again.", cam->v4ldev->num);
                return -EIO;
        }
 
@@ -2005,7 +2005,7 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
                goto fail;
        }
 
-       DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor);
+       DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->num);
 
        cam->module_param.force_munmap = force_munmap[dev_nr];
        cam->module_param.frame_timeout = frame_timeout[dev_nr];
@@ -2044,7 +2044,7 @@ static void zc0301_usb_disconnect(struct usb_interface* intf)
        if (cam->users) {
                DBG(2, "Device /dev/video%d is open! Deregistration and "
                       "memory deallocation are deferred.",
-                   cam->v4ldev->minor);
+                   cam->v4ldev->num);
                cam->state |= DEV_MISCONFIGURED;
                zc0301_stop_transfer(cam);
                cam->state |= DEV_DISCONNECTED;
index 7cdac99deea69fe909b0a03e5be6e25459e54b12..a1d81ed44c7c965451ae5acb00727dc079305c5f 100644 (file)
@@ -885,7 +885,7 @@ static int zr364xx_probe(struct usb_interface *intf,
        usb_set_intfdata(intf, cam);
 
        dev_info(&udev->dev, DRIVER_DESC " controlling video device %d\n",
-                cam->vdev->minor);
+                cam->vdev->num);
        return 0;
 }
 
index 5263913e0c69e8935add96731944373ee968f01d..7911151e56a34f2873d21aa45661d5a80252cd35 100644 (file)
@@ -172,9 +172,9 @@ static int mspro_block_complete_req(struct memstick_dev *card, int error);
 
 /*** Block device ***/
 
-static int mspro_block_bd_open(struct inode *inode, struct file *filp)
+static int mspro_block_bd_open(struct block_device *bdev, fmode_t mode)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
+       struct gendisk *disk = bdev->bd_disk;
        struct mspro_block_data *msb = disk->private_data;
        int rc = -ENXIO;
 
@@ -182,7 +182,7 @@ static int mspro_block_bd_open(struct inode *inode, struct file *filp)
 
        if (msb && msb->card) {
                msb->usage_count++;
-               if ((filp->f_mode & FMODE_WRITE) && msb->read_only)
+               if ((mode & FMODE_WRITE) && msb->read_only)
                        rc = -EROFS;
                else
                        rc = 0;
@@ -218,9 +218,8 @@ static int mspro_block_disk_release(struct gendisk *disk)
        return 0;
 }
 
-static int mspro_block_bd_release(struct inode *inode, struct file *filp)
+static int mspro_block_bd_release(struct gendisk *disk, fmode_t mode)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
        return mspro_block_disk_release(disk);
 }
 
index 9f9354fd35160f8a55515437d703973cc5f7323d..d62fd4f6b52e054db684e2af1e30ac12fa3a9240 100644 (file)
@@ -1760,10 +1760,9 @@ mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
        case FC:
                return 40;
        case SAS:
-               return 10;
        case SPI:
        default:
-               return 2;
+               return 10;
        }
 }
 
index 81483de8c0fdfeae0262dc745a1147ca5c28f966..11a617ab4243bf87d9b79921de44c4ac5f57a88a 100644 (file)
@@ -575,9 +575,9 @@ static void i2o_block_biosparam(unsigned long capacity, unsigned short *cyls,
  *
  *     Returns 0 on success or negative error code on failure.
  */
-static int i2o_block_open(struct inode *inode, struct file *file)
+static int i2o_block_open(struct block_device *bdev, fmode_t mode)
 {
-       struct i2o_block_device *dev = inode->i_bdev->bd_disk->private_data;
+       struct i2o_block_device *dev = bdev->bd_disk->private_data;
 
        if (!dev->i2o_dev)
                return -ENODEV;
@@ -604,9 +604,8 @@ static int i2o_block_open(struct inode *inode, struct file *file)
  *
  *     Returns 0 on success or negative error code on failure.
  */
-static int i2o_block_release(struct inode *inode, struct file *file)
+static int i2o_block_release(struct gendisk *disk, fmode_t mode)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
        struct i2o_block_device *dev = disk->private_data;
        u8 operation;
 
@@ -653,10 +652,10 @@ static int i2o_block_getgeo(struct block_device *bdev, struct hd_geometry *geo)
  *
  *     Return 0 on success or negative error on failure.
  */
-static int i2o_block_ioctl(struct inode *inode, struct file *file,
+static int i2o_block_ioctl(struct block_device *bdev, fmode_t mode,
                           unsigned int cmd, unsigned long arg)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
+       struct gendisk *disk = bdev->bd_disk;
        struct i2o_block_device *dev = disk->private_data;
 
        /* Anyone capable of this syscall can do *real bad* things */
@@ -933,7 +932,7 @@ static struct block_device_operations i2o_block_fops = {
        .owner = THIS_MODULE,
        .open = i2o_block_open,
        .release = i2o_block_release,
-       .ioctl = i2o_block_ioctl,
+       .locked_ioctl = i2o_block_ioctl,
        .getgeo = i2o_block_getgeo,
        .media_changed = i2o_block_media_changed
 };
index 68e237b830ad1b6294ab460d30de806ede18874e..0acefe8aff8729921ab5953c4a518e7450454cad 100644 (file)
@@ -17,7 +17,7 @@ wm8350-objs                   := wm8350-core.o wm8350-regmap.o wm8350-gpio.o
 obj-$(CONFIG_MFD_WM8350)       += wm8350.o
 obj-$(CONFIG_MFD_WM8350_I2C)   += wm8350-i2c.o
 
-obj-$(CONFIG_TWL4030_CORE)     += twl4030-core.o
+obj-$(CONFIG_TWL4030_CORE)     += twl4030-core.o twl4030-irq.o
 
 obj-$(CONFIG_MFD_CORE)         += mfd-core.o
 
index ba5aa2008273bebe869b12403d5f57ce8be0a2bb..e4c0db4dc7b199cfad30f9f4e318c54bc31d0e61 100644 (file)
@@ -123,7 +123,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc)
                                        irqnr = asic->irq_base +
                                                (ASIC3_GPIOS_PER_BANK * bank)
                                                + i;
-                                       desc = irq_desc + irqnr;
+                                       desc = irq_to_desc(irqnr);
                                        desc->handle_irq(irqnr, desc);
                                        if (asic->irq_bothedge[bank] & bit)
                                                asic3_irq_flip_edge(asic, base,
@@ -136,7 +136,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc)
                for (i = ASIC3_NUM_GPIOS; i < ASIC3_NR_IRQS; i++) {
                        /* They start at bit 4 and go up */
                        if (status & (1 << (i - ASIC3_NUM_GPIOS + 4))) {
-                               desc = irq_desc + asic->irq_base + i;
+                               desc = irq_to_desc(asic->irq_base + i);
                                desc->handle_irq(asic->irq_base + i,
                                                 desc);
                        }
index 50dff6e0088d919fae79f7769f412dbf5cc297ed..1a4d04664d6dca96426c965b0ad80062f3042a95 100644 (file)
@@ -112,7 +112,7 @@ static void egpio_handler(unsigned int irq, struct irq_desc *desc)
                /* Run irq handler */
                pr_debug("got IRQ %d\n", irqpin);
                irq = ei->irq_start + irqpin;
-               desc = &irq_desc[irq];
+               desc = irq_to_desc(irq);
                desc->handle_irq(irq, desc);
        }
 }
index 220e4371266be19dc304fb2b08ae42c203ea8bee..170f9d47c2f9cb909bf78dbd36f6fed0250b3031 100644 (file)
@@ -1374,31 +1374,31 @@ static int sm501_init_dev(struct sm501_devdata *sm)
 static int sm501_plat_probe(struct platform_device *dev)
 {
        struct sm501_devdata *sm;
-       int err;
+       int ret;
 
        sm = kzalloc(sizeof(struct sm501_devdata), GFP_KERNEL);
        if (sm == NULL) {
                dev_err(&dev->dev, "no memory for device data\n");
-               err = -ENOMEM;
+               ret = -ENOMEM;
                goto err1;
        }
 
        sm->dev = &dev->dev;
        sm->pdev_id = dev->id;
-       sm->irq = platform_get_irq(dev, 0);
-       sm->io_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
-       sm->mem_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
        sm->platdata = dev->dev.platform_data;
 
-       if (sm->irq < 0) {
+       ret = platform_get_irq(dev, 0);
+       if (ret < 0) {
                dev_err(&dev->dev, "failed to get irq resource\n");
-               err = sm->irq;
                goto err_res;
        }
+       sm->irq = ret;
 
+       sm->io_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
+       sm->mem_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
        if (sm->io_res == NULL || sm->mem_res == NULL) {
                dev_err(&dev->dev, "failed to get IO resource\n");
-               err = -ENOENT;
+               ret = -ENOENT;
                goto err_res;
        }
 
@@ -1407,7 +1407,7 @@ static int sm501_plat_probe(struct platform_device *dev)
 
        if (sm->regs_claim == NULL) {
                dev_err(&dev->dev, "cannot claim registers\n");
-               err= -EBUSY;
+               ret = -EBUSY;
                goto err_res;
        }
 
@@ -1418,7 +1418,7 @@ static int sm501_plat_probe(struct platform_device *dev)
 
        if (sm->regs == NULL) {
                dev_err(&dev->dev, "cannot remap registers\n");
-               err = -EIO;
+               ret = -EIO;
                goto err_claim;
        }
 
@@ -1430,7 +1430,7 @@ static int sm501_plat_probe(struct platform_device *dev)
  err_res:
        kfree(sm);
  err1:
-       return err;
+       return ret;
 
 }
 
@@ -1625,8 +1625,7 @@ static int sm501_pci_probe(struct pci_dev *dev,
                goto err3;
        }
 
-       sm->regs = ioremap(pci_resource_start(dev, 1),
-                          pci_resource_len(dev, 1));
+       sm->regs = pci_ioremap_bar(dev, 1);
 
        if (sm->regs == NULL) {
                dev_err(&dev->dev, "cannot remap registers\n");
index fd9a0160202cbf9c15105049ac2847ef6477b2fc..dd843c4fbcc7cc76330199fc917185dbf16680f1 100644 (file)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-#include <linux/kernel_stat.h>
 #include <linux/init.h>
 #include <linux/mutex.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/random.h>
-#include <linux/kthread.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/err.h>
 
 #include <linux/i2c.h>
 #include <linux/i2c/twl4030.h>
 #define twl_has_usb()  false
 #endif
 
-static inline void activate_irq(int irq)
-{
-#ifdef CONFIG_ARM
-       /* ARM requires an extra step to clear IRQ_NOREQUEST, which it
-        * sets on behalf of every irq_chip.  Also sets IRQ_NOPROBE.
-        */
-       set_irq_flags(irq, IRQF_VALID);
-#else
-       /* same effect on other architectures */
-       set_irq_noprobe(irq);
-#endif
-}
-
-/* Primary Interrupt Handler on TWL4030 Registers */
-
-/* Register Definitions */
-
-#define REG_PIH_ISR_P1                 (0x1)
-#define REG_PIH_ISR_P2                 (0x2)
-#define REG_PIH_SIR                    (0x3)
 
 /* Triton Core internal information (BEGIN) */
 
@@ -175,138 +151,6 @@ static inline void activate_irq(int irq)
 
 /*----------------------------------------------------------------------*/
 
-/**
- * struct twl4030_mod_iregs - TWL module IMR/ISR regs to mask/clear at init
- * @mod_no: TWL4030 module number (e.g., TWL4030_MODULE_GPIO)
- * @sih_ctrl: address of module SIH_CTRL register
- * @reg_cnt: number of IMR/ISR regs
- * @imrs: pointer to array of TWL module interrupt mask register indices
- * @isrs: pointer to array of TWL module interrupt status register indices
- *
- * Ties together TWL4030 modules and lists of IMR/ISR registers to mask/clear
- * during twl_init_irq().
- */
-struct twl4030_mod_iregs {
-       const u8 mod_no;
-       const u8 sih_ctrl;
-       const u8 reg_cnt;
-       const u8 *imrs;
-       const u8 *isrs;
-};
-
-/* TWL4030 INT module interrupt mask registers */
-static const u8 __initconst twl4030_int_imr_regs[] = {
-       TWL4030_INT_PWR_IMR1,
-       TWL4030_INT_PWR_IMR2,
-};
-
-/* TWL4030 INT module interrupt status registers */
-static const u8 __initconst twl4030_int_isr_regs[] = {
-       TWL4030_INT_PWR_ISR1,
-       TWL4030_INT_PWR_ISR2,
-};
-
-/* TWL4030 INTERRUPTS module interrupt mask registers */
-static const u8 __initconst twl4030_interrupts_imr_regs[] = {
-       TWL4030_INTERRUPTS_BCIIMR1A,
-       TWL4030_INTERRUPTS_BCIIMR1B,
-       TWL4030_INTERRUPTS_BCIIMR2A,
-       TWL4030_INTERRUPTS_BCIIMR2B,
-};
-
-/* TWL4030 INTERRUPTS module interrupt status registers */
-static const u8 __initconst twl4030_interrupts_isr_regs[] = {
-       TWL4030_INTERRUPTS_BCIISR1A,
-       TWL4030_INTERRUPTS_BCIISR1B,
-       TWL4030_INTERRUPTS_BCIISR2A,
-       TWL4030_INTERRUPTS_BCIISR2B,
-};
-
-/* TWL4030 MADC module interrupt mask registers */
-static const u8 __initconst twl4030_madc_imr_regs[] = {
-       TWL4030_MADC_IMR1,
-       TWL4030_MADC_IMR2,
-};
-
-/* TWL4030 MADC module interrupt status registers */
-static const u8 __initconst twl4030_madc_isr_regs[] = {
-       TWL4030_MADC_ISR1,
-       TWL4030_MADC_ISR2,
-};
-
-/* TWL4030 keypad module interrupt mask registers */
-static const u8 __initconst twl4030_keypad_imr_regs[] = {
-       TWL4030_KEYPAD_KEYP_IMR1,
-       TWL4030_KEYPAD_KEYP_IMR2,
-};
-
-/* TWL4030 keypad module interrupt status registers */
-static const u8 __initconst twl4030_keypad_isr_regs[] = {
-       TWL4030_KEYPAD_KEYP_ISR1,
-       TWL4030_KEYPAD_KEYP_ISR2,
-};
-
-/* TWL4030 GPIO module interrupt mask registers */
-static const u8 __initconst twl4030_gpio_imr_regs[] = {
-       REG_GPIO_IMR1A,
-       REG_GPIO_IMR1B,
-       REG_GPIO_IMR2A,
-       REG_GPIO_IMR2B,
-       REG_GPIO_IMR3A,
-       REG_GPIO_IMR3B,
-};
-
-/* TWL4030 GPIO module interrupt status registers */
-static const u8 __initconst twl4030_gpio_isr_regs[] = {
-       REG_GPIO_ISR1A,
-       REG_GPIO_ISR1B,
-       REG_GPIO_ISR2A,
-       REG_GPIO_ISR2B,
-       REG_GPIO_ISR3A,
-       REG_GPIO_ISR3B,
-};
-
-/* TWL4030 modules that have IMR/ISR registers that must be masked/cleared */
-static const struct twl4030_mod_iregs __initconst twl4030_mod_regs[] = {
-       {
-               .mod_no   = TWL4030_MODULE_INT,
-               .sih_ctrl = TWL4030_INT_PWR_SIH_CTRL,
-               .reg_cnt  = ARRAY_SIZE(twl4030_int_imr_regs),
-               .imrs     = twl4030_int_imr_regs,
-               .isrs     = twl4030_int_isr_regs,
-       },
-       {
-               .mod_no   = TWL4030_MODULE_INTERRUPTS,
-               .sih_ctrl = TWL4030_INTERRUPTS_BCISIHCTRL,
-               .reg_cnt  = ARRAY_SIZE(twl4030_interrupts_imr_regs),
-               .imrs     = twl4030_interrupts_imr_regs,
-               .isrs     = twl4030_interrupts_isr_regs,
-       },
-       {
-               .mod_no   = TWL4030_MODULE_MADC,
-               .sih_ctrl = TWL4030_MADC_SIH_CTRL,
-               .reg_cnt  = ARRAY_SIZE(twl4030_madc_imr_regs),
-               .imrs     = twl4030_madc_imr_regs,
-               .isrs     = twl4030_madc_isr_regs,
-       },
-       {
-               .mod_no   = TWL4030_MODULE_KEYPAD,
-               .sih_ctrl = TWL4030_KEYPAD_KEYP_SIH_CTRL,
-               .reg_cnt  = ARRAY_SIZE(twl4030_keypad_imr_regs),
-               .imrs     = twl4030_keypad_imr_regs,
-               .isrs     = twl4030_keypad_isr_regs,
-       },
-       {
-               .mod_no   = TWL4030_MODULE_GPIO,
-               .sih_ctrl = REG_GPIO_SIH_CTRL,
-               .reg_cnt  = ARRAY_SIZE(twl4030_gpio_imr_regs),
-               .imrs     = twl4030_gpio_imr_regs,
-               .isrs     = twl4030_gpio_isr_regs,
-       },
-};
-
-/*----------------------------------------------------------------*/
-
 /* is driver active, bound to a chip? */
 static bool inuse;
 
@@ -367,33 +211,6 @@ static struct twl4030mapping twl4030_map[TWL4030_MODULE_LAST + 1] = {
 
 /*----------------------------------------------------------------------*/
 
-/*
- * TWL4030 doesn't have PIH mask, hence dummy function for mask
- * and unmask of the (eight) interrupts reported at that level ...
- * masking is only available from SIH (secondary) modules.
- */
-
-static void twl4030_i2c_ackirq(unsigned int irq)
-{
-}
-
-static void twl4030_i2c_disableint(unsigned int irq)
-{
-}
-
-static void twl4030_i2c_enableint(unsigned int irq)
-{
-}
-
-static struct irq_chip twl4030_irq_chip = {
-       .name   = "twl4030",
-       .ack    = twl4030_i2c_ackirq,
-       .mask   = twl4030_i2c_disableint,
-       .unmask = twl4030_i2c_enableint,
-};
-
-/*----------------------------------------------------------------------*/
-
 /* Exported Functions */
 
 /**
@@ -535,108 +352,11 @@ EXPORT_SYMBOL(twl4030_i2c_read_u8);
 
 /*----------------------------------------------------------------------*/
 
-static unsigned twl4030_irq_base;
-
-static struct completion irq_event;
-
-/*
- * This thread processes interrupts reported by the Primary Interrupt Handler.
- */
-static int twl4030_irq_thread(void *data)
-{
-       long irq = (long)data;
-       irq_desc_t *desc = irq_desc + irq;
-       static unsigned i2c_errors;
-       const static unsigned max_i2c_errors = 100;
-
-       current->flags |= PF_NOFREEZE;
-
-       while (!kthread_should_stop()) {
-               int ret;
-               int module_irq;
-               u8 pih_isr;
-
-               /* Wait for IRQ, then read PIH irq status (also blocking) */
-               wait_for_completion_interruptible(&irq_event);
-
-               ret = twl4030_i2c_read_u8(TWL4030_MODULE_PIH, &pih_isr,
-                                         REG_PIH_ISR_P1);
-               if (ret) {
-                       pr_warning("%s: I2C error %d reading PIH ISR\n",
-                                       DRIVER_NAME, ret);
-                       if (++i2c_errors >= max_i2c_errors) {
-                               printk(KERN_ERR "Maximum I2C error count"
-                                               " exceeded.  Terminating %s.\n",
-                                               __func__);
-                               break;
-                       }
-                       complete(&irq_event);
-                       continue;
-               }
-
-               /* these handlers deal with the relevant SIH irq status */
-               local_irq_disable();
-               for (module_irq = twl4030_irq_base;
-                               pih_isr;
-                               pih_isr >>= 1, module_irq++) {
-                       if (pih_isr & 0x1) {
-                               irq_desc_t *d = irq_desc + module_irq;
-
-                               d->handle_irq(module_irq, d);
-                       }
-               }
-               local_irq_enable();
-
-               desc->chip->unmask(irq);
-       }
-
-       return 0;
-}
-
 /*
- * do_twl4030_irq() is the desc->handle method for the twl4030 interrupt.
- * This is a chained interrupt, so there is no desc->action method for it.
- * Now we need to query the interrupt controller in the twl4030 to determine
- * which module is generating the interrupt request.  However, we can't do i2c
- * transactions in interrupt context, so we must defer that work to a kernel
- * thread.  All we do here is acknowledge and mask the interrupt and wakeup
- * the kernel thread.
+ * NOTE:  We know the first 8 IRQs after pdata->base_irq are
+ * for the PIH, and the next are for the PWR_INT SIH, since
+ * that's how twl_init_irq() sets things up.
  */
-static void do_twl4030_irq(unsigned int irq, irq_desc_t *desc)
-{
-       const unsigned int cpu = smp_processor_id();
-
-       /*
-        * Earlier this was desc->triggered = 1;
-        */
-       desc->status |= IRQ_LEVEL;
-
-       /*
-        * Acknowledge, clear _AND_ disable the interrupt.
-        */
-       desc->chip->ack(irq);
-
-       if (!desc->depth) {
-               kstat_cpu(cpu).irqs[irq]++;
-
-               complete(&irq_event);
-       }
-}
-
-static struct task_struct * __init start_twl4030_irq_thread(long irq)
-{
-       struct task_struct *thread;
-
-       init_completion(&irq_event);
-       thread = kthread_run(twl4030_irq_thread, (void *)irq, "twl4030-irq");
-       if (!thread)
-               pr_err("%s: could not create twl4030 irq %ld thread!\n",
-                      DRIVER_NAME, irq);
-
-       return thread;
-}
-
-/*----------------------------------------------------------------------*/
 
 static int add_children(struct twl4030_platform_data *pdata)
 {
@@ -668,7 +388,7 @@ static int add_children(struct twl4030_platform_data *pdata)
 
                if (status == 0) {
                        struct resource r = {
-                               .start = TWL4030_PWRIRQ_CHG_PRES,
+                               .start = pdata->irq_base + 8 + 1,
                                .flags = IORESOURCE_IRQ,
                        };
 
@@ -817,8 +537,7 @@ static int add_children(struct twl4030_platform_data *pdata)
                /* RTC module IRQ */
                if (status == 0) {
                        struct resource r = {
-                               /* REVISIT don't hard-wire this stuff */
-                               .start = TWL4030_PWRIRQ_RTC,
+                               .start = pdata->irq_base + 8 + 3,
                                .flags = IORESOURCE_IRQ,
                        };
 
@@ -863,7 +582,7 @@ static int add_children(struct twl4030_platform_data *pdata)
 
                if (status == 0) {
                        struct resource r = {
-                               .start = TWL4030_PWRIRQ_USB_PRES,
+                               .start = pdata->irq_base + 8 + 2,
                                .flags = IORESOURCE_IRQ,
                        };
 
@@ -965,123 +684,17 @@ static void __init clocks_init(void)
 
 /*----------------------------------------------------------------------*/
 
-/**
- * twl4030_i2c_clear_isr - clear TWL4030 SIH ISR regs via read + write
- * @mod_no: TWL4030 module number
- * @reg: register index to clear
- * @cor: value of the <module>_SIH_CTRL.COR bit (1 or 0)
- *
- * Either reads (cor == 1) or writes (cor == 0) to a TWL4030 interrupt
- * status register to ensure that any prior interrupts are cleared.
- * Returns the status from the I2C read operation.
- */
-static int __init twl4030_i2c_clear_isr(u8 mod_no, u8 reg, u8 cor)
-{
-       u8 tmp;
-
-       return (cor) ? twl4030_i2c_read_u8(mod_no, &tmp, reg) :
-               twl4030_i2c_write_u8(mod_no, 0xff, reg);
-}
-
-/**
- * twl4030_read_cor_bit - are TWL module ISRs cleared by reads or writes?
- * @mod_no: TWL4030 module number
- * @reg: register index to clear
- *
- * Returns 1 if the TWL4030 SIH interrupt status registers (ISRs) for
- * the specified TWL module are cleared by reads, or 0 if cleared by
- * writes.
- */
-static int twl4030_read_cor_bit(u8 mod_no, u8 reg)
-{
-       u8 tmp = 0;
-
-       WARN_ON(twl4030_i2c_read_u8(mod_no, &tmp, reg) < 0);
-
-       tmp &= TWL4030_SIH_CTRL_COR_MASK;
-       tmp >>= __ffs(TWL4030_SIH_CTRL_COR_MASK);
-
-       return tmp;
-}
-
-/**
- * twl4030_mask_clear_intrs - mask and clear all TWL4030 interrupts
- * @t: pointer to twl4030_mod_iregs array
- * @t_sz: ARRAY_SIZE(t) (starting at 1)
- *
- * Mask all TWL4030 interrupt mask registers (IMRs) and clear all
- * interrupt status registers (ISRs).  No return value, but will WARN if
- * any I2C operations fail.
- */
-static void __init twl4030_mask_clear_intrs(const struct twl4030_mod_iregs *t,
-                                           const u8 t_sz)
-{
-       int i, j;
-
-       /*
-        * N.B. - further efficiency is possible here.  Eight I2C
-        * operations on BCI and GPIO modules are avoidable if I2C
-        * burst read/write transactions were implemented.  Would
-        * probably save about 1ms of boot time and a small amount of
-        * power.
-        */
-       for (i = 0; i < t_sz; i++) {
-               const struct twl4030_mod_iregs tmr = t[i];
-               int cor;
-
-               /* Are ISRs cleared by reads or writes? */
-               cor = twl4030_read_cor_bit(tmr.mod_no, tmr.sih_ctrl);
-
-               for (j = 0; j < tmr.reg_cnt; j++) {
-
-                       /* Mask interrupts at the TWL4030 */
-                       WARN_ON(twl4030_i2c_write_u8(tmr.mod_no, 0xff,
-                                                    tmr.imrs[j]) < 0);
-
-                       /* Clear TWL4030 ISRs */
-                       WARN_ON(twl4030_i2c_clear_isr(tmr.mod_no,
-                                                     tmr.isrs[j], cor) < 0);
-               }
-       }
-}
-
-
-static void twl_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
-{
-       int     i;
-
-       /*
-        * Mask and clear all TWL4030 interrupts since initially we do
-        * not have any TWL4030 module interrupt handlers present
-        */
-       twl4030_mask_clear_intrs(twl4030_mod_regs,
-                                ARRAY_SIZE(twl4030_mod_regs));
-
-       twl4030_irq_base = irq_base;
-
-       /* install an irq handler for each of the PIH modules */
-       for (i = irq_base; i < irq_end; i++) {
-               set_irq_chip_and_handler(i, &twl4030_irq_chip,
-                               handle_simple_irq);
-               activate_irq(i);
-       }
-
-       /* install an irq handler to demultiplex the TWL4030 interrupt */
-       set_irq_data(irq_num, start_twl4030_irq_thread(irq_num));
-       set_irq_chained_handler(irq_num, do_twl4030_irq);
-}
-
-/*----------------------------------------------------------------------*/
+int twl_init_irq(int irq_num, unsigned irq_base, unsigned irq_end);
+int twl_exit_irq(void);
 
 static int twl4030_remove(struct i2c_client *client)
 {
        unsigned i;
+       int status;
 
-       /* FIXME undo twl_init_irq() */
-       if (twl4030_irq_base) {
-               dev_err(&client->dev, "can't yet clean up IRQs?\n");
-               return -ENOSYS;
-       }
+       status = twl_exit_irq();
+       if (status < 0)
+               return status;
 
        for (i = 0; i < TWL4030_NUM_SLAVES; i++) {
                struct twl4030_client   *twl = &twl4030_modules[i];
@@ -1112,7 +725,7 @@ twl4030_probe(struct i2c_client *client, const struct i2c_device_id *id)
                return -EIO;
        }
 
-       if (inuse || twl4030_irq_base) {
+       if (inuse) {
                dev_dbg(&client->dev, "driver is already in use\n");
                return -EBUSY;
        }
@@ -1146,9 +759,9 @@ twl4030_probe(struct i2c_client *client, const struct i2c_device_id *id)
        if (client->irq
                        && pdata->irq_base
                        && pdata->irq_end > pdata->irq_base) {
-               twl_init_irq(client->irq, pdata->irq_base, pdata->irq_end);
-               dev_info(&client->dev, "IRQ %d chains IRQs %d..%d\n",
-                               client->irq, pdata->irq_base, pdata->irq_end - 1);
+               status = twl_init_irq(client->irq, pdata->irq_base, pdata->irq_end);
+               if (status < 0)
+                       goto fail;
        }
 
        status = add_children(pdata);
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
new file mode 100644 (file)
index 0000000..fae868a
--- /dev/null
@@ -0,0 +1,743 @@
+/*
+ * twl4030-irq.c - TWL4030/TPS659x0 irq support
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * Modifications to defer interrupt handling to a kernel thread:
+ * Copyright (C) 2006 MontaVista Software, Inc.
+ *
+ * Based on tlv320aic23.c:
+ * Copyright (c) by Kai Svahn <kai.svahn@nokia.com>
+ *
+ * Code cleanup and modifications to IRQ handler.
+ * by syed khasim <x0khasim@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kthread.h>
+
+#include <linux/i2c/twl4030.h>
+
+
+/*
+ * TWL4030 IRQ handling has two stages in hardware, and thus in software.
+ * The Primary Interrupt Handler (PIH) stage exposes status bits saying
+ * which Secondary Interrupt Handler (SIH) stage is raising an interrupt.
+ * SIH modules are more traditional IRQ components, which support per-IRQ
+ * enable/disable and trigger controls; they do most of the work.
+ *
+ * These chips are designed to support IRQ handling from two different
+ * I2C masters.  Each has a dedicated IRQ line, and dedicated IRQ status
+ * and mask registers in the PIH and SIH modules.
+ *
+ * We set up IRQs starting at a platform-specified base, always starting
+ * with PIH and the SIH for PWR_INT and then usually adding GPIO:
+ *     base + 0  .. base + 7   PIH
+ *     base + 8  .. base + 15  SIH for PWR_INT
+ *     base + 16 .. base + 33  SIH for GPIO
+ */
+
+/* PIH register offsets */
+#define REG_PIH_ISR_P1                 0x01
+#define REG_PIH_ISR_P2                 0x02
+#define REG_PIH_SIR                    0x03    /* for testing */
+
+
+/* Linux could (eventually) use either IRQ line */
+static int irq_line;
+
+struct sih {
+       char    name[8];
+       u8      module;                 /* module id */
+       u8      control_offset;         /* for SIH_CTRL */
+       bool    set_cor;
+
+       u8      bits;                   /* valid in isr/imr */
+       u8      bytes_ixr;              /* bytelen of ISR/IMR/SIR */
+
+       u8      edr_offset;
+       u8      bytes_edr;              /* bytelen of EDR */
+
+       /* SIR ignored -- set interrupt, for testing only */
+       struct irq_data {
+               u8      isr_offset;
+               u8      imr_offset;
+       } mask[2];
+       /* + 2 bytes padding */
+};
+
+#define SIH_INITIALIZER(modname, nbits) \
+       .module         = TWL4030_MODULE_ ## modname, \
+       .control_offset = TWL4030_ ## modname ## _SIH_CTRL, \
+       .bits           = nbits, \
+       .bytes_ixr      = DIV_ROUND_UP(nbits, 8), \
+       .edr_offset     = TWL4030_ ## modname ## _EDR, \
+       .bytes_edr      = DIV_ROUND_UP((2*(nbits)), 8), \
+       .mask = { { \
+               .isr_offset     = TWL4030_ ## modname ## _ISR1, \
+               .imr_offset     = TWL4030_ ## modname ## _IMR1, \
+       }, \
+       { \
+               .isr_offset     = TWL4030_ ## modname ## _ISR2, \
+               .imr_offset     = TWL4030_ ## modname ## _IMR2, \
+       }, },
+
+/* register naming policies are inconsistent ... */
+#define TWL4030_INT_PWR_EDR            TWL4030_INT_PWR_EDR1
+#define TWL4030_MODULE_KEYPAD_KEYP     TWL4030_MODULE_KEYPAD
+#define TWL4030_MODULE_INT_PWR         TWL4030_MODULE_INT
+
+
+/* Order in this table matches order in PIH_ISR.  That is,
+ * BIT(n) in PIH_ISR is sih_modules[n].
+ */
+static const struct sih sih_modules[6] = {
+       [0] = {
+               .name           = "gpio",
+               .module         = TWL4030_MODULE_GPIO,
+               .control_offset = REG_GPIO_SIH_CTRL,
+               .set_cor        = true,
+               .bits           = TWL4030_GPIO_MAX,
+               .bytes_ixr      = 3,
+               /* Note: *all* of these IRQs default to no-trigger */
+               .edr_offset     = REG_GPIO_EDR1,
+               .bytes_edr      = 5,
+               .mask = { {
+                       .isr_offset     = REG_GPIO_ISR1A,
+                       .imr_offset     = REG_GPIO_IMR1A,
+               }, {
+                       .isr_offset     = REG_GPIO_ISR1B,
+                       .imr_offset     = REG_GPIO_IMR1B,
+               }, },
+       },
+       [1] = {
+               .name           = "keypad",
+               .set_cor        = true,
+               SIH_INITIALIZER(KEYPAD_KEYP, 4)
+       },
+       [2] = {
+               .name           = "bci",
+               .module         = TWL4030_MODULE_INTERRUPTS,
+               .control_offset = TWL4030_INTERRUPTS_BCISIHCTRL,
+               .bits           = 12,
+               .bytes_ixr      = 2,
+               .edr_offset     = TWL4030_INTERRUPTS_BCIEDR1,
+               /* Note: most of these IRQs default to no-trigger */
+               .bytes_edr      = 3,
+               .mask = { {
+                       .isr_offset     = TWL4030_INTERRUPTS_BCIISR1A,
+                       .imr_offset     = TWL4030_INTERRUPTS_BCIIMR1A,
+               }, {
+                       .isr_offset     = TWL4030_INTERRUPTS_BCIISR1B,
+                       .imr_offset     = TWL4030_INTERRUPTS_BCIIMR1B,
+               }, },
+       },
+       [3] = {
+               .name           = "madc",
+               SIH_INITIALIZER(MADC, 4)
+       },
+       [4] = {
+               /* USB doesn't use the same SIH organization */
+               .name           = "usb",
+       },
+       [5] = {
+               .name           = "power",
+               .set_cor        = true,
+               SIH_INITIALIZER(INT_PWR, 8)
+       },
+               /* there are no SIH modules #6 or #7 ... */
+};
+
+#undef TWL4030_MODULE_KEYPAD_KEYP
+#undef TWL4030_MODULE_INT_PWR
+#undef TWL4030_INT_PWR_EDR
+
+/*----------------------------------------------------------------------*/
+
+static unsigned twl4030_irq_base;
+
+static struct completion irq_event;
+
+/*
+ * This thread processes interrupts reported by the Primary Interrupt Handler.
+ */
+static int twl4030_irq_thread(void *data)
+{
+       long irq = (long)data;
+       irq_desc_t *desc = irq_desc + irq;
+       static unsigned i2c_errors;
+       const static unsigned max_i2c_errors = 100;
+
+       current->flags |= PF_NOFREEZE;
+
+       while (!kthread_should_stop()) {
+               int ret;
+               int module_irq;
+               u8 pih_isr;
+
+               /* Wait for IRQ, then read PIH irq status (also blocking) */
+               wait_for_completion_interruptible(&irq_event);
+
+               ret = twl4030_i2c_read_u8(TWL4030_MODULE_PIH, &pih_isr,
+                                         REG_PIH_ISR_P1);
+               if (ret) {
+                       pr_warning("twl4030: I2C error %d reading PIH ISR\n",
+                                       ret);
+                       if (++i2c_errors >= max_i2c_errors) {
+                               printk(KERN_ERR "Maximum I2C error count"
+                                               " exceeded.  Terminating %s.\n",
+                                               __func__);
+                               break;
+                       }
+                       complete(&irq_event);
+                       continue;
+               }
+
+               /* these handlers deal with the relevant SIH irq status */
+               local_irq_disable();
+               for (module_irq = twl4030_irq_base;
+                               pih_isr;
+                               pih_isr >>= 1, module_irq++) {
+                       if (pih_isr & 0x1) {
+                               irq_desc_t *d = irq_desc + module_irq;
+
+                               /* These can't be masked ... always warn
+                                * if we get any surprises.
+                                */
+                               if (d->status & IRQ_DISABLED)
+                                       note_interrupt(module_irq, d,
+                                                       IRQ_NONE);
+                               else
+                                       d->handle_irq(module_irq, d);
+                       }
+               }
+               local_irq_enable();
+
+               desc->chip->unmask(irq);
+       }
+
+       return 0;
+}
+
+/*
+ * handle_twl4030_pih() is the desc->handle method for the twl4030 interrupt.
+ * This is a chained interrupt, so there is no desc->action method for it.
+ * Now we need to query the interrupt controller in the twl4030 to determine
+ * which module is generating the interrupt request.  However, we can't do i2c
+ * transactions in interrupt context, so we must defer that work to a kernel
+ * thread.  All we do here is acknowledge and mask the interrupt and wakeup
+ * the kernel thread.
+ */
+static void handle_twl4030_pih(unsigned int irq, irq_desc_t *desc)
+{
+       /* Acknowledge, clear *AND* mask the interrupt... */
+       desc->chip->ack(irq);
+       complete(&irq_event);
+}
+
+static struct task_struct *start_twl4030_irq_thread(long irq)
+{
+       struct task_struct *thread;
+
+       init_completion(&irq_event);
+       thread = kthread_run(twl4030_irq_thread, (void *)irq, "twl4030-irq");
+       if (!thread)
+               pr_err("twl4030: could not create irq %ld thread!\n", irq);
+
+       return thread;
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * twl4030_init_sih_modules() ... start from a known state where no
+ * IRQs will be coming in, and where we can quickly enable them then
+ * handle them as they arrive.  Mask all IRQs: maybe init SIH_CTRL.
+ *
+ * NOTE:  we don't touch EDR registers here; they stay with hardware
+ * defaults or whatever the last value was.  Note that when both EDR
+ * bits for an IRQ are clear, that's as if its IMR bit is set...
+ */
+static int twl4030_init_sih_modules(unsigned line)
+{
+       const struct sih *sih;
+       u8 buf[4];
+       int i;
+       int status;
+
+       /* line 0 == int1_n signal; line 1 == int2_n signal */
+       if (line > 1)
+               return -EINVAL;
+
+       irq_line = line;
+
+       /* disable all interrupts on our line */
+       memset(buf, 0xff, sizeof buf);
+       sih = sih_modules;
+       for (i = 0; i < ARRAY_SIZE(sih_modules); i++, sih++) {
+
+               /* skip USB -- it's funky */
+               if (!sih->bytes_ixr)
+                       continue;
+
+               status = twl4030_i2c_write(sih->module, buf,
+                               sih->mask[line].imr_offset, sih->bytes_ixr);
+               if (status < 0)
+                       pr_err("twl4030: err %d initializing %s %s\n",
+                                       status, sih->name, "IMR");
+
+               /* Maybe disable "exclusive" mode; buffer second pending irq;
+                * set Clear-On-Read (COR) bit.
+                *
+                * NOTE that sometimes COR polarity is documented as being
+                * inverted:  for MADC and BCI, COR=1 means "clear on write".
+                * And for PWR_INT it's not documented...
+                */
+               if (sih->set_cor) {
+                       status = twl4030_i2c_write_u8(sih->module,
+                                       TWL4030_SIH_CTRL_COR_MASK,
+                                       sih->control_offset);
+                       if (status < 0)
+                               pr_err("twl4030: err %d initializing %s %s\n",
+                                               status, sih->name, "SIH_CTRL");
+               }
+       }
+
+       sih = sih_modules;
+       for (i = 0; i < ARRAY_SIZE(sih_modules); i++, sih++) {
+               u8 rxbuf[4];
+               int j;
+
+               /* skip USB */
+               if (!sih->bytes_ixr)
+                       continue;
+
+               /* Clear pending interrupt status.  Either the read was
+                * enough, or we need to write those bits.  Repeat, in
+                * case an IRQ is pending (PENDDIS=0) ... that's not
+                * uncommon with PWR_INT.PWRON.
+                */
+               for (j = 0; j < 2; j++) {
+                       status = twl4030_i2c_read(sih->module, rxbuf,
+                               sih->mask[line].isr_offset, sih->bytes_ixr);
+                       if (status < 0)
+                               pr_err("twl4030: err %d initializing %s %s\n",
+                                       status, sih->name, "ISR");
+
+                       if (!sih->set_cor)
+                               status = twl4030_i2c_write(sih->module, buf,
+                                       sih->mask[line].isr_offset,
+                                       sih->bytes_ixr);
+                       /* else COR=1 means read sufficed.
+                        * (for most SIH modules...)
+                        */
+               }
+       }
+
+       return 0;
+}
+
+static inline void activate_irq(int irq)
+{
+#ifdef CONFIG_ARM
+       /* ARM requires an extra step to clear IRQ_NOREQUEST, which it
+        * sets on behalf of every irq_chip.  Also sets IRQ_NOPROBE.
+        */
+       set_irq_flags(irq, IRQF_VALID);
+#else
+       /* same effect on other architectures */
+       set_irq_noprobe(irq);
+#endif
+}
+
+/*----------------------------------------------------------------------*/
+
+static DEFINE_SPINLOCK(sih_agent_lock);
+
+static struct workqueue_struct *wq;
+
+struct sih_agent {
+       int                     irq_base;
+       const struct sih        *sih;
+
+       u32                     imr;
+       bool                    imr_change_pending;
+       struct work_struct      mask_work;
+
+       u32                     edge_change;
+       struct work_struct      edge_work;
+};
+
+static void twl4030_sih_do_mask(struct work_struct *work)
+{
+       struct sih_agent        *agent;
+       const struct sih        *sih;
+       union {
+               u8      bytes[4];
+               u32     word;
+       }                       imr;
+       int                     status;
+
+       agent = container_of(work, struct sih_agent, mask_work);
+
+       /* see what work we have */
+       spin_lock_irq(&sih_agent_lock);
+       if (agent->imr_change_pending) {
+               sih = agent->sih;
+               /* byte[0] gets overwritten as we write ... */
+               imr.word = cpu_to_le32(agent->imr << 8);
+               agent->imr_change_pending = false;
+       } else
+               sih = NULL;
+       spin_unlock_irq(&sih_agent_lock);
+       if (!sih)
+               return;
+
+       /* write the whole mask ... simpler than subsetting it */
+       status = twl4030_i2c_write(sih->module, imr.bytes,
+                       sih->mask[irq_line].imr_offset, sih->bytes_ixr);
+       if (status)
+               pr_err("twl4030: %s, %s --> %d\n", __func__,
+                               "write", status);
+}
+
+static void twl4030_sih_do_edge(struct work_struct *work)
+{
+       struct sih_agent        *agent;
+       const struct sih        *sih;
+       u8                      bytes[6];
+       u32                     edge_change;
+       int                     status;
+
+       agent = container_of(work, struct sih_agent, edge_work);
+
+       /* see what work we have */
+       spin_lock_irq(&sih_agent_lock);
+       edge_change = agent->edge_change;
+       agent->edge_change = 0;;
+       sih = edge_change ? agent->sih : NULL;
+       spin_unlock_irq(&sih_agent_lock);
+       if (!sih)
+               return;
+
+       /* Read, reserving first byte for write scratch.  Yes, this
+        * could be cached for some speedup ... but be careful about
+        * any processor on the other IRQ line, EDR registers are
+        * shared.
+        */
+       status = twl4030_i2c_read(sih->module, bytes + 1,
+                       sih->edr_offset, sih->bytes_edr);
+       if (status) {
+               pr_err("twl4030: %s, %s --> %d\n", __func__,
+                               "read", status);
+               return;
+       }
+
+       /* Modify only the bits we know must change */
+       while (edge_change) {
+               int             i = fls(edge_change) - 1;
+               struct irq_desc *d = irq_desc + i + agent->irq_base;
+               int             byte = 1 + (i >> 2);
+               int             off = (i & 0x3) * 2;
+
+               bytes[byte] &= ~(0x03 << off);
+
+               spin_lock_irq(&d->lock);
+               if (d->status & IRQ_TYPE_EDGE_RISING)
+                       bytes[byte] |= BIT(off + 1);
+               if (d->status & IRQ_TYPE_EDGE_FALLING)
+                       bytes[byte] |= BIT(off + 0);
+               spin_unlock_irq(&d->lock);
+
+               edge_change &= ~BIT(i);
+       }
+
+       /* Write */
+       status = twl4030_i2c_write(sih->module, bytes,
+                       sih->edr_offset, sih->bytes_edr);
+       if (status)
+               pr_err("twl4030: %s, %s --> %d\n", __func__,
+                               "write", status);
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * All irq_chip methods get issued from code holding irq_desc[irq].lock,
+ * which can't perform the underlying I2C operations (because they sleep).
+ * So we must hand them off to a thread (workqueue) and cope with asynch
+ * completion, potentially including some re-ordering, of these requests.
+ */
+
+static void twl4030_sih_mask(unsigned irq)
+{
+       struct sih_agent *sih = get_irq_chip_data(irq);
+       unsigned long flags;
+
+       spin_lock_irqsave(&sih_agent_lock, flags);
+       sih->imr |= BIT(irq - sih->irq_base);
+       sih->imr_change_pending = true;
+       queue_work(wq, &sih->mask_work);
+       spin_unlock_irqrestore(&sih_agent_lock, flags);
+}
+
+static void twl4030_sih_unmask(unsigned irq)
+{
+       struct sih_agent *sih = get_irq_chip_data(irq);
+       unsigned long flags;
+
+       spin_lock_irqsave(&sih_agent_lock, flags);
+       sih->imr &= ~BIT(irq - sih->irq_base);
+       sih->imr_change_pending = true;
+       queue_work(wq, &sih->mask_work);
+       spin_unlock_irqrestore(&sih_agent_lock, flags);
+}
+
+static int twl4030_sih_set_type(unsigned irq, unsigned trigger)
+{
+       struct sih_agent *sih = get_irq_chip_data(irq);
+       struct irq_desc *desc = irq_desc + irq;
+       unsigned long flags;
+
+       if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
+               return -EINVAL;
+
+       spin_lock_irqsave(&sih_agent_lock, flags);
+       if ((desc->status & IRQ_TYPE_SENSE_MASK) != trigger) {
+               desc->status &= ~IRQ_TYPE_SENSE_MASK;
+               desc->status |= trigger;
+               sih->edge_change |= BIT(irq - sih->irq_base);
+               queue_work(wq, &sih->edge_work);
+       }
+       spin_unlock_irqrestore(&sih_agent_lock, flags);
+       return 0;
+}
+
+static struct irq_chip twl4030_sih_irq_chip = {
+       .name           = "twl4030",
+       .mask           = twl4030_sih_mask,
+       .unmask         = twl4030_sih_unmask,
+       .set_type       = twl4030_sih_set_type,
+};
+
+/*----------------------------------------------------------------------*/
+
+static inline int sih_read_isr(const struct sih *sih)
+{
+       int status;
+       union {
+               u8 bytes[4];
+               u32 word;
+       } isr;
+
+       /* FIXME need retry-on-error ... */
+
+       isr.word = 0;
+       status = twl4030_i2c_read(sih->module, isr.bytes,
+                       sih->mask[irq_line].isr_offset, sih->bytes_ixr);
+
+       return (status < 0) ? status : le32_to_cpu(isr.word);
+}
+
+/*
+ * Generic handler for SIH interrupts ... we "know" this is called
+ * in task context, with IRQs enabled.
+ */
+static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc)
+{
+       struct sih_agent *agent = get_irq_data(irq);
+       const struct sih *sih = agent->sih;
+       int isr;
+
+       /* reading ISR acks the IRQs, using clear-on-read mode */
+       local_irq_enable();
+       isr = sih_read_isr(sih);
+       local_irq_disable();
+
+       if (isr < 0) {
+               pr_err("twl4030: %s SIH, read ISR error %d\n",
+                       sih->name, isr);
+               /* REVISIT:  recover; eventually mask it all, etc */
+               return;
+       }
+
+       while (isr) {
+               irq = fls(isr);
+               irq--;
+               isr &= ~BIT(irq);
+
+               if (irq < sih->bits)
+                       generic_handle_irq(agent->irq_base + irq);
+               else
+                       pr_err("twl4030: %s SIH, invalid ISR bit %d\n",
+                               sih->name, irq);
+       }
+}
+
+static unsigned twl4030_irq_next;
+
+/* returns the first IRQ used by this SIH bank,
+ * or negative errno
+ */
+int twl4030_sih_setup(int module)
+{
+       int                     sih_mod;
+       const struct sih        *sih = NULL;
+       struct sih_agent        *agent;
+       int                     i, irq;
+       int                     status = -EINVAL;
+       unsigned                irq_base = twl4030_irq_next;
+
+       /* only support modules with standard clear-on-read for now */
+       for (sih_mod = 0, sih = sih_modules;
+                       sih_mod < ARRAY_SIZE(sih_modules);
+                       sih_mod++, sih++) {
+               if (sih->module == module && sih->set_cor) {
+                       if (!WARN((irq_base + sih->bits) > NR_IRQS,
+                                       "irq %d for %s too big\n",
+                                       irq_base + sih->bits,
+                                       sih->name))
+                               status = 0;
+                       break;
+               }
+       }
+       if (status < 0)
+               return status;
+
+       agent = kzalloc(sizeof *agent, GFP_KERNEL);
+       if (!agent)
+               return -ENOMEM;
+
+       status = 0;
+
+       agent->irq_base = irq_base;
+       agent->sih = sih;
+       agent->imr = ~0;
+       INIT_WORK(&agent->mask_work, twl4030_sih_do_mask);
+       INIT_WORK(&agent->edge_work, twl4030_sih_do_edge);
+
+       for (i = 0; i < sih->bits; i++) {
+               irq = irq_base + i;
+
+               set_irq_chip_and_handler(irq, &twl4030_sih_irq_chip,
+                               handle_edge_irq);
+               set_irq_chip_data(irq, agent);
+               activate_irq(irq);
+       }
+
+       status = irq_base;
+       twl4030_irq_next += i;
+
+       /* replace generic PIH handler (handle_simple_irq) */
+       irq = sih_mod + twl4030_irq_base;
+       set_irq_data(irq, agent);
+       set_irq_chained_handler(irq, handle_twl4030_sih);
+
+       pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", sih->name,
+                       irq, irq_base, twl4030_irq_next - 1);
+
+       return status;
+}
+
+/* FIXME need a call to reverse twl4030_sih_setup() ... */
+
+
+/*----------------------------------------------------------------------*/
+
+/* FIXME pass in which interrupt line we'll use ... */
+#define twl_irq_line   0
+
+int twl_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
+{
+       static struct irq_chip  twl4030_irq_chip;
+
+       int                     status;
+       int                     i;
+       struct task_struct      *task;
+
+       /*
+        * Mask and clear all TWL4030 interrupts since initially we do
+        * not have any TWL4030 module interrupt handlers present
+        */
+       status = twl4030_init_sih_modules(twl_irq_line);
+       if (status < 0)
+               return status;
+
+       wq = create_singlethread_workqueue("twl4030-irqchip");
+       if (!wq) {
+               pr_err("twl4030: workqueue FAIL\n");
+               return -ESRCH;
+       }
+
+       twl4030_irq_base = irq_base;
+
+       /* install an irq handler for each of the SIH modules;
+        * clone dummy irq_chip since PIH can't *do* anything
+        */
+       twl4030_irq_chip = dummy_irq_chip;
+       twl4030_irq_chip.name = "twl4030";
+
+       twl4030_sih_irq_chip.ack = dummy_irq_chip.ack;
+
+       for (i = irq_base; i < irq_end; i++) {
+               set_irq_chip_and_handler(i, &twl4030_irq_chip,
+                               handle_simple_irq);
+               activate_irq(i);
+       }
+       twl4030_irq_next = i;
+       pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", "PIH",
+                       irq_num, irq_base, twl4030_irq_next - 1);
+
+       /* ... and the PWR_INT module ... */
+       status = twl4030_sih_setup(TWL4030_MODULE_INT);
+       if (status < 0) {
+               pr_err("twl4030: sih_setup PWR INT --> %d\n", status);
+               goto fail;
+       }
+
+       /* install an irq handler to demultiplex the TWL4030 interrupt */
+       task = start_twl4030_irq_thread(irq_num);
+       if (!task) {
+               pr_err("twl4030: irq thread FAIL\n");
+               status = -ESRCH;
+               goto fail;
+       }
+
+       set_irq_data(irq_num, task);
+       set_irq_chained_handler(irq_num, handle_twl4030_pih);
+
+       return status;
+
+fail:
+       for (i = irq_base; i < irq_end; i++)
+               set_irq_chip_and_handler(i, NULL, NULL);
+       destroy_workqueue(wq);
+       wq = NULL;
+       return status;
+}
+
+int twl_exit_irq(void)
+{
+       /* FIXME undo twl_init_irq() */
+       if (twl4030_irq_base) {
+               pr_err("twl4030: can't yet clean up IRQs?\n");
+               return -ENOSYS;
+       }
+       return 0;
+}
index bf87f675e7fa8a523be49287d9d99354ad6e31e3..0d47fb9e4b3bcec5248e510504d8c6b5f2b059ec 100644 (file)
@@ -183,6 +183,9 @@ static int wm8350_write(struct wm8350 *wm8350, u8 reg, int num_regs, u16 *src)
                        (wm8350->reg_cache[i] & ~wm8350_reg_io_map[i].writable)
                        | src[i - reg];
 
+               /* Don't store volatile bits */
+               wm8350->reg_cache[i] &= ~wm8350_reg_io_map[i].vol;
+
                src[i - reg] = cpu_to_be16(src[i - reg]);
        }
 
@@ -1120,6 +1123,7 @@ static int wm8350_create_cache(struct wm8350 *wm8350, int mode)
                        }
                        value = be16_to_cpu(value);
                        value &= wm8350_reg_io_map[i].readable;
+                       value &= ~wm8350_reg_io_map[i].vol;
                        wm8350->reg_cache[i] = value;
                } else
                        wm8350->reg_cache[i] = reg_map[i];
@@ -1128,7 +1132,6 @@ static int wm8350_create_cache(struct wm8350 *wm8350, int mode)
 out:
        return ret;
 }
-EXPORT_SYMBOL_GPL(wm8350_create_cache);
 
 /*
  * Register a client device.  This is non-fatal since there is no need to
index efd3aa08b88bb85c3ca8855084a8bd1314c2c30f..9494400e8fd0baea0723cb7ccf78d37535cd279e 100644 (file)
@@ -145,6 +145,7 @@ config ACER_WMI
        depends on NEW_LEDS
        depends on BACKLIGHT_CLASS_DEVICE
        depends on SERIO_I8042
+       depends on RFKILL
        select ACPI_WMI
        ---help---
          This is a driver for newer Acer (and Wistron) laptops. It adds
@@ -245,6 +246,17 @@ config MSI_LAPTOP
 
          If you have an MSI S270 laptop, say Y or M here.
 
+config PANASONIC_LAPTOP
+       tristate "Panasonic Laptop Extras"
+       depends on X86 && INPUT && ACPI
+        depends on BACKLIGHT_CLASS_DEVICE
+       ---help---
+         This driver adds support for access to backlight control and hotkeys
+         on Panasonic Let's Note laptops.
+
+         If you have a Panasonic Let's note laptop (such as the R1(N variant),
+         R2, R3, R5, T2, W2 and Y2 series), say Y.
+
 config COMPAL_LAPTOP
        tristate "Compal Laptop Extras"
        depends on X86
index c6c13f60b4520124f7ce918069f37cdbda6e7806..909e2468cdc974be5e4ffc7c3e85affc6f6129c6 100644 (file)
@@ -23,6 +23,7 @@ obj-$(CONFIG_SGI_IOC4)                += ioc4.o
 obj-$(CONFIG_SONY_LAPTOP)      += sony-laptop.o
 obj-$(CONFIG_THINKPAD_ACPI)    += thinkpad_acpi.o
 obj-$(CONFIG_FUJITSU_LAPTOP)   += fujitsu-laptop.o
+obj-$(CONFIG_PANASONIC_LAPTOP) += panasonic-laptop.o
 obj-$(CONFIG_EEPROM_93CX6)     += eeprom_93cx6.o
 obj-$(CONFIG_INTEL_MENLOW)     += intel_menlow.o
 obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o
index d8b0d326e4522232fbcc1455dce67fb3e207c059..0532a2de2ce4decf8ef2744d5bfcaa4054b13597 100644 (file)
@@ -33,6 +33,8 @@
 #include <linux/platform_device.h>
 #include <linux/acpi.h>
 #include <linux/i8042.h>
+#include <linux/rfkill.h>
+#include <linux/workqueue.h>
 #include <linux/debugfs.h>
 
 #include <acpi/acpi_drivers.h>
@@ -123,21 +125,15 @@ enum interface_flags {
 
 static int max_brightness = 0xF;
 
-static int wireless = -1;
-static int bluetooth = -1;
 static int mailled = -1;
 static int brightness = -1;
 static int threeg = -1;
 static int force_series;
 
 module_param(mailled, int, 0444);
-module_param(wireless, int, 0444);
-module_param(bluetooth, int, 0444);
 module_param(brightness, int, 0444);
 module_param(threeg, int, 0444);
 module_param(force_series, int, 0444);
-MODULE_PARM_DESC(wireless, "Set initial state of Wireless hardware");
-MODULE_PARM_DESC(bluetooth, "Set initial state of Bluetooth hardware");
 MODULE_PARM_DESC(mailled, "Set initial state of Mail LED");
 MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness");
 MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware");
@@ -145,8 +141,6 @@ MODULE_PARM_DESC(force_series, "Force a different laptop series");
 
 struct acer_data {
        int mailled;
-       int wireless;
-       int bluetooth;
        int threeg;
        int brightness;
 };
@@ -157,6 +151,9 @@ struct acer_debug {
        u32 wmid_devices;
 };
 
+static struct rfkill *wireless_rfkill;
+static struct rfkill *bluetooth_rfkill;
+
 /* Each low-level interface must define at least some of the following */
 struct wmi_interface {
        /* The WMI device type */
@@ -476,7 +473,7 @@ struct wmi_interface *iface)
                }
                break;
        default:
-               return AE_BAD_ADDRESS;
+               return AE_ERROR;
        }
        return AE_OK;
 }
@@ -514,7 +511,7 @@ static acpi_status AMW0_set_u32(u32 value, u32 cap, struct wmi_interface *iface)
                        break;
                }
        default:
-               return AE_BAD_ADDRESS;
+               return AE_ERROR;
        }
 
        /* Actually do the set */
@@ -689,7 +686,7 @@ struct wmi_interface *iface)
                        return 0;
                }
        default:
-               return AE_BAD_ADDRESS;
+               return AE_ERROR;
        }
        status = WMI_execute_u32(method_id, 0, &result);
 
@@ -735,7 +732,7 @@ static acpi_status WMID_set_u32(u32 value, u32 cap, struct wmi_interface *iface)
                }
                break;
        default:
-               return AE_BAD_ADDRESS;
+               return AE_ERROR;
        }
        return WMI_execute_u32(method_id, (u32)value, NULL);
 }
@@ -785,7 +782,7 @@ static struct wmi_interface wmid_interface = {
 
 static acpi_status get_u32(u32 *value, u32 cap)
 {
-       acpi_status status = AE_BAD_ADDRESS;
+       acpi_status status = AE_ERROR;
 
        switch (interface->type) {
        case ACER_AMW0:
@@ -846,8 +843,6 @@ static void __init acer_commandline_init(void)
         * capability isn't available on the given interface
         */
        set_u32(mailled, ACER_CAP_MAILLED);
-       set_u32(wireless, ACER_CAP_WIRELESS);
-       set_u32(bluetooth, ACER_CAP_BLUETOOTH);
        set_u32(threeg, ACER_CAP_THREEG);
        set_u32(brightness, ACER_CAP_BRIGHTNESS);
 }
@@ -933,40 +928,135 @@ static void acer_backlight_exit(void)
 }
 
 /*
- * Read/ write bool sysfs macro
+ * Rfkill devices
  */
-#define show_set_bool(value, cap) \
-static ssize_t \
-show_bool_##value(struct device *dev, struct device_attribute *attr, \
-       char *buf) \
-{ \
-       u32 result; \
-       acpi_status status = get_u32(&result, cap); \
-       if (ACPI_SUCCESS(status)) \
-               return sprintf(buf, "%u\n", result); \
-       return sprintf(buf, "Read error\n"); \
-} \
-\
-static ssize_t \
-set_bool_##value(struct device *dev, struct device_attribute *attr, \
-       const char *buf, size_t count) \
-{ \
-       u32 tmp = simple_strtoul(buf, NULL, 10); \
-       acpi_status status = set_u32(tmp, cap); \
-               if (ACPI_FAILURE(status)) \
-                       return -EINVAL; \
-       return count; \
-} \
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO | S_IWUSR, \
-       show_bool_##value, set_bool_##value);
-
-show_set_bool(wireless, ACER_CAP_WIRELESS);
-show_set_bool(bluetooth, ACER_CAP_BLUETOOTH);
-show_set_bool(threeg, ACER_CAP_THREEG);
+static void acer_rfkill_update(struct work_struct *ignored);
+static DECLARE_DELAYED_WORK(acer_rfkill_work, acer_rfkill_update);
+static void acer_rfkill_update(struct work_struct *ignored)
+{
+       u32 state;
+       acpi_status status;
+
+       status = get_u32(&state, ACER_CAP_WIRELESS);
+       if (ACPI_SUCCESS(status))
+               rfkill_force_state(wireless_rfkill, state ?
+                       RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED);
+
+       if (has_cap(ACER_CAP_BLUETOOTH)) {
+               status = get_u32(&state, ACER_CAP_BLUETOOTH);
+               if (ACPI_SUCCESS(status))
+                       rfkill_force_state(bluetooth_rfkill, state ?
+                               RFKILL_STATE_UNBLOCKED :
+                               RFKILL_STATE_SOFT_BLOCKED);
+       }
+
+       schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));
+}
+
+static int acer_rfkill_set(void *data, enum rfkill_state state)
+{
+       acpi_status status;
+       u32 *cap = data;
+       status = set_u32((u32) (state == RFKILL_STATE_UNBLOCKED), *cap);
+       if (ACPI_FAILURE(status))
+               return -ENODEV;
+       return 0;
+}
+
+static struct rfkill * acer_rfkill_register(struct device *dev,
+enum rfkill_type type, char *name, u32 cap)
+{
+       int err;
+       u32 state;
+       u32 *data;
+       struct rfkill *rfkill_dev;
+
+       rfkill_dev = rfkill_allocate(dev, type);
+       if (!rfkill_dev)
+               return ERR_PTR(-ENOMEM);
+       rfkill_dev->name = name;
+       get_u32(&state, cap);
+       rfkill_dev->state = state ? RFKILL_STATE_UNBLOCKED :
+               RFKILL_STATE_SOFT_BLOCKED;
+       data = kzalloc(sizeof(u32), GFP_KERNEL);
+       if (!data) {
+               rfkill_free(rfkill_dev);
+               return ERR_PTR(-ENOMEM);
+       }
+       *data = cap;
+       rfkill_dev->data = data;
+       rfkill_dev->toggle_radio = acer_rfkill_set;
+       rfkill_dev->user_claim_unsupported = 1;
+
+       err = rfkill_register(rfkill_dev);
+       if (err) {
+               kfree(rfkill_dev->data);
+               rfkill_free(rfkill_dev);
+               return ERR_PTR(err);
+       }
+       return rfkill_dev;
+}
+
+static int acer_rfkill_init(struct device *dev)
+{
+       wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN,
+               "acer-wireless", ACER_CAP_WIRELESS);
+       if (IS_ERR(wireless_rfkill))
+               return PTR_ERR(wireless_rfkill);
+
+       if (has_cap(ACER_CAP_BLUETOOTH)) {
+               bluetooth_rfkill = acer_rfkill_register(dev,
+                       RFKILL_TYPE_BLUETOOTH, "acer-bluetooth",
+                       ACER_CAP_BLUETOOTH);
+               if (IS_ERR(bluetooth_rfkill)) {
+                       kfree(wireless_rfkill->data);
+                       rfkill_unregister(wireless_rfkill);
+                       return PTR_ERR(bluetooth_rfkill);
+               }
+       }
+
+       schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));
+
+       return 0;
+}
+
+static void acer_rfkill_exit(void)
+{
+       cancel_delayed_work_sync(&acer_rfkill_work);
+       kfree(wireless_rfkill->data);
+       rfkill_unregister(wireless_rfkill);
+       if (has_cap(ACER_CAP_BLUETOOTH)) {
+               kfree(wireless_rfkill->data);
+               rfkill_unregister(bluetooth_rfkill);
+       }
+       return;
+}
 
 /*
- * Read interface sysfs macro
+ * sysfs interface
  */
+static ssize_t show_bool_threeg(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       u32 result; \
+       acpi_status status = get_u32(&result, ACER_CAP_THREEG);
+       if (ACPI_SUCCESS(status))
+               return sprintf(buf, "%u\n", result);
+       return sprintf(buf, "Read error\n");
+}
+
+static ssize_t set_bool_threeg(struct device *dev,
+       struct device_attribute *attr, const char *buf, size_t count)
+{
+       u32 tmp = simple_strtoul(buf, NULL, 10);
+       acpi_status status = set_u32(tmp, ACER_CAP_THREEG);
+               if (ACPI_FAILURE(status))
+                       return -EINVAL;
+       return count;
+}
+static DEVICE_ATTR(threeg, S_IWUGO | S_IRUGO | S_IWUSR, show_bool_threeg,
+       set_bool_threeg);
+
 static ssize_t show_interface(struct device *dev, struct device_attribute *attr,
        char *buf)
 {
@@ -1026,7 +1116,9 @@ static int __devinit acer_platform_probe(struct platform_device *device)
                        goto error_brightness;
        }
 
-       return 0;
+       err = acer_rfkill_init(&device->dev);
+
+       return err;
 
 error_brightness:
        acer_led_exit();
@@ -1040,6 +1132,8 @@ static int acer_platform_remove(struct platform_device *device)
                acer_led_exit();
        if (has_cap(ACER_CAP_BRIGHTNESS))
                acer_backlight_exit();
+
+       acer_rfkill_exit();
        return 0;
 }
 
@@ -1052,16 +1146,6 @@ pm_message_t state)
        if (!data)
                return -ENOMEM;
 
-       if (has_cap(ACER_CAP_WIRELESS)) {
-               get_u32(&value, ACER_CAP_WIRELESS);
-               data->wireless = value;
-       }
-
-       if (has_cap(ACER_CAP_BLUETOOTH)) {
-               get_u32(&value, ACER_CAP_BLUETOOTH);
-               data->bluetooth = value;
-       }
-
        if (has_cap(ACER_CAP_MAILLED)) {
                get_u32(&value, ACER_CAP_MAILLED);
                data->mailled = value;
@@ -1082,15 +1166,6 @@ static int acer_platform_resume(struct platform_device *device)
        if (!data)
                return -ENOMEM;
 
-       if (has_cap(ACER_CAP_WIRELESS))
-               set_u32(data->wireless, ACER_CAP_WIRELESS);
-
-       if (has_cap(ACER_CAP_BLUETOOTH))
-               set_u32(data->bluetooth, ACER_CAP_BLUETOOTH);
-
-       if (has_cap(ACER_CAP_THREEG))
-               set_u32(data->threeg, ACER_CAP_THREEG);
-
        if (has_cap(ACER_CAP_MAILLED))
                set_u32(data->mailled, ACER_CAP_MAILLED);
 
@@ -1115,12 +1190,6 @@ static struct platform_device *acer_platform_device;
 
 static int remove_sysfs(struct platform_device *device)
 {
-       if (has_cap(ACER_CAP_WIRELESS))
-               device_remove_file(&device->dev, &dev_attr_wireless);
-
-       if (has_cap(ACER_CAP_BLUETOOTH))
-               device_remove_file(&device->dev, &dev_attr_bluetooth);
-
        if (has_cap(ACER_CAP_THREEG))
                device_remove_file(&device->dev, &dev_attr_threeg);
 
@@ -1133,20 +1202,6 @@ static int create_sysfs(void)
 {
        int retval = -ENOMEM;
 
-       if (has_cap(ACER_CAP_WIRELESS)) {
-               retval = device_create_file(&acer_platform_device->dev,
-                       &dev_attr_wireless);
-               if (retval)
-                       goto error_sysfs;
-       }
-
-       if (has_cap(ACER_CAP_BLUETOOTH)) {
-               retval = device_create_file(&acer_platform_device->dev,
-                       &dev_attr_bluetooth);
-               if (retval)
-                       goto error_sysfs;
-       }
-
        if (has_cap(ACER_CAP_THREEG)) {
                retval = device_create_file(&acer_platform_device->dev,
                        &dev_attr_threeg);
index 7c6dfd03de9fc9db3a6295f2751ed046f7cac845..a9d5228724a6950d6e7cc42d70ab8ddfab2bdd05 100644 (file)
@@ -139,6 +139,7 @@ ASUS_HANDLE(lcd_switch, "\\_SB.PCI0.SBRG.EC0._Q10", /* All new models */
            "\\_SB.PCI0.PX40.ECD0._Q10",        /* L3C */
            "\\_SB.PCI0.PX40.EC0.Q10",  /* M1A */
            "\\_SB.PCI0.LPCB.EC0._Q10", /* P30 */
+           "\\_SB.PCI0.LPCB.EC0._Q0E", /* P30/P35 */
            "\\_SB.PCI0.PX40.Q10",      /* S1x */
            "\\Q10");           /* A2x, L2D, L3D, M2E */
 
@@ -280,7 +281,7 @@ static int write_acpi_int(acpi_handle handle, const char *method, int val,
 
 static int read_wireless_status(int mask)
 {
-       ulong status;
+       unsigned long long status;
        acpi_status rv = AE_OK;
 
        if (!wireless_status_handle)
@@ -297,7 +298,7 @@ static int read_wireless_status(int mask)
 
 static int read_gps_status(void)
 {
-       ulong status;
+       unsigned long long status;
        acpi_status rv = AE_OK;
 
        rv = acpi_evaluate_integer(gps_status_handle, NULL, NULL, &status);
@@ -350,7 +351,7 @@ static void write_status(acpi_handle handle, int out, int mask)
        static void object##_led_set(struct led_classdev *led_cdev,     \
                                     enum led_brightness value)         \
        {                                                               \
-               object##_led_wk = value;                                \
+               object##_led_wk = (value > 0) ? 1 : 0;                  \
                queue_work(led_workqueue, &object##_led_work);          \
        }                                                               \
        static void object##_led_update(struct work_struct *ignored)    \
@@ -404,7 +405,7 @@ static void lcd_blank(int blank)
 
 static int read_brightness(struct backlight_device *bd)
 {
-       ulong value;
+       unsigned long long value;
        acpi_status rv = AE_OK;
 
        rv = acpi_evaluate_integer(brightness_get_handle, NULL, NULL, &value);
@@ -455,7 +456,7 @@ static ssize_t show_infos(struct device *dev,
                          struct device_attribute *attr, char *page)
 {
        int len = 0;
-       ulong temp;
+       unsigned long long temp;
        char buf[16];           //enough for all info
        acpi_status rv = AE_OK;
 
@@ -603,7 +604,7 @@ static void set_display(int value)
 
 static int read_display(void)
 {
-       ulong value = 0;
+       unsigned long long value = 0;
        acpi_status rv = AE_OK;
 
        /* In most of the case, we know how to set the display, but sometime
@@ -849,7 +850,7 @@ static int asus_hotk_get_info(void)
 {
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
        union acpi_object *model = NULL;
-       ulong bsts_result, hwrs_result;
+       unsigned long long bsts_result, hwrs_result;
        char *string = NULL;
        acpi_status status;
 
@@ -996,7 +997,7 @@ static int asus_hotk_add(struct acpi_device *device)
        hotk->handle = device->handle;
        strcpy(acpi_device_name(device), ASUS_HOTK_DEVICE_NAME);
        strcpy(acpi_device_class(device), ASUS_HOTK_CLASS);
-       acpi_driver_data(device) = hotk;
+       device->driver_data = hotk;
        hotk->device = device;
 
        result = asus_hotk_check();
index 1ee8501e90f11eb7e350355712625120dd2a5aeb..9ef98b2d5039e76bd52054e47be358909c60f58e 100644 (file)
@@ -28,6 +28,8 @@
 #include <acpi/acpi_drivers.h>
 #include <acpi/acpi_bus.h>
 #include <linux/uaccess.h>
+#include <linux/input.h>
+#include <linux/rfkill.h>
 
 #define EEEPC_LAPTOP_VERSION   "0.1"
 
@@ -125,6 +127,10 @@ struct eeepc_hotk {
                                           by this BIOS */
        uint init_flag;                 /* Init flags */
        u16 event_count[128];           /* count for each event */
+       struct input_dev *inputdev;
+       u16 *keycode_map;
+       struct rfkill *eeepc_wlan_rfkill;
+       struct rfkill *eeepc_bluetooth_rfkill;
 };
 
 /* The actual device the driver binds to */
@@ -140,6 +146,27 @@ static struct platform_driver platform_driver = {
 
 static struct platform_device *platform_device;
 
+struct key_entry {
+       char type;
+       u8 code;
+       u16 keycode;
+};
+
+enum { KE_KEY, KE_END };
+
+static struct key_entry eeepc_keymap[] = {
+       /* Sleep already handled via generic ACPI code */
+       {KE_KEY, 0x10, KEY_WLAN },
+       {KE_KEY, 0x12, KEY_PROG1 },
+       {KE_KEY, 0x13, KEY_MUTE },
+       {KE_KEY, 0x14, KEY_VOLUMEDOWN },
+       {KE_KEY, 0x15, KEY_VOLUMEUP },
+       {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
+       {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
+       {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
+       {KE_END, 0},
+};
+
 /*
  * The hotkey driver declaration
  */
@@ -204,7 +231,7 @@ static int write_acpi_int(acpi_handle handle, const char *method, int val,
 static int read_acpi_int(acpi_handle handle, const char *method, int *val)
 {
        acpi_status status;
-       ulong result;
+       unsigned long long result;
 
        status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
        if (ACPI_FAILURE(status)) {
@@ -260,6 +287,44 @@ static int update_bl_status(struct backlight_device *bd)
        return set_brightness(bd, bd->props.brightness);
 }
 
+/*
+ * Rfkill helpers
+ */
+
+static int eeepc_wlan_rfkill_set(void *data, enum rfkill_state state)
+{
+       if (state == RFKILL_STATE_SOFT_BLOCKED)
+               return set_acpi(CM_ASL_WLAN, 0);
+       else
+               return set_acpi(CM_ASL_WLAN, 1);
+}
+
+static int eeepc_wlan_rfkill_state(void *data, enum rfkill_state *state)
+{
+       if (get_acpi(CM_ASL_WLAN) == 1)
+               *state = RFKILL_STATE_UNBLOCKED;
+       else
+               *state = RFKILL_STATE_SOFT_BLOCKED;
+       return 0;
+}
+
+static int eeepc_bluetooth_rfkill_set(void *data, enum rfkill_state state)
+{
+       if (state == RFKILL_STATE_SOFT_BLOCKED)
+               return set_acpi(CM_ASL_BLUETOOTH, 0);
+       else
+               return set_acpi(CM_ASL_BLUETOOTH, 1);
+}
+
+static int eeepc_bluetooth_rfkill_state(void *data, enum rfkill_state *state)
+{
+       if (get_acpi(CM_ASL_BLUETOOTH) == 1)
+               *state = RFKILL_STATE_UNBLOCKED;
+       else
+               *state = RFKILL_STATE_SOFT_BLOCKED;
+       return 0;
+}
+
 /*
  * Sys helpers
  */
@@ -311,13 +376,11 @@ static ssize_t show_sys_acpi(int cm, char *buf)
 EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA);
 EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER);
 EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH);
-EEEPC_CREATE_DEVICE_ATTR(wlan, CM_ASL_WLAN);
 
 static struct attribute *platform_attributes[] = {
        &dev_attr_camera.attr,
        &dev_attr_cardr.attr,
        &dev_attr_disp.attr,
-       &dev_attr_wlan.attr,
        NULL
 };
 
@@ -328,8 +391,64 @@ static struct attribute_group platform_attribute_group = {
 /*
  * Hotkey functions
  */
+static struct key_entry *eepc_get_entry_by_scancode(int code)
+{
+       struct key_entry *key;
+
+       for (key = eeepc_keymap; key->type != KE_END; key++)
+               if (code == key->code)
+                       return key;
+
+       return NULL;
+}
+
+static struct key_entry *eepc_get_entry_by_keycode(int code)
+{
+       struct key_entry *key;
+
+       for (key = eeepc_keymap; key->type != KE_END; key++)
+               if (code == key->keycode && key->type == KE_KEY)
+                       return key;
+
+       return NULL;
+}
+
+static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+{
+       struct key_entry *key = eepc_get_entry_by_scancode(scancode);
+
+       if (key && key->type == KE_KEY) {
+               *keycode = key->keycode;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
+{
+       struct key_entry *key;
+       int old_keycode;
+
+       if (keycode < 0 || keycode > KEY_MAX)
+               return -EINVAL;
+
+       key = eepc_get_entry_by_scancode(scancode);
+       if (key && key->type == KE_KEY) {
+               old_keycode = key->keycode;
+               key->keycode = keycode;
+               set_bit(keycode, dev->keybit);
+               if (!eepc_get_entry_by_keycode(old_keycode))
+                       clear_bit(old_keycode, dev->keybit);
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
 static int eeepc_hotk_check(void)
 {
+       const struct key_entry *key;
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
        int result;
 
@@ -356,6 +475,31 @@ static int eeepc_hotk_check(void)
                               "Get control methods supported: 0x%x\n",
                               ehotk->cm_supported);
                }
+               ehotk->inputdev = input_allocate_device();
+               if (!ehotk->inputdev) {
+                       printk(EEEPC_INFO "Unable to allocate input device\n");
+                       return 0;
+               }
+               ehotk->inputdev->name = "Asus EeePC extra buttons";
+               ehotk->inputdev->phys = EEEPC_HOTK_FILE "/input0";
+               ehotk->inputdev->id.bustype = BUS_HOST;
+               ehotk->inputdev->getkeycode = eeepc_getkeycode;
+               ehotk->inputdev->setkeycode = eeepc_setkeycode;
+
+               for (key = eeepc_keymap; key->type != KE_END; key++) {
+                       switch (key->type) {
+                       case KE_KEY:
+                               set_bit(EV_KEY, ehotk->inputdev->evbit);
+                               set_bit(key->keycode, ehotk->inputdev->keybit);
+                               break;
+                       }
+               }
+               result = input_register_device(ehotk->inputdev);
+               if (result) {
+                       printk(EEEPC_INFO "Unable to register input device\n");
+                       input_free_device(ehotk->inputdev);
+                       return 0;
+               }
        } else {
                printk(EEEPC_ERR "Hotkey device not present, aborting\n");
                return -EINVAL;
@@ -363,21 +507,6 @@ static int eeepc_hotk_check(void)
        return 0;
 }
 
-static void notify_wlan(u32 *event)
-{
-       /* if DISABLE_ASL_WLAN is set, the notify code for fn+f2
-          will always be 0x10 */
-       if (ehotk->cm_supported & (0x1 << CM_ASL_WLAN)) {
-               const char *method = cm_getv[CM_ASL_WLAN];
-               int value;
-               if (read_acpi_int(ehotk->handle, method, &value))
-                       printk(EEEPC_WARNING "Error reading %s\n",
-                              method);
-               else if (value == 1)
-                       *event = 0x11;
-       }
-}
-
 static void notify_brn(void)
 {
        struct backlight_device *bd = eeepc_backlight_device;
@@ -386,14 +515,28 @@ static void notify_brn(void)
 
 static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
 {
+       static struct key_entry *key;
        if (!ehotk)
                return;
-       if (event == NOTIFY_WLAN_ON && (DISABLE_ASL_WLAN & ehotk->init_flag))
-               notify_wlan(&event);
        if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
                notify_brn();
        acpi_bus_generate_proc_event(ehotk->device, event,
                                     ehotk->event_count[event % 128]++);
+       if (ehotk->inputdev) {
+               key = eepc_get_entry_by_scancode(event);
+               if (key) {
+                       switch (key->type) {
+                       case KE_KEY:
+                               input_report_key(ehotk->inputdev, key->keycode,
+                                                1);
+                               input_sync(ehotk->inputdev);
+                               input_report_key(ehotk->inputdev, key->keycode,
+                                                0);
+                               input_sync(ehotk->inputdev);
+                               break;
+                       }
+               }
+       }
 }
 
 static int eeepc_hotk_add(struct acpi_device *device)
@@ -411,7 +554,7 @@ static int eeepc_hotk_add(struct acpi_device *device)
        ehotk->handle = device->handle;
        strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME);
        strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS);
-       acpi_driver_data(device) = ehotk;
+       device->driver_data = ehotk;
        ehotk->device = device;
        result = eeepc_hotk_check();
        if (result)
@@ -420,6 +563,47 @@ static int eeepc_hotk_add(struct acpi_device *device)
                                             eeepc_hotk_notify, ehotk);
        if (ACPI_FAILURE(status))
                printk(EEEPC_ERR "Error installing notify handler\n");
+
+       if (get_acpi(CM_ASL_WLAN) != -1) {
+               ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev,
+                                                          RFKILL_TYPE_WLAN);
+
+               if (!ehotk->eeepc_wlan_rfkill)
+                       goto end;
+
+               ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan";
+               ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set;
+               ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state;
+               if (get_acpi(CM_ASL_WLAN) == 1)
+                       ehotk->eeepc_wlan_rfkill->state =
+                               RFKILL_STATE_UNBLOCKED;
+               else
+                       ehotk->eeepc_wlan_rfkill->state =
+                               RFKILL_STATE_SOFT_BLOCKED;
+               rfkill_register(ehotk->eeepc_wlan_rfkill);
+       }
+
+       if (get_acpi(CM_ASL_BLUETOOTH) != -1) {
+               ehotk->eeepc_bluetooth_rfkill =
+                       rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH);
+
+               if (!ehotk->eeepc_bluetooth_rfkill)
+                       goto end;
+
+               ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth";
+               ehotk->eeepc_bluetooth_rfkill->toggle_radio =
+                       eeepc_bluetooth_rfkill_set;
+               ehotk->eeepc_bluetooth_rfkill->get_state =
+                       eeepc_bluetooth_rfkill_state;
+               if (get_acpi(CM_ASL_BLUETOOTH) == 1)
+                       ehotk->eeepc_bluetooth_rfkill->state =
+                               RFKILL_STATE_UNBLOCKED;
+               else
+                       ehotk->eeepc_bluetooth_rfkill->state =
+                               RFKILL_STATE_SOFT_BLOCKED;
+               rfkill_register(ehotk->eeepc_bluetooth_rfkill);
+       }
+
  end:
        if (result) {
                kfree(ehotk);
@@ -553,6 +737,12 @@ static void eeepc_backlight_exit(void)
 {
        if (eeepc_backlight_device)
                backlight_device_unregister(eeepc_backlight_device);
+       if (ehotk->inputdev)
+               input_unregister_device(ehotk->inputdev);
+       if (ehotk->eeepc_wlan_rfkill)
+               rfkill_unregister(ehotk->eeepc_wlan_rfkill);
+       if (ehotk->eeepc_bluetooth_rfkill)
+               rfkill_unregister(ehotk->eeepc_bluetooth_rfkill);
        eeepc_backlight_device = NULL;
 }
 
index 3e56203e494720fc4af8bb8f44ed047f81cf1b8a..d2cf0bfe31638f4de679f47a73c13097d527f3d4 100644 (file)
@@ -44,8 +44,9 @@
  * Hotkeys present on certain Fujitsu laptops (eg: the S6xxx series) are
  * also supported by this driver.
  *
- * This driver has been tested on a Fujitsu Lifebook S6410 and S7020.  It
- * should work on most P-series and S-series Lifebooks, but YMMV.
+ * This driver has been tested on a Fujitsu Lifebook S6410, S7020 and
+ * P8010.  It should work on most P-series and S-series Lifebooks, but
+ * YMMV.
  *
  * The module parameter use_alt_lcd_levels switches between different ACPI
  * brightness controls which are used by different Fujitsu laptops.  In most
@@ -65,7 +66,7 @@
 #include <linux/video_output.h>
 #include <linux/platform_device.h>
 
-#define FUJITSU_DRIVER_VERSION "0.4.2"
+#define FUJITSU_DRIVER_VERSION "0.4.3"
 
 #define FUJITSU_LCD_N_LEVELS 8
 
 #define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS     0x87
 
 /* Hotkey details */
-#define LOCK_KEY       0x410   /* codes for the keys in the GIRB register */
-#define DISPLAY_KEY    0x411   /* keys are mapped to KEY_SCREENLOCK (the key with the key symbol) */
-#define ENERGY_KEY     0x412   /* KEY_MEDIA (the key with the laptop symbol, KEY_EMAIL (E key)) */
-#define REST_KEY       0x413   /* KEY_SUSPEND (R key) */
+#define KEY1_CODE      0x410   /* codes for the keys in the GIRB register */
+#define KEY2_CODE      0x411
+#define KEY3_CODE      0x412
+#define KEY4_CODE      0x413
 
 #define MAX_HOTKEY_RINGBUFFER_SIZE 100
 #define RINGBUFFERSIZE 40
@@ -123,6 +124,7 @@ struct fujitsu_t {
        char phys[32];
        struct backlight_device *bl_device;
        struct platform_device *pf_device;
+       int keycode1, keycode2, keycode3, keycode4;
 
        unsigned int max_brightness;
        unsigned int brightness_changed;
@@ -224,7 +226,7 @@ static int set_lcd_level_alt(int level)
 
 static int get_lcd_level(void)
 {
-       unsigned long state = 0;
+       unsigned long long state = 0;
        acpi_status status = AE_OK;
 
        vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLL\n");
@@ -246,7 +248,7 @@ static int get_lcd_level(void)
 
 static int get_max_brightness(void)
 {
-       unsigned long state = 0;
+       unsigned long long state = 0;
        acpi_status status = AE_OK;
 
        vdbg_printk(FUJLAPTOP_DBG_TRACE, "get max lcd level via RBLL\n");
@@ -263,7 +265,7 @@ static int get_max_brightness(void)
 
 static int get_lcd_level_alt(void)
 {
-       unsigned long state = 0;
+       unsigned long long state = 0;
        acpi_status status = AE_OK;
 
        vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLS\n");
@@ -384,7 +386,7 @@ static ssize_t store_lcd_level(struct device *dev,
 
 static int get_irb(void)
 {
-       unsigned long state = 0;
+       unsigned long long state = 0;
        acpi_status status = AE_OK;
 
        vdbg_printk(FUJLAPTOP_DBG_TRACE, "Get irb\n");
@@ -430,7 +432,7 @@ static struct platform_driver fujitsupf_driver = {
                   }
 };
 
-static int dmi_check_cb_s6410(const struct dmi_system_id *id)
+static void dmi_check_cb_common(const struct dmi_system_id *id)
 {
        acpi_handle handle;
        int have_blnf;
@@ -452,24 +454,40 @@ static int dmi_check_cb_s6410(const struct dmi_system_id *id)
                            "auto-detecting disable_adjust\n");
                disable_brightness_adjust = have_blnf ? 0 : 1;
        }
+}
+
+static int dmi_check_cb_s6410(const struct dmi_system_id *id)
+{
+       dmi_check_cb_common(id);
+       fujitsu->keycode1 = KEY_SCREENLOCK;     /* "Lock" */
+       fujitsu->keycode2 = KEY_HELP;   /* "Mobility Center" */
+       return 0;
+}
+
+static int dmi_check_cb_p8010(const struct dmi_system_id *id)
+{
+       dmi_check_cb_common(id);
+       fujitsu->keycode1 = KEY_HELP;   /* "Support" */
+       fujitsu->keycode3 = KEY_SWITCHVIDEOMODE;        /* "Presentation" */
+       fujitsu->keycode4 = KEY_WWW;    /* "Internet" */
        return 0;
 }
 
 static struct dmi_system_id __initdata fujitsu_dmi_table[] = {
        {
-        .ident = "Fujitsu Siemens",
+        .ident = "Fujitsu Siemens S6410",
         .matches = {
                     DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
                     DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK S6410"),
                     },
         .callback = dmi_check_cb_s6410},
        {
-        .ident = "FUJITSU LifeBook P8010",
+        .ident = "Fujitsu LifeBook P8010",
         .matches = {
                     DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
                     DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P8010"),
-                   },
-        .callback = dmi_check_cb_s6410},
+                    },
+        .callback = dmi_check_cb_p8010},
        {}
 };
 
@@ -490,7 +508,7 @@ static int acpi_fujitsu_add(struct acpi_device *device)
        fujitsu->acpi_handle = device->handle;
        sprintf(acpi_device_name(device), "%s", ACPI_FUJITSU_DEVICE_NAME);
        sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
-       acpi_driver_data(device) = fujitsu;
+       device->driver_data = fujitsu;
 
        status = acpi_install_notify_handler(device->handle,
                                             ACPI_DEVICE_NOTIFY,
@@ -547,7 +565,6 @@ static int acpi_fujitsu_add(struct acpi_device *device)
        }
 
        /* do config (detect defaults) */
-       dmi_check_system(fujitsu_dmi_table);
        use_alt_lcd_levels = use_alt_lcd_levels == 1 ? 1 : 0;
        disable_brightness_keys = disable_brightness_keys == 1 ? 1 : 0;
        disable_brightness_adjust = disable_brightness_adjust == 1 ? 1 : 0;
@@ -623,17 +640,17 @@ static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data)
                        keycode = 0;
                        if (disable_brightness_keys != 1) {
                                if (oldb == 0) {
-                                       acpi_bus_generate_proc_event(fujitsu->
-                                               dev,
-                                               ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS,
-                                               0);
+                                       acpi_bus_generate_proc_event
+                                           (fujitsu->dev,
+                                            ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS,
+                                            0);
                                        keycode = KEY_BRIGHTNESSDOWN;
                                } else if (oldb ==
                                           (fujitsu->max_brightness) - 1) {
-                                       acpi_bus_generate_proc_event(fujitsu->
-                                               dev,
-                                               ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS,
-                                               0);
+                                       acpi_bus_generate_proc_event
+                                           (fujitsu->dev,
+                                            ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS,
+                                            0);
                                        keycode = KEY_BRIGHTNESSUP;
                                }
                        }
@@ -646,8 +663,7 @@ static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data)
                        }
                        if (disable_brightness_keys != 1) {
                                acpi_bus_generate_proc_event(fujitsu->dev,
-                                       ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS,
-                                       0);
+                                       ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS, 0);
                                keycode = KEY_BRIGHTNESSUP;
                        }
                } else if (oldb > newb) {
@@ -659,8 +675,7 @@ static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data)
                        }
                        if (disable_brightness_keys != 1) {
                                acpi_bus_generate_proc_event(fujitsu->dev,
-                                       ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS,
-                                       0);
+                                       ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS, 0);
                                keycode = KEY_BRIGHTNESSDOWN;
                        }
                } else {
@@ -703,7 +718,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
        sprintf(acpi_device_name(device), "%s",
                ACPI_FUJITSU_HOTKEY_DEVICE_NAME);
        sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
-       acpi_driver_data(device) = fujitsu_hotkey;
+       device->driver_data = fujitsu_hotkey;
 
        status = acpi_install_notify_handler(device->handle,
                                             ACPI_DEVICE_NOTIFY,
@@ -742,10 +757,10 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
        input->id.product = 0x06;
        input->dev.parent = &device->dev;
        input->evbit[0] = BIT(EV_KEY);
-       set_bit(KEY_SCREENLOCK, input->keybit);
-       set_bit(KEY_MEDIA, input->keybit);
-       set_bit(KEY_EMAIL, input->keybit);
-       set_bit(KEY_SUSPEND, input->keybit);
+       set_bit(fujitsu->keycode1, input->keybit);
+       set_bit(fujitsu->keycode2, input->keybit);
+       set_bit(fujitsu->keycode3, input->keybit);
+       set_bit(fujitsu->keycode4, input->keybit);
        set_bit(KEY_UNKNOWN, input->keybit);
 
        error = input_register_device(input);
@@ -833,24 +848,24 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
                                    irb);
 
                        switch (irb & 0x4ff) {
-                       case LOCK_KEY:
-                               keycode = KEY_SCREENLOCK;
+                       case KEY1_CODE:
+                               keycode = fujitsu->keycode1;
                                break;
-                       case DISPLAY_KEY:
-                               keycode = KEY_MEDIA;
+                       case KEY2_CODE:
+                               keycode = fujitsu->keycode2;
                                break;
-                       case ENERGY_KEY:
-                               keycode = KEY_EMAIL;
+                       case KEY3_CODE:
+                               keycode = fujitsu->keycode3;
                                break;
-                       case REST_KEY:
-                               keycode = KEY_SUSPEND;
+                       case KEY4_CODE:
+                               keycode = fujitsu->keycode4;
                                break;
                        case 0:
                                keycode = 0;
                                break;
                        default:
                                vdbg_printk(FUJLAPTOP_DBG_WARN,
-                                       "Unknown GIRB result [%x]\n", irb);
+                                           "Unknown GIRB result [%x]\n", irb);
                                keycode = -1;
                                break;
                        }
@@ -859,12 +874,12 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
                                        "Push keycode into ringbuffer [%d]\n",
                                        keycode);
                                status = kfifo_put(fujitsu_hotkey->fifo,
-                                               (unsigned char *)&keycode,
-                                               sizeof(keycode));
+                                                  (unsigned char *)&keycode,
+                                                  sizeof(keycode));
                                if (status != sizeof(keycode)) {
                                        vdbg_printk(FUJLAPTOP_DBG_WARN,
-                                               "Could not push keycode [0x%x]\n",
-                                               keycode);
+                                           "Could not push keycode [0x%x]\n",
+                                           keycode);
                                } else {
                                        input_report_key(input, keycode, 1);
                                        input_sync(input);
@@ -879,8 +894,8 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
                                        input_report_key(input, keycode_r, 0);
                                        input_sync(input);
                                        vdbg_printk(FUJLAPTOP_DBG_TRACE,
-                                                   "Pop keycode from ringbuffer [%d]\n",
-                                                   keycode_r);
+                                         "Pop keycode from ringbuffer [%d]\n",
+                                         keycode_r);
                                }
                        }
                }
@@ -943,6 +958,11 @@ static int __init fujitsu_init(void)
        if (!fujitsu)
                return -ENOMEM;
        memset(fujitsu, 0, sizeof(struct fujitsu_t));
+       fujitsu->keycode1 = KEY_PROG1;
+       fujitsu->keycode2 = KEY_PROG2;
+       fujitsu->keycode3 = KEY_PROG3;
+       fujitsu->keycode4 = KEY_PROG4;
+       dmi_check_system(fujitsu_dmi_table);
 
        result = acpi_bus_register_driver(&acpi_fujitsu_driver);
        if (result < 0) {
@@ -1076,15 +1096,14 @@ MODULE_DESCRIPTION("Fujitsu laptop extras support");
 MODULE_VERSION(FUJITSU_DRIVER_VERSION);
 MODULE_LICENSE("GPL");
 
-MODULE_ALIAS
-    ("dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1D3:*:cvrS6410:*");
-MODULE_ALIAS
-    ("dmi:*:svnFUJITSU:*:pvr:rvnFUJITSU:rnFJNB19C:*:cvrS7020:*");
+MODULE_ALIAS("dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1D3:*:cvrS6410:*");
+MODULE_ALIAS("dmi:*:svnFUJITSU:*:pvr:rvnFUJITSU:rnFJNB19C:*:cvrS7020:*");
 
 static struct pnp_device_id pnp_ids[] = {
-       { .id = "FUJ02bf" },
-       { .id = "FUJ02B1" },
-       { .id = "FUJ02E3" },
-       { .id = "" }
+       {.id = "FUJ02bf"},
+       {.id = "FUJ02B1"},
+       {.id = "FUJ02E3"},
+       {.id = ""}
 };
+
 MODULE_DEVICE_TABLE(pnp, pnp_ids);
index 80a1363524087a1e66e575058360d071bbca352f..e00a2756e97e110654387efec263855a0cd5aaa3 100644 (file)
@@ -57,7 +57,7 @@ static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev,
 {
        struct acpi_device *device = cdev->devdata;
        acpi_handle handle = device->handle;
-       unsigned long value;
+       unsigned long long value;
        struct acpi_object_list arg_list;
        union acpi_object arg;
        acpi_status status = AE_OK;
@@ -90,7 +90,7 @@ static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev,
 {
        struct acpi_device *device = cdev->devdata;
        acpi_handle handle = device->handle;
-       unsigned long value;
+       unsigned long long value;
        struct acpi_object_list arg_list;
        union acpi_object arg;
        acpi_status status = AE_OK;
@@ -104,7 +104,7 @@ static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev,
        if (ACPI_FAILURE(status))
                return -EFAULT;
 
-       return sprintf(buf, "%ld\n", value);
+       return sprintf(buf, "%llu\n", value);
 }
 
 static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
@@ -115,7 +115,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
        struct acpi_object_list arg_list;
        union acpi_object arg;
        acpi_status status;
-       int temp;
+       unsigned long long temp;
        unsigned long max_state;
 
        if (memory_get_int_max_bandwidth(cdev, &max_state))
@@ -131,7 +131,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
 
        status =
            acpi_evaluate_integer(handle, MEMORY_SET_BANDWIDTH, &arg_list,
-                                 (unsigned long *)&temp);
+                                 &temp);
 
        printk(KERN_INFO
               "Bandwidth value was %d: status is %d\n", state, status);
@@ -175,7 +175,7 @@ static int intel_menlow_memory_add(struct acpi_device *device)
                goto end;
        }
 
-       acpi_driver_data(device) = cdev;
+       device->driver_data = cdev;
        result = sysfs_create_link(&device->dev.kobj,
                                &cdev->device.kobj, "thermal_cooling");
        if (result)
@@ -252,7 +252,8 @@ static DEFINE_MUTEX(intel_menlow_attr_lock);
  * @auxtype : AUX0/AUX1
  * @buf: syfs buffer
  */
-static int sensor_get_auxtrip(acpi_handle handle, int index, int *value)
+static int sensor_get_auxtrip(acpi_handle handle, int index,
+                                                       unsigned long long *value)
 {
        acpi_status status;
 
@@ -260,7 +261,7 @@ static int sensor_get_auxtrip(acpi_handle handle, int index, int *value)
                return -EINVAL;
 
        status = acpi_evaluate_integer(handle, index ? GET_AUX1 : GET_AUX0,
-                                      NULL, (unsigned long *)value);
+                                      NULL, value);
        if (ACPI_FAILURE(status))
                return -EIO;
 
@@ -282,13 +283,13 @@ static int sensor_set_auxtrip(acpi_handle handle, int index, int value)
        struct acpi_object_list args = {
                1, &arg
        };
-       int temp;
+       unsigned long long temp;
 
        if (index != 0 && index != 1)
                return -EINVAL;
 
        status = acpi_evaluate_integer(handle, index ? GET_AUX0 : GET_AUX1,
-                                      NULL, (unsigned long *)&temp);
+                                      NULL, &temp);
        if (ACPI_FAILURE(status))
                return -EIO;
        if ((index && value < temp) || (!index && value > temp))
@@ -296,7 +297,7 @@ static int sensor_set_auxtrip(acpi_handle handle, int index, int value)
 
        arg.integer.value = value;
        status = acpi_evaluate_integer(handle, index ? SET_AUX1 : SET_AUX0,
-                                      &args, (unsigned long *)&temp);
+                                      &args, &temp);
        if (ACPI_FAILURE(status))
                return -EIO;
 
@@ -312,7 +313,7 @@ static ssize_t aux0_show(struct device *dev,
                         struct device_attribute *dev_attr, char *buf)
 {
        struct intel_menlow_attribute *attr = to_intel_menlow_attr(dev_attr);
-       int value;
+       unsigned long long value;
        int result;
 
        result = sensor_get_auxtrip(attr->handle, 0, &value);
@@ -324,7 +325,7 @@ static ssize_t aux1_show(struct device *dev,
                         struct device_attribute *dev_attr, char *buf)
 {
        struct intel_menlow_attribute *attr = to_intel_menlow_attr(dev_attr);
-       int value;
+       unsigned long long value;
        int result;
 
        result = sensor_get_auxtrip(attr->handle, 1, &value);
@@ -376,7 +377,7 @@ static ssize_t bios_enabled_show(struct device *dev,
                                 struct device_attribute *attr, char *buf)
 {
        acpi_status status;
-       unsigned long bios_enabled;
+       unsigned long long bios_enabled;
 
        status = acpi_evaluate_integer(NULL, BIOS_ENABLED, NULL, &bios_enabled);
        if (ACPI_FAILURE(status))
@@ -492,7 +493,7 @@ static int __init intel_menlow_module_init(void)
 {
        int result = -ENODEV;
        acpi_status status;
-       unsigned long enable;
+       unsigned long long enable;
 
        if (acpi_disabled)
                return result;
diff --git a/drivers/misc/panasonic-laptop.c b/drivers/misc/panasonic-laptop.c
new file mode 100644 (file)
index 0000000..a2cb598
--- /dev/null
@@ -0,0 +1,767 @@
+/*
+ *  Panasonic HotKey and LCD brightness control driver
+ *  (C) 2004 Hiroshi Miura <miura@da-cha.org>
+ *  (C) 2004 NTT DATA Intellilink Co. http://www.intellilink.co.jp/
+ *  (C) YOKOTA Hiroshi <yokota (at) netlab. is. tsukuba. ac. jp>
+ *  (C) 2004 David Bronaugh <dbronaugh>
+ *  (C) 2006-2008 Harald Welte <laforge@gnumonks.org>
+ *
+ *  derived from toshiba_acpi.c, Copyright (C) 2002-2004 John Belmonte
+ *
+ *  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
+ *  publicshed 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
+ *
+ *---------------------------------------------------------------------------
+ *
+ * ChangeLog:
+ *     Sep.23, 2008    Harald Welte <laforge@gnumonks.org>
+ *             -v0.95  rename driver from drivers/acpi/pcc_acpi.c to
+ *                     drivers/misc/panasonic-laptop.c
+ *
+ *     Jul.04, 2008    Harald Welte <laforge@gnumonks.org>
+ *             -v0.94  replace /proc interface with device attributes
+ *                     support {set,get}keycode on th input device
+ *
+ *      Jun.27, 2008   Harald Welte <laforge@gnumonks.org>
+ *             -v0.92  merge with 2.6.26-rc6 input API changes
+ *                     remove broken <= 2.6.15 kernel support
+ *                     resolve all compiler warnings
+ *                     various coding style fixes (checkpatch.pl)
+ *                     add support for backlight api
+ *                     major code restructuring
+ *
+ *     Dac.28, 2007    Harald Welte <laforge@gnumonks.org>
+ *             -v0.91  merge with 2.6.24-rc6 ACPI changes
+ *
+ *     Nov.04, 2006    Hiroshi Miura <miura@da-cha.org>
+ *             -v0.9   remove warning about section reference.
+ *                     remove acpi_os_free
+ *                     add /proc/acpi/pcc/brightness interface for HAL access
+ *                     merge dbronaugh's enhancement
+ *                     Aug.17, 2004 David Bronaugh (dbronaugh)
+ *                             - Added screen brightness setting interface
+ *                               Thanks to FreeBSD crew (acpi_panasonic.c)
+ *                               for the ideas I needed to accomplish it
+ *
+ *     May.29, 2006    Hiroshi Miura <miura@da-cha.org>
+ *             -v0.8.4 follow to change keyinput structure
+ *                     thanks Fabian Yamaguchi <fabs@cs.tu-berlin.de>,
+ *                     Jacob Bower <jacob.bower@ic.ac.uk> and
+ *                     Hiroshi Yokota for providing solutions.
+ *
+ *     Oct.02, 2004    Hiroshi Miura <miura@da-cha.org>
+ *             -v0.8.2 merge code of YOKOTA Hiroshi
+ *                                     <yokota@netlab.is.tsukuba.ac.jp>.
+ *                     Add sticky key mode interface.
+ *                     Refactoring acpi_pcc_generate_keyinput().
+ *
+ *     Sep.15, 2004    Hiroshi Miura <miura@da-cha.org>
+ *             -v0.8   Generate key input event on input subsystem.
+ *                     This is based on yet another driver written by
+ *                                                     Ryuta Nakanishi.
+ *
+ *     Sep.10, 2004    Hiroshi Miura <miura@da-cha.org>
+ *             -v0.7   Change proc interface functions using seq_file
+ *                     facility as same as other ACPI drivers.
+ *
+ *     Aug.28, 2004    Hiroshi Miura <miura@da-cha.org>
+ *             -v0.6.4 Fix a silly error with status checking
+ *
+ *     Aug.25, 2004    Hiroshi Miura <miura@da-cha.org>
+ *             -v0.6.3 replace read_acpi_int by standard function
+ *                                                     acpi_evaluate_integer
+ *                     some clean up and make smart copyright notice.
+ *                     fix return value of pcc_acpi_get_key()
+ *                     fix checking return value of acpi_bus_register_driver()
+ *
+ *      Aug.22, 2004    David Bronaugh <dbronaugh@linuxboxen.org>
+ *              -v0.6.2 Add check on ACPI data (num_sifr)
+ *                      Coding style cleanups, better error messages/handling
+ *                     Fixed an off-by-one error in memory allocation
+ *
+ *      Aug.21, 2004    David Bronaugh <dbronaugh@linuxboxen.org>
+ *              -v0.6.1 Fix a silly error with status checking
+ *
+ *      Aug.20, 2004    David Bronaugh <dbronaugh@linuxboxen.org>
+ *              - v0.6  Correct brightness controls to reflect reality
+ *                      based on information gleaned by Hiroshi Miura
+ *                      and discussions with Hiroshi Miura
+ *
+ *     Aug.10, 2004    Hiroshi Miura <miura@da-cha.org>
+ *             - v0.5  support LCD brightness control
+ *                     based on the disclosed information by MEI.
+ *
+ *     Jul.25, 2004    Hiroshi Miura <miura@da-cha.org>
+ *             - v0.4  first post version
+ *                     add function to retrive SIFR
+ *
+ *     Jul.24, 2004    Hiroshi Miura <miura@da-cha.org>
+ *             - v0.3  get proper status of hotkey
+ *
+ *      Jul.22, 2004   Hiroshi Miura <miura@da-cha.org>
+ *             - v0.2  add HotKey handler
+ *
+ *      Jul.17, 2004   Hiroshi Miura <miura@da-cha.org>
+ *             - v0.1  start from toshiba_acpi driver written by John Belmonte
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/backlight.h>
+#include <linux/ctype.h>
+#include <linux/seq_file.h>
+#include <linux/uaccess.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+#include <linux/input.h>
+
+
+#ifndef ACPI_HOTKEY_COMPONENT
+#define ACPI_HOTKEY_COMPONENT  0x10000000
+#endif
+
+#define _COMPONENT             ACPI_HOTKEY_COMPONENT
+
+MODULE_AUTHOR("Hiroshi Miura, David Bronaugh and Harald Welte");
+MODULE_DESCRIPTION("ACPI HotKey driver for Panasonic Let's Note laptops");
+MODULE_LICENSE("GPL");
+
+#define LOGPREFIX "pcc_acpi: "
+
+/* Define ACPI PATHs */
+/* Lets note hotkeys */
+#define METHOD_HKEY_QUERY      "HINF"
+#define METHOD_HKEY_SQTY       "SQTY"
+#define METHOD_HKEY_SINF       "SINF"
+#define METHOD_HKEY_SSET       "SSET"
+#define HKEY_NOTIFY             0x80
+
+#define ACPI_PCC_DRIVER_NAME   "Panasonic Laptop Support"
+#define ACPI_PCC_DEVICE_NAME   "Hotkey"
+#define ACPI_PCC_CLASS         "pcc"
+
+#define ACPI_PCC_INPUT_PHYS    "panasonic/hkey0"
+
+/* LCD_TYPEs: 0 = Normal, 1 = Semi-transparent
+   ENV_STATEs: Normal temp=0x01, High temp=0x81, N/A=0x00
+*/
+enum SINF_BITS { SINF_NUM_BATTERIES = 0,
+                SINF_LCD_TYPE,
+                SINF_AC_MAX_BRIGHT,
+                SINF_AC_MIN_BRIGHT,
+                SINF_AC_CUR_BRIGHT,
+                SINF_DC_MAX_BRIGHT,
+                SINF_DC_MIN_BRIGHT,
+                SINF_DC_CUR_BRIGHT,
+                SINF_MUTE,
+                SINF_RESERVED,
+                SINF_ENV_STATE,
+                SINF_STICKY_KEY = 0x80,
+       };
+/* R1 handles SINF_AC_CUR_BRIGHT as SINF_CUR_BRIGHT, doesn't know AC state */
+
+static int acpi_pcc_hotkey_add(struct acpi_device *device);
+static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type);
+static int acpi_pcc_hotkey_resume(struct acpi_device *device);
+
+static const struct acpi_device_id pcc_device_ids[] = {
+       { "MAT0012", 0},
+       { "MAT0013", 0},
+       { "MAT0018", 0},
+       { "MAT0019", 0},
+       { "", 0},
+};
+
+static struct acpi_driver acpi_pcc_driver = {
+       .name =         ACPI_PCC_DRIVER_NAME,
+       .class =        ACPI_PCC_CLASS,
+       .ids =          pcc_device_ids,
+       .ops =          {
+                               .add =          acpi_pcc_hotkey_add,
+                               .remove =       acpi_pcc_hotkey_remove,
+                               .resume =       acpi_pcc_hotkey_resume,
+                       },
+};
+
+#define KEYMAP_SIZE            11
+static const int initial_keymap[KEYMAP_SIZE] = {
+       /*  0 */ KEY_RESERVED,
+       /*  1 */ KEY_BRIGHTNESSDOWN,
+       /*  2 */ KEY_BRIGHTNESSUP,
+       /*  3 */ KEY_DISPLAYTOGGLE,
+       /*  4 */ KEY_MUTE,
+       /*  5 */ KEY_VOLUMEDOWN,
+       /*  6 */ KEY_VOLUMEUP,
+       /*  7 */ KEY_SLEEP,
+       /*  8 */ KEY_PROG1, /* Change CPU boost */
+       /*  9 */ KEY_BATTERY,
+       /* 10 */ KEY_SUSPEND,
+};
+
+struct pcc_acpi {
+       acpi_handle             handle;
+       unsigned long           num_sifr;
+       int                     sticky_mode;
+       u32                     *sinf;
+       struct acpi_device      *device;
+       struct input_dev        *input_dev;
+       struct backlight_device *backlight;
+       int                     keymap[KEYMAP_SIZE];
+};
+
+struct pcc_keyinput {
+       struct acpi_hotkey      *hotkey;
+};
+
+/* method access functions */
+static int acpi_pcc_write_sset(struct pcc_acpi *pcc, int func, int val)
+{
+       union acpi_object in_objs[] = {
+               { .integer.type  = ACPI_TYPE_INTEGER,
+                 .integer.value = func, },
+               { .integer.type  = ACPI_TYPE_INTEGER,
+                 .integer.value = val, },
+       };
+       struct acpi_object_list params = {
+               .count   = ARRAY_SIZE(in_objs),
+               .pointer = in_objs,
+       };
+       acpi_status status = AE_OK;
+
+       ACPI_FUNCTION_TRACE("acpi_pcc_write_sset");
+
+       status = acpi_evaluate_object(pcc->handle, METHOD_HKEY_SSET,
+                                     &params, NULL);
+
+       return status == AE_OK;
+}
+
+static inline int acpi_pcc_get_sqty(struct acpi_device *device)
+{
+       unsigned long long s;
+       acpi_status status;
+
+       ACPI_FUNCTION_TRACE("acpi_pcc_get_sqty");
+
+       status = acpi_evaluate_integer(device->handle, METHOD_HKEY_SQTY,
+                                      NULL, &s);
+       if (ACPI_SUCCESS(status))
+               return s;
+       else {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                                 "evaluation error HKEY.SQTY\n"));
+               return -EINVAL;
+       }
+}
+
+static int acpi_pcc_retrieve_biosdata(struct pcc_acpi *pcc, u32 *sinf)
+{
+       acpi_status status;
+       struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+       union acpi_object *hkey = NULL;
+       int i;
+
+       ACPI_FUNCTION_TRACE("acpi_pcc_retrieve_biosdata");
+
+       status = acpi_evaluate_object(pcc->handle, METHOD_HKEY_SINF, 0,
+                                     &buffer);
+       if (ACPI_FAILURE(status)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                                 "evaluation error HKEY.SINF\n"));
+               return 0;
+       }
+
+       hkey = buffer.pointer;
+       if (!hkey || (hkey->type != ACPI_TYPE_PACKAGE)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid HKEY.SINF\n"));
+               goto end;
+       }
+
+       if (pcc->num_sifr < hkey->package.count) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                                "SQTY reports bad SINF length\n"));
+               status = AE_ERROR;
+               goto end;
+       }
+
+       for (i = 0; i < hkey->package.count; i++) {
+               union acpi_object *element = &(hkey->package.elements[i]);
+               if (likely(element->type == ACPI_TYPE_INTEGER)) {
+                       sinf[i] = element->integer.value;
+               } else
+                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                                        "Invalid HKEY.SINF data\n"));
+       }
+       sinf[hkey->package.count] = -1;
+
+end:
+       kfree(buffer.pointer);
+       return status == AE_OK;
+}
+
+/* backlight API interface functions */
+
+/* This driver currently treats AC and DC brightness identical,
+ * since we don't need to invent an interface to the core ACPI
+ * logic to receive events in case a power supply is plugged in
+ * or removed */
+
+static int bl_get(struct backlight_device *bd)
+{
+       struct pcc_acpi *pcc = bl_get_data(bd);
+
+       if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
+               return -EIO;
+
+       return pcc->sinf[SINF_AC_CUR_BRIGHT];
+}
+
+static int bl_set_status(struct backlight_device *bd)
+{
+       struct pcc_acpi *pcc = bl_get_data(bd);
+       int bright = bd->props.brightness;
+       int rc;
+
+       if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
+               return -EIO;
+
+       if (bright < pcc->sinf[SINF_AC_MIN_BRIGHT])
+               bright = pcc->sinf[SINF_AC_MIN_BRIGHT];
+
+       if (bright < pcc->sinf[SINF_DC_MIN_BRIGHT])
+               bright = pcc->sinf[SINF_DC_MIN_BRIGHT];
+
+       if (bright < pcc->sinf[SINF_AC_MIN_BRIGHT] ||
+           bright > pcc->sinf[SINF_AC_MAX_BRIGHT])
+               return -EINVAL;
+
+       rc = acpi_pcc_write_sset(pcc, SINF_AC_CUR_BRIGHT, bright);
+       if (rc < 0)
+               return rc;
+
+       return acpi_pcc_write_sset(pcc, SINF_DC_CUR_BRIGHT, bright);
+}
+
+static struct backlight_ops pcc_backlight_ops = {
+       .get_brightness = bl_get,
+       .update_status  = bl_set_status,
+};
+
+
+/* sysfs user interface functions */
+
+static ssize_t show_numbatt(struct device *dev, struct device_attribute *attr,
+                           char *buf)
+{
+       struct acpi_device *acpi = to_acpi_device(dev);
+       struct pcc_acpi *pcc = acpi_driver_data(acpi);
+
+       if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
+               return -EIO;
+
+       return sprintf(buf, "%u\n", pcc->sinf[SINF_NUM_BATTERIES]);
+}
+
+static ssize_t show_lcdtype(struct device *dev, struct device_attribute *attr,
+                           char *buf)
+{
+       struct acpi_device *acpi = to_acpi_device(dev);
+       struct pcc_acpi *pcc = acpi_driver_data(acpi);
+
+       if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
+               return -EIO;
+
+       return sprintf(buf, "%u\n", pcc->sinf[SINF_LCD_TYPE]);
+}
+
+static ssize_t show_mute(struct device *dev, struct device_attribute *attr,
+                        char *buf)
+{
+       struct acpi_device *acpi = to_acpi_device(dev);
+       struct pcc_acpi *pcc = acpi_driver_data(acpi);
+
+       if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
+               return -EIO;
+
+       return sprintf(buf, "%u\n", pcc->sinf[SINF_MUTE]);
+}
+
+static ssize_t show_sticky(struct device *dev, struct device_attribute *attr,
+                          char *buf)
+{
+       struct acpi_device *acpi = to_acpi_device(dev);
+       struct pcc_acpi *pcc = acpi_driver_data(acpi);
+
+       if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
+               return -EIO;
+
+       return sprintf(buf, "%u\n", pcc->sinf[SINF_STICKY_KEY]);
+}
+
+static ssize_t set_sticky(struct device *dev, struct device_attribute *attr,
+                         const char *buf, size_t count)
+{
+       struct acpi_device *acpi = to_acpi_device(dev);
+       struct pcc_acpi *pcc = acpi_driver_data(acpi);
+       int val;
+
+       if (count && sscanf(buf, "%i", &val) == 1 &&
+           (val == 0 || val == 1)) {
+               acpi_pcc_write_sset(pcc, SINF_STICKY_KEY, val);
+               pcc->sticky_mode = val;
+       }
+
+       return count;
+}
+
+static DEVICE_ATTR(numbatt, S_IRUGO, show_numbatt, NULL);
+static DEVICE_ATTR(lcdtype, S_IRUGO, show_lcdtype, NULL);
+static DEVICE_ATTR(mute, S_IRUGO, show_mute, NULL);
+static DEVICE_ATTR(sticky_key, S_IRUGO | S_IWUSR, show_sticky, set_sticky);
+
+static struct attribute *pcc_sysfs_entries[] = {
+       &dev_attr_numbatt.attr,
+       &dev_attr_lcdtype.attr,
+       &dev_attr_mute.attr,
+       &dev_attr_sticky_key.attr,
+       NULL,
+};
+
+static struct attribute_group pcc_attr_group = {
+       .name   = NULL,         /* put in device directory */
+       .attrs  = pcc_sysfs_entries,
+};
+
+
+/* hotkey input device driver */
+
+static int pcc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+{
+       struct pcc_acpi *pcc = input_get_drvdata(dev);
+
+       if (scancode >= ARRAY_SIZE(pcc->keymap))
+               return -EINVAL;
+
+       *keycode = pcc->keymap[scancode];
+
+       return 0;
+}
+
+static int keymap_get_by_keycode(struct pcc_acpi *pcc, int keycode)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(pcc->keymap); i++) {
+               if (pcc->keymap[i] == keycode)
+                       return i+1;
+       }
+
+       return 0;
+}
+
+static int pcc_setkeycode(struct input_dev *dev, int scancode, int keycode)
+{
+       struct pcc_acpi *pcc = input_get_drvdata(dev);
+       int oldkeycode;
+
+       if (scancode >= ARRAY_SIZE(pcc->keymap))
+               return -EINVAL;
+
+       if (keycode < 0 || keycode > KEY_MAX)
+               return -EINVAL;
+
+       oldkeycode = pcc->keymap[scancode];
+       pcc->keymap[scancode] = keycode;
+
+       set_bit(keycode, dev->keybit);
+
+       if (!keymap_get_by_keycode(pcc, oldkeycode))
+               clear_bit(oldkeycode, dev->keybit);
+
+       return 0;
+}
+
+static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc)
+{
+       struct input_dev *hotk_input_dev = pcc->input_dev;
+       int rc;
+       int key_code, hkey_num;
+       unsigned long long result;
+
+       ACPI_FUNCTION_TRACE("acpi_pcc_generate_keyinput");
+
+       rc = acpi_evaluate_integer(pcc->handle, METHOD_HKEY_QUERY,
+                                  NULL, &result);
+       if (!ACPI_SUCCESS(rc)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                                "error getting hotkey status\n"));
+               return;
+       }
+
+       acpi_bus_generate_proc_event(pcc->device, HKEY_NOTIFY, result);
+
+       hkey_num = result & 0xf;
+
+       if (hkey_num < 0 || hkey_num > ARRAY_SIZE(pcc->keymap)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                                 "hotkey number out of range: %d\n",
+                                 hkey_num));
+               return;
+       }
+
+       key_code = pcc->keymap[hkey_num];
+
+       if (key_code != KEY_RESERVED) {
+               int pushed = (result & 0x80) ? TRUE : FALSE;
+
+               input_report_key(hotk_input_dev, key_code, pushed);
+               input_sync(hotk_input_dev);
+       }
+
+       return;
+}
+
+static void acpi_pcc_hotkey_notify(acpi_handle handle, u32 event, void *data)
+{
+       struct pcc_acpi *pcc = (struct pcc_acpi *) data;
+
+       ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_notify");
+
+       switch (event) {
+       case HKEY_NOTIFY:
+               acpi_pcc_generate_keyinput(pcc);
+               break;
+       default:
+               /* nothing to do */
+               break;
+       }
+}
+
+static int acpi_pcc_init_input(struct pcc_acpi *pcc)
+{
+       int i, rc;
+
+       ACPI_FUNCTION_TRACE("acpi_pcc_init_input");
+
+       pcc->input_dev = input_allocate_device();
+       if (!pcc->input_dev) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                                 "Couldn't allocate input device for hotkey"));
+               return -ENOMEM;
+       }
+
+       pcc->input_dev->evbit[0] = BIT(EV_KEY);
+
+       pcc->input_dev->name = ACPI_PCC_DRIVER_NAME;
+       pcc->input_dev->phys = ACPI_PCC_INPUT_PHYS;
+       pcc->input_dev->id.bustype = BUS_HOST;
+       pcc->input_dev->id.vendor = 0x0001;
+       pcc->input_dev->id.product = 0x0001;
+       pcc->input_dev->id.version = 0x0100;
+       pcc->input_dev->getkeycode = pcc_getkeycode;
+       pcc->input_dev->setkeycode = pcc_setkeycode;
+
+       /* load initial keymap */
+       memcpy(pcc->keymap, initial_keymap, sizeof(pcc->keymap));
+
+       for (i = 0; i < ARRAY_SIZE(pcc->keymap); i++)
+               __set_bit(pcc->keymap[i], pcc->input_dev->keybit);
+       __clear_bit(KEY_RESERVED, pcc->input_dev->keybit);
+
+       input_set_drvdata(pcc->input_dev, pcc);
+
+       rc = input_register_device(pcc->input_dev);
+       if (rc < 0)
+               input_free_device(pcc->input_dev);
+
+       return rc;
+}
+
+/* kernel module interface */
+
+static int acpi_pcc_hotkey_resume(struct acpi_device *device)
+{
+       struct pcc_acpi *pcc = acpi_driver_data(device);
+       acpi_status status = AE_OK;
+
+       ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_resume");
+
+       if (device == NULL || pcc == NULL)
+               return -EINVAL;
+
+       ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Sticky mode restore: %d\n",
+                         pcc->sticky_mode));
+
+       status = acpi_pcc_write_sset(pcc, SINF_STICKY_KEY, pcc->sticky_mode);
+
+       return status == AE_OK ? 0 : -EINVAL;
+}
+
+static int acpi_pcc_hotkey_add(struct acpi_device *device)
+{
+       acpi_status status;
+       struct pcc_acpi *pcc;
+       int num_sifr, result;
+
+       ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_add");
+
+       if (!device)
+               return -EINVAL;
+
+       num_sifr = acpi_pcc_get_sqty(device);
+
+       if (num_sifr > 255) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "num_sifr too large"));
+               return -ENODEV;
+       }
+
+       pcc = kzalloc(sizeof(struct pcc_acpi), GFP_KERNEL);
+       if (!pcc) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                                 "Couldn't allocate mem for pcc"));
+               return -ENOMEM;
+       }
+
+       pcc->sinf = kzalloc(sizeof(u32) * (num_sifr + 1), GFP_KERNEL);
+       if (!pcc->sinf) {
+               result = -ENOMEM;
+               goto out_hotkey;
+       }
+
+       pcc->device = device;
+       pcc->handle = device->handle;
+       pcc->num_sifr = num_sifr;
+       device->driver_data = pcc;
+       strcpy(acpi_device_name(device), ACPI_PCC_DEVICE_NAME);
+       strcpy(acpi_device_class(device), ACPI_PCC_CLASS);
+
+       result = acpi_pcc_init_input(pcc);
+       if (result) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                                 "Error installing keyinput handler\n"));
+               goto out_sinf;
+       }
+
+       /* initialize hotkey input device */
+       status = acpi_install_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY,
+                                            acpi_pcc_hotkey_notify, pcc);
+
+       if (ACPI_FAILURE(status)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                                 "Error installing notify handler\n"));
+               result = -ENODEV;
+               goto out_input;
+       }
+
+       /* initialize backlight */
+       pcc->backlight = backlight_device_register("panasonic", NULL, pcc,
+                                                  &pcc_backlight_ops);
+       if (IS_ERR(pcc->backlight))
+               goto out_notify;
+
+       if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                                "Couldn't retrieve BIOS data\n"));
+               goto out_backlight;
+       }
+
+       /* 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 */
+       pcc->sticky_mode = pcc->sinf[SINF_STICKY_KEY];
+
+       /* add sysfs attributes */
+       result = sysfs_create_group(&device->dev.kobj, &pcc_attr_group);
+       if (result)
+               goto out_backlight;
+
+       return 0;
+
+out_backlight:
+       backlight_device_unregister(pcc->backlight);
+out_notify:
+       acpi_remove_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY,
+                                  acpi_pcc_hotkey_notify);
+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);
+
+       return result;
+}
+
+static int __init acpi_pcc_init(void)
+{
+       int result = 0;
+
+       ACPI_FUNCTION_TRACE("acpi_pcc_init");
+
+       if (acpi_disabled)
+               return -ENODEV;
+
+       result = acpi_bus_register_driver(&acpi_pcc_driver);
+       if (result < 0) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                                 "Error registering hotkey driver\n"));
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type)
+{
+       struct pcc_acpi *pcc = acpi_driver_data(device);
+
+       ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_remove");
+
+       if (!device || !pcc)
+               return -EINVAL;
+
+       sysfs_remove_group(&device->dev.kobj, &pcc_attr_group);
+
+       backlight_device_unregister(pcc->backlight);
+
+       acpi_remove_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY,
+                                  acpi_pcc_hotkey_notify);
+
+       input_unregister_device(pcc->input_dev);
+       /* no need to input_free_device() since core input API refcount and
+        * free()s the device */
+
+       kfree(pcc->sinf);
+       kfree(pcc);
+
+       return 0;
+}
+
+static void __exit acpi_pcc_exit(void)
+{
+       ACPI_FUNCTION_TRACE("acpi_pcc_exit");
+
+       acpi_bus_unregister_driver(&acpi_pcc_driver);
+}
+
+module_init(acpi_pcc_init);
+module_exit(acpi_pcc_exit);
index 60775be22822901f0a67e70878eceac666ab1afa..5a97d3a9d745ee3ab5d17e5e1b86bce5a9fae132 100644 (file)
@@ -970,7 +970,7 @@ static int sony_nc_resume(struct acpi_device *device)
        /* set the last requested brightness level */
        if (sony_backlight_device &&
                        !sony_backlight_update_status(sony_backlight_device))
-               printk(KERN_WARNING DRV_PFX "unable to restore brightness level");
+               printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n");
 
        /* re-initialize models with specific requirements */
        dmi_check_system(sony_nc_ids);
index 6b9300779a431c1828acad495ddfbbec41332836..4db1cf9078d9976b5206649aad3d0118272a000a 100644 (file)
@@ -158,7 +158,6 @@ enum {
 #define TPACPI_INFO   KERN_INFO   TPACPI_LOG
 #define TPACPI_DEBUG  KERN_DEBUG  TPACPI_LOG
 
-#define TPACPI_DBG_ALL         0xffff
 #define TPACPI_DBG_ALL         0xffff
 #define TPACPI_DBG_INIT                0x0001
 #define TPACPI_DBG_EXIT                0x0002
@@ -543,7 +542,7 @@ static int __init setup_acpi_notify(struct ibm_struct *ibm)
                return -ENODEV;
        }
 
-       acpi_driver_data(ibm->acpi->device) = ibm;
+       ibm->acpi->device->driver_data = ibm;
        sprintf(acpi_device_class(ibm->acpi->device), "%s/%s",
                TPACPI_ACPI_EVENT_PREFIX,
                ibm->name);
@@ -582,7 +581,8 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)
 
        ibm->acpi->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL);
        if (!ibm->acpi->driver) {
-               printk(TPACPI_ERR "kzalloc(ibm->driver) failed\n");
+               printk(TPACPI_ERR
+                      "failed to allocate memory for ibm->acpi->driver\n");
                return -ENOMEM;
        }
 
@@ -838,6 +838,13 @@ static int parse_strtoul(const char *buf,
        return 0;
 }
 
+static void tpacpi_disable_brightness_delay(void)
+{
+       if (acpi_evalf(hkey_handle, NULL, "PWMS", "qvd", 0))
+               printk(TPACPI_NOTICE
+                       "ACPI backlight control delay disabled\n");
+}
+
 static int __init tpacpi_query_bcl_levels(acpi_handle handle)
 {
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -2139,6 +2146,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
        if (!tp_features.hotkey)
                return 1;
 
+       tpacpi_disable_brightness_delay();
+
        hotkey_dev_attributes = create_attr_set(13, NULL);
        if (!hotkey_dev_attributes)
                return -ENOMEM;
@@ -2512,6 +2521,8 @@ static void hotkey_suspend(pm_message_t state)
 
 static void hotkey_resume(void)
 {
+       tpacpi_disable_brightness_delay();
+
        if (hotkey_mask_get())
                printk(TPACPI_ERR
                       "error while trying to read hot key mask "
@@ -5983,6 +5994,52 @@ static void fan_exit(void)
        flush_workqueue(tpacpi_wq);
 }
 
+static void fan_suspend(pm_message_t state)
+{
+       if (!fan_control_allowed)
+               return;
+
+       /* Store fan status in cache */
+       fan_get_status_safe(NULL);
+       if (tp_features.fan_ctrl_status_undef)
+               fan_control_desired_level = TP_EC_FAN_AUTO;
+}
+
+static void fan_resume(void)
+{
+       u8 saved_fan_level;
+       u8 current_level = 7;
+       bool do_set = false;
+
+       /* DSDT *always* updates status on resume */
+       tp_features.fan_ctrl_status_undef = 0;
+
+       saved_fan_level = fan_control_desired_level;
+       if (!fan_control_allowed ||
+           (fan_get_status_safe(&current_level) < 0))
+               return;
+
+       switch (fan_control_access_mode) {
+       case TPACPI_FAN_WR_ACPI_SFAN:
+               do_set = (saved_fan_level > current_level);
+               break;
+       case TPACPI_FAN_WR_ACPI_FANS:
+       case TPACPI_FAN_WR_TPEC:
+               do_set = ((saved_fan_level & TP_EC_FAN_FULLSPEED) ||
+                         (saved_fan_level == 7 &&
+                          !(current_level & TP_EC_FAN_FULLSPEED)));
+               break;
+       default:
+               return;
+       }
+       if (do_set) {
+               printk(TPACPI_NOTICE
+                       "restoring fan level to 0x%02x\n",
+                       saved_fan_level);
+               fan_set_level_safe(saved_fan_level);
+       }
+}
+
 static int fan_read(char *p)
 {
        int len = 0;
@@ -6174,6 +6231,8 @@ static struct ibm_struct fan_driver_data = {
        .read = fan_read,
        .write = fan_write,
        .exit = fan_exit,
+       .suspend = fan_suspend,
+       .resume = fan_resume,
 };
 
 /****************************************************************************
index 24c97d3d16bba43ab963d9b514ee27fbe938ddcc..3d067c35185db9704157d8bc4bddbecc20bf22c7 100644 (file)
@@ -92,18 +92,17 @@ static void mmc_blk_put(struct mmc_blk_data *md)
        mutex_unlock(&open_lock);
 }
 
-static int mmc_blk_open(struct inode *inode, struct file *filp)
+static int mmc_blk_open(struct block_device *bdev, fmode_t mode)
 {
-       struct mmc_blk_data *md;
+       struct mmc_blk_data *md = mmc_blk_get(bdev->bd_disk);
        int ret = -ENXIO;
 
-       md = mmc_blk_get(inode->i_bdev->bd_disk);
        if (md) {
                if (md->usage == 2)
-                       check_disk_change(inode->i_bdev);
+                       check_disk_change(bdev);
                ret = 0;
 
-               if ((filp->f_mode & FMODE_WRITE) && md->read_only) {
+               if ((mode & FMODE_WRITE) && md->read_only) {
                        mmc_blk_put(md);
                        ret = -EROFS;
                }
@@ -112,9 +111,9 @@ static int mmc_blk_open(struct inode *inode, struct file *filp)
        return ret;
 }
 
-static int mmc_blk_release(struct inode *inode, struct file *filp)
+static int mmc_blk_release(struct gendisk *disk, fmode_t mode)
 {
-       struct mmc_blk_data *md = inode->i_bdev->bd_disk->private_data;
+       struct mmc_blk_data *md = disk->private_data;
 
        mmc_blk_put(md);
        return 0;
index 91fbba767635baba3a3bc7755fd8b6c99b230975..8c295f40d2acfd3dde7f2cab8c753a01a2c07aff 100644 (file)
@@ -224,7 +224,7 @@ static void block2mtd_free_device(struct block2mtd_dev *dev)
        if (dev->blkdev) {
                invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping,
                                        0, -1);
-               close_bdev_excl(dev->blkdev);
+               close_bdev_exclusive(dev->blkdev, FMODE_READ|FMODE_WRITE);
        }
 
        kfree(dev);
@@ -246,7 +246,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
                return NULL;
 
        /* Get a handle on the device */
-       bdev = open_bdev_excl(devname, O_RDWR, NULL);
+       bdev = open_bdev_exclusive(devname, FMODE_READ|FMODE_WRITE, NULL);
 #ifndef MODULE
        if (IS_ERR(bdev)) {
 
index 681d5aca2af436630fda1d5124d8a3d6a1e70ce4..1409f01406f6e7ebc356cf906ab4880f7719b1c1 100644 (file)
@@ -133,15 +133,12 @@ static void mtd_blktrans_request(struct request_queue *rq)
 }
 
 
-static int blktrans_open(struct inode *i, struct file *f)
+static int blktrans_open(struct block_device *bdev, fmode_t mode)
 {
-       struct mtd_blktrans_dev *dev;
-       struct mtd_blktrans_ops *tr;
+       struct mtd_blktrans_dev *dev = bdev->bd_disk->private_data;
+       struct mtd_blktrans_ops *tr = dev->tr;
        int ret = -ENODEV;
 
-       dev = i->i_bdev->bd_disk->private_data;
-       tr = dev->tr;
-
        if (!try_module_get(dev->mtd->owner))
                goto out;
 
@@ -164,15 +161,12 @@ static int blktrans_open(struct inode *i, struct file *f)
        return ret;
 }
 
-static int blktrans_release(struct inode *i, struct file *f)
+static int blktrans_release(struct gendisk *disk, fmode_t mode)
 {
-       struct mtd_blktrans_dev *dev;
-       struct mtd_blktrans_ops *tr;
+       struct mtd_blktrans_dev *dev = disk->private_data;
+       struct mtd_blktrans_ops *tr = dev->tr;
        int ret = 0;
 
-       dev = i->i_bdev->bd_disk->private_data;
-       tr = dev->tr;
-
        if (tr->release)
                ret = tr->release(dev);
 
@@ -194,10 +188,10 @@ static int blktrans_getgeo(struct block_device *bdev, struct hd_geometry *geo)
        return -ENOTTY;
 }
 
-static int blktrans_ioctl(struct inode *inode, struct file *file,
+static int blktrans_ioctl(struct block_device *bdev, fmode_t mode,
                              unsigned int cmd, unsigned long arg)
 {
-       struct mtd_blktrans_dev *dev = inode->i_bdev->bd_disk->private_data;
+       struct mtd_blktrans_dev *dev = bdev->bd_disk->private_data;
        struct mtd_blktrans_ops *tr = dev->tr;
 
        switch (cmd) {
@@ -215,7 +209,7 @@ static struct block_device_operations mtd_blktrans_ops = {
        .owner          = THIS_MODULE,
        .open           = blktrans_open,
        .release        = blktrans_release,
-       .ioctl          = blktrans_ioctl,
+       .locked_ioctl   = blktrans_ioctl,
        .getgeo         = blktrans_getgeo,
 };
 
index 963840e9b5bf3d25177baa281b3eb70769d69950..bcffeda2df3d680babc66906151dd3641ec57208 100644 (file)
@@ -96,7 +96,7 @@ static int mtd_open(struct inode *inode, struct file *file)
                return -ENODEV;
 
        /* You can't open the RO devices RW */
-       if ((file->f_mode & 2) && (minor & 1))
+       if ((file->f_mode & FMODE_WRITE) && (minor & 1))
                return -EACCES;
 
        lock_kernel();
@@ -114,7 +114,7 @@ static int mtd_open(struct inode *inode, struct file *file)
        }
 
        /* You can't open it RW if it's not a writeable device */
-       if ((file->f_mode & 2) && !(mtd->flags & MTD_WRITEABLE)) {
+       if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) {
                put_mtd_device(mtd);
                ret = -EACCES;
                goto out;
@@ -144,7 +144,7 @@ static int mtd_close(struct inode *inode, struct file *file)
        DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n");
 
        /* Only sync if opened RW */
-       if ((file->f_mode & 2) && mtd->sync)
+       if ((file->f_mode & FMODE_WRITE) && mtd->sync)
                mtd->sync(mtd);
 
        put_mtd_device(mtd);
@@ -443,7 +443,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
        {
                struct erase_info *erase;
 
-               if(!(file->f_mode & 2))
+               if(!(file->f_mode & FMODE_WRITE))
                        return -EPERM;
 
                erase=kzalloc(sizeof(struct erase_info),GFP_KERNEL);
@@ -497,7 +497,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
                struct mtd_oob_buf __user *user_buf = argp;
                uint32_t retlen;
 
-               if(!(file->f_mode & 2))
+               if(!(file->f_mode & FMODE_WRITE))
                        return -EPERM;
 
                if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf)))
index 491ee16da5c13e27097d1dd58606ad15933af4bb..9ba295d9dd973b5713f7d49150a3807899ff3a77 100644 (file)
@@ -90,7 +90,7 @@ static int vortex_debug = 1;
 #include <linux/eisa.h>
 #include <linux/bitops.h>
 #include <linux/jiffies.h>
-#include <asm/irq.h>                   /* For NR_IRQS only. */
+#include <asm/irq.h>                   /* For nr_irqs only. */
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
@@ -1221,7 +1221,7 @@ static int __devinit vortex_probe1(struct device *gendev,
        if (print_info)
                printk(", IRQ %d\n", dev->irq);
        /* Tell them about an invalid IRQ. */
-       if (dev->irq <= 0 || dev->irq >= NR_IRQS)
+       if (dev->irq <= 0 || dev->irq >= nr_irqs)
                printk(KERN_WARNING " *** Warning: IRQ %d is unlikely to work! ***\n",
                           dev->irq);
 
index ad301ace608532521c448c8723edb94f45dc5776..0b71ebc074b68cc1bd90c50b185e8d6a0eb74956 100644 (file)
@@ -464,6 +464,12 @@ config MIPS_JAZZ_SONIC
          This is the driver for the onboard card of MIPS Magnum 4000,
          Acer PICA, Olivetti M700-10 and a few other identical OEM systems.
 
+config XTENSA_XT2000_SONIC
+       tristate "Xtensa XT2000 onboard SONIC Ethernet support"
+       depends on XTENSA_PLATFORM_XT2000
+       help
+         This is the driver for the onboard card of the Xtensa XT2000 board.
+
 config MIPS_AU1X00_ENET
        bool "MIPS AU1000 Ethernet support"
        depends on SOC_AU1X00
@@ -2504,6 +2510,15 @@ config PASEMI_MAC
          This driver supports the on-chip 1/10Gbit Ethernet controller on
          PA Semi's PWRficient line of chips.
 
+config MLX4_EN
+       tristate "Mellanox Technologies 10Gbit Ethernet support"
+       depends on PCI && INET
+       select MLX4_CORE
+       select INET_LRO
+       help
+         This driver supports Mellanox Technologies ConnectX Ethernet
+         devices.
+
 config MLX4_CORE
        tristate
        depends on PCI
index fa2510b2e60998ea9f32734652c9f22880bbf9c0..f19acf8b9220bf2e152ecae6fdc9727ee8e5fc19 100644 (file)
@@ -227,6 +227,8 @@ pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o
 obj-$(CONFIG_MLX4_CORE) += mlx4/
 obj-$(CONFIG_ENC28J60) += enc28j60.o
 
+obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o
+
 obj-$(CONFIG_MACB) += macb.o
 
 obj-$(CONFIG_ARM) += arm/
index 08e18bcb970f562c28c9be91b1f8c74cd1b04b05..45dd9bdc5d62ac0299058434aa4862ca277d8828 100644 (file)
@@ -2,6 +2,7 @@
  * Driver for the MPC5200 Fast Ethernet Controller - MDIO bus driver
  *
  * Copyright (C) 2007  Domen Puncer, Telargo, Inc.
+ * Copyright (C) 2008  Wolfram Sang, Pengutronix
  *
  * 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
@@ -21,58 +22,45 @@ struct mpc52xx_fec_mdio_priv {
        struct mpc52xx_fec __iomem *regs;
 };
 
-static int mpc52xx_fec_mdio_read(struct mii_bus *bus, int phy_id, int reg)
+static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
+               int reg, u32 value)
 {
        struct mpc52xx_fec_mdio_priv *priv = bus->priv;
        struct mpc52xx_fec __iomem *fec;
        int tries = 100;
-       u32 request = FEC_MII_READ_FRAME;
+
+       value |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
+       value |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
 
        fec = priv->regs;
        out_be32(&fec->ievent, FEC_IEVENT_MII);
-
-       request |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
-       request |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
-
-       out_be32(&priv->regs->mii_data, request);
+       out_be32(&priv->regs->mii_data, value);
 
        /* wait for it to finish, this takes about 23 us on lite5200b */
        while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries)
                udelay(5);
 
-       if (tries == 0)
+       if (!tries)
                return -ETIMEDOUT;
 
-       return in_be32(&priv->regs->mii_data) & FEC_MII_DATA_DATAMSK;
+       return value & FEC_MII_DATA_OP_RD ?
+               in_be32(&priv->regs->mii_data) & FEC_MII_DATA_DATAMSK : 0;
 }
 
-static int mpc52xx_fec_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 data)
+static int mpc52xx_fec_mdio_read(struct mii_bus *bus, int phy_id, int reg)
 {
-       struct mpc52xx_fec_mdio_priv *priv = bus->priv;
-       struct mpc52xx_fec __iomem *fec;
-       u32 value = data;
-       int tries = 100;
-
-       fec = priv->regs;
-       out_be32(&fec->ievent, FEC_IEVENT_MII);
-
-       value |= FEC_MII_WRITE_FRAME;
-       value |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
-       value |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
-
-       out_be32(&priv->regs->mii_data, value);
-
-       /* wait for request to finish */
-       while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries)
-               udelay(5);
-
-       if (tries == 0)
-               return -ETIMEDOUT;
+       return mpc52xx_fec_mdio_transfer(bus, phy_id, reg, FEC_MII_READ_FRAME);
+}
 
-       return 0;
+static int mpc52xx_fec_mdio_write(struct mii_bus *bus, int phy_id, int reg,
+               u16 data)
+{
+       return mpc52xx_fec_mdio_transfer(bus, phy_id, reg,
+               data | FEC_MII_WRITE_FRAME);
 }
 
-static int mpc52xx_fec_mdio_probe(struct of_device *of, const struct of_device_id *match)
+static int mpc52xx_fec_mdio_probe(struct of_device *of,
+               const struct of_device_id *match)
 {
        struct device *dev = &of->dev;
        struct device_node *np = of->node;
@@ -131,7 +119,8 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, const struct of_device_i
        dev_set_drvdata(dev, bus);
 
        /* set MII speed */
-       out_be32(&priv->regs->mii_speed, ((mpc52xx_find_ipb_freq(of->node) >> 20) / 5) << 1);
+       out_be32(&priv->regs->mii_speed,
+               ((mpc52xx_find_ipb_freq(of->node) >> 20) / 5) << 1);
 
        /* enable MII interrupt */
        out_be32(&priv->regs->imask, in_be32(&priv->regs->imask) | FEC_IMASK_MII);
index 17ac6975d70db9d0d1fdbe35487c03a2a1d1fa38..b6a816e60c0f74593b5e24d4cdded1115a6cc38b 100644 (file)
@@ -416,10 +416,10 @@ static int ser12_open(struct net_device *dev)
        if (!dev || !bc)
                return -ENXIO;
        if (!dev->base_addr || dev->base_addr > 0xffff-SER12_EXTENT ||
-           dev->irq < 2 || dev->irq > NR_IRQS) {
+           dev->irq < 2 || dev->irq > nr_irqs) {
                printk(KERN_INFO "baycom_ser_fdx: invalid portnumber (max %u) "
                                "or irq (2 <= irq <= %d)\n",
-                               0xffff-SER12_EXTENT, NR_IRQS);
+                               0xffff-SER12_EXTENT, nr_irqs);
                return -ENXIO;
        }
        if (bc->baud < 300 || bc->baud > 4800) {
index 45ae9d1191d7cb13db4ffb236c12595038f354f0..c17e39bc546007cda47673ead55580e4e6b22357 100644 (file)
@@ -1465,7 +1465,7 @@ static void z8530_init(void)
        printk(KERN_INFO "Init Z8530 driver: %u channels, IRQ", Nchips*2);
        
        flag=" ";
-       for (k = 0; k < NR_IRQS; k++)
+       for (k = 0; k < nr_irqs; k++)
                if (Ivec[k].used) 
                {
                        printk("%s%d", flag, k);
@@ -1728,7 +1728,7 @@ static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 
                        if (hwcfg.irq == 2) hwcfg.irq = 9;
 
-                       if (hwcfg.irq < 0 || hwcfg.irq >= NR_IRQS)
+                       if (hwcfg.irq < 0 || hwcfg.irq >= nr_irqs)
                                return -EINVAL;
                                
                        if (!Ivec[hwcfg.irq].used && hwcfg.irq)
@@ -2148,7 +2148,7 @@ static void __exit scc_cleanup_driver(void)
                }
                
        /* To unload the port must be closed so no real IRQ pending */
-       for (k=0; k < NR_IRQS ; k++)
+       for (k = 0; k < nr_irqs ; k++)
                if (Ivec[k].used) free_irq(k, NULL);
                
        local_irq_enable();
index efcf21c9f5c7a825ee66ca0671e689c90c13f5ff..2ee2622258f587c40196a8917ba78dcf6952b397 100644 (file)
@@ -2604,8 +2604,16 @@ static int __devinit emac_init_config(struct emac_instance *dev)
                if (of_device_is_compatible(np, "ibm,emac-440ep") ||
                    of_device_is_compatible(np, "ibm,emac-440gr"))
                        dev->features |= EMAC_FTR_440EP_PHY_CLK_FIX;
-               if (of_device_is_compatible(np, "ibm,emac-405ez"))
+               if (of_device_is_compatible(np, "ibm,emac-405ez")) {
+#ifdef CONFIG_IBM_NEW_EMAC_NO_FLOW_CONTROL
                        dev->features |= EMAC_FTR_NO_FLOW_CONTROL_40x;
+#else
+                       printk(KERN_ERR "%s: Flow control not disabled!\n",
+                                       np->full_name);
+                       return -ENXIO;
+#endif
+               }
+
        }
 
        /* Fixup some feature bits based on the device tree */
index 1839d3f154a3f3256f15b9d842f86fbd407a8fe5..ecf9798987fade1915904f6cb011b8f61f93346f 100644 (file)
@@ -280,9 +280,11 @@ static irqreturn_t mal_txeob(int irq, void *dev_instance)
        mal_schedule_poll(mal);
        set_mal_dcrn(mal, MAL_TXEOBISR, r);
 
+#ifdef CONFIG_PPC_DCR_NATIVE
        if (mal_has_feature(mal, MAL_FTR_CLEAR_ICINTSTAT))
                mtdcri(SDR0, DCRN_SDR_ICINTSTAT,
                                (mfdcri(SDR0, DCRN_SDR_ICINTSTAT) | ICINTSTAT_ICTX));
+#endif
 
        return IRQ_HANDLED;
 }
@@ -298,9 +300,11 @@ static irqreturn_t mal_rxeob(int irq, void *dev_instance)
        mal_schedule_poll(mal);
        set_mal_dcrn(mal, MAL_RXEOBISR, r);
 
+#ifdef CONFIG_PPC_DCR_NATIVE
        if (mal_has_feature(mal, MAL_FTR_CLEAR_ICINTSTAT))
                mtdcri(SDR0, DCRN_SDR_ICINTSTAT,
                                (mfdcri(SDR0, DCRN_SDR_ICINTSTAT) | ICINTSTAT_ICRX));
+#endif
 
        return IRQ_HANDLED;
 }
@@ -572,9 +576,18 @@ static int __devinit mal_probe(struct of_device *ofdev,
                goto fail;
        }
 
-       if (of_device_is_compatible(ofdev->node, "ibm,mcmal-405ez"))
+       if (of_device_is_compatible(ofdev->node, "ibm,mcmal-405ez")) {
+#if defined(CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT) && \
+               defined(CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR)
                mal->features |= (MAL_FTR_CLEAR_ICINTSTAT |
                                MAL_FTR_COMMON_ERR_INT);
+#else
+               printk(KERN_ERR "%s: Support for 405EZ not enabled!\n",
+                               ofdev->node->full_name);
+               err = -ENODEV;
+               goto fail;
+#endif
+       }
 
        mal->txeob_irq = irq_of_parse_and_map(ofdev->node, 0);
        mal->rxeob_irq = irq_of_parse_and_map(ofdev->node, 1);
index 0952a6528f583edd0139965a6300c8f4836ff5fd..a7a97bf998f866a8bdf4b471ed7ed140968a145d 100644 (file)
@@ -1,4 +1,9 @@
 obj-$(CONFIG_MLX4_CORE)                += mlx4_core.o
 
 mlx4_core-y := alloc.o catas.o cmd.o cq.o eq.o fw.o icm.o intf.o main.o mcg.o \
-               mr.o pd.o profile.o qp.o reset.o srq.o
+               mr.o pd.o port.o profile.o qp.o reset.o srq.o
+
+obj-$(CONFIG_MLX4_EN)               += mlx4_en.o
+
+mlx4_en-y :=   en_main.o en_tx.o en_rx.o en_params.o en_port.o en_cq.o \
+               en_resources.o en_netdev.o
index b411b79d72ad136322f8909a0cc3241111918fa5..ad95d5f7b63054c6e2e17ff6647fb008179ea5cf 100644 (file)
@@ -48,13 +48,16 @@ u32 mlx4_bitmap_alloc(struct mlx4_bitmap *bitmap)
 
        obj = find_next_zero_bit(bitmap->table, bitmap->max, bitmap->last);
        if (obj >= bitmap->max) {
-               bitmap->top = (bitmap->top + bitmap->max) & bitmap->mask;
+               bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
+                               & bitmap->mask;
                obj = find_first_zero_bit(bitmap->table, bitmap->max);
        }
 
        if (obj < bitmap->max) {
                set_bit(obj, bitmap->table);
-               bitmap->last = (obj + 1) & (bitmap->max - 1);
+               bitmap->last = (obj + 1);
+               if (bitmap->last == bitmap->max)
+                       bitmap->last = 0;
                obj |= bitmap->top;
        } else
                obj = -1;
@@ -66,16 +69,90 @@ u32 mlx4_bitmap_alloc(struct mlx4_bitmap *bitmap)
 
 void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj)
 {
-       obj &= bitmap->max - 1;
+       mlx4_bitmap_free_range(bitmap, obj, 1);
+}
+
+static unsigned long find_aligned_range(unsigned long *bitmap,
+                                       u32 start, u32 nbits,
+                                       int len, int align)
+{
+       unsigned long end, i;
+
+again:
+       start = ALIGN(start, align);
+
+       while ((start < nbits) && test_bit(start, bitmap))
+               start += align;
+
+       if (start >= nbits)
+               return -1;
+
+       end = start+len;
+       if (end > nbits)
+               return -1;
+
+       for (i = start + 1; i < end; i++) {
+               if (test_bit(i, bitmap)) {
+                       start = i + 1;
+                       goto again;
+               }
+       }
+
+       return start;
+}
+
+u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align)
+{
+       u32 obj, i;
+
+       if (likely(cnt == 1 && align == 1))
+               return mlx4_bitmap_alloc(bitmap);
+
+       spin_lock(&bitmap->lock);
+
+       obj = find_aligned_range(bitmap->table, bitmap->last,
+                                bitmap->max, cnt, align);
+       if (obj >= bitmap->max) {
+               bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
+                               & bitmap->mask;
+               obj = find_aligned_range(bitmap->table, 0, bitmap->max,
+                                        cnt, align);
+       }
+
+       if (obj < bitmap->max) {
+               for (i = 0; i < cnt; i++)
+                       set_bit(obj + i, bitmap->table);
+               if (obj == bitmap->last) {
+                       bitmap->last = (obj + cnt);
+                       if (bitmap->last >= bitmap->max)
+                               bitmap->last = 0;
+               }
+               obj |= bitmap->top;
+       } else
+               obj = -1;
+
+       spin_unlock(&bitmap->lock);
+
+       return obj;
+}
+
+void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt)
+{
+       u32 i;
+
+       obj &= bitmap->max + bitmap->reserved_top - 1;
 
        spin_lock(&bitmap->lock);
-       clear_bit(obj, bitmap->table);
+       for (i = 0; i < cnt; i++)
+               clear_bit(obj + i, bitmap->table);
        bitmap->last = min(bitmap->last, obj);
-       bitmap->top = (bitmap->top + bitmap->max) & bitmap->mask;
+       bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
+                       & bitmap->mask;
        spin_unlock(&bitmap->lock);
 }
 
-int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask, u32 reserved)
+int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask,
+                    u32 reserved_bot, u32 reserved_top)
 {
        int i;
 
@@ -85,14 +162,16 @@ int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask, u32 reserved
 
        bitmap->last = 0;
        bitmap->top  = 0;
-       bitmap->max  = num;
+       bitmap->max  = num - reserved_top;
        bitmap->mask = mask;
+       bitmap->reserved_top = reserved_top;
        spin_lock_init(&bitmap->lock);
-       bitmap->table = kzalloc(BITS_TO_LONGS(num) * sizeof (long), GFP_KERNEL);
+       bitmap->table = kzalloc(BITS_TO_LONGS(bitmap->max) *
+                               sizeof (long), GFP_KERNEL);
        if (!bitmap->table)
                return -ENOMEM;
 
-       for (i = 0; i < reserved; ++i)
+       for (i = 0; i < reserved_bot; ++i)
                set_bit(i, bitmap->table);
 
        return 0;
index 9bb50e3f8974386ff329d0d2d97671d27bf8a5f6..b7ad2829d67ecbe608422658b16f79ac890fd526 100644 (file)
@@ -300,7 +300,7 @@ int mlx4_init_cq_table(struct mlx4_dev *dev)
        INIT_RADIX_TREE(&cq_table->tree, GFP_ATOMIC);
 
        err = mlx4_bitmap_init(&cq_table->bitmap, dev->caps.num_cqs,
-                              dev->caps.num_cqs - 1, dev->caps.reserved_cqs);
+                              dev->caps.num_cqs - 1, dev->caps.reserved_cqs, 0);
        if (err)
                return err;
 
diff --git a/drivers/net/mlx4/en_cq.c b/drivers/net/mlx4/en_cq.c
new file mode 100644 (file)
index 0000000..1368a80
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2007 Mellanox Technologies. 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/mlx4/cq.h>
+#include <linux/mlx4/qp.h>
+#include <linux/mlx4/cmd.h>
+
+#include "mlx4_en.h"
+
+static void mlx4_en_cq_event(struct mlx4_cq *cq, enum mlx4_event event)
+{
+       return;
+}
+
+
+int mlx4_en_create_cq(struct mlx4_en_priv *priv,
+                     struct mlx4_en_cq *cq,
+                     int entries, int ring, enum cq_type mode)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+       int err;
+
+       cq->size = entries;
+       if (mode == RX)
+               cq->buf_size = cq->size * sizeof(struct mlx4_cqe);
+       else
+               cq->buf_size = sizeof(struct mlx4_cqe);
+
+       cq->ring = ring;
+       cq->is_tx = mode;
+       spin_lock_init(&cq->lock);
+
+       err = mlx4_alloc_hwq_res(mdev->dev, &cq->wqres,
+                               cq->buf_size, 2 * PAGE_SIZE);
+       if (err)
+               return err;
+
+       err = mlx4_en_map_buffer(&cq->wqres.buf);
+       if (err)
+               mlx4_free_hwq_res(mdev->dev, &cq->wqres, cq->buf_size);
+
+       return err;
+}
+
+int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+       int err;
+
+       cq->dev = mdev->pndev[priv->port];
+       cq->mcq.set_ci_db  = cq->wqres.db.db;
+       cq->mcq.arm_db     = cq->wqres.db.db + 1;
+       *cq->mcq.set_ci_db = 0;
+       *cq->mcq.arm_db    = 0;
+       cq->buf = (struct mlx4_cqe *) cq->wqres.buf.direct.buf;
+       memset(cq->buf, 0, cq->buf_size);
+
+       err = mlx4_cq_alloc(mdev->dev, cq->size, &cq->wqres.mtt, &mdev->priv_uar,
+                           cq->wqres.db.dma, &cq->mcq, cq->is_tx);
+       if (err)
+               return err;
+
+       cq->mcq.comp  = cq->is_tx ? mlx4_en_tx_irq : mlx4_en_rx_irq;
+       cq->mcq.event = mlx4_en_cq_event;
+
+       if (cq->is_tx) {
+               init_timer(&cq->timer);
+               cq->timer.function = mlx4_en_poll_tx_cq;
+               cq->timer.data = (unsigned long) cq;
+       } else {
+               netif_napi_add(cq->dev, &cq->napi, mlx4_en_poll_rx_cq, 64);
+               napi_enable(&cq->napi);
+       }
+
+       return 0;
+}
+
+void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+
+       mlx4_en_unmap_buffer(&cq->wqres.buf);
+       mlx4_free_hwq_res(mdev->dev, &cq->wqres, cq->buf_size);
+       cq->buf_size = 0;
+       cq->buf = NULL;
+}
+
+void mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+
+       if (cq->is_tx)
+               del_timer(&cq->timer);
+       else
+               napi_disable(&cq->napi);
+
+       mlx4_cq_free(mdev->dev, &cq->mcq);
+}
+
+/* Set rx cq moderation parameters */
+int mlx4_en_set_cq_moder(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
+{
+       return mlx4_cq_modify(priv->mdev->dev, &cq->mcq,
+                             cq->moder_cnt, cq->moder_time);
+}
+
+int mlx4_en_arm_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
+{
+       cq->armed = 1;
+       mlx4_cq_arm(&cq->mcq, MLX4_CQ_DB_REQ_NOT, priv->mdev->uar_map,
+                   &priv->mdev->uar_lock);
+
+       return 0;
+}
+
+
diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c
new file mode 100644 (file)
index 0000000..1b0eebf
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2007 Mellanox Technologies. 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/cpumask.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/cpumask.h>
+
+#include <linux/mlx4/driver.h>
+#include <linux/mlx4/device.h>
+#include <linux/mlx4/cmd.h>
+
+#include "mlx4_en.h"
+
+MODULE_AUTHOR("Liran Liss, Yevgeny Petrilin");
+MODULE_DESCRIPTION("Mellanox ConnectX HCA Ethernet driver");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION(DRV_VERSION " ("DRV_RELDATE")");
+
+static const char mlx4_en_version[] =
+       DRV_NAME ": Mellanox ConnectX HCA Ethernet driver v"
+       DRV_VERSION " (" DRV_RELDATE ")\n";
+
+static void mlx4_en_event(struct mlx4_dev *dev, void *endev_ptr,
+                         enum mlx4_dev_event event, int port)
+{
+       struct mlx4_en_dev *mdev = (struct mlx4_en_dev *) endev_ptr;
+       struct mlx4_en_priv *priv;
+
+       if (!mdev->pndev[port])
+               return;
+
+       priv = netdev_priv(mdev->pndev[port]);
+       switch (event) {
+       case MLX4_DEV_EVENT_PORT_UP:
+       case MLX4_DEV_EVENT_PORT_DOWN:
+               /* To prevent races, we poll the link state in a separate
+                 task rather than changing it here */
+               priv->link_state = event;
+               queue_work(mdev->workqueue, &priv->linkstate_task);
+               break;
+
+       case MLX4_DEV_EVENT_CATASTROPHIC_ERROR:
+               mlx4_err(mdev, "Internal error detected, restarting device\n");
+               break;
+
+       default:
+               mlx4_warn(mdev, "Unhandled event: %d\n", event);
+       }
+}
+
+static void mlx4_en_remove(struct mlx4_dev *dev, void *endev_ptr)
+{
+       struct mlx4_en_dev *mdev = endev_ptr;
+       int i;
+
+       mutex_lock(&mdev->state_lock);
+       mdev->device_up = false;
+       mutex_unlock(&mdev->state_lock);
+
+       mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH)
+               if (mdev->pndev[i])
+                       mlx4_en_destroy_netdev(mdev->pndev[i]);
+
+       flush_workqueue(mdev->workqueue);
+       destroy_workqueue(mdev->workqueue);
+       mlx4_mr_free(dev, &mdev->mr);
+       mlx4_uar_free(dev, &mdev->priv_uar);
+       mlx4_pd_free(dev, mdev->priv_pdn);
+       kfree(mdev);
+}
+
+static void *mlx4_en_add(struct mlx4_dev *dev)
+{
+       static int mlx4_en_version_printed;
+       struct mlx4_en_dev *mdev;
+       int i;
+       int err;
+
+       if (!mlx4_en_version_printed) {
+               printk(KERN_INFO "%s", mlx4_en_version);
+               mlx4_en_version_printed++;
+       }
+
+       mdev = kzalloc(sizeof *mdev, GFP_KERNEL);
+       if (!mdev) {
+               dev_err(&dev->pdev->dev, "Device struct alloc failed, "
+                       "aborting.\n");
+               err = -ENOMEM;
+               goto err_free_res;
+       }
+
+       if (mlx4_pd_alloc(dev, &mdev->priv_pdn))
+               goto err_free_dev;
+
+       if (mlx4_uar_alloc(dev, &mdev->priv_uar))
+               goto err_pd;
+
+       mdev->uar_map = ioremap(mdev->priv_uar.pfn << PAGE_SHIFT, PAGE_SIZE);
+       if (!mdev->uar_map)
+               goto err_uar;
+       spin_lock_init(&mdev->uar_lock);
+
+       mdev->dev = dev;
+       mdev->dma_device = &(dev->pdev->dev);
+       mdev->pdev = dev->pdev;
+       mdev->device_up = false;
+
+       mdev->LSO_support = !!(dev->caps.flags & (1 << 15));
+       if (!mdev->LSO_support)
+               mlx4_warn(mdev, "LSO not supported, please upgrade to later "
+                               "FW version to enable LSO\n");
+
+       if (mlx4_mr_alloc(mdev->dev, mdev->priv_pdn, 0, ~0ull,
+                        MLX4_PERM_LOCAL_WRITE |  MLX4_PERM_LOCAL_READ,
+                        0, 0, &mdev->mr)) {
+               mlx4_err(mdev, "Failed allocating memory region\n");
+               goto err_uar;
+       }
+       if (mlx4_mr_enable(mdev->dev, &mdev->mr)) {
+               mlx4_err(mdev, "Failed enabling memory region\n");
+               goto err_mr;
+       }
+
+       /* Build device profile according to supplied module parameters */
+       err = mlx4_en_get_profile(mdev);
+       if (err) {
+               mlx4_err(mdev, "Bad module parameters, aborting.\n");
+               goto err_mr;
+       }
+
+       /* Configure wich ports to start according to module parameters */
+       mdev->port_cnt = 0;
+       mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH)
+               mdev->port_cnt++;
+
+       /* If we did not receive an explicit number of Rx rings, default to
+        * the number of completion vectors populated by the mlx4_core */
+       mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH) {
+               mlx4_info(mdev, "Using %d tx rings for port:%d\n",
+                         mdev->profile.prof[i].tx_ring_num, i);
+               if (!mdev->profile.prof[i].rx_ring_num) {
+                       mdev->profile.prof[i].rx_ring_num = 1;
+                       mlx4_info(mdev, "Defaulting to %d rx rings for port:%d\n",
+                                 1, i);
+               } else
+                       mlx4_info(mdev, "Using %d rx rings for port:%d\n",
+                                 mdev->profile.prof[i].rx_ring_num, i);
+       }
+
+       /* Create our own workqueue for reset/multicast tasks
+        * Note: we cannot use the shared workqueue because of deadlocks caused
+        *       by the rtnl lock */
+       mdev->workqueue = create_singlethread_workqueue("mlx4_en");
+       if (!mdev->workqueue) {
+               err = -ENOMEM;
+               goto err_close_nic;
+       }
+
+       /* At this stage all non-port specific tasks are complete:
+        * mark the card state as up */
+       mutex_init(&mdev->state_lock);
+       mdev->device_up = true;
+
+       /* Setup ports */
+
+       /* Create a netdev for each port */
+       mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH) {
+               mlx4_info(mdev, "Activating port:%d\n", i);
+               if (mlx4_en_init_netdev(mdev, i, &mdev->profile.prof[i])) {
+                       mdev->pndev[i] = NULL;
+                       goto err_free_netdev;
+               }
+       }
+       return mdev;
+
+
+err_free_netdev:
+       mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH) {
+               if (mdev->pndev[i])
+                       mlx4_en_destroy_netdev(mdev->pndev[i]);
+       }
+
+       mutex_lock(&mdev->state_lock);
+       mdev->device_up = false;
+       mutex_unlock(&mdev->state_lock);
+       flush_workqueue(mdev->workqueue);
+
+       /* Stop event queue before we drop down to release shared SW state */
+
+err_close_nic:
+       destroy_workqueue(mdev->workqueue);
+err_mr:
+       mlx4_mr_free(dev, &mdev->mr);
+err_uar:
+       mlx4_uar_free(dev, &mdev->priv_uar);
+err_pd:
+       mlx4_pd_free(dev, mdev->priv_pdn);
+err_free_dev:
+       kfree(mdev);
+err_free_res:
+       return NULL;
+}
+
+static struct mlx4_interface mlx4_en_interface = {
+       .add    = mlx4_en_add,
+       .remove = mlx4_en_remove,
+       .event  = mlx4_en_event,
+};
+
+static int __init mlx4_en_init(void)
+{
+       return mlx4_register_interface(&mlx4_en_interface);
+}
+
+static void __exit mlx4_en_cleanup(void)
+{
+       mlx4_unregister_interface(&mlx4_en_interface);
+}
+
+module_init(mlx4_en_init);
+module_exit(mlx4_en_cleanup);
+
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
new file mode 100644 (file)
index 0000000..a339afb
--- /dev/null
@@ -0,0 +1,1088 @@
+/*
+ * Copyright (c) 2007 Mellanox Technologies. 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/etherdevice.h>
+#include <linux/tcp.h>
+#include <linux/if_vlan.h>
+#include <linux/delay.h>
+
+#include <linux/mlx4/driver.h>
+#include <linux/mlx4/device.h>
+#include <linux/mlx4/cmd.h>
+#include <linux/mlx4/cq.h>
+
+#include "mlx4_en.h"
+#include "en_port.h"
+
+
+static void mlx4_en_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       int err;
+
+       mlx4_dbg(HW, priv, "Registering VLAN group:%p\n", grp);
+       priv->vlgrp = grp;
+
+       mutex_lock(&mdev->state_lock);
+       if (mdev->device_up && priv->port_up) {
+               err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, grp);
+               if (err)
+                       mlx4_err(mdev, "Failed configuring VLAN filter\n");
+       }
+       mutex_unlock(&mdev->state_lock);
+}
+
+static void mlx4_en_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       int err;
+
+       if (!priv->vlgrp)
+               return;
+
+       mlx4_dbg(HW, priv, "adding VLAN:%d (vlgrp entry:%p)\n",
+                vid, vlan_group_get_device(priv->vlgrp, vid));
+
+       /* Add VID to port VLAN filter */
+       mutex_lock(&mdev->state_lock);
+       if (mdev->device_up && priv->port_up) {
+               err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp);
+               if (err)
+                       mlx4_err(mdev, "Failed configuring VLAN filter\n");
+       }
+       mutex_unlock(&mdev->state_lock);
+}
+
+static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       int err;
+
+       if (!priv->vlgrp)
+               return;
+
+       mlx4_dbg(HW, priv, "Killing VID:%d (vlgrp:%p vlgrp "
+                "entry:%p)\n", vid, priv->vlgrp,
+                vlan_group_get_device(priv->vlgrp, vid));
+       vlan_group_set_device(priv->vlgrp, vid, NULL);
+
+       /* Remove VID from port VLAN filter */
+       mutex_lock(&mdev->state_lock);
+       if (mdev->device_up && priv->port_up) {
+               err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp);
+               if (err)
+                       mlx4_err(mdev, "Failed configuring VLAN filter\n");
+       }
+       mutex_unlock(&mdev->state_lock);
+}
+
+static u64 mlx4_en_mac_to_u64(u8 *addr)
+{
+       u64 mac = 0;
+       int i;
+
+       for (i = 0; i < ETH_ALEN; i++) {
+               mac <<= 8;
+               mac |= addr[i];
+       }
+       return mac;
+}
+
+static int mlx4_en_set_mac(struct net_device *dev, void *addr)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct sockaddr *saddr = addr;
+
+       if (!is_valid_ether_addr(saddr->sa_data))
+               return -EADDRNOTAVAIL;
+
+       memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN);
+       priv->mac = mlx4_en_mac_to_u64(dev->dev_addr);
+       queue_work(mdev->workqueue, &priv->mac_task);
+       return 0;
+}
+
+static void mlx4_en_do_set_mac(struct work_struct *work)
+{
+       struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv,
+                                                mac_task);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       int err = 0;
+
+       mutex_lock(&mdev->state_lock);
+       if (priv->port_up) {
+               /* Remove old MAC and insert the new one */
+               mlx4_unregister_mac(mdev->dev, priv->port, priv->mac_index);
+               err = mlx4_register_mac(mdev->dev, priv->port,
+                                       priv->mac, &priv->mac_index);
+               if (err)
+                       mlx4_err(mdev, "Failed changing HW MAC address\n");
+       } else
+               mlx4_dbg(HW, priv, "Port is down, exiting...\n");
+
+       mutex_unlock(&mdev->state_lock);
+}
+
+static void mlx4_en_clear_list(struct net_device *dev)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct dev_mc_list *plist = priv->mc_list;
+       struct dev_mc_list *next;
+
+       while (plist) {
+               next = plist->next;
+               kfree(plist);
+               plist = next;
+       }
+       priv->mc_list = NULL;
+}
+
+static void mlx4_en_cache_mclist(struct net_device *dev)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct dev_mc_list *mclist;
+       struct dev_mc_list *tmp;
+       struct dev_mc_list *plist = NULL;
+
+       for (mclist = dev->mc_list; mclist; mclist = mclist->next) {
+               tmp = kmalloc(sizeof(struct dev_mc_list), GFP_ATOMIC);
+               if (!tmp) {
+                       mlx4_err(mdev, "failed to allocate multicast list\n");
+                       mlx4_en_clear_list(dev);
+                       return;
+               }
+               memcpy(tmp, mclist, sizeof(struct dev_mc_list));
+               tmp->next = NULL;
+               if (plist)
+                       plist->next = tmp;
+               else
+                       priv->mc_list = tmp;
+               plist = tmp;
+       }
+}
+
+
+static void mlx4_en_set_multicast(struct net_device *dev)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+
+       if (!priv->port_up)
+               return;
+
+       queue_work(priv->mdev->workqueue, &priv->mcast_task);
+}
+
+static void mlx4_en_do_set_multicast(struct work_struct *work)
+{
+       struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv,
+                                                mcast_task);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct net_device *dev = priv->dev;
+       struct dev_mc_list *mclist;
+       u64 mcast_addr = 0;
+       int err;
+
+       mutex_lock(&mdev->state_lock);
+       if (!mdev->device_up) {
+               mlx4_dbg(HW, priv, "Card is not up, ignoring "
+                                  "multicast change.\n");
+               goto out;
+       }
+       if (!priv->port_up) {
+               mlx4_dbg(HW, priv, "Port is down, ignoring "
+                                  "multicast change.\n");
+               goto out;
+       }
+
+       /*
+        * Promsicuous mode: disable all filters
+        */
+
+       if (dev->flags & IFF_PROMISC) {
+               if (!(priv->flags & MLX4_EN_FLAG_PROMISC)) {
+                       if (netif_msg_rx_status(priv))
+                               mlx4_warn(mdev, "Port:%d entering promiscuous mode\n",
+                                         priv->port);
+                       priv->flags |= MLX4_EN_FLAG_PROMISC;
+
+                       /* Enable promiscouos mode */
+                       err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port,
+                                                    priv->base_qpn, 1);
+                       if (err)
+                               mlx4_err(mdev, "Failed enabling "
+                                        "promiscous mode\n");
+
+                       /* Disable port multicast filter (unconditionally) */
+                       err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0,
+                                                 0, MLX4_MCAST_DISABLE);
+                       if (err)
+                               mlx4_err(mdev, "Failed disabling "
+                                        "multicast filter\n");
+
+                       /* Disable port VLAN filter */
+                       err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, NULL);
+                       if (err)
+                               mlx4_err(mdev, "Failed disabling "
+                                        "VLAN filter\n");
+               }
+               goto out;
+       }
+
+       /*
+        * Not in promiscous mode
+        */
+
+       if (priv->flags & MLX4_EN_FLAG_PROMISC) {
+               if (netif_msg_rx_status(priv))
+                       mlx4_warn(mdev, "Port:%d leaving promiscuous mode\n",
+                                 priv->port);
+               priv->flags &= ~MLX4_EN_FLAG_PROMISC;
+
+               /* Disable promiscouos mode */
+               err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port,
+                                            priv->base_qpn, 0);
+               if (err)
+                       mlx4_err(mdev, "Failed disabling promiscous mode\n");
+
+               /* Enable port VLAN filter */
+               err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp);
+               if (err)
+                       mlx4_err(mdev, "Failed enabling VLAN filter\n");
+       }
+
+       /* Enable/disable the multicast filter according to IFF_ALLMULTI */
+       if (dev->flags & IFF_ALLMULTI) {
+               err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0,
+                                         0, MLX4_MCAST_DISABLE);
+               if (err)
+                       mlx4_err(mdev, "Failed disabling multicast filter\n");
+       } else {
+               err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0,
+                                         0, MLX4_MCAST_DISABLE);
+               if (err)
+                       mlx4_err(mdev, "Failed disabling multicast filter\n");
+
+               /* Flush mcast filter and init it with broadcast address */
+               mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, ETH_BCAST,
+                                   1, MLX4_MCAST_CONFIG);
+
+               /* Update multicast list - we cache all addresses so they won't
+                * change while HW is updated holding the command semaphor */
+               netif_tx_lock_bh(dev);
+               mlx4_en_cache_mclist(dev);
+               netif_tx_unlock_bh(dev);
+               for (mclist = priv->mc_list; mclist; mclist = mclist->next) {
+                       mcast_addr = mlx4_en_mac_to_u64(mclist->dmi_addr);
+                       mlx4_SET_MCAST_FLTR(mdev->dev, priv->port,
+                                           mcast_addr, 0, MLX4_MCAST_CONFIG);
+               }
+               err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0,
+                                         0, MLX4_MCAST_ENABLE);
+               if (err)
+                       mlx4_err(mdev, "Failed enabling multicast filter\n");
+
+               mlx4_en_clear_list(dev);
+       }
+out:
+       mutex_unlock(&mdev->state_lock);
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void mlx4_en_netpoll(struct net_device *dev)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_cq *cq;
+       unsigned long flags;
+       int i;
+
+       for (i = 0; i < priv->rx_ring_num; i++) {
+               cq = &priv->rx_cq[i];
+               spin_lock_irqsave(&cq->lock, flags);
+               napi_synchronize(&cq->napi);
+               mlx4_en_process_rx_cq(dev, cq, 0);
+               spin_unlock_irqrestore(&cq->lock, flags);
+       }
+}
+#endif
+
+static void mlx4_en_tx_timeout(struct net_device *dev)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+
+       if (netif_msg_timer(priv))
+               mlx4_warn(mdev, "Tx timeout called on port:%d\n", priv->port);
+
+       if (netif_carrier_ok(dev)) {
+               priv->port_stats.tx_timeout++;
+               mlx4_dbg(DRV, priv, "Scheduling watchdog\n");
+               queue_work(mdev->workqueue, &priv->watchdog_task);
+       }
+}
+
+
+static struct net_device_stats *mlx4_en_get_stats(struct net_device *dev)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+
+       spin_lock_bh(&priv->stats_lock);
+       memcpy(&priv->ret_stats, &priv->stats, sizeof(priv->stats));
+       spin_unlock_bh(&priv->stats_lock);
+
+       return &priv->ret_stats;
+}
+
+static void mlx4_en_set_default_moderation(struct mlx4_en_priv *priv)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct mlx4_en_cq *cq;
+       int i;
+
+       /* If we haven't received a specific coalescing setting
+        * (module param), we set the moderation paramters as follows:
+        * - moder_cnt is set to the number of mtu sized packets to
+        *   satisfy our coelsing target.
+        * - moder_time is set to a fixed value.
+        */
+       priv->rx_frames = (mdev->profile.rx_moder_cnt ==
+                          MLX4_EN_AUTO_CONF) ?
+                               MLX4_EN_RX_COAL_TARGET /
+                               priv->dev->mtu + 1 :
+                               mdev->profile.rx_moder_cnt;
+       priv->rx_usecs = (mdev->profile.rx_moder_time ==
+                         MLX4_EN_AUTO_CONF) ?
+                               MLX4_EN_RX_COAL_TIME :
+                               mdev->profile.rx_moder_time;
+       mlx4_dbg(INTR, priv, "Default coalesing params for mtu:%d - "
+                            "rx_frames:%d rx_usecs:%d\n",
+                priv->dev->mtu, priv->rx_frames, priv->rx_usecs);
+
+       /* Setup cq moderation params */
+       for (i = 0; i < priv->rx_ring_num; i++) {
+               cq = &priv->rx_cq[i];
+               cq->moder_cnt = priv->rx_frames;
+               cq->moder_time = priv->rx_usecs;
+       }
+
+       for (i = 0; i < priv->tx_ring_num; i++) {
+               cq = &priv->tx_cq[i];
+               cq->moder_cnt = MLX4_EN_TX_COAL_PKTS;
+               cq->moder_time = MLX4_EN_TX_COAL_TIME;
+       }
+
+       /* Reset auto-moderation params */
+       priv->pkt_rate_low = MLX4_EN_RX_RATE_LOW;
+       priv->rx_usecs_low = MLX4_EN_RX_COAL_TIME_LOW;
+       priv->pkt_rate_high = MLX4_EN_RX_RATE_HIGH;
+       priv->rx_usecs_high = MLX4_EN_RX_COAL_TIME_HIGH;
+       priv->sample_interval = MLX4_EN_SAMPLE_INTERVAL;
+       priv->adaptive_rx_coal = mdev->profile.auto_moder;
+       priv->last_moder_time = MLX4_EN_AUTO_CONF;
+       priv->last_moder_jiffies = 0;
+       priv->last_moder_packets = 0;
+       priv->last_moder_tx_packets = 0;
+       priv->last_moder_bytes = 0;
+}
+
+static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv)
+{
+       unsigned long period = (unsigned long) (jiffies - priv->last_moder_jiffies);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct mlx4_en_cq *cq;
+       unsigned long packets;
+       unsigned long rate;
+       unsigned long avg_pkt_size;
+       unsigned long rx_packets;
+       unsigned long rx_bytes;
+       unsigned long tx_packets;
+       unsigned long tx_pkt_diff;
+       unsigned long rx_pkt_diff;
+       int moder_time;
+       int i, err;
+
+       if (!priv->adaptive_rx_coal || period < priv->sample_interval * HZ)
+               return;
+
+       spin_lock_bh(&priv->stats_lock);
+       rx_packets = priv->stats.rx_packets;
+       rx_bytes = priv->stats.rx_bytes;
+       tx_packets = priv->stats.tx_packets;
+       spin_unlock_bh(&priv->stats_lock);
+
+       if (!priv->last_moder_jiffies || !period)
+               goto out;
+
+       tx_pkt_diff = ((unsigned long) (tx_packets -
+                                       priv->last_moder_tx_packets));
+       rx_pkt_diff = ((unsigned long) (rx_packets -
+                                       priv->last_moder_packets));
+       packets = max(tx_pkt_diff, rx_pkt_diff);
+       rate = packets * HZ / period;
+       avg_pkt_size = packets ? ((unsigned long) (rx_bytes -
+                                priv->last_moder_bytes)) / packets : 0;
+
+       /* Apply auto-moderation only when packet rate exceeds a rate that
+        * it matters */
+       if (rate > MLX4_EN_RX_RATE_THRESH) {
+               /* If tx and rx packet rates are not balanced, assume that
+                * traffic is mainly BW bound and apply maximum moderation.
+                * Otherwise, moderate according to packet rate */
+               if (2 * tx_pkt_diff > 3 * rx_pkt_diff ||
+                   2 * rx_pkt_diff > 3 * tx_pkt_diff) {
+                       moder_time = priv->rx_usecs_high;
+               } else {
+                       if (rate < priv->pkt_rate_low)
+                               moder_time = priv->rx_usecs_low;
+                       else if (rate > priv->pkt_rate_high)
+                               moder_time = priv->rx_usecs_high;
+                       else
+                               moder_time = (rate - priv->pkt_rate_low) *
+                                       (priv->rx_usecs_high - priv->rx_usecs_low) /
+                                       (priv->pkt_rate_high - priv->pkt_rate_low) +
+                                       priv->rx_usecs_low;
+               }
+       } else {
+               /* When packet rate is low, use default moderation rather than
+                * 0 to prevent interrupt storms if traffic suddenly increases */
+               moder_time = priv->rx_usecs;
+       }
+
+       mlx4_dbg(INTR, priv, "tx rate:%lu rx_rate:%lu\n",
+                tx_pkt_diff * HZ / period, rx_pkt_diff * HZ / period);
+
+       mlx4_dbg(INTR, priv, "Rx moder_time changed from:%d to %d period:%lu "
+                "[jiff] packets:%lu avg_pkt_size:%lu rate:%lu [p/s])\n",
+                priv->last_moder_time, moder_time, period, packets,
+                avg_pkt_size, rate);
+
+       if (moder_time != priv->last_moder_time) {
+               priv->last_moder_time = moder_time;
+               for (i = 0; i < priv->rx_ring_num; i++) {
+                       cq = &priv->rx_cq[i];
+                       cq->moder_time = moder_time;
+                       err = mlx4_en_set_cq_moder(priv, cq);
+                       if (err) {
+                               mlx4_err(mdev, "Failed modifying moderation for cq:%d "
+                                        "on port:%d\n", i, priv->port);
+                               break;
+                       }
+               }
+       }
+
+out:
+       priv->last_moder_packets = rx_packets;
+       priv->last_moder_tx_packets = tx_packets;
+       priv->last_moder_bytes = rx_bytes;
+       priv->last_moder_jiffies = jiffies;
+}
+
+static void mlx4_en_do_get_stats(struct work_struct *work)
+{
+       struct delayed_work *delay = container_of(work, struct delayed_work, work);
+       struct mlx4_en_priv *priv = container_of(delay, struct mlx4_en_priv,
+                                                stats_task);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       int err;
+
+       err = mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 0);
+       if (err)
+               mlx4_dbg(HW, priv, "Could not update stats for "
+                                  "port:%d\n", priv->port);
+
+       mutex_lock(&mdev->state_lock);
+       if (mdev->device_up) {
+               if (priv->port_up)
+                       mlx4_en_auto_moderation(priv);
+
+               queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
+       }
+       mutex_unlock(&mdev->state_lock);
+}
+
+static void mlx4_en_linkstate(struct work_struct *work)
+{
+       struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv,
+                                                linkstate_task);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       int linkstate = priv->link_state;
+
+       mutex_lock(&mdev->state_lock);
+       /* If observable port state changed set carrier state and
+        * report to system log */
+       if (priv->last_link_state != linkstate) {
+               if (linkstate == MLX4_DEV_EVENT_PORT_DOWN) {
+                       if (netif_msg_link(priv))
+                               mlx4_info(mdev, "Port %d - link down\n", priv->port);
+                       netif_carrier_off(priv->dev);
+               } else {
+                       if (netif_msg_link(priv))
+                               mlx4_info(mdev, "Port %d - link up\n", priv->port);
+                       netif_carrier_on(priv->dev);
+               }
+       }
+       priv->last_link_state = linkstate;
+       mutex_unlock(&mdev->state_lock);
+}
+
+
+static int mlx4_en_start_port(struct net_device *dev)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct mlx4_en_cq *cq;
+       struct mlx4_en_tx_ring *tx_ring;
+       struct mlx4_en_rx_ring *rx_ring;
+       int rx_index = 0;
+       int tx_index = 0;
+       u16 stride;
+       int err = 0;
+       int i;
+       int j;
+
+       if (priv->port_up) {
+               mlx4_dbg(DRV, priv, "start port called while port already up\n");
+               return 0;
+       }
+
+       /* Calculate Rx buf size */
+       dev->mtu = min(dev->mtu, priv->max_mtu);
+       mlx4_en_calc_rx_buf(dev);
+       mlx4_dbg(DRV, priv, "Rx buf size:%d\n", priv->rx_skb_size);
+       stride = roundup_pow_of_two(sizeof(struct mlx4_en_rx_desc) +
+                                   DS_SIZE * priv->num_frags);
+       /* Configure rx cq's and rings */
+       for (i = 0; i < priv->rx_ring_num; i++) {
+               cq = &priv->rx_cq[i];
+               rx_ring = &priv->rx_ring[i];
+
+               err = mlx4_en_activate_cq(priv, cq);
+               if (err) {
+                       mlx4_err(mdev, "Failed activating Rx CQ\n");
+                       goto rx_err;
+               }
+               for (j = 0; j < cq->size; j++)
+                       cq->buf[j].owner_sr_opcode = MLX4_CQE_OWNER_MASK;
+               err = mlx4_en_set_cq_moder(priv, cq);
+               if (err) {
+                       mlx4_err(mdev, "Failed setting cq moderation parameters");
+                       mlx4_en_deactivate_cq(priv, cq);
+                       goto cq_err;
+               }
+               mlx4_en_arm_cq(priv, cq);
+
+               ++rx_index;
+       }
+
+       err = mlx4_en_activate_rx_rings(priv);
+       if (err) {
+               mlx4_err(mdev, "Failed to activate RX rings\n");
+               goto cq_err;
+       }
+
+       err = mlx4_en_config_rss_steer(priv);
+       if (err) {
+               mlx4_err(mdev, "Failed configuring rss steering\n");
+               goto rx_err;
+       }
+
+       /* Configure tx cq's and rings */
+       for (i = 0; i < priv->tx_ring_num; i++) {
+               /* Configure cq */
+               cq = &priv->tx_cq[i];
+               err = mlx4_en_activate_cq(priv, cq);
+               if (err) {
+                       mlx4_err(mdev, "Failed allocating Tx CQ\n");
+                       goto tx_err;
+               }
+               err = mlx4_en_set_cq_moder(priv, cq);
+               if (err) {
+                       mlx4_err(mdev, "Failed setting cq moderation parameters");
+                       mlx4_en_deactivate_cq(priv, cq);
+                       goto tx_err;
+               }
+               mlx4_dbg(DRV, priv, "Resetting index of collapsed CQ:%d to -1\n", i);
+               cq->buf->wqe_index = cpu_to_be16(0xffff);
+
+               /* Configure ring */
+               tx_ring = &priv->tx_ring[i];
+               err = mlx4_en_activate_tx_ring(priv, tx_ring, cq->mcq.cqn,
+                                              priv->rx_ring[0].srq.srqn);
+               if (err) {
+                       mlx4_err(mdev, "Failed allocating Tx ring\n");
+                       mlx4_en_deactivate_cq(priv, cq);
+                       goto tx_err;
+               }
+               /* Set initial ownership of all Tx TXBBs to SW (1) */
+               for (j = 0; j < tx_ring->buf_size; j += STAMP_STRIDE)
+                       *((u32 *) (tx_ring->buf + j)) = 0xffffffff;
+               ++tx_index;
+       }
+
+       /* Configure port */
+       err = mlx4_SET_PORT_general(mdev->dev, priv->port,
+                                   priv->rx_skb_size + ETH_FCS_LEN,
+                                   mdev->profile.tx_pause,
+                                   mdev->profile.tx_ppp,
+                                   mdev->profile.rx_pause,
+                                   mdev->profile.rx_ppp);
+       if (err) {
+               mlx4_err(mdev, "Failed setting port general configurations"
+                              " for port %d, with error %d\n", priv->port, err);
+               goto tx_err;
+       }
+       /* Set default qp number */
+       err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port, priv->base_qpn, 0);
+       if (err) {
+               mlx4_err(mdev, "Failed setting default qp numbers\n");
+               goto tx_err;
+       }
+       /* Set port mac number */
+       mlx4_dbg(DRV, priv, "Setting mac for port %d\n", priv->port);
+       err = mlx4_register_mac(mdev->dev, priv->port,
+                               priv->mac, &priv->mac_index);
+       if (err) {
+               mlx4_err(mdev, "Failed setting port mac\n");
+               goto tx_err;
+       }
+
+       /* Init port */
+       mlx4_dbg(HW, priv, "Initializing port\n");
+       err = mlx4_INIT_PORT(mdev->dev, priv->port);
+       if (err) {
+               mlx4_err(mdev, "Failed Initializing port\n");
+               goto mac_err;
+       }
+
+       /* Schedule multicast task to populate multicast list */
+       queue_work(mdev->workqueue, &priv->mcast_task);
+
+       priv->port_up = true;
+       netif_start_queue(dev);
+       return 0;
+
+mac_err:
+       mlx4_unregister_mac(mdev->dev, priv->port, priv->mac_index);
+tx_err:
+       while (tx_index--) {
+               mlx4_en_deactivate_tx_ring(priv, &priv->tx_ring[tx_index]);
+               mlx4_en_deactivate_cq(priv, &priv->tx_cq[tx_index]);
+       }
+
+       mlx4_en_release_rss_steer(priv);
+rx_err:
+       for (i = 0; i < priv->rx_ring_num; i++)
+               mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[rx_index]);
+cq_err:
+       while (rx_index--)
+               mlx4_en_deactivate_cq(priv, &priv->rx_cq[rx_index]);
+
+       return err; /* need to close devices */
+}
+
+
+static void mlx4_en_stop_port(struct net_device *dev)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       int i;
+
+       if (!priv->port_up) {
+               mlx4_dbg(DRV, priv, "stop port (%d) called while port already down\n",
+                        priv->port);
+               return;
+       }
+       netif_stop_queue(dev);
+
+       /* Synchronize with tx routine */
+       netif_tx_lock_bh(dev);
+       priv->port_up = false;
+       netif_tx_unlock_bh(dev);
+
+       /* close port*/
+       mlx4_CLOSE_PORT(mdev->dev, priv->port);
+
+       /* Unregister Mac address for the port */
+       mlx4_unregister_mac(mdev->dev, priv->port, priv->mac_index);
+
+       /* Free TX Rings */
+       for (i = 0; i < priv->tx_ring_num; i++) {
+               mlx4_en_deactivate_tx_ring(priv, &priv->tx_ring[i]);
+               mlx4_en_deactivate_cq(priv, &priv->tx_cq[i]);
+       }
+       msleep(10);
+
+       for (i = 0; i < priv->tx_ring_num; i++)
+               mlx4_en_free_tx_buf(dev, &priv->tx_ring[i]);
+
+       /* Free RSS qps */
+       mlx4_en_release_rss_steer(priv);
+
+       /* Free RX Rings */
+       for (i = 0; i < priv->rx_ring_num; i++) {
+               mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]);
+               while (test_bit(NAPI_STATE_SCHED, &priv->rx_cq[i].napi.state))
+                       msleep(1);
+               mlx4_en_deactivate_cq(priv, &priv->rx_cq[i]);
+       }
+}
+
+static void mlx4_en_restart(struct work_struct *work)
+{
+       struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv,
+                                                watchdog_task);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct net_device *dev = priv->dev;
+
+       mlx4_dbg(DRV, priv, "Watchdog task called for port %d\n", priv->port);
+       mlx4_en_stop_port(dev);
+       if (mlx4_en_start_port(dev))
+           mlx4_err(mdev, "Failed restarting port %d\n", priv->port);
+}
+
+
+static int mlx4_en_open(struct net_device *dev)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       int i;
+       int err = 0;
+
+       mutex_lock(&mdev->state_lock);
+
+       if (!mdev->device_up) {
+               mlx4_err(mdev, "Cannot open - device down/disabled\n");
+               err = -EBUSY;
+               goto out;
+       }
+
+       /* Reset HW statistics and performance counters */
+       if (mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 1))
+               mlx4_dbg(HW, priv, "Failed dumping statistics\n");
+
+       memset(&priv->stats, 0, sizeof(priv->stats));
+       memset(&priv->pstats, 0, sizeof(priv->pstats));
+
+       for (i = 0; i < priv->tx_ring_num; i++) {
+               priv->tx_ring[i].bytes = 0;
+               priv->tx_ring[i].packets = 0;
+       }
+       for (i = 0; i < priv->rx_ring_num; i++) {
+               priv->rx_ring[i].bytes = 0;
+               priv->rx_ring[i].packets = 0;
+       }
+
+       mlx4_en_set_default_moderation(priv);
+       err = mlx4_en_start_port(dev);
+       if (err)
+               mlx4_err(mdev, "Failed starting port:%d\n", priv->port);
+
+out:
+       mutex_unlock(&mdev->state_lock);
+       return err;
+}
+
+
+static int mlx4_en_close(struct net_device *dev)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+
+       if (netif_msg_ifdown(priv))
+               mlx4_info(mdev, "Close called for port:%d\n", priv->port);
+
+       mutex_lock(&mdev->state_lock);
+
+       mlx4_en_stop_port(dev);
+       netif_carrier_off(dev);
+
+       mutex_unlock(&mdev->state_lock);
+       return 0;
+}
+
+static void mlx4_en_free_resources(struct mlx4_en_priv *priv)
+{
+       int i;
+
+       for (i = 0; i < priv->tx_ring_num; i++) {
+               if (priv->tx_ring[i].tx_info)
+                       mlx4_en_destroy_tx_ring(priv, &priv->tx_ring[i]);
+               if (priv->tx_cq[i].buf)
+                       mlx4_en_destroy_cq(priv, &priv->tx_cq[i]);
+       }
+
+       for (i = 0; i < priv->rx_ring_num; i++) {
+               if (priv->rx_ring[i].rx_info)
+                       mlx4_en_destroy_rx_ring(priv, &priv->rx_ring[i]);
+               if (priv->rx_cq[i].buf)
+                       mlx4_en_destroy_cq(priv, &priv->rx_cq[i]);
+       }
+}
+
+static int mlx4_en_alloc_resources(struct mlx4_en_priv *priv)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct mlx4_en_port_profile *prof = priv->prof;
+       int i;
+
+       /* Create tx Rings */
+       for (i = 0; i < priv->tx_ring_num; i++) {
+               if (mlx4_en_create_cq(priv, &priv->tx_cq[i],
+                                     prof->tx_ring_size, i, TX))
+                       goto err;
+
+               if (mlx4_en_create_tx_ring(priv, &priv->tx_ring[i],
+                                          prof->tx_ring_size, TXBB_SIZE))
+                       goto err;
+       }
+
+       /* Create rx Rings */
+       for (i = 0; i < priv->rx_ring_num; i++) {
+               if (mlx4_en_create_cq(priv, &priv->rx_cq[i],
+                                     prof->rx_ring_size, i, RX))
+                       goto err;
+
+               if (mlx4_en_create_rx_ring(priv, &priv->rx_ring[i],
+                                          prof->rx_ring_size, priv->stride))
+                       goto err;
+       }
+
+       return 0;
+
+err:
+       mlx4_err(mdev, "Failed to allocate NIC resources\n");
+       return -ENOMEM;
+}
+
+
+void mlx4_en_destroy_netdev(struct net_device *dev)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+
+       mlx4_dbg(DRV, priv, "Destroying netdev on port:%d\n", priv->port);
+
+       /* Unregister device - this will close the port if it was up */
+       if (priv->registered)
+               unregister_netdev(dev);
+
+       if (priv->allocated)
+               mlx4_free_hwq_res(mdev->dev, &priv->res, MLX4_EN_PAGE_SIZE);
+
+       cancel_delayed_work(&priv->stats_task);
+       cancel_delayed_work(&priv->refill_task);
+       /* flush any pending task for this netdev */
+       flush_workqueue(mdev->workqueue);
+
+       /* Detach the netdev so tasks would not attempt to access it */
+       mutex_lock(&mdev->state_lock);
+       mdev->pndev[priv->port] = NULL;
+       mutex_unlock(&mdev->state_lock);
+
+       mlx4_en_free_resources(priv);
+       free_netdev(dev);
+}
+
+static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       int err = 0;
+
+       mlx4_dbg(DRV, priv, "Change MTU called - current:%d new:%d\n",
+                dev->mtu, new_mtu);
+
+       if ((new_mtu < MLX4_EN_MIN_MTU) || (new_mtu > priv->max_mtu)) {
+               mlx4_err(mdev, "Bad MTU size:%d.\n", new_mtu);
+               return -EPERM;
+       }
+       dev->mtu = new_mtu;
+
+       if (netif_running(dev)) {
+               mutex_lock(&mdev->state_lock);
+               if (!mdev->device_up) {
+                       /* NIC is probably restarting - let watchdog task reset
+                        * the port */
+                       mlx4_dbg(DRV, priv, "Change MTU called with card down!?\n");
+               } else {
+                       mlx4_en_stop_port(dev);
+                       mlx4_en_set_default_moderation(priv);
+                       err = mlx4_en_start_port(dev);
+                       if (err) {
+                               mlx4_err(mdev, "Failed restarting port:%d\n",
+                                        priv->port);
+                               queue_work(mdev->workqueue, &priv->watchdog_task);
+                       }
+               }
+               mutex_unlock(&mdev->state_lock);
+       }
+       return 0;
+}
+
+int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+                       struct mlx4_en_port_profile *prof)
+{
+       struct net_device *dev;
+       struct mlx4_en_priv *priv;
+       int i;
+       int err;
+
+       dev = alloc_etherdev(sizeof(struct mlx4_en_priv));
+       if (dev == NULL) {
+               mlx4_err(mdev, "Net device allocation failed\n");
+               return -ENOMEM;
+       }
+
+       SET_NETDEV_DEV(dev, &mdev->dev->pdev->dev);
+
+       /*
+        * Initialize driver private data
+        */
+
+       priv = netdev_priv(dev);
+       memset(priv, 0, sizeof(struct mlx4_en_priv));
+       priv->dev = dev;
+       priv->mdev = mdev;
+       priv->prof = prof;
+       priv->port = port;
+       priv->port_up = false;
+       priv->rx_csum = 1;
+       priv->flags = prof->flags;
+       priv->tx_ring_num = prof->tx_ring_num;
+       priv->rx_ring_num = prof->rx_ring_num;
+       priv->mc_list = NULL;
+       priv->mac_index = -1;
+       priv->msg_enable = MLX4_EN_MSG_LEVEL;
+       spin_lock_init(&priv->stats_lock);
+       INIT_WORK(&priv->mcast_task, mlx4_en_do_set_multicast);
+       INIT_WORK(&priv->mac_task, mlx4_en_do_set_mac);
+       INIT_DELAYED_WORK(&priv->refill_task, mlx4_en_rx_refill);
+       INIT_WORK(&priv->watchdog_task, mlx4_en_restart);
+       INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate);
+       INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats);
+
+       /* Query for default mac and max mtu */
+       priv->max_mtu = mdev->dev->caps.eth_mtu_cap[priv->port];
+       priv->mac = mdev->dev->caps.def_mac[priv->port];
+       if (ILLEGAL_MAC(priv->mac)) {
+               mlx4_err(mdev, "Port: %d, invalid mac burned: 0x%llx, quiting\n",
+                        priv->port, priv->mac);
+               err = -EINVAL;
+               goto out;
+       }
+
+       priv->stride = roundup_pow_of_two(sizeof(struct mlx4_en_rx_desc) +
+                                         DS_SIZE * MLX4_EN_MAX_RX_FRAGS);
+       err = mlx4_en_alloc_resources(priv);
+       if (err)
+               goto out;
+
+       /* Populate Rx default RSS mappings */
+       mlx4_en_set_default_rss_map(priv, &priv->rss_map, priv->rx_ring_num *
+                                               RSS_FACTOR, priv->rx_ring_num);
+       /* Allocate page for receive rings */
+       err = mlx4_alloc_hwq_res(mdev->dev, &priv->res,
+                               MLX4_EN_PAGE_SIZE, MLX4_EN_PAGE_SIZE);
+       if (err) {
+               mlx4_err(mdev, "Failed to allocate page for rx qps\n");
+               goto out;
+       }
+       priv->allocated = 1;
+
+       /* Populate Tx priority mappings */
+       mlx4_en_set_prio_map(priv, priv->tx_prio_map, prof->tx_ring_num);
+
+       /*
+        * Initialize netdev entry points
+        */
+
+       dev->open = &mlx4_en_open;
+       dev->stop = &mlx4_en_close;
+       dev->hard_start_xmit = &mlx4_en_xmit;
+       dev->get_stats = &mlx4_en_get_stats;
+       dev->set_multicast_list = &mlx4_en_set_multicast;
+       dev->set_mac_address = &mlx4_en_set_mac;
+       dev->change_mtu = &mlx4_en_change_mtu;
+       dev->tx_timeout = &mlx4_en_tx_timeout;
+       dev->watchdog_timeo = MLX4_EN_WATCHDOG_TIMEOUT;
+       dev->vlan_rx_register = mlx4_en_vlan_rx_register;
+       dev->vlan_rx_add_vid = mlx4_en_vlan_rx_add_vid;
+       dev->vlan_rx_kill_vid = mlx4_en_vlan_rx_kill_vid;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       dev->poll_controller = mlx4_en_netpoll;
+#endif
+       SET_ETHTOOL_OPS(dev, &mlx4_en_ethtool_ops);
+
+       /* Set defualt MAC */
+       dev->addr_len = ETH_ALEN;
+       for (i = 0; i < ETH_ALEN; i++)
+               dev->dev_addr[ETH_ALEN - 1 - i] =
+               (u8) (priv->mac >> (8 * i));
+
+       /*
+        * Set driver features
+        */
+       dev->features |= NETIF_F_SG;
+       dev->features |= NETIF_F_HW_CSUM;
+       dev->features |= NETIF_F_HIGHDMA;
+       dev->features |= NETIF_F_HW_VLAN_TX |
+                        NETIF_F_HW_VLAN_RX |
+                        NETIF_F_HW_VLAN_FILTER;
+       if (mdev->profile.num_lro)
+               dev->features |= NETIF_F_LRO;
+       if (mdev->LSO_support) {
+               dev->features |= NETIF_F_TSO;
+               dev->features |= NETIF_F_TSO6;
+       }
+
+       mdev->pndev[port] = dev;
+
+       netif_carrier_off(dev);
+       err = register_netdev(dev);
+       if (err) {
+               mlx4_err(mdev, "Netdev registration failed\n");
+               goto out;
+       }
+       priv->registered = 1;
+       queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
+       return 0;
+
+out:
+       mlx4_en_destroy_netdev(dev);
+       return err;
+}
+
diff --git a/drivers/net/mlx4/en_params.c b/drivers/net/mlx4/en_params.c
new file mode 100644 (file)
index 0000000..c2e69b1
--- /dev/null
@@ -0,0 +1,480 @@
+/*
+ * Copyright (c) 2007 Mellanox Technologies. 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/kernel.h>
+#include <linux/ethtool.h>
+#include <linux/netdevice.h>
+
+#include "mlx4_en.h"
+#include "en_port.h"
+
+#define MLX4_EN_PARM_INT(X, def_val, desc) \
+       static unsigned int X = def_val;\
+       module_param(X , uint, 0444); \
+       MODULE_PARM_DESC(X, desc);
+
+
+/*
+ * Device scope module parameters
+ */
+
+
+/* Use a XOR rathern than Toeplitz hash function for RSS */
+MLX4_EN_PARM_INT(rss_xor, 0, "Use XOR hash function for RSS");
+
+/* RSS hash type mask - default to <saddr, daddr, sport, dport> */
+MLX4_EN_PARM_INT(rss_mask, 0xf, "RSS hash type bitmask");
+
+/* Number of LRO sessions per Rx ring (rounded up to a power of two) */
+MLX4_EN_PARM_INT(num_lro, MLX4_EN_MAX_LRO_DESCRIPTORS,
+                "Number of LRO sessions per ring or disabled (0)");
+
+/* Priority pausing */
+MLX4_EN_PARM_INT(pptx, MLX4_EN_DEF_TX_PAUSE,
+                "Pause policy on TX: 0 never generate pause frames "
+                "1 generate pause frames according to RX buffer threshold");
+MLX4_EN_PARM_INT(pprx, MLX4_EN_DEF_RX_PAUSE,
+                "Pause policy on RX: 0 ignore received pause frames "
+                "1 respect received pause frames");
+MLX4_EN_PARM_INT(pfctx, 0, "Priority based Flow Control policy on TX[7:0]."
+                          " Per priority bit mask");
+MLX4_EN_PARM_INT(pfcrx, 0, "Priority based Flow Control policy on RX[7:0]."
+                          " Per priority bit mask");
+
+/* Interrupt moderation tunning */
+MLX4_EN_PARM_INT(rx_moder_cnt, MLX4_EN_AUTO_CONF,
+              "Max coalesced descriptors for Rx interrupt moderation");
+MLX4_EN_PARM_INT(rx_moder_time, MLX4_EN_AUTO_CONF,
+              "Timeout following last packet for Rx interrupt moderation");
+MLX4_EN_PARM_INT(auto_moder, 1, "Enable dynamic interrupt moderation");
+
+MLX4_EN_PARM_INT(rx_ring_num1, 0, "Number or Rx rings for port 1 (0 = #cores)");
+MLX4_EN_PARM_INT(rx_ring_num2, 0, "Number or Rx rings for port 2 (0 = #cores)");
+
+MLX4_EN_PARM_INT(tx_ring_size1, MLX4_EN_AUTO_CONF, "Tx ring size for port 1");
+MLX4_EN_PARM_INT(tx_ring_size2, MLX4_EN_AUTO_CONF, "Tx ring size for port 2");
+MLX4_EN_PARM_INT(rx_ring_size1, MLX4_EN_AUTO_CONF, "Rx ring size for port 1");
+MLX4_EN_PARM_INT(rx_ring_size2, MLX4_EN_AUTO_CONF, "Rx ring size for port 2");
+
+
+int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
+{
+       struct mlx4_en_profile *params = &mdev->profile;
+
+       params->rx_moder_cnt = min_t(int, rx_moder_cnt, MLX4_EN_AUTO_CONF);
+       params->rx_moder_time = min_t(int, rx_moder_time, MLX4_EN_AUTO_CONF);
+       params->auto_moder = auto_moder;
+       params->rss_xor = (rss_xor != 0);
+       params->rss_mask = rss_mask & 0x1f;
+       params->num_lro = min_t(int, num_lro , MLX4_EN_MAX_LRO_DESCRIPTORS);
+       params->rx_pause = pprx;
+       params->rx_ppp = pfcrx;
+       params->tx_pause = pptx;
+       params->tx_ppp = pfctx;
+       if (params->rx_ppp || params->tx_ppp) {
+               params->prof[1].tx_ring_num = MLX4_EN_TX_RING_NUM;
+               params->prof[2].tx_ring_num = MLX4_EN_TX_RING_NUM;
+       } else {
+               params->prof[1].tx_ring_num = 1;
+               params->prof[2].tx_ring_num = 1;
+       }
+       params->prof[1].rx_ring_num = min_t(int, rx_ring_num1, MAX_RX_RINGS);
+       params->prof[2].rx_ring_num = min_t(int, rx_ring_num2, MAX_RX_RINGS);
+
+       if (tx_ring_size1 == MLX4_EN_AUTO_CONF)
+               tx_ring_size1 = MLX4_EN_DEF_TX_RING_SIZE;
+       params->prof[1].tx_ring_size =
+               (tx_ring_size1 < MLX4_EN_MIN_TX_SIZE) ?
+                MLX4_EN_MIN_TX_SIZE : roundup_pow_of_two(tx_ring_size1);
+
+       if (tx_ring_size2 == MLX4_EN_AUTO_CONF)
+               tx_ring_size2 = MLX4_EN_DEF_TX_RING_SIZE;
+       params->prof[2].tx_ring_size =
+               (tx_ring_size2 < MLX4_EN_MIN_TX_SIZE) ?
+                MLX4_EN_MIN_TX_SIZE : roundup_pow_of_two(tx_ring_size2);
+
+       if (rx_ring_size1 == MLX4_EN_AUTO_CONF)
+               rx_ring_size1 = MLX4_EN_DEF_RX_RING_SIZE;
+       params->prof[1].rx_ring_size =
+               (rx_ring_size1 < MLX4_EN_MIN_RX_SIZE) ?
+                MLX4_EN_MIN_RX_SIZE : roundup_pow_of_two(rx_ring_size1);
+
+       if (rx_ring_size2 == MLX4_EN_AUTO_CONF)
+               rx_ring_size2 = MLX4_EN_DEF_RX_RING_SIZE;
+       params->prof[2].rx_ring_size =
+               (rx_ring_size2 < MLX4_EN_MIN_RX_SIZE) ?
+                MLX4_EN_MIN_RX_SIZE : roundup_pow_of_two(rx_ring_size2);
+       return 0;
+}
+
+
+/*
+ * Ethtool support
+ */
+
+static void mlx4_en_update_lro_stats(struct mlx4_en_priv *priv)
+{
+       int i;
+
+       priv->port_stats.lro_aggregated = 0;
+       priv->port_stats.lro_flushed = 0;
+       priv->port_stats.lro_no_desc = 0;
+
+       for (i = 0; i < priv->rx_ring_num; i++) {
+               priv->port_stats.lro_aggregated += priv->rx_ring[i].lro.stats.aggregated;
+               priv->port_stats.lro_flushed += priv->rx_ring[i].lro.stats.flushed;
+               priv->port_stats.lro_no_desc += priv->rx_ring[i].lro.stats.no_desc;
+       }
+}
+
+static void
+mlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+
+       sprintf(drvinfo->driver, DRV_NAME " (%s)", mdev->dev->board_id);
+       strncpy(drvinfo->version, DRV_VERSION " (" DRV_RELDATE ")", 32);
+       sprintf(drvinfo->fw_version, "%d.%d.%d",
+               (u16) (mdev->dev->caps.fw_ver >> 32),
+               (u16) ((mdev->dev->caps.fw_ver >> 16) & 0xffff),
+               (u16) (mdev->dev->caps.fw_ver & 0xffff));
+       strncpy(drvinfo->bus_info, pci_name(mdev->dev->pdev), 32);
+       drvinfo->n_stats = 0;
+       drvinfo->regdump_len = 0;
+       drvinfo->eedump_len = 0;
+}
+
+static u32 mlx4_en_get_tso(struct net_device *dev)
+{
+       return (dev->features & NETIF_F_TSO) != 0;
+}
+
+static int mlx4_en_set_tso(struct net_device *dev, u32 data)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+
+       if (data) {
+               if (!priv->mdev->LSO_support)
+                       return -EPERM;
+               dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
+       } else
+               dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
+       return 0;
+}
+
+static u32 mlx4_en_get_rx_csum(struct net_device *dev)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       return priv->rx_csum;
+}
+
+static int mlx4_en_set_rx_csum(struct net_device *dev, u32 data)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       priv->rx_csum = (data != 0);
+       return 0;
+}
+
+static const char main_strings[][ETH_GSTRING_LEN] = {
+       "rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
+       "tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
+       "rx_length_errors", "rx_over_errors", "rx_crc_errors",
+       "rx_frame_errors", "rx_fifo_errors", "rx_missed_errors",
+       "tx_aborted_errors", "tx_carrier_errors", "tx_fifo_errors",
+       "tx_heartbeat_errors", "tx_window_errors",
+
+       /* port statistics */
+       "lro_aggregated", "lro_flushed", "lro_no_desc", "tso_packets",
+       "queue_stopped", "wake_queue", "tx_timeout", "rx_alloc_failed",
+       "rx_csum_good", "rx_csum_none", "tx_chksum_offload",
+
+       /* packet statistics */
+       "broadcast", "rx_prio_0", "rx_prio_1", "rx_prio_2", "rx_prio_3",
+       "rx_prio_4", "rx_prio_5", "rx_prio_6", "rx_prio_7", "tx_prio_0",
+       "tx_prio_1", "tx_prio_2", "tx_prio_3", "tx_prio_4", "tx_prio_5",
+       "tx_prio_6", "tx_prio_7",
+};
+#define NUM_MAIN_STATS 21
+#define NUM_ALL_STATS  (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + NUM_PERF_STATS)
+
+static u32 mlx4_en_get_msglevel(struct net_device *dev)
+{
+       return ((struct mlx4_en_priv *) netdev_priv(dev))->msg_enable;
+}
+
+static void mlx4_en_set_msglevel(struct net_device *dev, u32 val)
+{
+       ((struct mlx4_en_priv *) netdev_priv(dev))->msg_enable = val;
+}
+
+static void mlx4_en_get_wol(struct net_device *netdev,
+                           struct ethtool_wolinfo *wol)
+{
+       wol->supported = 0;
+       wol->wolopts = 0;
+
+       return;
+}
+
+static int mlx4_en_get_sset_count(struct net_device *dev, int sset)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+
+       if (sset != ETH_SS_STATS)
+               return -EOPNOTSUPP;
+
+       return NUM_ALL_STATS + (priv->tx_ring_num + priv->rx_ring_num) * 2;
+}
+
+static void mlx4_en_get_ethtool_stats(struct net_device *dev,
+               struct ethtool_stats *stats, uint64_t *data)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       int index = 0;
+       int i;
+
+       spin_lock_bh(&priv->stats_lock);
+
+       mlx4_en_update_lro_stats(priv);
+
+       for (i = 0; i < NUM_MAIN_STATS; i++)
+               data[index++] = ((unsigned long *) &priv->stats)[i];
+       for (i = 0; i < NUM_PORT_STATS; i++)
+               data[index++] = ((unsigned long *) &priv->port_stats)[i];
+       for (i = 0; i < priv->tx_ring_num; i++) {
+               data[index++] = priv->tx_ring[i].packets;
+               data[index++] = priv->tx_ring[i].bytes;
+       }
+       for (i = 0; i < priv->rx_ring_num; i++) {
+               data[index++] = priv->rx_ring[i].packets;
+               data[index++] = priv->rx_ring[i].bytes;
+       }
+       for (i = 0; i < NUM_PKT_STATS; i++)
+               data[index++] = ((unsigned long *) &priv->pkstats)[i];
+       spin_unlock_bh(&priv->stats_lock);
+
+}
+
+static void mlx4_en_get_strings(struct net_device *dev,
+                               uint32_t stringset, uint8_t *data)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       int index = 0;
+       int i;
+
+       if (stringset != ETH_SS_STATS)
+               return;
+
+       /* Add main counters */
+       for (i = 0; i < NUM_MAIN_STATS; i++)
+               strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i]);
+       for (i = 0; i < NUM_PORT_STATS; i++)
+               strcpy(data + (index++) * ETH_GSTRING_LEN,
+                       main_strings[i + NUM_MAIN_STATS]);
+       for (i = 0; i < priv->tx_ring_num; i++) {
+               sprintf(data + (index++) * ETH_GSTRING_LEN,
+                       "tx%d_packets", i);
+               sprintf(data + (index++) * ETH_GSTRING_LEN,
+                       "tx%d_bytes", i);
+       }
+       for (i = 0; i < priv->rx_ring_num; i++) {
+               sprintf(data + (index++) * ETH_GSTRING_LEN,
+                       "rx%d_packets", i);
+               sprintf(data + (index++) * ETH_GSTRING_LEN,
+                       "rx%d_bytes", i);
+       }
+       for (i = 0; i < NUM_PKT_STATS; i++)
+               strcpy(data + (index++) * ETH_GSTRING_LEN,
+                       main_strings[i + NUM_MAIN_STATS + NUM_PORT_STATS]);
+}
+
+static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       cmd->autoneg = AUTONEG_DISABLE;
+       cmd->supported = SUPPORTED_10000baseT_Full;
+       cmd->advertising = SUPPORTED_10000baseT_Full;
+       if (netif_carrier_ok(dev)) {
+               cmd->speed = SPEED_10000;
+               cmd->duplex = DUPLEX_FULL;
+       } else {
+               cmd->speed = -1;
+               cmd->duplex = -1;
+       }
+       return 0;
+}
+
+static int mlx4_en_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       if ((cmd->autoneg == AUTONEG_ENABLE) ||
+           (cmd->speed != SPEED_10000) || (cmd->duplex != DUPLEX_FULL))
+               return -EINVAL;
+
+       /* Nothing to change */
+       return 0;
+}
+
+static int mlx4_en_get_coalesce(struct net_device *dev,
+                             struct ethtool_coalesce *coal)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+
+       coal->tx_coalesce_usecs = 0;
+       coal->tx_max_coalesced_frames = 0;
+       coal->rx_coalesce_usecs = priv->rx_usecs;
+       coal->rx_max_coalesced_frames = priv->rx_frames;
+
+       coal->pkt_rate_low = priv->pkt_rate_low;
+       coal->rx_coalesce_usecs_low = priv->rx_usecs_low;
+       coal->pkt_rate_high = priv->pkt_rate_high;
+       coal->rx_coalesce_usecs_high = priv->rx_usecs_high;
+       coal->rate_sample_interval = priv->sample_interval;
+       coal->use_adaptive_rx_coalesce = priv->adaptive_rx_coal;
+       return 0;
+}
+
+static int mlx4_en_set_coalesce(struct net_device *dev,
+                             struct ethtool_coalesce *coal)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       int err, i;
+
+       priv->rx_frames = (coal->rx_max_coalesced_frames ==
+                          MLX4_EN_AUTO_CONF) ?
+                               MLX4_EN_RX_COAL_TARGET /
+                               priv->dev->mtu + 1 :
+                               coal->rx_max_coalesced_frames;
+       priv->rx_usecs = (coal->rx_coalesce_usecs ==
+                         MLX4_EN_AUTO_CONF) ?
+                               MLX4_EN_RX_COAL_TIME :
+                               coal->rx_coalesce_usecs;
+
+       /* Set adaptive coalescing params */
+       priv->pkt_rate_low = coal->pkt_rate_low;
+       priv->rx_usecs_low = coal->rx_coalesce_usecs_low;
+       priv->pkt_rate_high = coal->pkt_rate_high;
+       priv->rx_usecs_high = coal->rx_coalesce_usecs_high;
+       priv->sample_interval = coal->rate_sample_interval;
+       priv->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
+       priv->last_moder_time = MLX4_EN_AUTO_CONF;
+       if (priv->adaptive_rx_coal)
+               return 0;
+
+       for (i = 0; i < priv->rx_ring_num; i++) {
+               priv->rx_cq[i].moder_cnt = priv->rx_frames;
+               priv->rx_cq[i].moder_time = priv->rx_usecs;
+               err = mlx4_en_set_cq_moder(priv, &priv->rx_cq[i]);
+               if (err)
+                       return err;
+       }
+       return 0;
+}
+
+static int mlx4_en_set_pauseparam(struct net_device *dev,
+                               struct ethtool_pauseparam *pause)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       int err;
+
+       mdev->profile.tx_pause = pause->tx_pause != 0;
+       mdev->profile.rx_pause = pause->rx_pause != 0;
+       err = mlx4_SET_PORT_general(mdev->dev, priv->port,
+                                   priv->rx_skb_size + ETH_FCS_LEN,
+                                   mdev->profile.tx_pause,
+                                   mdev->profile.tx_ppp,
+                                   mdev->profile.rx_pause,
+                                   mdev->profile.rx_ppp);
+       if (err)
+               mlx4_err(mdev, "Failed setting pause params to\n");
+
+       return err;
+}
+
+static void mlx4_en_get_pauseparam(struct net_device *dev,
+                                struct ethtool_pauseparam *pause)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+
+       pause->tx_pause = mdev->profile.tx_pause;
+       pause->rx_pause = mdev->profile.rx_pause;
+}
+
+static void mlx4_en_get_ringparam(struct net_device *dev,
+                                 struct ethtool_ringparam *param)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+
+       memset(param, 0, sizeof(*param));
+       param->rx_max_pending = mdev->dev->caps.max_rq_sg;
+       param->tx_max_pending = mdev->dev->caps.max_sq_sg;
+       param->rx_pending = mdev->profile.prof[priv->port].rx_ring_size;
+       param->tx_pending = mdev->profile.prof[priv->port].tx_ring_size;
+}
+
+const struct ethtool_ops mlx4_en_ethtool_ops = {
+       .get_drvinfo = mlx4_en_get_drvinfo,
+       .get_settings = mlx4_en_get_settings,
+       .set_settings = mlx4_en_set_settings,
+#ifdef NETIF_F_TSO
+       .get_tso = mlx4_en_get_tso,
+       .set_tso = mlx4_en_set_tso,
+#endif
+       .get_sg = ethtool_op_get_sg,
+       .set_sg = ethtool_op_set_sg,
+       .get_link = ethtool_op_get_link,
+       .get_rx_csum = mlx4_en_get_rx_csum,
+       .set_rx_csum = mlx4_en_set_rx_csum,
+       .get_tx_csum = ethtool_op_get_tx_csum,
+       .set_tx_csum = ethtool_op_set_tx_ipv6_csum,
+       .get_strings = mlx4_en_get_strings,
+       .get_sset_count = mlx4_en_get_sset_count,
+       .get_ethtool_stats = mlx4_en_get_ethtool_stats,
+       .get_wol = mlx4_en_get_wol,
+       .get_msglevel = mlx4_en_get_msglevel,
+       .set_msglevel = mlx4_en_set_msglevel,
+       .get_coalesce = mlx4_en_get_coalesce,
+       .set_coalesce = mlx4_en_set_coalesce,
+       .get_pauseparam = mlx4_en_get_pauseparam,
+       .set_pauseparam = mlx4_en_set_pauseparam,
+       .get_ringparam = mlx4_en_get_ringparam,
+       .get_flags = ethtool_op_get_flags,
+       .set_flags = ethtool_op_set_flags,
+};
+
+
+
+
+
diff --git a/drivers/net/mlx4/en_port.c b/drivers/net/mlx4/en_port.c
new file mode 100644 (file)
index 0000000..c5a4c03
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2007 Mellanox Technologies. 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/if_vlan.h>
+
+#include <linux/mlx4/device.h>
+#include <linux/mlx4/cmd.h>
+
+#include "en_port.h"
+#include "mlx4_en.h"
+
+
+int mlx4_SET_MCAST_FLTR(struct mlx4_dev *dev, u8 port,
+                       u64 mac, u64 clear, u8 mode)
+{
+       return mlx4_cmd(dev, (mac | (clear << 63)), port, mode,
+                       MLX4_CMD_SET_MCAST_FLTR, MLX4_CMD_TIME_CLASS_B);
+}
+
+int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, u8 port, struct vlan_group *grp)
+{
+       struct mlx4_cmd_mailbox *mailbox;
+       struct mlx4_set_vlan_fltr_mbox *filter;
+       int i;
+       int j;
+       int index = 0;
+       u32 entry;
+       int err = 0;
+
+       mailbox = mlx4_alloc_cmd_mailbox(dev);
+       if (IS_ERR(mailbox))
+               return PTR_ERR(mailbox);
+
+       filter = mailbox->buf;
+       if (grp) {
+               memset(filter, 0, sizeof *filter);
+               for (i = VLAN_FLTR_SIZE - 1; i >= 0; i--) {
+                       entry = 0;
+                       for (j = 0; j < 32; j++)
+                               if (vlan_group_get_device(grp, index++))
+                                       entry |= 1 << j;
+                       filter->entry[i] = cpu_to_be32(entry);
+               }
+       } else {
+               /* When no vlans are configured we block all vlans */
+               memset(filter, 0, sizeof(*filter));
+       }
+       err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_VLAN_FLTR,
+                      MLX4_CMD_TIME_CLASS_B);
+       mlx4_free_cmd_mailbox(dev, mailbox);
+       return err;
+}
+
+
+int mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu,
+                         u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx)
+{
+       struct mlx4_cmd_mailbox *mailbox;
+       struct mlx4_set_port_general_context *context;
+       int err;
+       u32 in_mod;
+
+       mailbox = mlx4_alloc_cmd_mailbox(dev);
+       if (IS_ERR(mailbox))
+               return PTR_ERR(mailbox);
+       context = mailbox->buf;
+       memset(context, 0, sizeof *context);
+
+       context->flags = SET_PORT_GEN_ALL_VALID;
+       context->mtu = cpu_to_be16(mtu);
+       context->pptx = (pptx * (!pfctx)) << 7;
+       context->pfctx = pfctx;
+       context->pprx = (pprx * (!pfcrx)) << 7;
+       context->pfcrx = pfcrx;
+
+       in_mod = MLX4_SET_PORT_GENERAL << 8 | port;
+       err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
+                      MLX4_CMD_TIME_CLASS_B);
+
+       mlx4_free_cmd_mailbox(dev, mailbox);
+       return err;
+}
+
+int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
+                          u8 promisc)
+{
+       struct mlx4_cmd_mailbox *mailbox;
+       struct mlx4_set_port_rqp_calc_context *context;
+       int err;
+       u32 in_mod;
+
+       mailbox = mlx4_alloc_cmd_mailbox(dev);
+       if (IS_ERR(mailbox))
+               return PTR_ERR(mailbox);
+       context = mailbox->buf;
+       memset(context, 0, sizeof *context);
+
+       context->base_qpn = cpu_to_be32(base_qpn);
+       context->promisc = cpu_to_be32(promisc << SET_PORT_PROMISC_SHIFT | base_qpn);
+       context->mcast = cpu_to_be32(1 << SET_PORT_PROMISC_SHIFT | base_qpn);
+       context->intra_no_vlan = 0;
+       context->no_vlan = MLX4_NO_VLAN_IDX;
+       context->intra_vlan_miss = 0;
+       context->vlan_miss = MLX4_VLAN_MISS_IDX;
+
+       in_mod = MLX4_SET_PORT_RQP_CALC << 8 | port;
+       err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
+                      MLX4_CMD_TIME_CLASS_B);
+
+       mlx4_free_cmd_mailbox(dev, mailbox);
+       return err;
+}
+
+
+int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
+{
+       struct mlx4_en_stat_out_mbox *mlx4_en_stats;
+       struct mlx4_en_priv *priv = netdev_priv(mdev->pndev[port]);
+       struct net_device_stats *stats = &priv->stats;
+       struct mlx4_cmd_mailbox *mailbox;
+       u64 in_mod = reset << 8 | port;
+       int err;
+
+       mailbox = mlx4_alloc_cmd_mailbox(mdev->dev);
+       if (IS_ERR(mailbox))
+               return PTR_ERR(mailbox);
+       memset(mailbox->buf, 0, sizeof(*mlx4_en_stats));
+       err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma, in_mod, 0,
+                          MLX4_CMD_DUMP_ETH_STATS, MLX4_CMD_TIME_CLASS_B);
+       if (err)
+               goto out;
+
+       mlx4_en_stats = mailbox->buf;
+
+       spin_lock_bh(&priv->stats_lock);
+
+       stats->rx_packets = be32_to_cpu(mlx4_en_stats->RTOTFRMS) -
+                           be32_to_cpu(mlx4_en_stats->RDROP);
+       stats->tx_packets = be64_to_cpu(mlx4_en_stats->TTOT_prio_0) +
+                           be64_to_cpu(mlx4_en_stats->TTOT_prio_1) +
+                           be64_to_cpu(mlx4_en_stats->TTOT_prio_2) +
+                           be64_to_cpu(mlx4_en_stats->TTOT_prio_3) +
+                           be64_to_cpu(mlx4_en_stats->TTOT_prio_4) +
+                           be64_to_cpu(mlx4_en_stats->TTOT_prio_5) +
+                           be64_to_cpu(mlx4_en_stats->TTOT_prio_6) +
+                           be64_to_cpu(mlx4_en_stats->TTOT_prio_7) +
+                           be64_to_cpu(mlx4_en_stats->TTOT_novlan) +
+                           be64_to_cpu(mlx4_en_stats->TTOT_loopbk);
+       stats->rx_bytes = be64_to_cpu(mlx4_en_stats->ROCT_prio_0) +
+                         be64_to_cpu(mlx4_en_stats->ROCT_prio_1) +
+                         be64_to_cpu(mlx4_en_stats->ROCT_prio_2) +
+                         be64_to_cpu(mlx4_en_stats->ROCT_prio_3) +
+                         be64_to_cpu(mlx4_en_stats->ROCT_prio_4) +
+                         be64_to_cpu(mlx4_en_stats->ROCT_prio_5) +
+                         be64_to_cpu(mlx4_en_stats->ROCT_prio_6) +
+                         be64_to_cpu(mlx4_en_stats->ROCT_prio_7) +
+                         be64_to_cpu(mlx4_en_stats->ROCT_novlan);
+
+       stats->tx_bytes = be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_0) +
+                         be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_1) +
+                         be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_2) +
+                         be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_3) +
+                         be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_4) +
+                         be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_5) +
+                         be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_6) +
+                         be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_7) +
+                         be64_to_cpu(mlx4_en_stats->TTTLOCT_novlan) +
+                         be64_to_cpu(mlx4_en_stats->TTTLOCT_loopbk);
+
+       stats->rx_errors = be64_to_cpu(mlx4_en_stats->PCS) +
+                          be32_to_cpu(mlx4_en_stats->RdropLength) +
+                          be32_to_cpu(mlx4_en_stats->RJBBR) +
+                          be32_to_cpu(mlx4_en_stats->RCRC) +
+                          be32_to_cpu(mlx4_en_stats->RRUNT);
+       stats->tx_errors = be32_to_cpu(mlx4_en_stats->TDROP);
+       stats->multicast = be64_to_cpu(mlx4_en_stats->MCAST_prio_0) +
+                          be64_to_cpu(mlx4_en_stats->MCAST_prio_1) +
+                          be64_to_cpu(mlx4_en_stats->MCAST_prio_2) +
+                          be64_to_cpu(mlx4_en_stats->MCAST_prio_3) +
+                          be64_to_cpu(mlx4_en_stats->MCAST_prio_4) +
+                          be64_to_cpu(mlx4_en_stats->MCAST_prio_5) +
+                          be64_to_cpu(mlx4_en_stats->MCAST_prio_6) +
+                          be64_to_cpu(mlx4_en_stats->MCAST_prio_7) +
+                          be64_to_cpu(mlx4_en_stats->MCAST_novlan);
+       stats->collisions = 0;
+       stats->rx_length_errors = be32_to_cpu(mlx4_en_stats->RdropLength);
+       stats->rx_over_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw);
+       stats->rx_crc_errors = be32_to_cpu(mlx4_en_stats->RCRC);
+       stats->rx_frame_errors = 0;
+       stats->rx_fifo_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw);
+       stats->rx_missed_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw);
+       stats->tx_aborted_errors = 0;
+       stats->tx_carrier_errors = 0;
+       stats->tx_fifo_errors = 0;
+       stats->tx_heartbeat_errors = 0;
+       stats->tx_window_errors = 0;
+
+       priv->pkstats.broadcast =
+                               be64_to_cpu(mlx4_en_stats->RBCAST_prio_0) +
+                               be64_to_cpu(mlx4_en_stats->RBCAST_prio_1) +
+                               be64_to_cpu(mlx4_en_stats->RBCAST_prio_2) +
+                               be64_to_cpu(mlx4_en_stats->RBCAST_prio_3) +
+                               be64_to_cpu(mlx4_en_stats->RBCAST_prio_4) +
+                               be64_to_cpu(mlx4_en_stats->RBCAST_prio_5) +
+                               be64_to_cpu(mlx4_en_stats->RBCAST_prio_6) +
+                               be64_to_cpu(mlx4_en_stats->RBCAST_prio_7) +
+                               be64_to_cpu(mlx4_en_stats->RBCAST_novlan);
+       priv->pkstats.rx_prio[0] = be64_to_cpu(mlx4_en_stats->RTOT_prio_0);
+       priv->pkstats.rx_prio[1] = be64_to_cpu(mlx4_en_stats->RTOT_prio_1);
+       priv->pkstats.rx_prio[2] = be64_to_cpu(mlx4_en_stats->RTOT_prio_2);
+       priv->pkstats.rx_prio[3] = be64_to_cpu(mlx4_en_stats->RTOT_prio_3);
+       priv->pkstats.rx_prio[4] = be64_to_cpu(mlx4_en_stats->RTOT_prio_4);
+       priv->pkstats.rx_prio[5] = be64_to_cpu(mlx4_en_stats->RTOT_prio_5);
+       priv->pkstats.rx_prio[6] = be64_to_cpu(mlx4_en_stats->RTOT_prio_6);
+       priv->pkstats.rx_prio[7] = be64_to_cpu(mlx4_en_stats->RTOT_prio_7);
+       priv->pkstats.tx_prio[0] = be64_to_cpu(mlx4_en_stats->TTOT_prio_0);
+       priv->pkstats.tx_prio[1] = be64_to_cpu(mlx4_en_stats->TTOT_prio_1);
+       priv->pkstats.tx_prio[2] = be64_to_cpu(mlx4_en_stats->TTOT_prio_2);
+       priv->pkstats.tx_prio[3] = be64_to_cpu(mlx4_en_stats->TTOT_prio_3);
+       priv->pkstats.tx_prio[4] = be64_to_cpu(mlx4_en_stats->TTOT_prio_4);
+       priv->pkstats.tx_prio[5] = be64_to_cpu(mlx4_en_stats->TTOT_prio_5);
+       priv->pkstats.tx_prio[6] = be64_to_cpu(mlx4_en_stats->TTOT_prio_6);
+       priv->pkstats.tx_prio[7] = be64_to_cpu(mlx4_en_stats->TTOT_prio_7);
+       spin_unlock_bh(&priv->stats_lock);
+
+out:
+       mlx4_free_cmd_mailbox(mdev->dev, mailbox);
+       return err;
+}
+
diff --git a/drivers/net/mlx4/en_port.h b/drivers/net/mlx4/en_port.h
new file mode 100644 (file)
index 0000000..e6477f1
--- /dev/null
@@ -0,0 +1,570 @@
+/*
+ * Copyright (c) 2007 Mellanox Technologies. 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 _MLX4_EN_PORT_H_
+#define _MLX4_EN_PORT_H_
+
+
+#define SET_PORT_GEN_ALL_VALID 0x7
+#define SET_PORT_PROMISC_SHIFT 31
+
+enum {
+       MLX4_CMD_SET_VLAN_FLTR  = 0x47,
+       MLX4_CMD_SET_MCAST_FLTR = 0x48,
+       MLX4_CMD_DUMP_ETH_STATS = 0x49,
+};
+
+struct mlx4_set_port_general_context {
+       u8 reserved[3];
+       u8 flags;
+       u16 reserved2;
+       __be16 mtu;
+       u8 pptx;
+       u8 pfctx;
+       u16 reserved3;
+       u8 pprx;
+       u8 pfcrx;
+       u16 reserved4;
+};
+
+struct mlx4_set_port_rqp_calc_context {
+       __be32 base_qpn;
+       __be32 flags;
+       u8 reserved[3];
+       u8 mac_miss;
+       u8 intra_no_vlan;
+       u8 no_vlan;
+       u8 intra_vlan_miss;
+       u8 vlan_miss;
+       u8 reserved2[3];
+       u8 no_vlan_prio;
+       __be32 promisc;
+       __be32 mcast;
+};
+
+#define VLAN_FLTR_SIZE 128
+struct mlx4_set_vlan_fltr_mbox {
+       __be32 entry[VLAN_FLTR_SIZE];
+};
+
+
+enum {
+       MLX4_MCAST_CONFIG       = 0,
+       MLX4_MCAST_DISABLE      = 1,
+       MLX4_MCAST_ENABLE       = 2,
+};
+
+
+struct mlx4_en_stat_out_mbox {
+       /* Received frames with a length of 64 octets */
+       __be64 R64_prio_0;
+       __be64 R64_prio_1;
+       __be64 R64_prio_2;
+       __be64 R64_prio_3;
+       __be64 R64_prio_4;
+       __be64 R64_prio_5;
+       __be64 R64_prio_6;
+       __be64 R64_prio_7;
+       __be64 R64_novlan;
+       /* Received frames with a length of 127 octets */
+       __be64 R127_prio_0;
+       __be64 R127_prio_1;
+       __be64 R127_prio_2;
+       __be64 R127_prio_3;
+       __be64 R127_prio_4;
+       __be64 R127_prio_5;
+       __be64 R127_prio_6;
+       __be64 R127_prio_7;
+       __be64 R127_novlan;
+       /* Received frames with a length of 255 octets */
+       __be64 R255_prio_0;
+       __be64 R255_prio_1;
+       __be64 R255_prio_2;
+       __be64 R255_prio_3;
+       __be64 R255_prio_4;
+       __be64 R255_prio_5;
+       __be64 R255_prio_6;
+       __be64 R255_prio_7;
+       __be64 R255_novlan;
+       /* Received frames with a length of 511 octets */
+       __be64 R511_prio_0;
+       __be64 R511_prio_1;
+       __be64 R511_prio_2;
+       __be64 R511_prio_3;
+       __be64 R511_prio_4;
+       __be64 R511_prio_5;
+       __be64 R511_prio_6;
+       __be64 R511_prio_7;
+       __be64 R511_novlan;
+       /* Received frames with a length of 1023 octets */
+       __be64 R1023_prio_0;
+       __be64 R1023_prio_1;
+       __be64 R1023_prio_2;
+       __be64 R1023_prio_3;
+       __be64 R1023_prio_4;
+       __be64 R1023_prio_5;
+       __be64 R1023_prio_6;
+       __be64 R1023_prio_7;
+       __be64 R1023_novlan;
+       /* Received frames with a length of 1518 octets */
+       __be64 R1518_prio_0;
+       __be64 R1518_prio_1;
+       __be64 R1518_prio_2;
+       __be64 R1518_prio_3;
+       __be64 R1518_prio_4;
+       __be64 R1518_prio_5;
+       __be64 R1518_prio_6;
+       __be64 R1518_prio_7;
+       __be64 R1518_novlan;
+       /* Received frames with a length of 1522 octets */
+       __be64 R1522_prio_0;
+       __be64 R1522_prio_1;
+       __be64 R1522_prio_2;
+       __be64 R1522_prio_3;
+       __be64 R1522_prio_4;
+       __be64 R1522_prio_5;
+       __be64 R1522_prio_6;
+       __be64 R1522_prio_7;
+       __be64 R1522_novlan;
+       /* Received frames with a length of 1548 octets */
+       __be64 R1548_prio_0;
+       __be64 R1548_prio_1;
+       __be64 R1548_prio_2;
+       __be64 R1548_prio_3;
+       __be64 R1548_prio_4;
+       __be64 R1548_prio_5;
+       __be64 R1548_prio_6;
+       __be64 R1548_prio_7;
+       __be64 R1548_novlan;
+       /* Received frames with a length of 1548 < octets < MTU */
+       __be64 R2MTU_prio_0;
+       __be64 R2MTU_prio_1;
+       __be64 R2MTU_prio_2;
+       __be64 R2MTU_prio_3;
+       __be64 R2MTU_prio_4;
+       __be64 R2MTU_prio_5;
+       __be64 R2MTU_prio_6;
+       __be64 R2MTU_prio_7;
+       __be64 R2MTU_novlan;
+       /* Received frames with a length of MTU< octets and good CRC */
+       __be64 RGIANT_prio_0;
+       __be64 RGIANT_prio_1;
+       __be64 RGIANT_prio_2;
+       __be64 RGIANT_prio_3;
+       __be64 RGIANT_prio_4;
+       __be64 RGIANT_prio_5;
+       __be64 RGIANT_prio_6;
+       __be64 RGIANT_prio_7;
+       __be64 RGIANT_novlan;
+       /* Received broadcast frames with good CRC */
+       __be64 RBCAST_prio_0;
+       __be64 RBCAST_prio_1;
+       __be64 RBCAST_prio_2;
+       __be64 RBCAST_prio_3;
+       __be64 RBCAST_prio_4;
+       __be64 RBCAST_prio_5;
+       __be64 RBCAST_prio_6;
+       __be64 RBCAST_prio_7;
+       __be64 RBCAST_novlan;
+       /* Received multicast frames with good CRC */
+       __be64 MCAST_prio_0;
+       __be64 MCAST_prio_1;
+       __be64 MCAST_prio_2;
+       __be64 MCAST_prio_3;
+       __be64 MCAST_prio_4;
+       __be64 MCAST_prio_5;
+       __be64 MCAST_prio_6;
+       __be64 MCAST_prio_7;
+       __be64 MCAST_novlan;
+       /* Received unicast not short or GIANT frames with good CRC */
+       __be64 RTOTG_prio_0;
+       __be64 RTOTG_prio_1;
+       __be64 RTOTG_prio_2;
+       __be64 RTOTG_prio_3;
+       __be64 RTOTG_prio_4;
+       __be64 RTOTG_prio_5;
+       __be64 RTOTG_prio_6;
+       __be64 RTOTG_prio_7;
+       __be64 RTOTG_novlan;
+
+       /* Count of total octets of received frames, includes framing characters */
+       __be64 RTTLOCT_prio_0;
+       /* Count of total octets of received frames, not including framing
+          characters */
+       __be64 RTTLOCT_NOFRM_prio_0;
+       /* Count of Total number of octets received
+          (only for frames without errors) */
+       __be64 ROCT_prio_0;
+
+       __be64 RTTLOCT_prio_1;
+       __be64 RTTLOCT_NOFRM_prio_1;
+       __be64 ROCT_prio_1;
+
+       __be64 RTTLOCT_prio_2;
+       __be64 RTTLOCT_NOFRM_prio_2;
+       __be64 ROCT_prio_2;
+
+       __be64 RTTLOCT_prio_3;
+       __be64 RTTLOCT_NOFRM_prio_3;
+       __be64 ROCT_prio_3;
+
+       __be64 RTTLOCT_prio_4;
+       __be64 RTTLOCT_NOFRM_prio_4;
+       __be64 ROCT_prio_4;
+
+       __be64 RTTLOCT_prio_5;
+       __be64 RTTLOCT_NOFRM_prio_5;
+       __be64 ROCT_prio_5;
+
+       __be64 RTTLOCT_prio_6;
+       __be64 RTTLOCT_NOFRM_prio_6;
+       __be64 ROCT_prio_6;
+
+       __be64 RTTLOCT_prio_7;
+       __be64 RTTLOCT_NOFRM_prio_7;
+       __be64 ROCT_prio_7;
+
+       __be64 RTTLOCT_novlan;
+       __be64 RTTLOCT_NOFRM_novlan;
+       __be64 ROCT_novlan;
+
+       /* Count of Total received frames including bad frames */
+       __be64 RTOT_prio_0;
+       /* Count of  Total number of received frames with 802.1Q encapsulation */
+       __be64 R1Q_prio_0;
+       __be64 reserved1;
+
+       __be64 RTOT_prio_1;
+       __be64 R1Q_prio_1;
+       __be64 reserved2;
+
+       __be64 RTOT_prio_2;
+       __be64 R1Q_prio_2;
+       __be64 reserved3;
+
+       __be64 RTOT_prio_3;
+       __be64 R1Q_prio_3;
+       __be64 reserved4;
+
+       __be64 RTOT_prio_4;
+       __be64 R1Q_prio_4;
+       __be64 reserved5;
+
+       __be64 RTOT_prio_5;
+       __be64 R1Q_prio_5;
+       __be64 reserved6;
+
+       __be64 RTOT_prio_6;
+       __be64 R1Q_prio_6;
+       __be64 reserved7;
+
+       __be64 RTOT_prio_7;
+       __be64 R1Q_prio_7;
+       __be64 reserved8;
+
+       __be64 RTOT_novlan;
+       __be64 R1Q_novlan;
+       __be64 reserved9;
+
+       /* Total number of Successfully Received Control Frames */
+       __be64 RCNTL;
+       __be64 reserved10;
+       __be64 reserved11;
+       __be64 reserved12;
+       /* Count of received frames with a length/type field  value between 46
+          (42 for VLANtagged frames) and 1500 (also 1500 for VLAN-tagged frames),
+          inclusive */
+       __be64 RInRangeLengthErr;
+       /* Count of received frames with length/type field between 1501 and 1535
+          decimal, inclusive */
+       __be64 ROutRangeLengthErr;
+       /* Count of received frames that are longer than max allowed size for
+          802.3 frames (1518/1522) */
+       __be64 RFrmTooLong;
+       /* Count frames received with PCS error */
+       __be64 PCS;
+
+       /* Transmit frames with a length of 64 octets */
+       __be64 T64_prio_0;
+       __be64 T64_prio_1;
+       __be64 T64_prio_2;
+       __be64 T64_prio_3;
+       __be64 T64_prio_4;
+       __be64 T64_prio_5;
+       __be64 T64_prio_6;
+       __be64 T64_prio_7;
+       __be64 T64_novlan;
+       __be64 T64_loopbk;
+       /* Transmit frames with a length of 65 to 127 octets. */
+       __be64 T127_prio_0;
+       __be64 T127_prio_1;
+       __be64 T127_prio_2;
+       __be64 T127_prio_3;
+       __be64 T127_prio_4;
+       __be64 T127_prio_5;
+       __be64 T127_prio_6;
+       __be64 T127_prio_7;
+       __be64 T127_novlan;
+       __be64 T127_loopbk;
+       /* Transmit frames with a length of 128 to 255 octets */
+       __be64 T255_prio_0;
+       __be64 T255_prio_1;
+       __be64 T255_prio_2;
+       __be64 T255_prio_3;
+       __be64 T255_prio_4;
+       __be64 T255_prio_5;
+       __be64 T255_prio_6;
+       __be64 T255_prio_7;
+       __be64 T255_novlan;
+       __be64 T255_loopbk;
+       /* Transmit frames with a length of 256 to 511 octets */
+       __be64 T511_prio_0;
+       __be64 T511_prio_1;
+       __be64 T511_prio_2;
+       __be64 T511_prio_3;
+       __be64 T511_prio_4;
+       __be64 T511_prio_5;
+       __be64 T511_prio_6;
+       __be64 T511_prio_7;
+       __be64 T511_novlan;
+       __be64 T511_loopbk;
+       /* Transmit frames with a length of 512 to 1023 octets */
+       __be64 T1023_prio_0;
+       __be64 T1023_prio_1;
+       __be64 T1023_prio_2;
+       __be64 T1023_prio_3;
+       __be64 T1023_prio_4;
+       __be64 T1023_prio_5;
+       __be64 T1023_prio_6;
+       __be64 T1023_prio_7;
+       __be64 T1023_novlan;
+       __be64 T1023_loopbk;
+       /* Transmit frames with a length of 1024 to 1518 octets */
+       __be64 T1518_prio_0;
+       __be64 T1518_prio_1;
+       __be64 T1518_prio_2;
+       __be64 T1518_prio_3;
+       __be64 T1518_prio_4;
+       __be64 T1518_prio_5;
+       __be64 T1518_prio_6;
+       __be64 T1518_prio_7;
+       __be64 T1518_novlan;
+       __be64 T1518_loopbk;
+       /* Counts transmit frames with a length of 1519 to 1522 bytes */
+       __be64 T1522_prio_0;
+       __be64 T1522_prio_1;
+       __be64 T1522_prio_2;
+       __be64 T1522_prio_3;
+       __be64 T1522_prio_4;
+       __be64 T1522_prio_5;
+       __be64 T1522_prio_6;
+       __be64 T1522_prio_7;
+       __be64 T1522_novlan;
+       __be64 T1522_loopbk;
+       /* Transmit frames with a length of 1523 to 1548 octets */
+       __be64 T1548_prio_0;
+       __be64 T1548_prio_1;
+       __be64 T1548_prio_2;
+       __be64 T1548_prio_3;
+       __be64 T1548_prio_4;
+       __be64 T1548_prio_5;
+       __be64 T1548_prio_6;
+       __be64 T1548_prio_7;
+       __be64 T1548_novlan;
+       __be64 T1548_loopbk;
+       /* Counts transmit frames with a length of 1549 to MTU bytes */
+       __be64 T2MTU_prio_0;
+       __be64 T2MTU_prio_1;
+       __be64 T2MTU_prio_2;
+       __be64 T2MTU_prio_3;
+       __be64 T2MTU_prio_4;
+       __be64 T2MTU_prio_5;
+       __be64 T2MTU_prio_6;
+       __be64 T2MTU_prio_7;
+       __be64 T2MTU_novlan;
+       __be64 T2MTU_loopbk;
+       /* Transmit frames with a length greater than MTU octets and a good CRC. */
+       __be64 TGIANT_prio_0;
+       __be64 TGIANT_prio_1;
+       __be64 TGIANT_prio_2;
+       __be64 TGIANT_prio_3;
+       __be64 TGIANT_prio_4;
+       __be64 TGIANT_prio_5;
+       __be64 TGIANT_prio_6;
+       __be64 TGIANT_prio_7;
+       __be64 TGIANT_novlan;
+       __be64 TGIANT_loopbk;
+       /* Transmit broadcast frames with a good CRC */
+       __be64 TBCAST_prio_0;
+       __be64 TBCAST_prio_1;
+       __be64 TBCAST_prio_2;
+       __be64 TBCAST_prio_3;
+       __be64 TBCAST_prio_4;
+       __be64 TBCAST_prio_5;
+       __be64 TBCAST_prio_6;
+       __be64 TBCAST_prio_7;
+       __be64 TBCAST_novlan;
+       __be64 TBCAST_loopbk;
+       /* Transmit multicast frames with a good CRC */
+       __be64 TMCAST_prio_0;
+       __be64 TMCAST_prio_1;
+       __be64 TMCAST_prio_2;
+       __be64 TMCAST_prio_3;
+       __be64 TMCAST_prio_4;
+       __be64 TMCAST_prio_5;
+       __be64 TMCAST_prio_6;
+       __be64 TMCAST_prio_7;
+       __be64 TMCAST_novlan;
+       __be64 TMCAST_loopbk;
+       /* Transmit good frames that are neither broadcast nor multicast */
+       __be64 TTOTG_prio_0;
+       __be64 TTOTG_prio_1;
+       __be64 TTOTG_prio_2;
+       __be64 TTOTG_prio_3;
+       __be64 TTOTG_prio_4;
+       __be64 TTOTG_prio_5;
+       __be64 TTOTG_prio_6;
+       __be64 TTOTG_prio_7;
+       __be64 TTOTG_novlan;
+       __be64 TTOTG_loopbk;
+
+       /* total octets of transmitted frames, including framing characters */
+       __be64 TTTLOCT_prio_0;
+       /* total octets of transmitted frames, not including framing characters */
+       __be64 TTTLOCT_NOFRM_prio_0;
+       /* ifOutOctets */
+       __be64 TOCT_prio_0;
+
+       __be64 TTTLOCT_prio_1;
+       __be64 TTTLOCT_NOFRM_prio_1;
+       __be64 TOCT_prio_1;
+
+       __be64 TTTLOCT_prio_2;
+       __be64 TTTLOCT_NOFRM_prio_2;
+       __be64 TOCT_prio_2;
+
+       __be64 TTTLOCT_prio_3;
+       __be64 TTTLOCT_NOFRM_prio_3;
+       __be64 TOCT_prio_3;
+
+       __be64 TTTLOCT_prio_4;
+       __be64 TTTLOCT_NOFRM_prio_4;
+       __be64 TOCT_prio_4;
+
+       __be64 TTTLOCT_prio_5;
+       __be64 TTTLOCT_NOFRM_prio_5;
+       __be64 TOCT_prio_5;
+
+       __be64 TTTLOCT_prio_6;
+       __be64 TTTLOCT_NOFRM_prio_6;
+       __be64 TOCT_prio_6;
+
+       __be64 TTTLOCT_prio_7;
+       __be64 TTTLOCT_NOFRM_prio_7;
+       __be64 TOCT_prio_7;
+
+       __be64 TTTLOCT_novlan;
+       __be64 TTTLOCT_NOFRM_novlan;
+       __be64 TOCT_novlan;
+
+       __be64 TTTLOCT_loopbk;
+       __be64 TTTLOCT_NOFRM_loopbk;
+       __be64 TOCT_loopbk;
+
+       /* Total frames transmitted with a good CRC that are not aborted  */
+       __be64 TTOT_prio_0;
+       /* Total number of frames transmitted with 802.1Q encapsulation */
+       __be64 T1Q_prio_0;
+       __be64 reserved13;
+
+       __be64 TTOT_prio_1;
+       __be64 T1Q_prio_1;
+       __be64 reserved14;
+
+       __be64 TTOT_prio_2;
+       __be64 T1Q_prio_2;
+       __be64 reserved15;
+
+       __be64 TTOT_prio_3;
+       __be64 T1Q_prio_3;
+       __be64 reserved16;
+
+       __be64 TTOT_prio_4;
+       __be64 T1Q_prio_4;
+       __be64 reserved17;
+
+       __be64 TTOT_prio_5;
+       __be64 T1Q_prio_5;
+       __be64 reserved18;
+
+       __be64 TTOT_prio_6;
+       __be64 T1Q_prio_6;
+       __be64 reserved19;
+
+       __be64 TTOT_prio_7;
+       __be64 T1Q_prio_7;
+       __be64 reserved20;
+
+       __be64 TTOT_novlan;
+       __be64 T1Q_novlan;
+       __be64 reserved21;
+
+       __be64 TTOT_loopbk;
+       __be64 T1Q_loopbk;
+       __be64 reserved22;
+
+       /* Received frames with a length greater than MTU octets and a bad CRC */
+       __be32 RJBBR;
+       /* Received frames with a bad CRC that are not runts, jabbers,
+          or alignment errors */
+       __be32 RCRC;
+       /* Received frames with SFD with a length of less than 64 octets and a
+          bad CRC */
+       __be32 RRUNT;
+       /* Received frames with a length less than 64 octets and a good CRC */
+       __be32 RSHORT;
+       /* Total Number of Received Packets Dropped */
+       __be32 RDROP;
+       /* Drop due to overflow  */
+       __be32 RdropOvflw;
+       /* Drop due to overflow */
+       __be32 RdropLength;
+       /* Total of good frames. Does not include frames received with
+          frame-too-long, FCS, or length errors */
+       __be32 RTOTFRMS;
+       /* Total dropped Xmited packets */
+       __be32 TDROP;
+};
+
+
+#endif
diff --git a/drivers/net/mlx4/en_resources.c b/drivers/net/mlx4/en_resources.c
new file mode 100644 (file)
index 0000000..a054520
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2007 Mellanox Technologies. 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/vmalloc.h>
+#include <linux/mlx4/qp.h>
+
+#include "mlx4_en.h"
+
+void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
+                            int is_tx, int rss, int qpn, int cqn, int srqn,
+                            struct mlx4_qp_context *context)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+
+       memset(context, 0, sizeof *context);
+       context->flags = cpu_to_be32(7 << 16 | rss << 13);
+       context->pd = cpu_to_be32(mdev->priv_pdn);
+       context->mtu_msgmax = 0xff;
+       context->rq_size_stride = 0;
+       if (is_tx)
+               context->sq_size_stride = ilog2(size) << 3 | (ilog2(stride) - 4);
+       else
+               context->sq_size_stride = 1;
+       context->usr_page = cpu_to_be32(mdev->priv_uar.index);
+       context->local_qpn = cpu_to_be32(qpn);
+       context->pri_path.ackto = 1 & 0x07;
+       context->pri_path.sched_queue = 0x83 | (priv->port - 1) << 6;
+       context->pri_path.counter_index = 0xff;
+       context->cqn_send = cpu_to_be32(cqn);
+       context->cqn_recv = cpu_to_be32(cqn);
+       context->db_rec_addr = cpu_to_be64(priv->res.db.dma << 2);
+       if (!rss)
+               context->srqn = cpu_to_be32(MLX4_EN_USE_SRQ | srqn);
+}
+
+
+int mlx4_en_map_buffer(struct mlx4_buf *buf)
+{
+       struct page **pages;
+       int i;
+
+       if (BITS_PER_LONG == 64 || buf->nbufs == 1)
+               return 0;
+
+       pages = kmalloc(sizeof *pages * buf->nbufs, GFP_KERNEL);
+       if (!pages)
+               return -ENOMEM;
+
+       for (i = 0; i < buf->nbufs; ++i)
+               pages[i] = virt_to_page(buf->page_list[i].buf);
+
+       buf->direct.buf = vmap(pages, buf->nbufs, VM_MAP, PAGE_KERNEL);
+       kfree(pages);
+       if (!buf->direct.buf)
+               return -ENOMEM;
+
+       return 0;
+}
+
+void mlx4_en_unmap_buffer(struct mlx4_buf *buf)
+{
+       if (BITS_PER_LONG == 64 || buf->nbufs == 1)
+               return;
+
+       vunmap(buf->direct.buf);
+}
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
new file mode 100644 (file)
index 0000000..6232227
--- /dev/null
@@ -0,0 +1,1080 @@
+/*
+ * Copyright (c) 2007 Mellanox Technologies. 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/mlx4/cq.h>
+#include <linux/mlx4/qp.h>
+#include <linux/skbuff.h>
+#include <linux/if_ether.h>
+#include <linux/if_vlan.h>
+#include <linux/vmalloc.h>
+
+#include "mlx4_en.h"
+
+static void *get_wqe(struct mlx4_en_rx_ring *ring, int n)
+{
+       int offset = n << ring->srq.wqe_shift;
+       return ring->buf + offset;
+}
+
+static void mlx4_en_srq_event(struct mlx4_srq *srq, enum mlx4_event type)
+{
+       return;
+}
+
+static int mlx4_en_get_frag_header(struct skb_frag_struct *frags, void **mac_hdr,
+                                  void **ip_hdr, void **tcpudp_hdr,
+                                  u64 *hdr_flags, void *priv)
+{
+       *mac_hdr = page_address(frags->page) + frags->page_offset;
+       *ip_hdr = *mac_hdr + ETH_HLEN;
+       *tcpudp_hdr = (struct tcphdr *)(*ip_hdr + sizeof(struct iphdr));
+       *hdr_flags = LRO_IPV4 | LRO_TCP;
+
+       return 0;
+}
+
+static int mlx4_en_alloc_frag(struct mlx4_en_priv *priv,
+                             struct mlx4_en_rx_desc *rx_desc,
+                             struct skb_frag_struct *skb_frags,
+                             struct mlx4_en_rx_alloc *ring_alloc,
+                             int i)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct mlx4_en_frag_info *frag_info = &priv->frag_info[i];
+       struct mlx4_en_rx_alloc *page_alloc = &ring_alloc[i];
+       struct page *page;
+       dma_addr_t dma;
+
+       if (page_alloc->offset == frag_info->last_offset) {
+               /* Allocate new page */
+               page = alloc_pages(GFP_ATOMIC | __GFP_COMP, MLX4_EN_ALLOC_ORDER);
+               if (!page)
+                       return -ENOMEM;
+
+               skb_frags[i].page = page_alloc->page;
+               skb_frags[i].page_offset = page_alloc->offset;
+               page_alloc->page = page;
+               page_alloc->offset = frag_info->frag_align;
+       } else {
+               page = page_alloc->page;
+               get_page(page);
+
+               skb_frags[i].page = page;
+               skb_frags[i].page_offset = page_alloc->offset;
+               page_alloc->offset += frag_info->frag_stride;
+       }
+       dma = pci_map_single(mdev->pdev, page_address(skb_frags[i].page) +
+                            skb_frags[i].page_offset, frag_info->frag_size,
+                            PCI_DMA_FROMDEVICE);
+       rx_desc->data[i].addr = cpu_to_be64(dma);
+       return 0;
+}
+
+static int mlx4_en_init_allocator(struct mlx4_en_priv *priv,
+                                 struct mlx4_en_rx_ring *ring)
+{
+       struct mlx4_en_rx_alloc *page_alloc;
+       int i;
+
+       for (i = 0; i < priv->num_frags; i++) {
+               page_alloc = &ring->page_alloc[i];
+               page_alloc->page = alloc_pages(GFP_ATOMIC | __GFP_COMP,
+                                              MLX4_EN_ALLOC_ORDER);
+               if (!page_alloc->page)
+                       goto out;
+
+               page_alloc->offset = priv->frag_info[i].frag_align;
+               mlx4_dbg(DRV, priv, "Initialized allocator:%d with page:%p\n",
+                        i, page_alloc->page);
+       }
+       return 0;
+
+out:
+       while (i--) {
+               page_alloc = &ring->page_alloc[i];
+               put_page(page_alloc->page);
+               page_alloc->page = NULL;
+       }
+       return -ENOMEM;
+}
+
+static void mlx4_en_destroy_allocator(struct mlx4_en_priv *priv,
+                                     struct mlx4_en_rx_ring *ring)
+{
+       struct mlx4_en_rx_alloc *page_alloc;
+       int i;
+
+       for (i = 0; i < priv->num_frags; i++) {
+               page_alloc = &ring->page_alloc[i];
+               mlx4_dbg(DRV, priv, "Freeing allocator:%d count:%d\n",
+                        i, page_count(page_alloc->page));
+
+               put_page(page_alloc->page);
+               page_alloc->page = NULL;
+       }
+}
+
+
+static void mlx4_en_init_rx_desc(struct mlx4_en_priv *priv,
+                                struct mlx4_en_rx_ring *ring, int index)
+{
+       struct mlx4_en_rx_desc *rx_desc = ring->buf + ring->stride * index;
+       struct skb_frag_struct *skb_frags = ring->rx_info +
+                                           (index << priv->log_rx_info);
+       int possible_frags;
+       int i;
+
+       /* Pre-link descriptor */
+       rx_desc->next.next_wqe_index = cpu_to_be16((index + 1) & ring->size_mask);
+
+       /* Set size and memtype fields */
+       for (i = 0; i < priv->num_frags; i++) {
+               skb_frags[i].size = priv->frag_info[i].frag_size;
+               rx_desc->data[i].byte_count =
+                       cpu_to_be32(priv->frag_info[i].frag_size);
+               rx_desc->data[i].lkey = cpu_to_be32(priv->mdev->mr.key);
+       }
+
+       /* If the number of used fragments does not fill up the ring stride,
+        * remaining (unused) fragments must be padded with null address/size
+        * and a special memory key */
+       possible_frags = (ring->stride - sizeof(struct mlx4_en_rx_desc)) / DS_SIZE;
+       for (i = priv->num_frags; i < possible_frags; i++) {
+               rx_desc->data[i].byte_count = 0;
+               rx_desc->data[i].lkey = cpu_to_be32(MLX4_EN_MEMTYPE_PAD);
+               rx_desc->data[i].addr = 0;
+       }
+}
+
+
+static int mlx4_en_prepare_rx_desc(struct mlx4_en_priv *priv,
+                                  struct mlx4_en_rx_ring *ring, int index)
+{
+       struct mlx4_en_rx_desc *rx_desc = ring->buf + (index * ring->stride);
+       struct skb_frag_struct *skb_frags = ring->rx_info +
+                                           (index << priv->log_rx_info);
+       int i;
+
+       for (i = 0; i < priv->num_frags; i++)
+               if (mlx4_en_alloc_frag(priv, rx_desc, skb_frags, ring->page_alloc, i))
+                       goto err;
+
+       return 0;
+
+err:
+       while (i--)
+               put_page(skb_frags[i].page);
+       return -ENOMEM;
+}
+
+static inline void mlx4_en_update_rx_prod_db(struct mlx4_en_rx_ring *ring)
+{
+       *ring->wqres.db.db = cpu_to_be32(ring->prod & 0xffff);
+}
+
+static int mlx4_en_fill_rx_buffers(struct mlx4_en_priv *priv)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct mlx4_en_rx_ring *ring;
+       int ring_ind;
+       int buf_ind;
+
+       for (buf_ind = 0; buf_ind < priv->prof->rx_ring_size; buf_ind++) {
+               for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) {
+                       ring = &priv->rx_ring[ring_ind];
+
+                       if (mlx4_en_prepare_rx_desc(priv, ring,
+                                                   ring->actual_size)) {
+                               if (ring->actual_size < MLX4_EN_MIN_RX_SIZE) {
+                                       mlx4_err(mdev, "Failed to allocate "
+                                                      "enough rx buffers\n");
+                                       return -ENOMEM;
+                               } else {
+                                       if (netif_msg_rx_err(priv))
+                                               mlx4_warn(mdev,
+                                                         "Only %d buffers allocated\n",
+                                                         ring->actual_size);
+                                       goto out;
+                               }
+                       }
+                       ring->actual_size++;
+                       ring->prod++;
+               }
+       }
+out:
+       return 0;
+}
+
+static int mlx4_en_fill_rx_buf(struct net_device *dev,
+                              struct mlx4_en_rx_ring *ring)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       int num = 0;
+       int err;
+
+       while ((u32) (ring->prod - ring->cons) < ring->actual_size) {
+               err = mlx4_en_prepare_rx_desc(priv, ring, ring->prod &
+                                             ring->size_mask);
+               if (err) {
+                       if (netif_msg_rx_err(priv))
+                               mlx4_warn(priv->mdev,
+                                         "Failed preparing rx descriptor\n");
+                       priv->port_stats.rx_alloc_failed++;
+                       break;
+               }
+               ++num;
+               ++ring->prod;
+       }
+       if ((u32) (ring->prod - ring->cons) == ring->size)
+               ring->full = 1;
+
+       return num;
+}
+
+static void mlx4_en_free_rx_buf(struct mlx4_en_priv *priv,
+                               struct mlx4_en_rx_ring *ring)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct skb_frag_struct *skb_frags;
+       struct mlx4_en_rx_desc *rx_desc;
+       dma_addr_t dma;
+       int index;
+       int nr;
+
+       mlx4_dbg(DRV, priv, "Freeing Rx buf - cons:%d prod:%d\n",
+                       ring->cons, ring->prod);
+
+       /* Unmap and free Rx buffers */
+       BUG_ON((u32) (ring->prod - ring->cons) > ring->size);
+       while (ring->cons != ring->prod) {
+               index = ring->cons & ring->size_mask;
+               rx_desc = ring->buf + (index << ring->log_stride);
+               skb_frags = ring->rx_info + (index << priv->log_rx_info);
+               mlx4_dbg(DRV, priv, "Processing descriptor:%d\n", index);
+
+               for (nr = 0; nr < priv->num_frags; nr++) {
+                       mlx4_dbg(DRV, priv, "Freeing fragment:%d\n", nr);
+                       dma = be64_to_cpu(rx_desc->data[nr].addr);
+
+                       mlx4_dbg(DRV, priv, "Unmaping buffer at dma:0x%llx\n", (u64) dma);
+                       pci_unmap_single(mdev->pdev, dma, skb_frags[nr].size,
+                                        PCI_DMA_FROMDEVICE);
+                       put_page(skb_frags[nr].page);
+               }
+               ++ring->cons;
+       }
+}
+
+
+void mlx4_en_rx_refill(struct work_struct *work)
+{
+       struct delayed_work *delay = container_of(work, struct delayed_work, work);
+       struct mlx4_en_priv *priv = container_of(delay, struct mlx4_en_priv,
+                                                refill_task);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct net_device *dev = priv->dev;
+       struct mlx4_en_rx_ring *ring;
+       int need_refill = 0;
+       int i;
+
+       mutex_lock(&mdev->state_lock);
+       if (!mdev->device_up || !priv->port_up)
+               goto out;
+
+       /* We only get here if there are no receive buffers, so we can't race
+        * with Rx interrupts while filling buffers */
+       for (i = 0; i < priv->rx_ring_num; i++) {
+               ring = &priv->rx_ring[i];
+               if (ring->need_refill) {
+                       if (mlx4_en_fill_rx_buf(dev, ring)) {
+                               ring->need_refill = 0;
+                               mlx4_en_update_rx_prod_db(ring);
+                       } else
+                               need_refill = 1;
+               }
+       }
+       if (need_refill)
+               queue_delayed_work(mdev->workqueue, &priv->refill_task, HZ);
+
+out:
+       mutex_unlock(&mdev->state_lock);
+}
+
+
+int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv,
+                          struct mlx4_en_rx_ring *ring, u32 size, u16 stride)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+       int err;
+       int tmp;
+
+       /* Sanity check SRQ size before proceeding */
+       if (size >= mdev->dev->caps.max_srq_wqes)
+               return -EINVAL;
+
+       ring->prod = 0;
+       ring->cons = 0;
+       ring->size = size;
+       ring->size_mask = size - 1;
+       ring->stride = stride;
+       ring->log_stride = ffs(ring->stride) - 1;
+       ring->buf_size = ring->size * ring->stride;
+
+       tmp = size * roundup_pow_of_two(MLX4_EN_MAX_RX_FRAGS *
+                                       sizeof(struct skb_frag_struct));
+       ring->rx_info = vmalloc(tmp);
+       if (!ring->rx_info) {
+               mlx4_err(mdev, "Failed allocating rx_info ring\n");
+               return -ENOMEM;
+       }
+       mlx4_dbg(DRV, priv, "Allocated rx_info ring at addr:%p size:%d\n",
+                ring->rx_info, tmp);
+
+       err = mlx4_alloc_hwq_res(mdev->dev, &ring->wqres,
+                                ring->buf_size, 2 * PAGE_SIZE);
+       if (err)
+               goto err_ring;
+
+       err = mlx4_en_map_buffer(&ring->wqres.buf);
+       if (err) {
+               mlx4_err(mdev, "Failed to map RX buffer\n");
+               goto err_hwq;
+       }
+       ring->buf = ring->wqres.buf.direct.buf;
+
+       /* Configure lro mngr */
+       memset(&ring->lro, 0, sizeof(struct net_lro_mgr));
+       ring->lro.dev = priv->dev;
+       ring->lro.features = LRO_F_NAPI;
+       ring->lro.frag_align_pad = NET_IP_ALIGN;
+       ring->lro.ip_summed = CHECKSUM_UNNECESSARY;
+       ring->lro.ip_summed_aggr = CHECKSUM_UNNECESSARY;
+       ring->lro.max_desc = mdev->profile.num_lro;
+       ring->lro.max_aggr = MAX_SKB_FRAGS;
+       ring->lro.lro_arr = kzalloc(mdev->profile.num_lro *
+                                   sizeof(struct net_lro_desc),
+                                   GFP_KERNEL);
+       if (!ring->lro.lro_arr) {
+               mlx4_err(mdev, "Failed to allocate lro array\n");
+               goto err_map;
+       }
+       ring->lro.get_frag_header = mlx4_en_get_frag_header;
+
+       return 0;
+
+err_map:
+       mlx4_en_unmap_buffer(&ring->wqres.buf);
+err_hwq:
+       mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size);
+err_ring:
+       vfree(ring->rx_info);
+       ring->rx_info = NULL;
+       return err;
+}
+
+int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct mlx4_wqe_srq_next_seg *next;
+       struct mlx4_en_rx_ring *ring;
+       int i;
+       int ring_ind;
+       int err;
+       int stride = roundup_pow_of_two(sizeof(struct mlx4_en_rx_desc) +
+                                       DS_SIZE * priv->num_frags);
+       int max_gs = (stride - sizeof(struct mlx4_wqe_srq_next_seg)) / DS_SIZE;
+
+       for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) {
+               ring = &priv->rx_ring[ring_ind];
+
+               ring->prod = 0;
+               ring->cons = 0;
+               ring->actual_size = 0;
+               ring->cqn = priv->rx_cq[ring_ind].mcq.cqn;
+
+               ring->stride = stride;
+               ring->log_stride = ffs(ring->stride) - 1;
+               ring->buf_size = ring->size * ring->stride;
+
+               memset(ring->buf, 0, ring->buf_size);
+               mlx4_en_update_rx_prod_db(ring);
+
+               /* Initailize all descriptors */
+               for (i = 0; i < ring->size; i++)
+                       mlx4_en_init_rx_desc(priv, ring, i);
+
+               /* Initialize page allocators */
+               err = mlx4_en_init_allocator(priv, ring);
+               if (err) {
+                        mlx4_err(mdev, "Failed initializing ring allocator\n");
+                        goto err_allocator;
+               }
+
+               /* Fill Rx buffers */
+               ring->full = 0;
+       }
+       if (mlx4_en_fill_rx_buffers(priv))
+               goto err_buffers;
+
+       for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) {
+               ring = &priv->rx_ring[ring_ind];
+
+               mlx4_en_update_rx_prod_db(ring);
+
+               /* Configure SRQ representing the ring */
+               ring->srq.max    = ring->size;
+               ring->srq.max_gs = max_gs;
+               ring->srq.wqe_shift = ilog2(ring->stride);
+
+               for (i = 0; i < ring->srq.max; ++i) {
+                       next = get_wqe(ring, i);
+                       next->next_wqe_index =
+                       cpu_to_be16((i + 1) & (ring->srq.max - 1));
+               }
+
+               err = mlx4_srq_alloc(mdev->dev, mdev->priv_pdn, &ring->wqres.mtt,
+                                    ring->wqres.db.dma, &ring->srq);
+               if (err){
+                       mlx4_err(mdev, "Failed to allocate srq\n");
+                       goto err_srq;
+               }
+               ring->srq.event = mlx4_en_srq_event;
+       }
+
+       return 0;
+
+err_srq:
+       while (ring_ind >= 0) {
+               ring = &priv->rx_ring[ring_ind];
+               mlx4_srq_free(mdev->dev, &ring->srq);
+               ring_ind--;
+       }
+
+err_buffers:
+       for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++)
+               mlx4_en_free_rx_buf(priv, &priv->rx_ring[ring_ind]);
+
+       ring_ind = priv->rx_ring_num - 1;
+err_allocator:
+       while (ring_ind >= 0) {
+               mlx4_en_destroy_allocator(priv, &priv->rx_ring[ring_ind]);
+               ring_ind--;
+       }
+       return err;
+}
+
+void mlx4_en_destroy_rx_ring(struct mlx4_en_priv *priv,
+                            struct mlx4_en_rx_ring *ring)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+
+       kfree(ring->lro.lro_arr);
+       mlx4_en_unmap_buffer(&ring->wqres.buf);
+       mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size);
+       vfree(ring->rx_info);
+       ring->rx_info = NULL;
+}
+
+void mlx4_en_deactivate_rx_ring(struct mlx4_en_priv *priv,
+                               struct mlx4_en_rx_ring *ring)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+
+       mlx4_srq_free(mdev->dev, &ring->srq);
+       mlx4_en_free_rx_buf(priv, ring);
+       mlx4_en_destroy_allocator(priv, ring);
+}
+
+
+/* Unmap a completed descriptor and free unused pages */
+static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
+                                   struct mlx4_en_rx_desc *rx_desc,
+                                   struct skb_frag_struct *skb_frags,
+                                   struct skb_frag_struct *skb_frags_rx,
+                                   struct mlx4_en_rx_alloc *page_alloc,
+                                   int length)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct mlx4_en_frag_info *frag_info;
+       int nr;
+       dma_addr_t dma;
+
+       /* Collect used fragments while replacing them in the HW descirptors */
+       for (nr = 0; nr < priv->num_frags; nr++) {
+               frag_info = &priv->frag_info[nr];
+               if (length <= frag_info->frag_prefix_size)
+                       break;
+
+               /* Save page reference in skb */
+               skb_frags_rx[nr].page = skb_frags[nr].page;
+               skb_frags_rx[nr].size = skb_frags[nr].size;
+               skb_frags_rx[nr].page_offset = skb_frags[nr].page_offset;
+               dma = be64_to_cpu(rx_desc->data[nr].addr);
+
+               /* Allocate a replacement page */
+               if (mlx4_en_alloc_frag(priv, rx_desc, skb_frags, page_alloc, nr))
+                       goto fail;
+
+               /* Unmap buffer */
+               pci_unmap_single(mdev->pdev, dma, skb_frags[nr].size,
+                                PCI_DMA_FROMDEVICE);
+       }
+       /* Adjust size of last fragment to match actual length */
+       skb_frags_rx[nr - 1].size = length -
+               priv->frag_info[nr - 1].frag_prefix_size;
+       return nr;
+
+fail:
+       /* Drop all accumulated fragments (which have already been replaced in
+        * the descriptor) of this packet; remaining fragments are reused... */
+       while (nr > 0) {
+               nr--;
+               put_page(skb_frags_rx[nr].page);
+       }
+       return 0;
+}
+
+
+static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv,
+                                     struct mlx4_en_rx_desc *rx_desc,
+                                     struct skb_frag_struct *skb_frags,
+                                     struct mlx4_en_rx_alloc *page_alloc,
+                                     unsigned int length)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct sk_buff *skb;
+       void *va;
+       int used_frags;
+       dma_addr_t dma;
+
+       skb = dev_alloc_skb(SMALL_PACKET_SIZE + NET_IP_ALIGN);
+       if (!skb) {
+               mlx4_dbg(RX_ERR, priv, "Failed allocating skb\n");
+               return NULL;
+       }
+       skb->dev = priv->dev;
+       skb_reserve(skb, NET_IP_ALIGN);
+       skb->len = length;
+       skb->truesize = length + sizeof(struct sk_buff);
+
+       /* Get pointer to first fragment so we could copy the headers into the
+        * (linear part of the) skb */
+       va = page_address(skb_frags[0].page) + skb_frags[0].page_offset;
+
+       if (length <= SMALL_PACKET_SIZE) {
+               /* We are copying all relevant data to the skb - temporarily
+                * synch buffers for the copy */
+               dma = be64_to_cpu(rx_desc->data[0].addr);
+               dma_sync_single_range_for_cpu(&mdev->pdev->dev, dma, 0,
+                                             length, DMA_FROM_DEVICE);
+               skb_copy_to_linear_data(skb, va, length);
+               dma_sync_single_range_for_device(&mdev->pdev->dev, dma, 0,
+                                                length, DMA_FROM_DEVICE);
+               skb->tail += length;
+       } else {
+
+               /* Move relevant fragments to skb */
+               used_frags = mlx4_en_complete_rx_desc(priv, rx_desc, skb_frags,
+                                                     skb_shinfo(skb)->frags,
+                                                     page_alloc, length);
+               skb_shinfo(skb)->nr_frags = used_frags;
+
+               /* Copy headers into the skb linear buffer */
+               memcpy(skb->data, va, HEADER_COPY_SIZE);
+               skb->tail += HEADER_COPY_SIZE;
+
+               /* Skip headers in first fragment */
+               skb_shinfo(skb)->frags[0].page_offset += HEADER_COPY_SIZE;
+
+               /* Adjust size of first fragment */
+               skb_shinfo(skb)->frags[0].size -= HEADER_COPY_SIZE;
+               skb->data_len = length - HEADER_COPY_SIZE;
+       }
+       return skb;
+}
+
+static void mlx4_en_copy_desc(struct mlx4_en_priv *priv,
+                             struct mlx4_en_rx_ring *ring,
+                             int from, int to, int num)
+{
+       struct skb_frag_struct *skb_frags_from;
+       struct skb_frag_struct *skb_frags_to;
+       struct mlx4_en_rx_desc *rx_desc_from;
+       struct mlx4_en_rx_desc *rx_desc_to;
+       int from_index, to_index;
+       int nr, i;
+
+       for (i = 0; i < num; i++) {
+               from_index = (from + i) & ring->size_mask;
+               to_index = (to + i) & ring->size_mask;
+               skb_frags_from = ring->rx_info + (from_index << priv->log_rx_info);
+               skb_frags_to = ring->rx_info + (to_index << priv->log_rx_info);
+               rx_desc_from = ring->buf + (from_index << ring->log_stride);
+               rx_desc_to = ring->buf + (to_index << ring->log_stride);
+
+               for (nr = 0; nr < priv->num_frags; nr++) {
+                       skb_frags_to[nr].page = skb_frags_from[nr].page;
+                       skb_frags_to[nr].page_offset = skb_frags_from[nr].page_offset;
+                       rx_desc_to->data[nr].addr = rx_desc_from->data[nr].addr;
+               }
+       }
+}
+
+
+int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int budget)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct mlx4_cqe *cqe;
+       struct mlx4_en_rx_ring *ring = &priv->rx_ring[cq->ring];
+       struct skb_frag_struct *skb_frags;
+       struct skb_frag_struct lro_frags[MLX4_EN_MAX_RX_FRAGS];
+       struct mlx4_en_rx_desc *rx_desc;
+       struct sk_buff *skb;
+       int index;
+       int nr;
+       unsigned int length;
+       int polled = 0;
+       int ip_summed;
+
+       if (!priv->port_up)
+               return 0;
+
+       /* We assume a 1:1 mapping between CQEs and Rx descriptors, so Rx
+        * descriptor offset can be deduced from the CQE index instead of
+        * reading 'cqe->index' */
+       index = cq->mcq.cons_index & ring->size_mask;
+       cqe = &cq->buf[index];
+
+       /* Process all completed CQEs */
+       while (XNOR(cqe->owner_sr_opcode & MLX4_CQE_OWNER_MASK,
+                   cq->mcq.cons_index & cq->size)) {
+
+               skb_frags = ring->rx_info + (index << priv->log_rx_info);
+               rx_desc = ring->buf + (index << ring->log_stride);
+
+               /*
+                * make sure we read the CQE after we read the ownership bit
+                */
+               rmb();
+
+               /* Drop packet on bad receive or bad checksum */
+               if (unlikely((cqe->owner_sr_opcode & MLX4_CQE_OPCODE_MASK) ==
+                                               MLX4_CQE_OPCODE_ERROR)) {
+                       mlx4_err(mdev, "CQE completed in error - vendor "
+                                 "syndrom:%d syndrom:%d\n",
+                                 ((struct mlx4_err_cqe *) cqe)->vendor_err_syndrome,
+                                 ((struct mlx4_err_cqe *) cqe)->syndrome);
+                       goto next;
+               }
+               if (unlikely(cqe->badfcs_enc & MLX4_CQE_BAD_FCS)) {
+                       mlx4_dbg(RX_ERR, priv, "Accepted frame with bad FCS\n");
+                       goto next;
+               }
+
+               /*
+                * Packet is OK - process it.
+                */
+               length = be32_to_cpu(cqe->byte_cnt);
+               ring->bytes += length;
+               ring->packets++;
+
+               if (likely(priv->rx_csum)) {
+                       if ((cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPOK)) &&
+                           (cqe->checksum == cpu_to_be16(0xffff))) {
+                               priv->port_stats.rx_chksum_good++;
+                               /* This packet is eligible for LRO if it is:
+                                * - DIX Ethernet (type interpretation)
+                                * - TCP/IP (v4)
+                                * - without IP options
+                                * - not an IP fragment */
+                               if (mlx4_en_can_lro(cqe->status) &&
+                                   dev->features & NETIF_F_LRO) {
+
+                                       nr = mlx4_en_complete_rx_desc(
+                                               priv, rx_desc,
+                                               skb_frags, lro_frags,
+                                               ring->page_alloc, length);
+                                       if (!nr)
+                                               goto next;
+
+                                       if (priv->vlgrp && (cqe->vlan_my_qpn &
+                                                           cpu_to_be32(MLX4_CQE_VLAN_PRESENT_MASK))) {
+                                               lro_vlan_hwaccel_receive_frags(
+                                                      &ring->lro, lro_frags,
+                                                      length, length,
+                                                      priv->vlgrp,
+                                                      be16_to_cpu(cqe->sl_vid),
+                                                      NULL, 0);
+                                       } else
+                                               lro_receive_frags(&ring->lro,
+                                                                 lro_frags,
+                                                                 length,
+                                                                 length,
+                                                                 NULL, 0);
+
+                                       goto next;
+                               }
+
+                               /* LRO not possible, complete processing here */
+                               ip_summed = CHECKSUM_UNNECESSARY;
+                               INC_PERF_COUNTER(priv->pstats.lro_misses);
+                       } else {
+                               ip_summed = CHECKSUM_NONE;
+                               priv->port_stats.rx_chksum_none++;
+                       }
+               } else {
+                       ip_summed = CHECKSUM_NONE;
+                       priv->port_stats.rx_chksum_none++;
+               }
+
+               skb = mlx4_en_rx_skb(priv, rx_desc, skb_frags,
+                                    ring->page_alloc, length);
+               if (!skb) {
+                       priv->stats.rx_dropped++;
+                       goto next;
+               }
+
+               skb->ip_summed = ip_summed;
+               skb->protocol = eth_type_trans(skb, dev);
+
+               /* Push it up the stack */
+               if (priv->vlgrp && (be32_to_cpu(cqe->vlan_my_qpn) &
+                                   MLX4_CQE_VLAN_PRESENT_MASK)) {
+                       vlan_hwaccel_receive_skb(skb, priv->vlgrp,
+                                               be16_to_cpu(cqe->sl_vid));
+               } else
+                       netif_receive_skb(skb);
+
+               dev->last_rx = jiffies;
+
+next:
+               ++cq->mcq.cons_index;
+               index = (cq->mcq.cons_index) & ring->size_mask;
+               cqe = &cq->buf[index];
+               if (++polled == budget) {
+                       /* We are here because we reached the NAPI budget -
+                        * flush only pending LRO sessions */
+                       lro_flush_all(&ring->lro);
+                       goto out;
+               }
+       }
+
+       /* If CQ is empty flush all LRO sessions unconditionally */
+       lro_flush_all(&ring->lro);
+
+out:
+       AVG_PERF_COUNTER(priv->pstats.rx_coal_avg, polled);
+       mlx4_cq_set_ci(&cq->mcq);
+       wmb(); /* ensure HW sees CQ consumer before we post new buffers */
+       ring->cons = cq->mcq.cons_index;
+       ring->prod += polled; /* Polled descriptors were realocated in place */
+       if (unlikely(!ring->full)) {
+               mlx4_en_copy_desc(priv, ring, ring->cons - polled,
+                                 ring->prod - polled, polled);
+               mlx4_en_fill_rx_buf(dev, ring);
+       }
+       mlx4_en_update_rx_prod_db(ring);
+       return polled;
+}
+
+
+void mlx4_en_rx_irq(struct mlx4_cq *mcq)
+{
+       struct mlx4_en_cq *cq = container_of(mcq, struct mlx4_en_cq, mcq);
+       struct mlx4_en_priv *priv = netdev_priv(cq->dev);
+
+       if (priv->port_up)
+               netif_rx_schedule(cq->dev, &cq->napi);
+       else
+               mlx4_en_arm_cq(priv, cq);
+}
+
+/* Rx CQ polling - called by NAPI */
+int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget)
+{
+       struct mlx4_en_cq *cq = container_of(napi, struct mlx4_en_cq, napi);
+       struct net_device *dev = cq->dev;
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       int done;
+
+       done = mlx4_en_process_rx_cq(dev, cq, budget);
+
+       /* If we used up all the quota - we're probably not done yet... */
+       if (done == budget)
+               INC_PERF_COUNTER(priv->pstats.napi_quota);
+       else {
+               /* Done for now */
+               netif_rx_complete(dev, napi);
+               mlx4_en_arm_cq(priv, cq);
+       }
+       return done;
+}
+
+
+/* Calculate the last offset position that accomodates a full fragment
+ * (assuming fagment size = stride-align) */
+static int mlx4_en_last_alloc_offset(struct mlx4_en_priv *priv, u16 stride, u16 align)
+{
+       u16 res = MLX4_EN_ALLOC_SIZE % stride;
+       u16 offset = MLX4_EN_ALLOC_SIZE - stride - res + align;
+
+       mlx4_dbg(DRV, priv, "Calculated last offset for stride:%d align:%d "
+                           "res:%d offset:%d\n", stride, align, res, offset);
+       return offset;
+}
+
+
+static int frag_sizes[] = {
+       FRAG_SZ0,
+       FRAG_SZ1,
+       FRAG_SZ2,
+       FRAG_SZ3
+};
+
+void mlx4_en_calc_rx_buf(struct net_device *dev)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       int eff_mtu = dev->mtu + ETH_HLEN + VLAN_HLEN + ETH_LLC_SNAP_SIZE;
+       int buf_size = 0;
+       int i = 0;
+
+       while (buf_size < eff_mtu) {
+               priv->frag_info[i].frag_size =
+                       (eff_mtu > buf_size + frag_sizes[i]) ?
+                               frag_sizes[i] : eff_mtu - buf_size;
+               priv->frag_info[i].frag_prefix_size = buf_size;
+               if (!i) {
+                       priv->frag_info[i].frag_align = NET_IP_ALIGN;
+                       priv->frag_info[i].frag_stride =
+                               ALIGN(frag_sizes[i] + NET_IP_ALIGN, SMP_CACHE_BYTES);
+               } else {
+                       priv->frag_info[i].frag_align = 0;
+                       priv->frag_info[i].frag_stride =
+                               ALIGN(frag_sizes[i], SMP_CACHE_BYTES);
+               }
+               priv->frag_info[i].last_offset = mlx4_en_last_alloc_offset(
+                                               priv, priv->frag_info[i].frag_stride,
+                                               priv->frag_info[i].frag_align);
+               buf_size += priv->frag_info[i].frag_size;
+               i++;
+       }
+
+       priv->num_frags = i;
+       priv->rx_skb_size = eff_mtu;
+       priv->log_rx_info = ROUNDUP_LOG2(i * sizeof(struct skb_frag_struct));
+
+       mlx4_dbg(DRV, priv, "Rx buffer scatter-list (effective-mtu:%d "
+                 "num_frags:%d):\n", eff_mtu, priv->num_frags);
+       for (i = 0; i < priv->num_frags; i++) {
+               mlx4_dbg(DRV, priv, "  frag:%d - size:%d prefix:%d align:%d "
+                               "stride:%d last_offset:%d\n", i,
+                               priv->frag_info[i].frag_size,
+                               priv->frag_info[i].frag_prefix_size,
+                               priv->frag_info[i].frag_align,
+                               priv->frag_info[i].frag_stride,
+                               priv->frag_info[i].last_offset);
+       }
+}
+
+/* RSS related functions */
+
+/* Calculate rss size and map each entry in rss table to rx ring */
+void mlx4_en_set_default_rss_map(struct mlx4_en_priv *priv,
+                                struct mlx4_en_rss_map *rss_map,
+                                int num_entries, int num_rings)
+{
+       int i;
+
+       rss_map->size = roundup_pow_of_two(num_entries);
+       mlx4_dbg(DRV, priv, "Setting default RSS map of %d entires\n",
+                rss_map->size);
+
+       for (i = 0; i < rss_map->size; i++) {
+               rss_map->map[i] = i % num_rings;
+               mlx4_dbg(DRV, priv, "Entry %d ---> ring %d\n", i, rss_map->map[i]);
+       }
+}
+
+static void mlx4_en_sqp_event(struct mlx4_qp *qp, enum mlx4_event event)
+{
+    return;
+}
+
+
+static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv,
+                                int qpn, int srqn, int cqn,
+                                enum mlx4_qp_state *state,
+                                struct mlx4_qp *qp)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct mlx4_qp_context *context;
+       int err = 0;
+
+       context = kmalloc(sizeof *context , GFP_KERNEL);
+       if (!context) {
+               mlx4_err(mdev, "Failed to allocate qp context\n");
+               return -ENOMEM;
+       }
+
+       err = mlx4_qp_alloc(mdev->dev, qpn, qp);
+       if (err) {
+               mlx4_err(mdev, "Failed to allocate qp #%d\n", qpn);
+               goto out;
+               return err;
+       }
+       qp->event = mlx4_en_sqp_event;
+
+       memset(context, 0, sizeof *context);
+       mlx4_en_fill_qp_context(priv, 0, 0, 0, 0, qpn, cqn, srqn, context);
+
+       err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, context, qp, state);
+       if (err) {
+               mlx4_qp_remove(mdev->dev, qp);
+               mlx4_qp_free(mdev->dev, qp);
+       }
+out:
+       kfree(context);
+       return err;
+}
+
+/* Allocate rx qp's and configure them according to rss map */
+int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct mlx4_en_rss_map *rss_map = &priv->rss_map;
+       struct mlx4_qp_context context;
+       struct mlx4_en_rss_context *rss_context;
+       void *ptr;
+       int rss_xor = mdev->profile.rss_xor;
+       u8 rss_mask = mdev->profile.rss_mask;
+       int i, srqn, qpn, cqn;
+       int err = 0;
+       int good_qps = 0;
+
+       mlx4_dbg(DRV, priv, "Configuring rss steering for port %u\n", priv->port);
+       err = mlx4_qp_reserve_range(mdev->dev, rss_map->size,
+                                   rss_map->size, &rss_map->base_qpn);
+       if (err) {
+               mlx4_err(mdev, "Failed reserving %d qps for port %u\n",
+                        rss_map->size, priv->port);
+               return err;
+       }
+
+       for (i = 0; i < rss_map->size; i++) {
+               cqn = priv->rx_ring[rss_map->map[i]].cqn;
+               srqn = priv->rx_ring[rss_map->map[i]].srq.srqn;
+               qpn = rss_map->base_qpn + i;
+               err = mlx4_en_config_rss_qp(priv, qpn, srqn, cqn,
+                                           &rss_map->state[i],
+                                           &rss_map->qps[i]);
+               if (err)
+                       goto rss_err;
+
+               ++good_qps;
+       }
+
+       /* Configure RSS indirection qp */
+       err = mlx4_qp_reserve_range(mdev->dev, 1, 1, &priv->base_qpn);
+       if (err) {
+               mlx4_err(mdev, "Failed to reserve range for RSS "
+                              "indirection qp\n");
+               goto rss_err;
+       }
+       err = mlx4_qp_alloc(mdev->dev, priv->base_qpn, &rss_map->indir_qp);
+       if (err) {
+               mlx4_err(mdev, "Failed to allocate RSS indirection QP\n");
+               goto reserve_err;
+       }
+       rss_map->indir_qp.event = mlx4_en_sqp_event;
+       mlx4_en_fill_qp_context(priv, 0, 0, 0, 1, priv->base_qpn,
+                               priv->rx_ring[0].cqn, 0, &context);
+
+       ptr = ((void *) &context) + 0x3c;
+       rss_context = (struct mlx4_en_rss_context *) ptr;
+       rss_context->base_qpn = cpu_to_be32(ilog2(rss_map->size) << 24 |
+                                           (rss_map->base_qpn));
+       rss_context->default_qpn = cpu_to_be32(rss_map->base_qpn);
+       rss_context->hash_fn = rss_xor & 0x3;
+       rss_context->flags = rss_mask << 2;
+
+       err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, &context,
+                              &rss_map->indir_qp, &rss_map->indir_state);
+       if (err)
+               goto indir_err;
+
+       return 0;
+
+indir_err:
+       mlx4_qp_modify(mdev->dev, NULL, rss_map->indir_state,
+                      MLX4_QP_STATE_RST, NULL, 0, 0, &rss_map->indir_qp);
+       mlx4_qp_remove(mdev->dev, &rss_map->indir_qp);
+       mlx4_qp_free(mdev->dev, &rss_map->indir_qp);
+reserve_err:
+       mlx4_qp_release_range(mdev->dev, priv->base_qpn, 1);
+rss_err:
+       for (i = 0; i < good_qps; i++) {
+               mlx4_qp_modify(mdev->dev, NULL, rss_map->state[i],
+                              MLX4_QP_STATE_RST, NULL, 0, 0, &rss_map->qps[i]);
+               mlx4_qp_remove(mdev->dev, &rss_map->qps[i]);
+               mlx4_qp_free(mdev->dev, &rss_map->qps[i]);
+       }
+       mlx4_qp_release_range(mdev->dev, rss_map->base_qpn, rss_map->size);
+       return err;
+}
+
+void mlx4_en_release_rss_steer(struct mlx4_en_priv *priv)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct mlx4_en_rss_map *rss_map = &priv->rss_map;
+       int i;
+
+       mlx4_qp_modify(mdev->dev, NULL, rss_map->indir_state,
+                      MLX4_QP_STATE_RST, NULL, 0, 0, &rss_map->indir_qp);
+       mlx4_qp_remove(mdev->dev, &rss_map->indir_qp);
+       mlx4_qp_free(mdev->dev, &rss_map->indir_qp);
+       mlx4_qp_release_range(mdev->dev, priv->base_qpn, 1);
+
+       for (i = 0; i < rss_map->size; i++) {
+               mlx4_qp_modify(mdev->dev, NULL, rss_map->state[i],
+                              MLX4_QP_STATE_RST, NULL, 0, 0, &rss_map->qps[i]);
+               mlx4_qp_remove(mdev->dev, &rss_map->qps[i]);
+               mlx4_qp_free(mdev->dev, &rss_map->qps[i]);
+       }
+       mlx4_qp_release_range(mdev->dev, rss_map->base_qpn, rss_map->size);
+}
+
+
+
+
+
diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c
new file mode 100644 (file)
index 0000000..8592f8f
--- /dev/null
@@ -0,0 +1,820 @@
+/*
+ * Copyright (c) 2007 Mellanox Technologies. 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 <asm/page.h>
+#include <linux/mlx4/cq.h>
+#include <linux/mlx4/qp.h>
+#include <linux/skbuff.h>
+#include <linux/if_vlan.h>
+#include <linux/vmalloc.h>
+
+#include "mlx4_en.h"
+
+enum {
+       MAX_INLINE = 104, /* 128 - 16 - 4 - 4 */
+};
+
+static int inline_thold __read_mostly = MAX_INLINE;
+
+module_param_named(inline_thold, inline_thold, int, 0444);
+MODULE_PARM_DESC(inline_thold, "treshold for using inline data");
+
+int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv,
+                          struct mlx4_en_tx_ring *ring, u32 size,
+                          u16 stride)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+       int tmp;
+       int err;
+
+       ring->size = size;
+       ring->size_mask = size - 1;
+       ring->stride = stride;
+
+       inline_thold = min(inline_thold, MAX_INLINE);
+
+       spin_lock_init(&ring->comp_lock);
+
+       tmp = size * sizeof(struct mlx4_en_tx_info);
+       ring->tx_info = vmalloc(tmp);
+       if (!ring->tx_info) {
+               mlx4_err(mdev, "Failed allocating tx_info ring\n");
+               return -ENOMEM;
+       }
+       mlx4_dbg(DRV, priv, "Allocated tx_info ring at addr:%p size:%d\n",
+                ring->tx_info, tmp);
+
+       ring->bounce_buf = kmalloc(MAX_DESC_SIZE, GFP_KERNEL);
+       if (!ring->bounce_buf) {
+               mlx4_err(mdev, "Failed allocating bounce buffer\n");
+               err = -ENOMEM;
+               goto err_tx;
+       }
+       ring->buf_size = ALIGN(size * ring->stride, MLX4_EN_PAGE_SIZE);
+
+       err = mlx4_alloc_hwq_res(mdev->dev, &ring->wqres, ring->buf_size,
+                                2 * PAGE_SIZE);
+       if (err) {
+               mlx4_err(mdev, "Failed allocating hwq resources\n");
+               goto err_bounce;
+       }
+
+       err = mlx4_en_map_buffer(&ring->wqres.buf);
+       if (err) {
+               mlx4_err(mdev, "Failed to map TX buffer\n");
+               goto err_hwq_res;
+       }
+
+       ring->buf = ring->wqres.buf.direct.buf;
+
+       mlx4_dbg(DRV, priv, "Allocated TX ring (addr:%p) - buf:%p size:%d "
+                "buf_size:%d dma:%llx\n", ring, ring->buf, ring->size,
+                ring->buf_size, (unsigned long long) ring->wqres.buf.direct.map);
+
+       err = mlx4_qp_reserve_range(mdev->dev, 1, 1, &ring->qpn);
+       if (err) {
+               mlx4_err(mdev, "Failed reserving qp for tx ring.\n");
+               goto err_map;
+       }
+
+       err = mlx4_qp_alloc(mdev->dev, ring->qpn, &ring->qp);
+       if (err) {
+               mlx4_err(mdev, "Failed allocating qp %d\n", ring->qpn);
+               goto err_reserve;
+       }
+
+       return 0;
+
+err_reserve:
+       mlx4_qp_release_range(mdev->dev, ring->qpn, 1);
+err_map:
+       mlx4_en_unmap_buffer(&ring->wqres.buf);
+err_hwq_res:
+       mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size);
+err_bounce:
+       kfree(ring->bounce_buf);
+       ring->bounce_buf = NULL;
+err_tx:
+       vfree(ring->tx_info);
+       ring->tx_info = NULL;
+       return err;
+}
+
+void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *priv,
+                            struct mlx4_en_tx_ring *ring)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+       mlx4_dbg(DRV, priv, "Destroying tx ring, qpn: %d\n", ring->qpn);
+
+       mlx4_qp_remove(mdev->dev, &ring->qp);
+       mlx4_qp_free(mdev->dev, &ring->qp);
+       mlx4_qp_release_range(mdev->dev, ring->qpn, 1);
+       mlx4_en_unmap_buffer(&ring->wqres.buf);
+       mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size);
+       kfree(ring->bounce_buf);
+       ring->bounce_buf = NULL;
+       vfree(ring->tx_info);
+       ring->tx_info = NULL;
+}
+
+int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv,
+                            struct mlx4_en_tx_ring *ring,
+                            int cq, int srqn)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+       int err;
+
+       ring->cqn = cq;
+       ring->prod = 0;
+       ring->cons = 0xffffffff;
+       ring->last_nr_txbb = 1;
+       ring->poll_cnt = 0;
+       ring->blocked = 0;
+       memset(ring->tx_info, 0, ring->size * sizeof(struct mlx4_en_tx_info));
+       memset(ring->buf, 0, ring->buf_size);
+
+       ring->qp_state = MLX4_QP_STATE_RST;
+       ring->doorbell_qpn = swab32(ring->qp.qpn << 8);
+
+       mlx4_en_fill_qp_context(priv, ring->size, ring->stride, 1, 0, ring->qpn,
+                               ring->cqn, srqn, &ring->context);
+
+       err = mlx4_qp_to_ready(mdev->dev, &ring->wqres.mtt, &ring->context,
+                              &ring->qp, &ring->qp_state);
+
+       return err;
+}
+
+void mlx4_en_deactivate_tx_ring(struct mlx4_en_priv *priv,
+                               struct mlx4_en_tx_ring *ring)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+
+       mlx4_qp_modify(mdev->dev, NULL, ring->qp_state,
+                      MLX4_QP_STATE_RST, NULL, 0, 0, &ring->qp);
+}
+
+
+static u32 mlx4_en_free_tx_desc(struct mlx4_en_priv *priv,
+                               struct mlx4_en_tx_ring *ring,
+                               int index, u8 owner)
+{
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct mlx4_en_tx_info *tx_info = &ring->tx_info[index];
+       struct mlx4_en_tx_desc *tx_desc = ring->buf + index * TXBB_SIZE;
+       struct mlx4_wqe_data_seg *data = (void *) tx_desc + tx_info->data_offset;
+       struct sk_buff *skb = tx_info->skb;
+       struct skb_frag_struct *frag;
+       void *end = ring->buf + ring->buf_size;
+       int frags = skb_shinfo(skb)->nr_frags;
+       int i;
+       __be32 *ptr = (__be32 *)tx_desc;
+       __be32 stamp = cpu_to_be32(STAMP_VAL | (!!owner << STAMP_SHIFT));
+
+       /* Optimize the common case when there are no wraparounds */
+       if (likely((void *) tx_desc + tx_info->nr_txbb * TXBB_SIZE <= end)) {
+               if (tx_info->linear) {
+                       pci_unmap_single(mdev->pdev,
+                                        (dma_addr_t) be64_to_cpu(data->addr),
+                                        be32_to_cpu(data->byte_count),
+                                        PCI_DMA_TODEVICE);
+                       ++data;
+               }
+
+               for (i = 0; i < frags; i++) {
+                       frag = &skb_shinfo(skb)->frags[i];
+                       pci_unmap_page(mdev->pdev,
+                                      (dma_addr_t) be64_to_cpu(data[i].addr),
+                                      frag->size, PCI_DMA_TODEVICE);
+               }
+               /* Stamp the freed descriptor */
+               for (i = 0; i < tx_info->nr_txbb * TXBB_SIZE; i += STAMP_STRIDE) {
+                       *ptr = stamp;
+                       ptr += STAMP_DWORDS;
+               }
+
+       } else {
+               if ((void *) data >= end) {
+                       data = (struct mlx4_wqe_data_seg *)
+                                       (ring->buf + ((void *) data - end));
+               }
+
+               if (tx_info->linear) {
+                       pci_unmap_single(mdev->pdev,
+                                        (dma_addr_t) be64_to_cpu(data->addr),
+                                        be32_to_cpu(data->byte_count),
+                                        PCI_DMA_TODEVICE);
+                       ++data;
+               }
+
+               for (i = 0; i < frags; i++) {
+                       /* Check for wraparound before unmapping */
+                       if ((void *) data >= end)
+                               data = (struct mlx4_wqe_data_seg *) ring->buf;
+                       frag = &skb_shinfo(skb)->frags[i];
+                       pci_unmap_page(mdev->pdev,
+                                       (dma_addr_t) be64_to_cpu(data->addr),
+                                        frag->size, PCI_DMA_TODEVICE);
+               }
+               /* Stamp the freed descriptor */
+               for (i = 0; i < tx_info->nr_txbb * TXBB_SIZE; i += STAMP_STRIDE) {
+                       *ptr = stamp;
+                       ptr += STAMP_DWORDS;
+                       if ((void *) ptr >= end) {
+                               ptr = ring->buf;
+                               stamp ^= cpu_to_be32(0x80000000);
+                       }
+               }
+
+       }
+       dev_kfree_skb_any(skb);
+       return tx_info->nr_txbb;
+}
+
+
+int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       int cnt = 0;
+
+       /* Skip last polled descriptor */
+       ring->cons += ring->last_nr_txbb;
+       mlx4_dbg(DRV, priv, "Freeing Tx buf - cons:0x%x prod:0x%x\n",
+                ring->cons, ring->prod);
+
+       if ((u32) (ring->prod - ring->cons) > ring->size) {
+               if (netif_msg_tx_err(priv))
+                       mlx4_warn(priv->mdev, "Tx consumer passed producer!\n");
+               return 0;
+       }
+
+       while (ring->cons != ring->prod) {
+               ring->last_nr_txbb = mlx4_en_free_tx_desc(priv, ring,
+                                               ring->cons & ring->size_mask,
+                                               !!(ring->cons & ring->size));
+               ring->cons += ring->last_nr_txbb;
+               cnt++;
+       }
+
+       if (cnt)
+               mlx4_dbg(DRV, priv, "Freed %d uncompleted tx descriptors\n", cnt);
+
+       return cnt;
+}
+
+void mlx4_en_set_prio_map(struct mlx4_en_priv *priv, u16 *prio_map, u32 ring_num)
+{
+       int block = 8 / ring_num;
+       int extra = 8 - (block * ring_num);
+       int num = 0;
+       u16 ring = 1;
+       int prio;
+
+       if (ring_num == 1) {
+               for (prio = 0; prio < 8; prio++)
+                       prio_map[prio] = 0;
+               return;
+       }
+
+       for (prio = 0; prio < 8; prio++) {
+               if (extra && (num == block + 1)) {
+                       ring++;
+                       num = 0;
+                       extra--;
+               } else if (!extra && (num == block)) {
+                       ring++;
+                       num = 0;
+               }
+               prio_map[prio] = ring;
+               mlx4_dbg(DRV, priv, " prio:%d --> ring:%d\n", prio, ring);
+               num++;
+       }
+}
+
+static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_cq *mcq = &cq->mcq;
+       struct mlx4_en_tx_ring *ring = &priv->tx_ring[cq->ring];
+       struct mlx4_cqe *cqe = cq->buf;
+       u16 index;
+       u16 new_index;
+       u32 txbbs_skipped = 0;
+       u32 cq_last_sav;
+
+       /* index always points to the first TXBB of the last polled descriptor */
+       index = ring->cons & ring->size_mask;
+       new_index = be16_to_cpu(cqe->wqe_index) & ring->size_mask;
+       if (index == new_index)
+               return;
+
+       if (!priv->port_up)
+               return;
+
+       /*
+        * We use a two-stage loop:
+        * - the first samples the HW-updated CQE
+        * - the second frees TXBBs until the last sample
+        * This lets us amortize CQE cache misses, while still polling the CQ
+        * until is quiescent.
+        */
+       cq_last_sav = mcq->cons_index;
+       do {
+               do {
+                       /* Skip over last polled CQE */
+                       index = (index + ring->last_nr_txbb) & ring->size_mask;
+                       txbbs_skipped += ring->last_nr_txbb;
+
+                       /* Poll next CQE */
+                       ring->last_nr_txbb = mlx4_en_free_tx_desc(
+                                               priv, ring, index,
+                                               !!((ring->cons + txbbs_skipped) &
+                                                  ring->size));
+                       ++mcq->cons_index;
+
+               } while (index != new_index);
+
+               new_index = be16_to_cpu(cqe->wqe_index) & ring->size_mask;
+       } while (index != new_index);
+       AVG_PERF_COUNTER(priv->pstats.tx_coal_avg,
+                        (u32) (mcq->cons_index - cq_last_sav));
+
+       /*
+        * To prevent CQ overflow we first update CQ consumer and only then
+        * the ring consumer.
+        */
+       mlx4_cq_set_ci(mcq);
+       wmb();
+       ring->cons += txbbs_skipped;
+
+       /* Wakeup Tx queue if this ring stopped it */
+       if (unlikely(ring->blocked)) {
+               if (((u32) (ring->prod - ring->cons) <=
+                    ring->size - HEADROOM - MAX_DESC_TXBBS) && !cq->armed) {
+
+                       /* TODO: support multiqueue netdevs. Currently, we block
+                        * when *any* ring is full. Note that:
+                        * - 2 Tx rings can unblock at the same time and call
+                        *   netif_wake_queue(), which is OK since this
+                        *   operation is idempotent.
+                        * - We might wake the queue just after another ring
+                        *   stopped it. This is no big deal because the next
+                        *   transmission on that ring would stop the queue.
+                        */
+                       ring->blocked = 0;
+                       netif_wake_queue(dev);
+                       priv->port_stats.wake_queue++;
+               }
+       }
+}
+
+void mlx4_en_tx_irq(struct mlx4_cq *mcq)
+{
+       struct mlx4_en_cq *cq = container_of(mcq, struct mlx4_en_cq, mcq);
+       struct mlx4_en_priv *priv = netdev_priv(cq->dev);
+       struct mlx4_en_tx_ring *ring = &priv->tx_ring[cq->ring];
+
+       spin_lock_irq(&ring->comp_lock);
+       cq->armed = 0;
+       mlx4_en_process_tx_cq(cq->dev, cq);
+       if (ring->blocked)
+               mlx4_en_arm_cq(priv, cq);
+       else
+               mod_timer(&cq->timer, jiffies + 1);
+       spin_unlock_irq(&ring->comp_lock);
+}
+
+
+void mlx4_en_poll_tx_cq(unsigned long data)
+{
+       struct mlx4_en_cq *cq = (struct mlx4_en_cq *) data;
+       struct mlx4_en_priv *priv = netdev_priv(cq->dev);
+       struct mlx4_en_tx_ring *ring = &priv->tx_ring[cq->ring];
+       u32 inflight;
+
+       INC_PERF_COUNTER(priv->pstats.tx_poll);
+
+       netif_tx_lock(priv->dev);
+       spin_lock_irq(&ring->comp_lock);
+       mlx4_en_process_tx_cq(cq->dev, cq);
+       inflight = (u32) (ring->prod - ring->cons - ring->last_nr_txbb);
+
+       /* If there are still packets in flight and the timer has not already
+        * been scheduled by the Tx routine then schedule it here to guarantee
+        * completion processing of these packets */
+       if (inflight && priv->port_up)
+               mod_timer(&cq->timer, jiffies + MLX4_EN_TX_POLL_TIMEOUT);
+
+       spin_unlock_irq(&ring->comp_lock);
+       netif_tx_unlock(priv->dev);
+}
+
+static struct mlx4_en_tx_desc *mlx4_en_bounce_to_desc(struct mlx4_en_priv *priv,
+                                                     struct mlx4_en_tx_ring *ring,
+                                                     u32 index,
+                                                     unsigned int desc_size)
+{
+       u32 copy = (ring->size - index) * TXBB_SIZE;
+       int i;
+
+       for (i = desc_size - copy - 4; i >= 0; i -= 4) {
+               if ((i & (TXBB_SIZE - 1)) == 0)
+                       wmb();
+
+               *((u32 *) (ring->buf + i)) =
+                       *((u32 *) (ring->bounce_buf + copy + i));
+       }
+
+       for (i = copy - 4; i >= 4 ; i -= 4) {
+               if ((i & (TXBB_SIZE - 1)) == 0)
+                       wmb();
+
+               *((u32 *) (ring->buf + index * TXBB_SIZE + i)) =
+                       *((u32 *) (ring->bounce_buf + i));
+       }
+
+       /* Return real descriptor location */
+       return ring->buf + index * TXBB_SIZE;
+}
+
+static inline void mlx4_en_xmit_poll(struct mlx4_en_priv *priv, int tx_ind)
+{
+       struct mlx4_en_cq *cq = &priv->tx_cq[tx_ind];
+       struct mlx4_en_tx_ring *ring = &priv->tx_ring[tx_ind];
+
+       /* If we don't have a pending timer, set one up to catch our recent
+          post in case the interface becomes idle */
+       if (!timer_pending(&cq->timer))
+               mod_timer(&cq->timer, jiffies + MLX4_EN_TX_POLL_TIMEOUT);
+
+       /* Poll the CQ every mlx4_en_TX_MODER_POLL packets */
+       if ((++ring->poll_cnt & (MLX4_EN_TX_POLL_MODER - 1)) == 0)
+               mlx4_en_process_tx_cq(priv->dev, cq);
+}
+
+static void *get_frag_ptr(struct sk_buff *skb)
+{
+       struct skb_frag_struct *frag =  &skb_shinfo(skb)->frags[0];
+       struct page *page = frag->page;
+       void *ptr;
+
+       ptr = page_address(page);
+       if (unlikely(!ptr))
+               return NULL;
+
+       return ptr + frag->page_offset;
+}
+
+static int is_inline(struct sk_buff *skb, void **pfrag)
+{
+       void *ptr;
+
+       if (inline_thold && !skb_is_gso(skb) && skb->len <= inline_thold) {
+               if (skb_shinfo(skb)->nr_frags == 1) {
+                       ptr = get_frag_ptr(skb);
+                       if (unlikely(!ptr))
+                               return 0;
+
+                       if (pfrag)
+                               *pfrag = ptr;
+
+                       return 1;
+               } else if (unlikely(skb_shinfo(skb)->nr_frags))
+                       return 0;
+               else
+                       return 1;
+       }
+
+       return 0;
+}
+
+static int inline_size(struct sk_buff *skb)
+{
+       if (skb->len + CTRL_SIZE + sizeof(struct mlx4_wqe_inline_seg)
+           <= MLX4_INLINE_ALIGN)
+               return ALIGN(skb->len + CTRL_SIZE +
+                            sizeof(struct mlx4_wqe_inline_seg), 16);
+       else
+               return ALIGN(skb->len + CTRL_SIZE + 2 *
+                            sizeof(struct mlx4_wqe_inline_seg), 16);
+}
+
+static int get_real_size(struct sk_buff *skb, struct net_device *dev,
+                        int *lso_header_size)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       int real_size;
+
+       if (skb_is_gso(skb)) {
+               *lso_header_size = skb_transport_offset(skb) + tcp_hdrlen(skb);
+               real_size = CTRL_SIZE + skb_shinfo(skb)->nr_frags * DS_SIZE +
+                       ALIGN(*lso_header_size + 4, DS_SIZE);
+               if (unlikely(*lso_header_size != skb_headlen(skb))) {
+                       /* We add a segment for the skb linear buffer only if
+                        * it contains data */
+                       if (*lso_header_size < skb_headlen(skb))
+                               real_size += DS_SIZE;
+                       else {
+                               if (netif_msg_tx_err(priv))
+                                       mlx4_warn(mdev, "Non-linear headers\n");
+                               dev_kfree_skb_any(skb);
+                               return 0;
+                       }
+               }
+               if (unlikely(*lso_header_size > MAX_LSO_HDR_SIZE)) {
+                       if (netif_msg_tx_err(priv))
+                               mlx4_warn(mdev, "LSO header size too big\n");
+                       dev_kfree_skb_any(skb);
+                       return 0;
+               }
+       } else {
+               *lso_header_size = 0;
+               if (!is_inline(skb, NULL))
+                       real_size = CTRL_SIZE + (skb_shinfo(skb)->nr_frags + 1) * DS_SIZE;
+               else
+                       real_size = inline_size(skb);
+       }
+
+       return real_size;
+}
+
+static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *skb,
+                            int real_size, u16 *vlan_tag, int tx_ind, void *fragptr)
+{
+       struct mlx4_wqe_inline_seg *inl = &tx_desc->inl;
+       int spc = MLX4_INLINE_ALIGN - CTRL_SIZE - sizeof *inl;
+
+       if (skb->len <= spc) {
+               inl->byte_count = cpu_to_be32(1 << 31 | skb->len);
+               skb_copy_from_linear_data(skb, inl + 1, skb_headlen(skb));
+               if (skb_shinfo(skb)->nr_frags)
+                       memcpy(((void *)(inl + 1)) + skb_headlen(skb), fragptr,
+                              skb_shinfo(skb)->frags[0].size);
+
+       } else {
+               inl->byte_count = cpu_to_be32(1 << 31 | spc);
+               if (skb_headlen(skb) <= spc) {
+                       skb_copy_from_linear_data(skb, inl + 1, skb_headlen(skb));
+                       if (skb_headlen(skb) < spc) {
+                               memcpy(((void *)(inl + 1)) + skb_headlen(skb),
+                                       fragptr, spc - skb_headlen(skb));
+                               fragptr +=  spc - skb_headlen(skb);
+                       }
+                       inl = (void *) (inl + 1) + spc;
+                       memcpy(((void *)(inl + 1)), fragptr, skb->len - spc);
+               } else {
+                       skb_copy_from_linear_data(skb, inl + 1, spc);
+                       inl = (void *) (inl + 1) + spc;
+                       skb_copy_from_linear_data_offset(skb, spc, inl + 1,
+                                       skb_headlen(skb) - spc);
+                       if (skb_shinfo(skb)->nr_frags)
+                               memcpy(((void *)(inl + 1)) + skb_headlen(skb) - spc,
+                                       fragptr, skb_shinfo(skb)->frags[0].size);
+               }
+
+               wmb();
+               inl->byte_count = cpu_to_be32(1 << 31 | (skb->len - spc));
+       }
+       tx_desc->ctrl.vlan_tag = cpu_to_be16(*vlan_tag);
+       tx_desc->ctrl.ins_vlan = MLX4_WQE_CTRL_INS_VLAN * !!(*vlan_tag);
+       tx_desc->ctrl.fence_size = (real_size / 16) & 0x3f;
+}
+
+static int get_vlan_info(struct mlx4_en_priv *priv, struct sk_buff *skb,
+                        u16 *vlan_tag)
+{
+       int tx_ind;
+
+       /* Obtain VLAN information if present */
+       if (priv->vlgrp && vlan_tx_tag_present(skb)) {
+               *vlan_tag = vlan_tx_tag_get(skb);
+               /* Set the Tx ring to use according to vlan priority */
+               tx_ind = priv->tx_prio_map[*vlan_tag >> 13];
+       } else {
+               *vlan_tag = 0;
+               tx_ind = 0;
+       }
+       return tx_ind;
+}
+
+int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct mlx4_en_tx_ring *ring;
+       struct mlx4_en_cq *cq;
+       struct mlx4_en_tx_desc *tx_desc;
+       struct mlx4_wqe_data_seg *data;
+       struct skb_frag_struct *frag;
+       struct mlx4_en_tx_info *tx_info;
+       int tx_ind = 0;
+       int nr_txbb;
+       int desc_size;
+       int real_size;
+       dma_addr_t dma;
+       u32 index;
+       __be32 op_own;
+       u16 vlan_tag;
+       int i;
+       int lso_header_size;
+       void *fragptr;
+
+       if (unlikely(!skb->len)) {
+               dev_kfree_skb_any(skb);
+               return NETDEV_TX_OK;
+       }
+       real_size = get_real_size(skb, dev, &lso_header_size);
+       if (unlikely(!real_size))
+               return NETDEV_TX_OK;
+
+       /* Allign descriptor to TXBB size */
+       desc_size = ALIGN(real_size, TXBB_SIZE);
+       nr_txbb = desc_size / TXBB_SIZE;
+       if (unlikely(nr_txbb > MAX_DESC_TXBBS)) {
+               if (netif_msg_tx_err(priv))
+                       mlx4_warn(mdev, "Oversized header or SG list\n");
+               dev_kfree_skb_any(skb);
+               return NETDEV_TX_OK;
+       }
+
+       tx_ind = get_vlan_info(priv, skb, &vlan_tag);
+       ring = &priv->tx_ring[tx_ind];
+
+       /* Check available TXBBs And 2K spare for prefetch */
+       if (unlikely(((int)(ring->prod - ring->cons)) >
+                    ring->size - HEADROOM - MAX_DESC_TXBBS)) {
+               /* every full Tx ring stops queue.
+                * TODO: implement multi-queue support (per-queue stop) */
+               netif_stop_queue(dev);
+               ring->blocked = 1;
+               priv->port_stats.queue_stopped++;
+
+               /* Use interrupts to find out when queue opened */
+               cq = &priv->tx_cq[tx_ind];
+               mlx4_en_arm_cq(priv, cq);
+               return NETDEV_TX_BUSY;
+       }
+
+       /* Now that we know what Tx ring to use */
+       if (unlikely(!priv->port_up)) {
+               if (netif_msg_tx_err(priv))
+                       mlx4_warn(mdev, "xmit: port down!\n");
+               dev_kfree_skb_any(skb);
+               return NETDEV_TX_OK;
+       }
+
+       /* Track current inflight packets for performance analysis */
+       AVG_PERF_COUNTER(priv->pstats.inflight_avg,
+                        (u32) (ring->prod - ring->cons - 1));
+
+       /* Packet is good - grab an index and transmit it */
+       index = ring->prod & ring->size_mask;
+
+       /* See if we have enough space for whole descriptor TXBB for setting
+        * SW ownership on next descriptor; if not, use a bounce buffer. */
+       if (likely(index + nr_txbb <= ring->size))
+               tx_desc = ring->buf + index * TXBB_SIZE;
+       else
+               tx_desc = (struct mlx4_en_tx_desc *) ring->bounce_buf;
+
+       /* Save skb in tx_info ring */
+       tx_info = &ring->tx_info[index];
+       tx_info->skb = skb;
+       tx_info->nr_txbb = nr_txbb;
+
+       /* Prepare ctrl segement apart opcode+ownership, which depends on
+        * whether LSO is used */
+       tx_desc->ctrl.vlan_tag = cpu_to_be16(vlan_tag);
+       tx_desc->ctrl.ins_vlan = MLX4_WQE_CTRL_INS_VLAN * !!vlan_tag;
+       tx_desc->ctrl.fence_size = (real_size / 16) & 0x3f;
+       tx_desc->ctrl.srcrb_flags = cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE |
+                                               MLX4_WQE_CTRL_SOLICITED);
+       if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
+               tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM |
+                                                        MLX4_WQE_CTRL_TCP_UDP_CSUM);
+               priv->port_stats.tx_chksum_offload++;
+       }
+
+       /* Handle LSO (TSO) packets */
+       if (lso_header_size) {
+               /* Mark opcode as LSO */
+               op_own = cpu_to_be32(MLX4_OPCODE_LSO | (1 << 6)) |
+                       ((ring->prod & ring->size) ?
+                               cpu_to_be32(MLX4_EN_BIT_DESC_OWN) : 0);
+
+               /* Fill in the LSO prefix */
+               tx_desc->lso.mss_hdr_size = cpu_to_be32(
+                       skb_shinfo(skb)->gso_size << 16 | lso_header_size);
+
+               /* Copy headers;
+                * note that we already verified that it is linear */
+               memcpy(tx_desc->lso.header, skb->data, lso_header_size);
+               data = ((void *) &tx_desc->lso +
+                       ALIGN(lso_header_size + 4, DS_SIZE));
+
+               priv->port_stats.tso_packets++;
+               i = ((skb->len - lso_header_size) / skb_shinfo(skb)->gso_size) +
+                       !!((skb->len - lso_header_size) % skb_shinfo(skb)->gso_size);
+               ring->bytes += skb->len + (i - 1) * lso_header_size;
+               ring->packets += i;
+       } else {
+               /* Normal (Non LSO) packet */
+               op_own = cpu_to_be32(MLX4_OPCODE_SEND) |
+                       ((ring->prod & ring->size) ?
+                        cpu_to_be32(MLX4_EN_BIT_DESC_OWN) : 0);
+               data = &tx_desc->data;
+               ring->bytes += max(skb->len, (unsigned int) ETH_ZLEN);
+               ring->packets++;
+
+       }
+       AVG_PERF_COUNTER(priv->pstats.tx_pktsz_avg, skb->len);
+
+
+       /* valid only for none inline segments */
+       tx_info->data_offset = (void *) data - (void *) tx_desc;
+
+       tx_info->linear = (lso_header_size < skb_headlen(skb) && !is_inline(skb, NULL)) ? 1 : 0;
+       data += skb_shinfo(skb)->nr_frags + tx_info->linear - 1;
+
+       if (!is_inline(skb, &fragptr)) {
+               /* Map fragments */
+               for (i = skb_shinfo(skb)->nr_frags - 1; i >= 0; i--) {
+                       frag = &skb_shinfo(skb)->frags[i];
+                       dma = pci_map_page(mdev->dev->pdev, frag->page, frag->page_offset,
+                                          frag->size, PCI_DMA_TODEVICE);
+                       data->addr = cpu_to_be64(dma);
+                       data->lkey = cpu_to_be32(mdev->mr.key);
+                       wmb();
+                       data->byte_count = cpu_to_be32(frag->size);
+                       --data;
+               }
+
+               /* Map linear part */
+               if (tx_info->linear) {
+                       dma = pci_map_single(mdev->dev->pdev, skb->data + lso_header_size,
+                                            skb_headlen(skb) - lso_header_size, PCI_DMA_TODEVICE);
+                       data->addr = cpu_to_be64(dma);
+                       data->lkey = cpu_to_be32(mdev->mr.key);
+                       wmb();
+                       data->byte_count = cpu_to_be32(skb_headlen(skb) - lso_header_size);
+               }
+       } else
+               build_inline_wqe(tx_desc, skb, real_size, &vlan_tag, tx_ind, fragptr);
+
+       ring->prod += nr_txbb;
+
+       /* If we used a bounce buffer then copy descriptor back into place */
+       if (tx_desc == (struct mlx4_en_tx_desc *) ring->bounce_buf)
+               tx_desc = mlx4_en_bounce_to_desc(priv, ring, index, desc_size);
+
+       /* Run destructor before passing skb to HW */
+       if (likely(!skb_shared(skb)))
+               skb_orphan(skb);
+
+       /* Ensure new descirptor hits memory
+        * before setting ownership of this descriptor to HW */
+       wmb();
+       tx_desc->ctrl.owner_opcode = op_own;
+
+       /* Ring doorbell! */
+       wmb();
+       writel(ring->doorbell_qpn, mdev->uar_map + MLX4_SEND_DOORBELL);
+       dev->trans_start = jiffies;
+
+       /* Poll CQ here */
+       mlx4_en_xmit_poll(priv, tx_ind);
+
+       return 0;
+}
+
index 8a8b56135a58bda015fac0a4b184b4e344072072..de169338cd901a448fffc668ea083b2c8d5498e7 100644 (file)
@@ -558,7 +558,7 @@ int mlx4_init_eq_table(struct mlx4_dev *dev)
        int i;
 
        err = mlx4_bitmap_init(&priv->eq_table.bitmap, dev->caps.num_eqs,
-                              dev->caps.num_eqs - 1, dev->caps.reserved_eqs);
+                              dev->caps.num_eqs - 1, dev->caps.reserved_eqs, 0);
        if (err)
                return err;
 
index 7e32955da9829afcc9b80c16f2a06bae1402af96..be09fdb79cb892c8dbf9842d0aee639fe33bfe3a 100644 (file)
@@ -88,6 +88,7 @@ static void dump_dev_cap_flags(struct mlx4_dev *dev, u32 flags)
                [ 8] = "P_Key violation counter",
                [ 9] = "Q_Key violation counter",
                [10] = "VMM",
+               [12] = "DPDP",
                [16] = "MW support",
                [17] = "APM support",
                [18] = "Atomic ops support",
@@ -346,7 +347,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
                        MLX4_GET(field, outbox, QUERY_DEV_CAP_VL_PORT_OFFSET);
                        dev_cap->max_vl[i]         = field >> 4;
                        MLX4_GET(field, outbox, QUERY_DEV_CAP_MTU_WIDTH_OFFSET);
-                       dev_cap->max_mtu[i]        = field >> 4;
+                       dev_cap->ib_mtu[i]         = field >> 4;
                        dev_cap->max_port_width[i] = field & 0xf;
                        MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_GID_OFFSET);
                        dev_cap->max_gids[i]       = 1 << (field & 0xf);
@@ -354,9 +355,13 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
                        dev_cap->max_pkeys[i]      = 1 << (field & 0xf);
                }
        } else {
+#define QUERY_PORT_SUPPORTED_TYPE_OFFSET       0x00
 #define QUERY_PORT_MTU_OFFSET                  0x01
+#define QUERY_PORT_ETH_MTU_OFFSET              0x02
 #define QUERY_PORT_WIDTH_OFFSET                        0x06
 #define QUERY_PORT_MAX_GID_PKEY_OFFSET         0x07
+#define QUERY_PORT_MAC_OFFSET                  0x08
+#define QUERY_PORT_MAX_MACVLAN_OFFSET          0x0a
 #define QUERY_PORT_MAX_VL_OFFSET               0x0b
 
                for (i = 1; i <= dev_cap->num_ports; ++i) {
@@ -365,8 +370,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
                        if (err)
                                goto out;
 
+                       MLX4_GET(field, outbox, QUERY_PORT_SUPPORTED_TYPE_OFFSET);
+                       dev_cap->supported_port_types[i] = field & 3;
                        MLX4_GET(field, outbox, QUERY_PORT_MTU_OFFSET);
-                       dev_cap->max_mtu[i]        = field & 0xf;
+                       dev_cap->ib_mtu[i]         = field & 0xf;
                        MLX4_GET(field, outbox, QUERY_PORT_WIDTH_OFFSET);
                        dev_cap->max_port_width[i] = field & 0xf;
                        MLX4_GET(field, outbox, QUERY_PORT_MAX_GID_PKEY_OFFSET);
@@ -374,6 +381,11 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
                        dev_cap->max_pkeys[i]      = 1 << (field & 0xf);
                        MLX4_GET(field, outbox, QUERY_PORT_MAX_VL_OFFSET);
                        dev_cap->max_vl[i]         = field & 0xf;
+                       MLX4_GET(field, outbox, QUERY_PORT_MAX_MACVLAN_OFFSET);
+                       dev_cap->log_max_macs[i]  = field & 0xf;
+                       dev_cap->log_max_vlans[i] = field >> 4;
+                       MLX4_GET(dev_cap->eth_mtu[i], outbox, QUERY_PORT_ETH_MTU_OFFSET);
+                       MLX4_GET(dev_cap->def_mac[i], outbox, QUERY_PORT_MAC_OFFSET);
                }
        }
 
@@ -407,7 +419,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
        mlx4_dbg(dev, "Max CQEs: %d, max WQEs: %d, max SRQ WQEs: %d\n",
                 dev_cap->max_cq_sz, dev_cap->max_qp_sz, dev_cap->max_srq_sz);
        mlx4_dbg(dev, "Local CA ACK delay: %d, max MTU: %d, port width cap: %d\n",
-                dev_cap->local_ca_ack_delay, 128 << dev_cap->max_mtu[1],
+                dev_cap->local_ca_ack_delay, 128 << dev_cap->ib_mtu[1],
                 dev_cap->max_port_width[1]);
        mlx4_dbg(dev, "Max SQ desc size: %d, max SQ S/G: %d\n",
                 dev_cap->max_sq_desc_sz, dev_cap->max_sq_sg);
@@ -819,7 +831,7 @@ int mlx4_INIT_PORT(struct mlx4_dev *dev, int port)
                flags |= (dev->caps.port_width_cap[port] & 0xf) << INIT_PORT_PORT_WIDTH_SHIFT;
                MLX4_PUT(inbox, flags,            INIT_PORT_FLAGS_OFFSET);
 
-               field = 128 << dev->caps.mtu_cap[port];
+               field = 128 << dev->caps.ib_mtu_cap[port];
                MLX4_PUT(inbox, field, INIT_PORT_MTU_OFFSET);
                field = dev->caps.gid_table_len[port];
                MLX4_PUT(inbox, field, INIT_PORT_MAX_GID_OFFSET);
index decbb5c2ad41b7379ddbe5b5ce8df81abc4243ca..526d7f30c041849da3b27077bbb8d9007222a5aa 100644 (file)
@@ -66,11 +66,13 @@ struct mlx4_dev_cap {
        int local_ca_ack_delay;
        int num_ports;
        u32 max_msg_sz;
-       int max_mtu[MLX4_MAX_PORTS + 1];
+       int ib_mtu[MLX4_MAX_PORTS + 1];
        int max_port_width[MLX4_MAX_PORTS + 1];
        int max_vl[MLX4_MAX_PORTS + 1];
        int max_gids[MLX4_MAX_PORTS + 1];
        int max_pkeys[MLX4_MAX_PORTS + 1];
+       u64 def_mac[MLX4_MAX_PORTS + 1];
+       u16 eth_mtu[MLX4_MAX_PORTS + 1];
        u16 stat_rate_support;
        u32 flags;
        int reserved_uars;
@@ -102,6 +104,9 @@ struct mlx4_dev_cap {
        u32 reserved_lkey;
        u64 max_icm_sz;
        int max_gso_sz;
+       u8  supported_port_types[MLX4_MAX_PORTS + 1];
+       u8  log_max_macs[MLX4_MAX_PORTS + 1];
+       u8  log_max_vlans[MLX4_MAX_PORTS + 1];
 };
 
 struct mlx4_adapter {
index 1252a919de2eb9bd43e8e3c92aa5792b47e81932..468921b8f4b68a047abdf2f247e4a1c3e0ed5d41 100644 (file)
@@ -85,6 +85,57 @@ static struct mlx4_profile default_profile = {
        .num_mtt        = 1 << 20,
 };
 
+static int log_num_mac = 2;
+module_param_named(log_num_mac, log_num_mac, int, 0444);
+MODULE_PARM_DESC(log_num_mac, "Log2 max number of MACs per ETH port (1-7)");
+
+static int log_num_vlan;
+module_param_named(log_num_vlan, log_num_vlan, int, 0444);
+MODULE_PARM_DESC(log_num_vlan, "Log2 max number of VLANs per ETH port (0-7)");
+
+static int use_prio;
+module_param_named(use_prio, use_prio, bool, 0444);
+MODULE_PARM_DESC(use_prio, "Enable steering by VLAN priority on ETH ports "
+                 "(0/1, default 0)");
+
+static int mlx4_check_port_params(struct mlx4_dev *dev,
+                                 enum mlx4_port_type *port_type)
+{
+       int i;
+
+       for (i = 0; i < dev->caps.num_ports - 1; i++) {
+               if (port_type[i] != port_type[i+1] &&
+                   !(dev->caps.flags & MLX4_DEV_CAP_FLAG_DPDP)) {
+                       mlx4_err(dev, "Only same port types supported "
+                                "on this HCA, aborting.\n");
+                       return -EINVAL;
+               }
+       }
+       if ((port_type[0] == MLX4_PORT_TYPE_ETH) &&
+           (port_type[1] == MLX4_PORT_TYPE_IB)) {
+               mlx4_err(dev, "eth-ib configuration is not supported.\n");
+               return -EINVAL;
+       }
+
+       for (i = 0; i < dev->caps.num_ports; i++) {
+               if (!(port_type[i] & dev->caps.supported_type[i+1])) {
+                       mlx4_err(dev, "Requested port type for port %d is not "
+                                     "supported on this HCA\n", i + 1);
+                       return -EINVAL;
+               }
+       }
+       return 0;
+}
+
+static void mlx4_set_port_mask(struct mlx4_dev *dev)
+{
+       int i;
+
+       dev->caps.port_mask = 0;
+       for (i = 1; i <= dev->caps.num_ports; ++i)
+               if (dev->caps.port_type[i] == MLX4_PORT_TYPE_IB)
+                       dev->caps.port_mask |= 1 << (i - 1);
+}
 static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
 {
        int err;
@@ -120,10 +171,13 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
        dev->caps.num_ports          = dev_cap->num_ports;
        for (i = 1; i <= dev->caps.num_ports; ++i) {
                dev->caps.vl_cap[i]         = dev_cap->max_vl[i];
-               dev->caps.mtu_cap[i]        = dev_cap->max_mtu[i];
+               dev->caps.ib_mtu_cap[i]     = dev_cap->ib_mtu[i];
                dev->caps.gid_table_len[i]  = dev_cap->max_gids[i];
                dev->caps.pkey_table_len[i] = dev_cap->max_pkeys[i];
                dev->caps.port_width_cap[i] = dev_cap->max_port_width[i];
+               dev->caps.eth_mtu_cap[i]    = dev_cap->eth_mtu[i];
+               dev->caps.def_mac[i]        = dev_cap->def_mac[i];
+               dev->caps.supported_type[i] = dev_cap->supported_port_types[i];
        }
 
        dev->caps.num_uars           = dev_cap->uar_size / PAGE_SIZE;
@@ -134,7 +188,6 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
        dev->caps.max_rq_sg          = dev_cap->max_rq_sg;
        dev->caps.max_wqes           = dev_cap->max_qp_sz;
        dev->caps.max_qp_init_rdma   = dev_cap->max_requester_per_qp;
-       dev->caps.reserved_qps       = dev_cap->reserved_qps;
        dev->caps.max_srq_wqes       = dev_cap->max_srq_sz;
        dev->caps.max_srq_sge        = dev_cap->max_rq_sg - 1;
        dev->caps.reserved_srqs      = dev_cap->reserved_srqs;
@@ -163,9 +216,138 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
        dev->caps.stat_rate_support  = dev_cap->stat_rate_support;
        dev->caps.max_gso_sz         = dev_cap->max_gso_sz;
 
+       dev->caps.log_num_macs  = log_num_mac;
+       dev->caps.log_num_vlans = log_num_vlan;
+       dev->caps.log_num_prios = use_prio ? 3 : 0;
+
+       for (i = 1; i <= dev->caps.num_ports; ++i) {
+               if (dev->caps.supported_type[i] != MLX4_PORT_TYPE_ETH)
+                       dev->caps.port_type[i] = MLX4_PORT_TYPE_IB;
+               else
+                       dev->caps.port_type[i] = MLX4_PORT_TYPE_ETH;
+
+               if (dev->caps.log_num_macs > dev_cap->log_max_macs[i]) {
+                       dev->caps.log_num_macs = dev_cap->log_max_macs[i];
+                       mlx4_warn(dev, "Requested number of MACs is too much "
+                                 "for port %d, reducing to %d.\n",
+                                 i, 1 << dev->caps.log_num_macs);
+               }
+               if (dev->caps.log_num_vlans > dev_cap->log_max_vlans[i]) {
+                       dev->caps.log_num_vlans = dev_cap->log_max_vlans[i];
+                       mlx4_warn(dev, "Requested number of VLANs is too much "
+                                 "for port %d, reducing to %d.\n",
+                                 i, 1 << dev->caps.log_num_vlans);
+               }
+       }
+
+       mlx4_set_port_mask(dev);
+
+       dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW] = dev_cap->reserved_qps;
+       dev->caps.reserved_qps_cnt[MLX4_QP_REGION_ETH_ADDR] =
+               dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FC_ADDR] =
+               (1 << dev->caps.log_num_macs) *
+               (1 << dev->caps.log_num_vlans) *
+               (1 << dev->caps.log_num_prios) *
+               dev->caps.num_ports;
+       dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FC_EXCH] = MLX4_NUM_FEXCH;
+
+       dev->caps.reserved_qps = dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW] +
+               dev->caps.reserved_qps_cnt[MLX4_QP_REGION_ETH_ADDR] +
+               dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FC_ADDR] +
+               dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FC_EXCH];
+
        return 0;
 }
 
+/*
+ * Change the port configuration of the device.
+ * Every user of this function must hold the port mutex.
+ */
+static int mlx4_change_port_types(struct mlx4_dev *dev,
+                                 enum mlx4_port_type *port_types)
+{
+       int err = 0;
+       int change = 0;
+       int port;
+
+       for (port = 0; port <  dev->caps.num_ports; port++) {
+               if (port_types[port] != dev->caps.port_type[port + 1]) {
+                       change = 1;
+                       dev->caps.port_type[port + 1] = port_types[port];
+               }
+       }
+       if (change) {
+               mlx4_unregister_device(dev);
+               for (port = 1; port <= dev->caps.num_ports; port++) {
+                       mlx4_CLOSE_PORT(dev, port);
+                       err = mlx4_SET_PORT(dev, port);
+                       if (err) {
+                               mlx4_err(dev, "Failed to set port %d, "
+                                             "aborting\n", port);
+                               goto out;
+                       }
+               }
+               mlx4_set_port_mask(dev);
+               err = mlx4_register_device(dev);
+       }
+
+out:
+       return err;
+}
+
+static ssize_t show_port_type(struct device *dev,
+                             struct device_attribute *attr,
+                             char *buf)
+{
+       struct mlx4_port_info *info = container_of(attr, struct mlx4_port_info,
+                                                  port_attr);
+       struct mlx4_dev *mdev = info->dev;
+
+       return sprintf(buf, "%s\n",
+                      mdev->caps.port_type[info->port] == MLX4_PORT_TYPE_IB ?
+                      "ib" : "eth");
+}
+
+static ssize_t set_port_type(struct device *dev,
+                            struct device_attribute *attr,
+                            const char *buf, size_t count)
+{
+       struct mlx4_port_info *info = container_of(attr, struct mlx4_port_info,
+                                                  port_attr);
+       struct mlx4_dev *mdev = info->dev;
+       struct mlx4_priv *priv = mlx4_priv(mdev);
+       enum mlx4_port_type types[MLX4_MAX_PORTS];
+       int i;
+       int err = 0;
+
+       if (!strcmp(buf, "ib\n"))
+               info->tmp_type = MLX4_PORT_TYPE_IB;
+       else if (!strcmp(buf, "eth\n"))
+               info->tmp_type = MLX4_PORT_TYPE_ETH;
+       else {
+               mlx4_err(mdev, "%s is not supported port type\n", buf);
+               return -EINVAL;
+       }
+
+       mutex_lock(&priv->port_mutex);
+       for (i = 0; i < mdev->caps.num_ports; i++)
+               types[i] = priv->port[i+1].tmp_type ? priv->port[i+1].tmp_type :
+                                       mdev->caps.port_type[i+1];
+
+       err = mlx4_check_port_params(mdev, types);
+       if (err)
+               goto out;
+
+       for (i = 1; i <= mdev->caps.num_ports; i++)
+               priv->port[i].tmp_type = 0;
+
+       err = mlx4_change_port_types(mdev, types);
+
+out:
+       mutex_unlock(&priv->port_mutex);
+       return err ? err : count;
+}
+
 static int mlx4_load_fw(struct mlx4_dev *dev)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
@@ -211,7 +393,8 @@ static int mlx4_init_cmpt_table(struct mlx4_dev *dev, u64 cmpt_base,
                                  ((u64) (MLX4_CMPT_TYPE_QP *
                                          cmpt_entry_sz) << MLX4_CMPT_SHIFT),
                                  cmpt_entry_sz, dev->caps.num_qps,
-                                 dev->caps.reserved_qps, 0, 0);
+                                 dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW],
+                                 0, 0);
        if (err)
                goto err;
 
@@ -336,7 +519,8 @@ static int mlx4_init_icm(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap,
                                  init_hca->qpc_base,
                                  dev_cap->qpc_entry_sz,
                                  dev->caps.num_qps,
-                                 dev->caps.reserved_qps, 0, 0);
+                                 dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW],
+                                 0, 0);
        if (err) {
                mlx4_err(dev, "Failed to map QP context memory, aborting.\n");
                goto err_unmap_dmpt;
@@ -346,7 +530,8 @@ static int mlx4_init_icm(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap,
                                  init_hca->auxc_base,
                                  dev_cap->aux_entry_sz,
                                  dev->caps.num_qps,
-                                 dev->caps.reserved_qps, 0, 0);
+                                 dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW],
+                                 0, 0);
        if (err) {
                mlx4_err(dev, "Failed to map AUXC context memory, aborting.\n");
                goto err_unmap_qp;
@@ -356,7 +541,8 @@ static int mlx4_init_icm(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap,
                                  init_hca->altc_base,
                                  dev_cap->altc_entry_sz,
                                  dev->caps.num_qps,
-                                 dev->caps.reserved_qps, 0, 0);
+                                 dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW],
+                                 0, 0);
        if (err) {
                mlx4_err(dev, "Failed to map ALTC context memory, aborting.\n");
                goto err_unmap_auxc;
@@ -366,7 +552,8 @@ static int mlx4_init_icm(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap,
                                  init_hca->rdmarc_base,
                                  dev_cap->rdmarc_entry_sz << priv->qp_table.rdmarc_shift,
                                  dev->caps.num_qps,
-                                 dev->caps.reserved_qps, 0, 0);
+                                 dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW],
+                                 0, 0);
        if (err) {
                mlx4_err(dev, "Failed to map RDMARC context memory, aborting\n");
                goto err_unmap_altc;
@@ -565,6 +752,7 @@ static int mlx4_setup_hca(struct mlx4_dev *dev)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
        int err;
+       int port;
 
        err = mlx4_init_uar_table(dev);
        if (err) {
@@ -663,8 +851,20 @@ static int mlx4_setup_hca(struct mlx4_dev *dev)
                goto err_qp_table_free;
        }
 
+       for (port = 1; port <= dev->caps.num_ports; port++) {
+               err = mlx4_SET_PORT(dev, port);
+               if (err) {
+                       mlx4_err(dev, "Failed to set port %d, aborting\n",
+                               port);
+                       goto err_mcg_table_free;
+               }
+       }
+
        return 0;
 
+err_mcg_table_free:
+       mlx4_cleanup_mcg_table(dev);
+
 err_qp_table_free:
        mlx4_cleanup_qp_table(dev);
 
@@ -728,11 +928,45 @@ no_msi:
                priv->eq_table.eq[i].irq = dev->pdev->irq;
 }
 
+static int mlx4_init_port_info(struct mlx4_dev *dev, int port)
+{
+       struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
+       int err = 0;
+
+       info->dev = dev;
+       info->port = port;
+       mlx4_init_mac_table(dev, &info->mac_table);
+       mlx4_init_vlan_table(dev, &info->vlan_table);
+
+       sprintf(info->dev_name, "mlx4_port%d", port);
+       info->port_attr.attr.name = info->dev_name;
+       info->port_attr.attr.mode = S_IRUGO | S_IWUSR;
+       info->port_attr.show      = show_port_type;
+       info->port_attr.store     = set_port_type;
+
+       err = device_create_file(&dev->pdev->dev, &info->port_attr);
+       if (err) {
+               mlx4_err(dev, "Failed to create file for port %d\n", port);
+               info->port = -1;
+       }
+
+       return err;
+}
+
+static void mlx4_cleanup_port_info(struct mlx4_port_info *info)
+{
+       if (info->port < 0)
+               return;
+
+       device_remove_file(&info->dev->pdev->dev, &info->port_attr);
+}
+
 static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
        struct mlx4_priv *priv;
        struct mlx4_dev *dev;
        int err;
+       int port;
 
        printk(KERN_INFO PFX "Initializing %s\n",
               pci_name(pdev));
@@ -807,6 +1041,8 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        INIT_LIST_HEAD(&priv->ctx_list);
        spin_lock_init(&priv->ctx_lock);
 
+       mutex_init(&priv->port_mutex);
+
        INIT_LIST_HEAD(&priv->pgdir_list);
        mutex_init(&priv->pgdir_mutex);
 
@@ -842,15 +1078,24 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        if (err)
                goto err_close;
 
+       for (port = 1; port <= dev->caps.num_ports; port++) {
+               err = mlx4_init_port_info(dev, port);
+               if (err)
+                       goto err_port;
+       }
+
        err = mlx4_register_device(dev);
        if (err)
-               goto err_cleanup;
+               goto err_port;
 
        pci_set_drvdata(pdev, dev);
 
        return 0;
 
-err_cleanup:
+err_port:
+       for (port = 1; port <= dev->caps.num_ports; port++)
+               mlx4_cleanup_port_info(&priv->port[port]);
+
        mlx4_cleanup_mcg_table(dev);
        mlx4_cleanup_qp_table(dev);
        mlx4_cleanup_srq_table(dev);
@@ -907,8 +1152,10 @@ static void mlx4_remove_one(struct pci_dev *pdev)
        if (dev) {
                mlx4_unregister_device(dev);
 
-               for (p = 1; p <= dev->caps.num_ports; ++p)
+               for (p = 1; p <= dev->caps.num_ports; p++) {
+                       mlx4_cleanup_port_info(&priv->port[p]);
                        mlx4_CLOSE_PORT(dev, p);
+               }
 
                mlx4_cleanup_mcg_table(dev);
                mlx4_cleanup_qp_table(dev);
@@ -948,6 +1195,8 @@ static struct pci_device_id mlx4_pci_table[] = {
        { PCI_VDEVICE(MELLANOX, 0x6354) }, /* MT25408 "Hermon" QDR */
        { PCI_VDEVICE(MELLANOX, 0x6732) }, /* MT25408 "Hermon" DDR PCIe gen2 */
        { PCI_VDEVICE(MELLANOX, 0x673c) }, /* MT25408 "Hermon" QDR PCIe gen2 */
+       { PCI_VDEVICE(MELLANOX, 0x6368) }, /* MT25408 "Hermon" EN 10GigE */
+       { PCI_VDEVICE(MELLANOX, 0x6750) }, /* MT25408 "Hermon" EN 10GigE PCIe gen2 */
        { 0, }
 };
 
@@ -960,10 +1209,28 @@ static struct pci_driver mlx4_driver = {
        .remove         = __devexit_p(mlx4_remove_one)
 };
 
+static int __init mlx4_verify_params(void)
+{
+       if ((log_num_mac < 0) || (log_num_mac > 7)) {
+               printk(KERN_WARNING "mlx4_core: bad num_mac: %d\n", log_num_mac);
+               return -1;
+       }
+
+       if ((log_num_vlan < 0) || (log_num_vlan > 7)) {
+               printk(KERN_WARNING "mlx4_core: bad num_vlan: %d\n", log_num_vlan);
+               return -1;
+       }
+
+       return 0;
+}
+
 static int __init mlx4_init(void)
 {
        int ret;
 
+       if (mlx4_verify_params())
+               return -EINVAL;
+
        ret = mlx4_catas_init();
        if (ret)
                return ret;
index c83f88ce073663697e7cff88b6a6428e59b1b547..592c01ae2c5dc119f6c6e213126099bf0557228e 100644 (file)
@@ -368,8 +368,8 @@ int mlx4_init_mcg_table(struct mlx4_dev *dev)
        struct mlx4_priv *priv = mlx4_priv(dev);
        int err;
 
-       err = mlx4_bitmap_init(&priv->mcg_table.bitmap,
-                              dev->caps.num_amgms, dev->caps.num_amgms - 1, 0);
+       err = mlx4_bitmap_init(&priv->mcg_table.bitmap, dev->caps.num_amgms,
+                              dev->caps.num_amgms - 1, 0, 0);
        if (err)
                return err;
 
index 5337e3ac3e78c152143e31bc2283f2dc2c7b1752..fa431fad0eecf7a8f9ead90bf97bfd08ddc9cdf7 100644 (file)
@@ -111,6 +111,7 @@ struct mlx4_bitmap {
        u32                     last;
        u32                     top;
        u32                     max;
+       u32                     reserved_top;
        u32                     mask;
        spinlock_t              lock;
        unsigned long          *table;
@@ -251,6 +252,38 @@ struct mlx4_catas_err {
        struct list_head        list;
 };
 
+#define MLX4_MAX_MAC_NUM       128
+#define MLX4_MAC_TABLE_SIZE    (MLX4_MAX_MAC_NUM << 3)
+
+struct mlx4_mac_table {
+       __be64                  entries[MLX4_MAX_MAC_NUM];
+       int                     refs[MLX4_MAX_MAC_NUM];
+       struct mutex            mutex;
+       int                     total;
+       int                     max;
+};
+
+#define MLX4_MAX_VLAN_NUM      128
+#define MLX4_VLAN_TABLE_SIZE   (MLX4_MAX_VLAN_NUM << 2)
+
+struct mlx4_vlan_table {
+       __be32                  entries[MLX4_MAX_VLAN_NUM];
+       int                     refs[MLX4_MAX_VLAN_NUM];
+       struct mutex            mutex;
+       int                     total;
+       int                     max;
+};
+
+struct mlx4_port_info {
+       struct mlx4_dev        *dev;
+       int                     port;
+       char                    dev_name[16];
+       struct device_attribute port_attr;
+       enum mlx4_port_type     tmp_type;
+       struct mlx4_mac_table   mac_table;
+       struct mlx4_vlan_table  vlan_table;
+};
+
 struct mlx4_priv {
        struct mlx4_dev         dev;
 
@@ -279,6 +312,8 @@ struct mlx4_priv {
 
        struct mlx4_uar         driver_uar;
        void __iomem           *kar;
+       struct mlx4_port_info   port[MLX4_MAX_PORTS + 1];
+       struct mutex            port_mutex;
 };
 
 static inline struct mlx4_priv *mlx4_priv(struct mlx4_dev *dev)
@@ -288,7 +323,10 @@ static inline struct mlx4_priv *mlx4_priv(struct mlx4_dev *dev)
 
 u32 mlx4_bitmap_alloc(struct mlx4_bitmap *bitmap);
 void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj);
-int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask, u32 reserved);
+u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align);
+void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt);
+int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask,
+                    u32 reserved_bot, u32 resetrved_top);
 void mlx4_bitmap_cleanup(struct mlx4_bitmap *bitmap);
 
 int mlx4_reset(struct mlx4_dev *dev);
@@ -346,4 +384,9 @@ void mlx4_srq_event(struct mlx4_dev *dev, u32 srqn, int event_type);
 
 void mlx4_handle_catas_err(struct mlx4_dev *dev);
 
+void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table);
+void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table);
+
+int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port);
+
 #endif /* MLX4_H */
diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h
new file mode 100644 (file)
index 0000000..11fb17c
--- /dev/null
@@ -0,0 +1,561 @@
+/*
+ * Copyright (c) 2007 Mellanox Technologies. 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 _MLX4_EN_H_
+#define _MLX4_EN_H_
+
+#include <linux/compiler.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/netdevice.h>
+#include <linux/inet_lro.h>
+
+#include <linux/mlx4/device.h>
+#include <linux/mlx4/qp.h>
+#include <linux/mlx4/cq.h>
+#include <linux/mlx4/srq.h>
+#include <linux/mlx4/doorbell.h>
+
+#include "en_port.h"
+
+#define DRV_NAME       "mlx4_en"
+#define DRV_VERSION    "1.4.0"
+#define DRV_RELDATE    "Sep 2008"
+
+
+#define MLX4_EN_MSG_LEVEL      (NETIF_MSG_LINK | NETIF_MSG_IFDOWN)
+
+#define mlx4_dbg(mlevel, priv, format, arg...) \
+       if (NETIF_MSG_##mlevel & priv->msg_enable) \
+       printk(KERN_DEBUG "%s %s: " format , DRV_NAME ,\
+               (&priv->mdev->pdev->dev)->bus_id , ## arg)
+
+#define mlx4_err(mdev, format, arg...) \
+       printk(KERN_ERR "%s %s: " format , DRV_NAME ,\
+               (&mdev->pdev->dev)->bus_id , ## arg)
+#define mlx4_info(mdev, format, arg...) \
+       printk(KERN_INFO "%s %s: " format , DRV_NAME ,\
+               (&mdev->pdev->dev)->bus_id , ## arg)
+#define mlx4_warn(mdev, format, arg...) \
+       printk(KERN_WARNING "%s %s: " format , DRV_NAME ,\
+               (&mdev->pdev->dev)->bus_id , ## arg)
+
+/*
+ * Device constants
+ */
+
+
+#define MLX4_EN_PAGE_SHIFT     12
+#define MLX4_EN_PAGE_SIZE      (1 << MLX4_EN_PAGE_SHIFT)
+#define MAX_TX_RINGS           16
+#define MAX_RX_RINGS           16
+#define MAX_RSS_MAP_SIZE       64
+#define RSS_FACTOR             2
+#define TXBB_SIZE              64
+#define HEADROOM               (2048 / TXBB_SIZE + 1)
+#define MAX_LSO_HDR_SIZE       92
+#define STAMP_STRIDE           64
+#define STAMP_DWORDS           (STAMP_STRIDE / 4)
+#define STAMP_SHIFT            31
+#define STAMP_VAL              0x7fffffff
+#define STATS_DELAY            (HZ / 4)
+
+/* Typical TSO descriptor with 16 gather entries is 352 bytes... */
+#define MAX_DESC_SIZE          512
+#define MAX_DESC_TXBBS         (MAX_DESC_SIZE / TXBB_SIZE)
+
+/*
+ * OS related constants and tunables
+ */
+
+#define MLX4_EN_WATCHDOG_TIMEOUT       (15 * HZ)
+
+#define MLX4_EN_ALLOC_ORDER    2
+#define MLX4_EN_ALLOC_SIZE     (PAGE_SIZE << MLX4_EN_ALLOC_ORDER)
+
+#define MLX4_EN_MAX_LRO_DESCRIPTORS    32
+
+/* Receive fragment sizes; we use at most 4 fragments (for 9600 byte MTU
+ * and 4K allocations) */
+enum {
+       FRAG_SZ0 = 512 - NET_IP_ALIGN,
+       FRAG_SZ1 = 1024,
+       FRAG_SZ2 = 4096,
+       FRAG_SZ3 = MLX4_EN_ALLOC_SIZE
+};
+#define MLX4_EN_MAX_RX_FRAGS   4
+
+/* Minimum ring size for our page-allocation sceme to work */
+#define MLX4_EN_MIN_RX_SIZE    (MLX4_EN_ALLOC_SIZE / SMP_CACHE_BYTES)
+#define MLX4_EN_MIN_TX_SIZE    (4096 / TXBB_SIZE)
+
+#define MLX4_EN_TX_RING_NUM            9
+#define MLX4_EN_DEF_TX_RING_SIZE       1024
+#define MLX4_EN_DEF_RX_RING_SIZE       1024
+
+/* Target number of bytes to coalesce with interrupt moderation */
+#define MLX4_EN_RX_COAL_TARGET 0x20000
+#define MLX4_EN_RX_COAL_TIME   0x10
+
+#define MLX4_EN_TX_COAL_PKTS   5
+#define MLX4_EN_TX_COAL_TIME   0x80
+
+#define MLX4_EN_RX_RATE_LOW            400000
+#define MLX4_EN_RX_COAL_TIME_LOW       0
+#define MLX4_EN_RX_RATE_HIGH           450000
+#define MLX4_EN_RX_COAL_TIME_HIGH      128
+#define MLX4_EN_RX_SIZE_THRESH         1024
+#define MLX4_EN_RX_RATE_THRESH         (1000000 / MLX4_EN_RX_COAL_TIME_HIGH)
+#define MLX4_EN_SAMPLE_INTERVAL                0
+
+#define MLX4_EN_AUTO_CONF      0xffff
+
+#define MLX4_EN_DEF_RX_PAUSE   1
+#define MLX4_EN_DEF_TX_PAUSE   1
+
+/* Interval between sucessive polls in the Tx routine when polling is used
+   instead of interrupts (in per-core Tx rings) - should be power of 2 */
+#define MLX4_EN_TX_POLL_MODER  16
+#define MLX4_EN_TX_POLL_TIMEOUT        (HZ / 4)
+
+#define ETH_LLC_SNAP_SIZE      8
+
+#define SMALL_PACKET_SIZE      (256 - NET_IP_ALIGN)
+#define HEADER_COPY_SIZE       (128 - NET_IP_ALIGN)
+
+#define MLX4_EN_MIN_MTU                46
+#define ETH_BCAST              0xffffffffffffULL
+
+#ifdef MLX4_EN_PERF_STAT
+/* Number of samples to 'average' */
+#define AVG_SIZE                       128
+#define AVG_FACTOR                     1024
+#define NUM_PERF_STATS                 NUM_PERF_COUNTERS
+
+#define INC_PERF_COUNTER(cnt)          (++(cnt))
+#define ADD_PERF_COUNTER(cnt, add)     ((cnt) += (add))
+#define AVG_PERF_COUNTER(cnt, sample) \
+       ((cnt) = ((cnt) * (AVG_SIZE - 1) + (sample) * AVG_FACTOR) / AVG_SIZE)
+#define GET_PERF_COUNTER(cnt)          (cnt)
+#define GET_AVG_PERF_COUNTER(cnt)      ((cnt) / AVG_FACTOR)
+
+#else
+
+#define NUM_PERF_STATS                 0
+#define INC_PERF_COUNTER(cnt)          do {} while (0)
+#define ADD_PERF_COUNTER(cnt, add)     do {} while (0)
+#define AVG_PERF_COUNTER(cnt, sample)  do {} while (0)
+#define GET_PERF_COUNTER(cnt)          (0)
+#define GET_AVG_PERF_COUNTER(cnt)      (0)
+#endif /* MLX4_EN_PERF_STAT */
+
+/*
+ * Configurables
+ */
+
+enum cq_type {
+       RX = 0,
+       TX = 1,
+};
+
+
+/*
+ * Useful macros
+ */
+#define ROUNDUP_LOG2(x)                ilog2(roundup_pow_of_two(x))
+#define XNOR(x, y)             (!(x) == !(y))
+#define ILLEGAL_MAC(addr)      (addr == 0xffffffffffffULL || addr == 0x0)
+
+
+struct mlx4_en_tx_info {
+       struct sk_buff *skb;
+       u32 nr_txbb;
+       u8 linear;
+       u8 data_offset;
+};
+
+
+#define MLX4_EN_BIT_DESC_OWN   0x80000000
+#define CTRL_SIZE      sizeof(struct mlx4_wqe_ctrl_seg)
+#define MLX4_EN_MEMTYPE_PAD    0x100
+#define DS_SIZE                sizeof(struct mlx4_wqe_data_seg)
+
+
+struct mlx4_en_tx_desc {
+       struct mlx4_wqe_ctrl_seg ctrl;
+       union {
+               struct mlx4_wqe_data_seg data; /* at least one data segment */
+               struct mlx4_wqe_lso_seg lso;
+               struct mlx4_wqe_inline_seg inl;
+       };
+};
+
+#define MLX4_EN_USE_SRQ                0x01000000
+
+struct mlx4_en_rx_alloc {
+       struct page *page;
+       u16 offset;
+};
+
+struct mlx4_en_tx_ring {
+       struct mlx4_hwq_resources wqres;
+       u32 size ; /* number of TXBBs */
+       u32 size_mask;
+       u16 stride;
+       u16 cqn;        /* index of port CQ associated with this ring */
+       u32 prod;
+       u32 cons;
+       u32 buf_size;
+       u32 doorbell_qpn;
+       void *buf;
+       u16 poll_cnt;
+       int blocked;
+       struct mlx4_en_tx_info *tx_info;
+       u8 *bounce_buf;
+       u32 last_nr_txbb;
+       struct mlx4_qp qp;
+       struct mlx4_qp_context context;
+       int qpn;
+       enum mlx4_qp_state qp_state;
+       struct mlx4_srq dummy;
+       unsigned long bytes;
+       unsigned long packets;
+       spinlock_t comp_lock;
+};
+
+struct mlx4_en_rx_desc {
+       struct mlx4_wqe_srq_next_seg next;
+       /* actual number of entries depends on rx ring stride */
+       struct mlx4_wqe_data_seg data[0];
+};
+
+struct mlx4_en_rx_ring {
+       struct mlx4_srq srq;
+       struct mlx4_hwq_resources wqres;
+       struct mlx4_en_rx_alloc page_alloc[MLX4_EN_MAX_RX_FRAGS];
+       struct net_lro_mgr lro;
+       u32 size ;      /* number of Rx descs*/
+       u32 actual_size;
+       u32 size_mask;
+       u16 stride;
+       u16 log_stride;
+       u16 cqn;        /* index of port CQ associated with this ring */
+       u32 prod;
+       u32 cons;
+       u32 buf_size;
+       int need_refill;
+       int full;
+       void *buf;
+       void *rx_info;
+       unsigned long bytes;
+       unsigned long packets;
+};
+
+
+static inline int mlx4_en_can_lro(__be16 status)
+{
+       return (status & cpu_to_be16(MLX4_CQE_STATUS_IPV4       |
+                                    MLX4_CQE_STATUS_IPV4F      |
+                                    MLX4_CQE_STATUS_IPV6       |
+                                    MLX4_CQE_STATUS_IPV4OPT    |
+                                    MLX4_CQE_STATUS_TCP        |
+                                    MLX4_CQE_STATUS_UDP        |
+                                    MLX4_CQE_STATUS_IPOK)) ==
+               cpu_to_be16(MLX4_CQE_STATUS_IPV4 |
+                           MLX4_CQE_STATUS_IPOK |
+                           MLX4_CQE_STATUS_TCP);
+}
+
+struct mlx4_en_cq {
+       struct mlx4_cq          mcq;
+       struct mlx4_hwq_resources wqres;
+       int                     ring;
+       spinlock_t              lock;
+       struct net_device      *dev;
+       struct napi_struct      napi;
+       /* Per-core Tx cq processing support */
+       struct timer_list timer;
+       int size;
+       int buf_size;
+       unsigned vector;
+       enum cq_type is_tx;
+       u16 moder_time;
+       u16 moder_cnt;
+       int armed;
+       struct mlx4_cqe *buf;
+#define MLX4_EN_OPCODE_ERROR   0x1e
+};
+
+struct mlx4_en_port_profile {
+       u32 flags;
+       u32 tx_ring_num;
+       u32 rx_ring_num;
+       u32 tx_ring_size;
+       u32 rx_ring_size;
+};
+
+struct mlx4_en_profile {
+       int rss_xor;
+       int num_lro;
+       u8 rss_mask;
+       u32 active_ports;
+       u32 small_pkt_int;
+       int rx_moder_cnt;
+       int rx_moder_time;
+       int auto_moder;
+       u8 rx_pause;
+       u8 rx_ppp;
+       u8 tx_pause;
+       u8 tx_ppp;
+       u8 no_reset;
+       struct mlx4_en_port_profile prof[MLX4_MAX_PORTS + 1];
+};
+
+struct mlx4_en_dev {
+       struct mlx4_dev         *dev;
+       struct pci_dev          *pdev;
+       struct mutex            state_lock;
+       struct net_device       *pndev[MLX4_MAX_PORTS + 1];
+       u32                     port_cnt;
+       bool                    device_up;
+       struct mlx4_en_profile  profile;
+       u32                     LSO_support;
+       struct workqueue_struct *workqueue;
+       struct device           *dma_device;
+       void __iomem            *uar_map;
+       struct mlx4_uar         priv_uar;
+       struct mlx4_mr          mr;
+       u32                     priv_pdn;
+       spinlock_t              uar_lock;
+};
+
+
+struct mlx4_en_rss_map {
+       int size;
+       int base_qpn;
+       u16 map[MAX_RSS_MAP_SIZE];
+       struct mlx4_qp qps[MAX_RSS_MAP_SIZE];
+       enum mlx4_qp_state state[MAX_RSS_MAP_SIZE];
+       struct mlx4_qp indir_qp;
+       enum mlx4_qp_state indir_state;
+};
+
+struct mlx4_en_rss_context {
+       __be32 base_qpn;
+       __be32 default_qpn;
+       u16 reserved;
+       u8 hash_fn;
+       u8 flags;
+       __be32 rss_key[10];
+};
+
+struct mlx4_en_pkt_stats {
+       unsigned long broadcast;
+       unsigned long rx_prio[8];
+       unsigned long tx_prio[8];
+#define NUM_PKT_STATS          17
+};
+
+struct mlx4_en_port_stats {
+       unsigned long lro_aggregated;
+       unsigned long lro_flushed;
+       unsigned long lro_no_desc;
+       unsigned long tso_packets;
+       unsigned long queue_stopped;
+       unsigned long wake_queue;
+       unsigned long tx_timeout;
+       unsigned long rx_alloc_failed;
+       unsigned long rx_chksum_good;
+       unsigned long rx_chksum_none;
+       unsigned long tx_chksum_offload;
+#define NUM_PORT_STATS         11
+};
+
+struct mlx4_en_perf_stats {
+       u32 tx_poll;
+       u64 tx_pktsz_avg;
+       u32 inflight_avg;
+       u16 tx_coal_avg;
+       u16 rx_coal_avg;
+       u32 napi_quota;
+#define NUM_PERF_COUNTERS              6
+};
+
+struct mlx4_en_frag_info {
+       u16 frag_size;
+       u16 frag_prefix_size;
+       u16 frag_stride;
+       u16 frag_align;
+       u16 last_offset;
+
+};
+
+struct mlx4_en_priv {
+       struct mlx4_en_dev *mdev;
+       struct mlx4_en_port_profile *prof;
+       struct net_device *dev;
+       struct vlan_group *vlgrp;
+       struct net_device_stats stats;
+       struct net_device_stats ret_stats;
+       spinlock_t stats_lock;
+
+       unsigned long last_moder_packets;
+       unsigned long last_moder_tx_packets;
+       unsigned long last_moder_bytes;
+       unsigned long last_moder_jiffies;
+       int last_moder_time;
+       u16 rx_usecs;
+       u16 rx_frames;
+       u16 tx_usecs;
+       u16 tx_frames;
+       u32 pkt_rate_low;
+       u16 rx_usecs_low;
+       u32 pkt_rate_high;
+       u16 rx_usecs_high;
+       u16 sample_interval;
+       u16 adaptive_rx_coal;
+       u32 msg_enable;
+
+       struct mlx4_hwq_resources res;
+       int link_state;
+       int last_link_state;
+       bool port_up;
+       int port;
+       int registered;
+       int allocated;
+       int stride;
+       int rx_csum;
+       u64 mac;
+       int mac_index;
+       unsigned max_mtu;
+       int base_qpn;
+
+       struct mlx4_en_rss_map rss_map;
+       u16 tx_prio_map[8];
+       u32 flags;
+#define MLX4_EN_FLAG_PROMISC   0x1
+       u32 tx_ring_num;
+       u32 rx_ring_num;
+       u32 rx_skb_size;
+       struct mlx4_en_frag_info frag_info[MLX4_EN_MAX_RX_FRAGS];
+       u16 num_frags;
+       u16 log_rx_info;
+
+       struct mlx4_en_tx_ring tx_ring[MAX_TX_RINGS];
+       struct mlx4_en_rx_ring rx_ring[MAX_RX_RINGS];
+       struct mlx4_en_cq tx_cq[MAX_TX_RINGS];
+       struct mlx4_en_cq rx_cq[MAX_RX_RINGS];
+       struct work_struct mcast_task;
+       struct work_struct mac_task;
+       struct delayed_work refill_task;
+       struct work_struct watchdog_task;
+       struct work_struct linkstate_task;
+       struct delayed_work stats_task;
+       struct mlx4_en_perf_stats pstats;
+       struct mlx4_en_pkt_stats pkstats;
+       struct mlx4_en_port_stats port_stats;
+       struct dev_mc_list *mc_list;
+       struct mlx4_en_stat_out_mbox hw_stats;
+};
+
+
+void mlx4_en_destroy_netdev(struct net_device *dev);
+int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+                       struct mlx4_en_port_profile *prof);
+
+int mlx4_en_get_profile(struct mlx4_en_dev *mdev);
+
+int mlx4_en_create_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
+                     int entries, int ring, enum cq_type mode);
+void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq);
+int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq);
+void mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq);
+int mlx4_en_set_cq_moder(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq);
+int mlx4_en_arm_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq);
+
+void mlx4_en_poll_tx_cq(unsigned long data);
+void mlx4_en_tx_irq(struct mlx4_cq *mcq);
+int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev);
+
+int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, struct mlx4_en_tx_ring *ring,
+                          u32 size, u16 stride);
+void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *priv, struct mlx4_en_tx_ring *ring);
+int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv,
+                            struct mlx4_en_tx_ring *ring,
+                            int cq, int srqn);
+void mlx4_en_deactivate_tx_ring(struct mlx4_en_priv *priv,
+                               struct mlx4_en_tx_ring *ring);
+
+int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv,
+                          struct mlx4_en_rx_ring *ring,
+                          u32 size, u16 stride);
+void mlx4_en_destroy_rx_ring(struct mlx4_en_priv *priv,
+                            struct mlx4_en_rx_ring *ring);
+int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv);
+void mlx4_en_deactivate_rx_ring(struct mlx4_en_priv *priv,
+                               struct mlx4_en_rx_ring *ring);
+int mlx4_en_process_rx_cq(struct net_device *dev,
+                         struct mlx4_en_cq *cq,
+                         int budget);
+int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget);
+void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
+                            int is_tx, int rss, int qpn, int cqn, int srqn,
+                            struct mlx4_qp_context *context);
+int mlx4_en_map_buffer(struct mlx4_buf *buf);
+void mlx4_en_unmap_buffer(struct mlx4_buf *buf);
+
+void mlx4_en_calc_rx_buf(struct net_device *dev);
+void mlx4_en_set_default_rss_map(struct mlx4_en_priv *priv,
+                                struct mlx4_en_rss_map *rss_map,
+                                int num_entries, int num_rings);
+void mlx4_en_set_prio_map(struct mlx4_en_priv *priv, u16 *prio_map, u32 ring_num);
+int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv);
+void mlx4_en_release_rss_steer(struct mlx4_en_priv *priv);
+int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring);
+void mlx4_en_rx_refill(struct work_struct *work);
+void mlx4_en_rx_irq(struct mlx4_cq *mcq);
+
+int mlx4_SET_MCAST_FLTR(struct mlx4_dev *dev, u8 port, u64 mac, u64 clear, u8 mode);
+int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, u8 port, struct vlan_group *grp);
+int mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu,
+                         u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx);
+int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
+                          u8 promisc);
+
+int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset);
+
+/*
+ * Globals
+ */
+extern const struct ethtool_ops mlx4_en_ethtool_ops;
+#endif
index d1dd5b48dbd1412bddf6321ebd3cceb89d18bacd..0caf74cae8bccea2446004f65d1a8ddd53efacb4 100644 (file)
@@ -461,7 +461,7 @@ int mlx4_init_mr_table(struct mlx4_dev *dev)
        int err;
 
        err = mlx4_bitmap_init(&mr_table->mpt_bitmap, dev->caps.num_mpts,
-                              ~0, dev->caps.reserved_mrws);
+                              ~0, dev->caps.reserved_mrws, 0);
        if (err)
                return err;
 
index aa616892d09cbac5c2169e334a5893515ca9fb99..26d1a7a9e375e55db351c29919b3187215e6c784 100644 (file)
@@ -62,7 +62,7 @@ int mlx4_init_pd_table(struct mlx4_dev *dev)
        struct mlx4_priv *priv = mlx4_priv(dev);
 
        return mlx4_bitmap_init(&priv->pd_bitmap, dev->caps.num_pds,
-                               (1 << 24) - 1, dev->caps.reserved_pds);
+                               (1 << 24) - 1, dev->caps.reserved_pds, 0);
 }
 
 void mlx4_cleanup_pd_table(struct mlx4_dev *dev)
@@ -100,7 +100,7 @@ int mlx4_init_uar_table(struct mlx4_dev *dev)
 
        return mlx4_bitmap_init(&mlx4_priv(dev)->uar_table.bitmap,
                                dev->caps.num_uars, dev->caps.num_uars - 1,
-                               max(128, dev->caps.reserved_uars));
+                               max(128, dev->caps.reserved_uars), 0);
 }
 
 void mlx4_cleanup_uar_table(struct mlx4_dev *dev)
diff --git a/drivers/net/mlx4/port.c b/drivers/net/mlx4/port.c
new file mode 100644 (file)
index 0000000..e2fdab4
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2007 Mellanox Technologies. 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/errno.h>
+#include <linux/if_ether.h>
+
+#include <linux/mlx4/cmd.h>
+
+#include "mlx4.h"
+
+#define MLX4_MAC_VALID         (1ull << 63)
+#define MLX4_MAC_MASK          0xffffffffffffULL
+
+#define MLX4_VLAN_VALID                (1u << 31)
+#define MLX4_VLAN_MASK         0xfff
+
+void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table)
+{
+       int i;
+
+       mutex_init(&table->mutex);
+       for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
+               table->entries[i] = 0;
+               table->refs[i]   = 0;
+       }
+       table->max   = 1 << dev->caps.log_num_macs;
+       table->total = 0;
+}
+
+void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table)
+{
+       int i;
+
+       mutex_init(&table->mutex);
+       for (i = 0; i < MLX4_MAX_VLAN_NUM; i++) {
+               table->entries[i] = 0;
+               table->refs[i]   = 0;
+       }
+       table->max   = 1 << dev->caps.log_num_vlans;
+       table->total = 0;
+}
+
+static int mlx4_set_port_mac_table(struct mlx4_dev *dev, u8 port,
+                                  __be64 *entries)
+{
+       struct mlx4_cmd_mailbox *mailbox;
+       u32 in_mod;
+       int err;
+
+       mailbox = mlx4_alloc_cmd_mailbox(dev);
+       if (IS_ERR(mailbox))
+               return PTR_ERR(mailbox);
+
+       memcpy(mailbox->buf, entries, MLX4_MAC_TABLE_SIZE);
+
+       in_mod = MLX4_SET_PORT_MAC_TABLE << 8 | port;
+       err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
+                      MLX4_CMD_TIME_CLASS_B);
+
+       mlx4_free_cmd_mailbox(dev, mailbox);
+       return err;
+}
+
+int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *index)
+{
+       struct mlx4_mac_table *table = &mlx4_priv(dev)->port[port].mac_table;
+       int i, err = 0;
+       int free = -1;
+
+       mlx4_dbg(dev, "Registering MAC: 0x%llx\n", (unsigned long long) mac);
+       mutex_lock(&table->mutex);
+       for (i = 0; i < MLX4_MAX_MAC_NUM - 1; i++) {
+               if (free < 0 && !table->refs[i]) {
+                       free = i;
+                       continue;
+               }
+
+               if (mac == (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))) {
+                       /* MAC already registered, increase refernce count */
+                       *index = i;
+                       ++table->refs[i];
+                       goto out;
+               }
+       }
+       mlx4_dbg(dev, "Free MAC index is %d\n", free);
+
+       if (table->total == table->max) {
+               /* No free mac entries */
+               err = -ENOSPC;
+               goto out;
+       }
+
+       /* Register new MAC */
+       table->refs[free] = 1;
+       table->entries[free] = cpu_to_be64(mac | MLX4_MAC_VALID);
+
+       err = mlx4_set_port_mac_table(dev, port, table->entries);
+       if (unlikely(err)) {
+               mlx4_err(dev, "Failed adding MAC: 0x%llx\n", (unsigned long long) mac);
+               table->refs[free] = 0;
+               table->entries[free] = 0;
+               goto out;
+       }
+
+       *index = free;
+       ++table->total;
+out:
+       mutex_unlock(&table->mutex);
+       return err;
+}
+EXPORT_SYMBOL_GPL(mlx4_register_mac);
+
+void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, int index)
+{
+       struct mlx4_mac_table *table = &mlx4_priv(dev)->port[port].mac_table;
+
+       mutex_lock(&table->mutex);
+       if (!table->refs[index]) {
+               mlx4_warn(dev, "No MAC entry for index %d\n", index);
+               goto out;
+       }
+       if (--table->refs[index]) {
+               mlx4_warn(dev, "Have more references for index %d,"
+                         "no need to modify MAC table\n", index);
+               goto out;
+       }
+       table->entries[index] = 0;
+       mlx4_set_port_mac_table(dev, port, table->entries);
+       --table->total;
+out:
+       mutex_unlock(&table->mutex);
+}
+EXPORT_SYMBOL_GPL(mlx4_unregister_mac);
+
+static int mlx4_set_port_vlan_table(struct mlx4_dev *dev, u8 port,
+                                   __be32 *entries)
+{
+       struct mlx4_cmd_mailbox *mailbox;
+       u32 in_mod;
+       int err;
+
+       mailbox = mlx4_alloc_cmd_mailbox(dev);
+       if (IS_ERR(mailbox))
+               return PTR_ERR(mailbox);
+
+       memcpy(mailbox->buf, entries, MLX4_VLAN_TABLE_SIZE);
+       in_mod = MLX4_SET_PORT_VLAN_TABLE << 8 | port;
+       err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
+                      MLX4_CMD_TIME_CLASS_B);
+
+       mlx4_free_cmd_mailbox(dev, mailbox);
+
+       return err;
+}
+
+int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)
+{
+       struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
+       int i, err = 0;
+       int free = -1;
+
+       mutex_lock(&table->mutex);
+       for (i = MLX4_VLAN_REGULAR; i < MLX4_MAX_VLAN_NUM; i++) {
+               if (free < 0 && (table->refs[i] == 0)) {
+                       free = i;
+                       continue;
+               }
+
+               if (table->refs[i] &&
+                   (vlan == (MLX4_VLAN_MASK &
+                             be32_to_cpu(table->entries[i])))) {
+                       /* Vlan already registered, increase refernce count */
+                       *index = i;
+                       ++table->refs[i];
+                       goto out;
+               }
+       }
+
+       if (table->total == table->max) {
+               /* No free vlan entries */
+               err = -ENOSPC;
+               goto out;
+       }
+
+       /* Register new MAC */
+       table->refs[free] = 1;
+       table->entries[free] = cpu_to_be32(vlan | MLX4_VLAN_VALID);
+
+       err = mlx4_set_port_vlan_table(dev, port, table->entries);
+       if (unlikely(err)) {
+               mlx4_warn(dev, "Failed adding vlan: %u\n", vlan);
+               table->refs[free] = 0;
+               table->entries[free] = 0;
+               goto out;
+       }
+
+       *index = free;
+       ++table->total;
+out:
+       mutex_unlock(&table->mutex);
+       return err;
+}
+EXPORT_SYMBOL_GPL(mlx4_register_vlan);
+
+void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)
+{
+       struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
+
+       if (index < MLX4_VLAN_REGULAR) {
+               mlx4_warn(dev, "Trying to free special vlan index %d\n", index);
+               return;
+       }
+
+       mutex_lock(&table->mutex);
+       if (!table->refs[index]) {
+               mlx4_warn(dev, "No vlan entry for index %d\n", index);
+               goto out;
+       }
+       if (--table->refs[index]) {
+               mlx4_dbg(dev, "Have more references for index %d,"
+                        "no need to modify vlan table\n", index);
+               goto out;
+       }
+       table->entries[index] = 0;
+       mlx4_set_port_vlan_table(dev, port, table->entries);
+       --table->total;
+out:
+       mutex_unlock(&table->mutex);
+}
+EXPORT_SYMBOL_GPL(mlx4_unregister_vlan);
+
+int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port)
+{
+       struct mlx4_cmd_mailbox *mailbox;
+       int err;
+       u8 is_eth = dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH;
+
+       mailbox = mlx4_alloc_cmd_mailbox(dev);
+       if (IS_ERR(mailbox))
+               return PTR_ERR(mailbox);
+
+       memset(mailbox->buf, 0, 256);
+       if (is_eth) {
+               ((u8 *) mailbox->buf)[3] = 6;
+               ((__be16 *) mailbox->buf)[4] = cpu_to_be16(1 << 15);
+               ((__be16 *) mailbox->buf)[6] = cpu_to_be16(1 << 15);
+       }
+       err = mlx4_cmd(dev, mailbox->dma, port, is_eth, MLX4_CMD_SET_PORT,
+                      MLX4_CMD_TIME_CLASS_B);
+
+       mlx4_free_cmd_mailbox(dev, mailbox);
+       return err;
+}
index c49a86044bf7bec2c53d77264164e0c5e223e005..1c565ef8d179148ead7408457778dff904f9d439 100644 (file)
@@ -147,19 +147,42 @@ int mlx4_qp_modify(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
 }
 EXPORT_SYMBOL_GPL(mlx4_qp_modify);
 
-int mlx4_qp_alloc(struct mlx4_dev *dev, int sqpn, struct mlx4_qp *qp)
+int mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align, int *base)
+{
+       struct mlx4_priv *priv = mlx4_priv(dev);
+       struct mlx4_qp_table *qp_table = &priv->qp_table;
+       int qpn;
+
+       qpn = mlx4_bitmap_alloc_range(&qp_table->bitmap, cnt, align);
+       if (qpn == -1)
+               return -ENOMEM;
+
+       *base = qpn;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(mlx4_qp_reserve_range);
+
+void mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt)
+{
+       struct mlx4_priv *priv = mlx4_priv(dev);
+       struct mlx4_qp_table *qp_table = &priv->qp_table;
+       if (base_qpn < dev->caps.sqp_start + 8)
+               return;
+
+       mlx4_bitmap_free_range(&qp_table->bitmap, base_qpn, cnt);
+}
+EXPORT_SYMBOL_GPL(mlx4_qp_release_range);
+
+int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
        struct mlx4_qp_table *qp_table = &priv->qp_table;
        int err;
 
-       if (sqpn)
-               qp->qpn = sqpn;
-       else {
-               qp->qpn = mlx4_bitmap_alloc(&qp_table->bitmap);
-               if (qp->qpn == -1)
-                       return -ENOMEM;
-       }
+       if (!qpn)
+               return -EINVAL;
+
+       qp->qpn = qpn;
 
        err = mlx4_table_get(dev, &qp_table->qp_table, qp->qpn);
        if (err)
@@ -208,9 +231,6 @@ err_put_qp:
        mlx4_table_put(dev, &qp_table->qp_table, qp->qpn);
 
 err_out:
-       if (!sqpn)
-               mlx4_bitmap_free(&qp_table->bitmap, qp->qpn);
-
        return err;
 }
 EXPORT_SYMBOL_GPL(mlx4_qp_alloc);
@@ -239,9 +259,6 @@ void mlx4_qp_free(struct mlx4_dev *dev, struct mlx4_qp *qp)
        mlx4_table_put(dev, &qp_table->altc_table, qp->qpn);
        mlx4_table_put(dev, &qp_table->auxc_table, qp->qpn);
        mlx4_table_put(dev, &qp_table->qp_table, qp->qpn);
-
-       if (qp->qpn >= dev->caps.sqp_start + 8)
-               mlx4_bitmap_free(&qp_table->bitmap, qp->qpn);
 }
 EXPORT_SYMBOL_GPL(mlx4_qp_free);
 
@@ -255,6 +272,7 @@ int mlx4_init_qp_table(struct mlx4_dev *dev)
 {
        struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table;
        int err;
+       int reserved_from_top = 0;
 
        spin_lock_init(&qp_table->lock);
        INIT_RADIX_TREE(&dev->qp_table_tree, GFP_ATOMIC);
@@ -264,9 +282,40 @@ int mlx4_init_qp_table(struct mlx4_dev *dev)
         * block of special QPs must be aligned to a multiple of 8, so
         * round up.
         */
-       dev->caps.sqp_start = ALIGN(dev->caps.reserved_qps, 8);
+       dev->caps.sqp_start =
+               ALIGN(dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW], 8);
+
+       {
+               int sort[MLX4_NUM_QP_REGION];
+               int i, j, tmp;
+               int last_base = dev->caps.num_qps;
+
+               for (i = 1; i < MLX4_NUM_QP_REGION; ++i)
+                       sort[i] = i;
+
+               for (i = MLX4_NUM_QP_REGION; i > 0; --i) {
+                       for (j = 2; j < i; ++j) {
+                               if (dev->caps.reserved_qps_cnt[sort[j]] >
+                                   dev->caps.reserved_qps_cnt[sort[j - 1]]) {
+                                       tmp             = sort[j];
+                                       sort[j]         = sort[j - 1];
+                                       sort[j - 1]     = tmp;
+                               }
+                       }
+               }
+
+               for (i = 1; i < MLX4_NUM_QP_REGION; ++i) {
+                       last_base -= dev->caps.reserved_qps_cnt[sort[i]];
+                       dev->caps.reserved_qps_base[sort[i]] = last_base;
+                       reserved_from_top +=
+                               dev->caps.reserved_qps_cnt[sort[i]];
+               }
+
+       }
+
        err = mlx4_bitmap_init(&qp_table->bitmap, dev->caps.num_qps,
-                              (1 << 24) - 1, dev->caps.sqp_start + 8);
+                              (1 << 23) - 1, dev->caps.sqp_start + 8,
+                              reserved_from_top);
        if (err)
                return err;
 
index 533eb6db24b37d589996baa8ea882c3e764116b8..fe9f218691f5f0d48306b3586efe87a4b47a9007 100644 (file)
@@ -245,7 +245,7 @@ int mlx4_init_srq_table(struct mlx4_dev *dev)
        INIT_RADIX_TREE(&srq_table->tree, GFP_ATOMIC);
 
        err = mlx4_bitmap_init(&srq_table->bitmap, dev->caps.num_srqs,
-                              dev->caps.num_srqs - 1, dev->caps.reserved_srqs);
+                              dev->caps.num_srqs - 1, dev->caps.reserved_srqs, 0);
        if (err)
                return err;
 
index 38b90e7a7ed30b52d04fe46f64411a2991c3b5b0..7914867110ed74ef3e0f17f4dcba685ea4450d73 100644 (file)
@@ -168,7 +168,7 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
                        netif_device_detach(pegasus->net);
                if (netif_msg_drv(pegasus) && printk_ratelimit())
                        dev_err(&pegasus->intf->dev, "%s, status %d\n",
-                                       __FUNCTION__, ret);
+                                       __func__, ret);
                goto out;
        }
 
@@ -192,7 +192,7 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
        if (!buffer) {
                if (netif_msg_drv(pegasus))
                        dev_warn(&pegasus->intf->dev, "out of memory in %s\n",
-                                       __FUNCTION__);
+                                       __func__);
                return -ENOMEM;
        }
        memcpy(buffer, data, size);
index f972fef87c98839a9d3c8e1fc4f7c2516ed01199..ee51b6a5e60569be9d955e2bb0259a5341d0f6f5 100644 (file)
@@ -318,7 +318,7 @@ sbni_pci_probe( struct net_device  *dev )
                                continue;
                }
 
-               if( pci_irq_line <= 0  ||  pci_irq_line >= NR_IRQS )
+               if (pci_irq_line <= 0 || pci_irq_line >= nr_irqs)
                        printk( KERN_WARNING "  WARNING: The PCI BIOS assigned "
                                "this PCI card to IRQ %d, which is unlikely "
                                "to work!.\n"
diff --git a/drivers/net/xtsonic.c b/drivers/net/xtsonic.c
new file mode 100644 (file)
index 0000000..da42aa0
--- /dev/null
@@ -0,0 +1,319 @@
+/*
+ * xtsonic.c
+ *
+ * (C) 2001 - 2007 Tensilica Inc.
+ *     Kevin Chea <kchea@yahoo.com>
+ *     Marc Gauthier <marc@linux-xtensa.org>
+ *     Chris Zankel <chris@zankel.net>
+ *
+ * (C) 1996,1998 by Thomas Bogendoerfer (tsbogend@alpha.franken.de)
+ *
+ * This driver is based on work from Andreas Busse, but most of
+ * the code is rewritten.
+ *
+ * (C) 1995 by Andreas Busse (andy@waldorf-gmbh.de)
+ *
+ * A driver for the onboard Sonic ethernet controller on the XT2000.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/fcntl.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>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/dma.h>
+
+static char xtsonic_string[] = "xtsonic";
+
+extern unsigned xtboard_nvram_valid(void);
+extern void xtboard_get_ether_addr(unsigned char *buf);
+
+#include "sonic.h"
+
+/*
+ * According to the documentation for the Sonic ethernet controller,
+ * EOBC should be 760 words (1520 bytes) for 32-bit applications, and,
+ * as such, 2 words less than the buffer size. The value for RBSIZE
+ * defined in sonic.h, however is only 1520.
+ *
+ * (Note that in 16-bit configurations, EOBC is 759 words (1518 bytes) and
+ * RBSIZE 1520 bytes)
+ */
+#undef SONIC_RBSIZE
+#define SONIC_RBSIZE   1524
+
+/*
+ * The chip provides 256 byte register space.
+ */
+#define SONIC_MEM_SIZE 0x100
+
+/*
+ * Macros to access SONIC registers
+ */
+#define SONIC_READ(reg) \
+       (0xffff & *((volatile unsigned int *)dev->base_addr+reg))
+
+#define SONIC_WRITE(reg,val) \
+       *((volatile unsigned int *)dev->base_addr+reg) = val
+
+
+/* Use 0 for production, 1 for verification, and >2 for debug */
+#ifdef SONIC_DEBUG
+static unsigned int sonic_debug = SONIC_DEBUG;
+#else
+static unsigned int sonic_debug = 1;
+#endif
+
+/*
+ * We cannot use station (ethernet) address prefixes to detect the
+ * sonic controller since these are board manufacturer depended.
+ * So we check for known Silicon Revision IDs instead.
+ */
+static unsigned short known_revisions[] =
+{
+       0x101,                  /* SONIC 83934 */
+       0xffff                  /* end of list */
+};
+
+static int xtsonic_open(struct net_device *dev)
+{
+       if (request_irq(dev->irq,&sonic_interrupt,IRQF_DISABLED,"sonic",dev)) {
+               printk(KERN_ERR "%s: unable to get IRQ %d.\n",
+                      dev->name, dev->irq);
+               return -EAGAIN;
+       }
+       return sonic_open(dev);
+}
+
+static int xtsonic_close(struct net_device *dev)
+{
+       int err;
+       err = sonic_close(dev);
+       free_irq(dev->irq, dev);
+       return err;
+}
+
+static int __init sonic_probe1(struct net_device *dev)
+{
+       static unsigned version_printed = 0;
+       unsigned int silicon_revision;
+       struct sonic_local *lp = netdev_priv(dev);
+       unsigned int base_addr = dev->base_addr;
+       int i;
+       int err = 0;
+
+       if (!request_mem_region(base_addr, 0x100, xtsonic_string))
+               return -EBUSY;
+
+       /*
+        * get the Silicon Revision ID. If this is one of the known
+        * one assume that we found a SONIC ethernet controller at
+        * the expected location.
+        */
+       silicon_revision = SONIC_READ(SONIC_SR);
+       if (sonic_debug > 1)
+               printk("SONIC Silicon Revision = 0x%04x\n",silicon_revision);
+
+       i = 0;
+       while ((known_revisions[i] != 0xffff) &&
+                       (known_revisions[i] != silicon_revision))
+               i++;
+
+       if (known_revisions[i] == 0xffff) {
+               printk("SONIC ethernet controller not found (0x%4x)\n",
+                               silicon_revision);
+               return -ENODEV;
+       }
+
+       if (sonic_debug  &&  version_printed++ == 0)
+               printk(version);
+
+       /*
+        * Put the sonic into software reset, then retrieve ethernet address.
+        * Note: we are assuming that the boot-loader has initialized the cam.
+        */
+       SONIC_WRITE(SONIC_CMD,SONIC_CR_RST);
+       SONIC_WRITE(SONIC_DCR,
+                   SONIC_DCR_WC0|SONIC_DCR_DW|SONIC_DCR_LBR|SONIC_DCR_SBUS);
+       SONIC_WRITE(SONIC_CEP,0);
+       SONIC_WRITE(SONIC_IMR,0);
+
+       SONIC_WRITE(SONIC_CMD,SONIC_CR_RST);
+       SONIC_WRITE(SONIC_CEP,0);
+
+       for (i=0; i<3; i++) {
+               unsigned int val = SONIC_READ(SONIC_CAP0-i);
+               dev->dev_addr[i*2] = val;
+               dev->dev_addr[i*2+1] = val >> 8;
+       }
+
+       /* Initialize the device structure. */
+
+       lp->dma_bitmode = SONIC_BITMODE32;
+
+       /*
+        *  Allocate local private descriptor areas in uncached space.
+        *  The entire structure must be located within the same 64kb segment.
+        *  A simple way to ensure this is to allocate twice the
+        *  size of the structure -- given that the structure is
+        *  much less than 64 kB, at least one of the halves of
+        *  the allocated area will be contained entirely in 64 kB.
+        *  We also allocate extra space for a pointer to allow freeing
+        *  this structure later on (in xtsonic_cleanup_module()).
+        */
+       lp->descriptors =
+               dma_alloc_coherent(lp->device,
+                       SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
+                       &lp->descriptors_laddr, GFP_KERNEL);
+
+       if (lp->descriptors == NULL) {
+               printk(KERN_ERR "%s: couldn't alloc DMA memory for "
+                               " descriptors.\n", lp->device->bus_id);
+               goto out;
+       }
+
+       lp->cda = lp->descriptors;
+       lp->tda = lp->cda + (SIZEOF_SONIC_CDA
+                            * SONIC_BUS_SCALE(lp->dma_bitmode));
+       lp->rda = lp->tda + (SIZEOF_SONIC_TD * SONIC_NUM_TDS
+                            * SONIC_BUS_SCALE(lp->dma_bitmode));
+       lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
+                            * SONIC_BUS_SCALE(lp->dma_bitmode));
+
+       /* get the virtual dma address */
+
+       lp->cda_laddr = lp->descriptors_laddr;
+       lp->tda_laddr = lp->cda_laddr + (SIZEOF_SONIC_CDA
+                                        * SONIC_BUS_SCALE(lp->dma_bitmode));
+       lp->rda_laddr = lp->tda_laddr + (SIZEOF_SONIC_TD * SONIC_NUM_TDS
+                                        * SONIC_BUS_SCALE(lp->dma_bitmode));
+       lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
+                                        * SONIC_BUS_SCALE(lp->dma_bitmode));
+
+       dev->open = xtsonic_open;
+       dev->stop = xtsonic_close;
+       dev->hard_start_xmit    = sonic_send_packet;
+       dev->get_stats          = sonic_get_stats;
+       dev->set_multicast_list = &sonic_multicast_list;
+       dev->tx_timeout         = sonic_tx_timeout;
+       dev->watchdog_timeo     = TX_TIMEOUT;
+
+       /*
+        * clear tally counter
+        */
+       SONIC_WRITE(SONIC_CRCT,0xffff);
+       SONIC_WRITE(SONIC_FAET,0xffff);
+       SONIC_WRITE(SONIC_MPT,0xffff);
+
+       return 0;
+out:
+       release_region(dev->base_addr, SONIC_MEM_SIZE);
+       return err;
+}
+
+
+/*
+ * Probe for a SONIC ethernet controller on an XT2000 board.
+ * Actually probing is superfluous but we're paranoid.
+ */
+
+int __init xtsonic_probe(struct platform_device *pdev)
+{
+       struct net_device *dev;
+       struct sonic_local *lp;
+       struct resource *resmem, *resirq;
+       int err = 0;
+
+       DECLARE_MAC_BUF(mac);
+
+       if ((resmem = platform_get_resource(pdev, IORESOURCE_MEM, 0)) == NULL)
+               return -ENODEV;
+
+       if ((resirq = platform_get_resource(pdev, IORESOURCE_IRQ, 0)) == NULL)
+               return -ENODEV;
+
+       if ((dev = alloc_etherdev(sizeof(struct sonic_local))) == NULL)
+               return -ENOMEM;
+
+       lp = netdev_priv(dev);
+       lp->device = &pdev->dev;
+       SET_NETDEV_DEV(dev, &pdev->dev);
+       netdev_boot_setup_check(dev);
+
+       dev->base_addr = resmem->start;
+       dev->irq = resirq->start;
+
+       if ((err = sonic_probe1(dev)))
+               goto out;
+       if ((err = register_netdev(dev)))
+               goto out1;
+
+       printk("%s: SONIC ethernet @%08lx, MAC %s, IRQ %d\n", dev->name,
+              dev->base_addr, print_mac(mac, dev->dev_addr), dev->irq);
+
+       return 0;
+
+out1:
+       release_region(dev->base_addr, SONIC_MEM_SIZE);
+out:
+       free_netdev(dev);
+
+       return err;
+}
+
+MODULE_DESCRIPTION("Xtensa XT2000 SONIC ethernet driver");
+module_param(sonic_debug, int, 0);
+MODULE_PARM_DESC(sonic_debug, "xtsonic debug level (1-4)");
+
+#include "sonic.c"
+
+static int __devexit xtsonic_device_remove (struct platform_device *pdev)
+{
+       struct net_device *dev = platform_get_drvdata(pdev);
+       struct sonic_local *lp = netdev_priv(dev);
+
+       unregister_netdev(dev);
+       dma_free_coherent(lp->device,
+                         SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
+                         lp->descriptors, lp->descriptors_laddr);
+       release_region (dev->base_addr, SONIC_MEM_SIZE);
+       free_netdev(dev);
+
+       return 0;
+}
+
+static struct platform_driver xtsonic_driver = {
+       .probe = xtsonic_probe,
+       .remove = __devexit_p(xtsonic_device_remove),
+       .driver = {
+               .name = xtsonic_string,
+       },
+};
+
+static int __init xtsonic_init(void)
+{
+       return platform_driver_register(&xtsonic_driver);
+}
+
+static void __exit xtsonic_cleanup(void)
+{
+       platform_driver_unregister(&xtsonic_driver);
+}
+
+module_init(xtsonic_init);
+module_exit(xtsonic_cleanup);
index 6a98dc8aa30b1af9a1e8ce9a2a8264073a631eee..24bbef777c1914cfb7096cec8f198fdbc7512618 100644 (file)
@@ -41,7 +41,7 @@ void of_register_i2c_devices(struct i2c_adapter *adap,
 
                info.addr = *addr;
 
-               request_module(info.type);
+               request_module("%s", info.type);
 
                result = i2c_new_device(adap, &info);
                if (result == NULL) {
index b01eec026f68b3f8765bd50d35070757b1795785..bed0ed6dcdc1329259c58a72e2b697bfbd72e091 100644 (file)
@@ -61,6 +61,8 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np)
                        spi->mode |= SPI_CPHA;
                if (of_find_property(nc, "spi-cpol", NULL))
                        spi->mode |= SPI_CPOL;
+               if (of_find_property(nc, "spi-cs-high", NULL))
+                       spi->mode |= SPI_CS_HIGH;
 
                /* Device speed */
                prop = of_get_property(nc, "spi-max-frequency", &len);
index ed982273fb8b1d9311aba68a3b2a42de5d174e78..b55cd23ffdefc81dfb80409a98c5697c21822b50 100644 (file)
@@ -41,7 +41,6 @@ static cpumask_t marked_cpus = CPU_MASK_NONE;
 static DEFINE_SPINLOCK(task_mortuary);
 static void process_task_mortuary(void);
 
-
 /* Take ownership of the task struct and place it on the
  * list for processing. Only after two full buffer syncs
  * does the task eventually get freed, because by then
@@ -341,7 +340,7 @@ static void add_trace_begin(void)
  * Add IBS fetch and op entries to event buffer
  */
 static void add_ibs_begin(struct oprofile_cpu_buffer *cpu_buf, int code,
-       int in_kernel, struct mm_struct *mm)
+                         struct mm_struct *mm)
 {
        unsigned long rip;
        int i, count;
@@ -565,9 +564,11 @@ void sync_buffer(int cpu)
        struct task_struct *new;
        unsigned long cookie = 0;
        int in_kernel = 1;
-       unsigned int i;
        sync_buffer_state state = sb_buffer_start;
+#ifndef CONFIG_OPROFILE_IBS
+       unsigned int i;
        unsigned long available;
+#endif
 
        mutex_lock(&buffer_mutex);
 
@@ -575,9 +576,13 @@ void sync_buffer(int cpu)
 
        /* Remember, only we can modify tail_pos */
 
+#ifndef CONFIG_OPROFILE_IBS
        available = get_slots(cpu_buf);
 
        for (i = 0; i < available; ++i) {
+#else
+       while (get_slots(cpu_buf)) {
+#endif
                struct op_sample *s = &cpu_buf->buffer[cpu_buf->tail_pos];
 
                if (is_code(s->eip)) {
@@ -593,12 +598,10 @@ void sync_buffer(int cpu)
 #ifdef CONFIG_OPROFILE_IBS
                        } else if (s->event == IBS_FETCH_BEGIN) {
                                state = sb_bt_start;
-                               add_ibs_begin(cpu_buf,
-                                       IBS_FETCH_CODE, in_kernel, mm);
+                               add_ibs_begin(cpu_buf, IBS_FETCH_CODE, mm);
                        } else if (s->event == IBS_OP_BEGIN) {
                                state = sb_bt_start;
-                               add_ibs_begin(cpu_buf,
-                                       IBS_OP_CODE, in_kernel, mm);
+                               add_ibs_begin(cpu_buf, IBS_OP_CODE, mm);
 #endif
                        } else {
                                struct mm_struct *oldmm = mm;
@@ -628,3 +631,27 @@ void sync_buffer(int cpu)
 
        mutex_unlock(&buffer_mutex);
 }
+
+/* The function can be used to add a buffer worth of data directly to
+ * the kernel buffer. The buffer is assumed to be a circular buffer.
+ * Take the entries from index start and end at index end, wrapping
+ * at max_entries.
+ */
+void oprofile_put_buff(unsigned long *buf, unsigned int start,
+                      unsigned int stop, unsigned int max)
+{
+       int i;
+
+       i = start;
+
+       mutex_lock(&buffer_mutex);
+       while (i != stop) {
+               add_event_entry(buf[i++]);
+
+               if (i >= max)
+                       i = 0;
+       }
+
+       mutex_unlock(&buffer_mutex);
+}
+
index 08866f6a96a36c6ef4e5355634c284fe29a530fd..3110732c1835acc640dbbc248d7a5c02403f0d83 100644 (file)
@@ -9,13 +9,13 @@
 
 #ifndef OPROFILE_BUFFER_SYNC_H
 #define OPROFILE_BUFFER_SYNC_H
+
 /* add the necessary profiling hooks */
 int sync_start(void);
 
 /* remove the hooks */
 void sync_stop(void);
+
 /* sync the given CPU's buffer */
 void sync_buffer(int cpu);
 
index e1bd5a937f6c77d33ac1f92a16966e556c8bfff8..01d38e78cde18bd341fca22940249e4a80068217 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/oprofile.h>
 #include <linux/vmalloc.h>
 #include <linux/errno.h>
+
 #include "event_buffer.h"
 #include "cpu_buffer.h"
 #include "buffer_sync.h"
@@ -38,27 +38,40 @@ static int work_enabled;
 void free_cpu_buffers(void)
 {
        int i;
-       for_each_online_cpu(i) {
+
+       for_each_possible_cpu(i) {
                vfree(per_cpu(cpu_buffer, i).buffer);
                per_cpu(cpu_buffer, i).buffer = NULL;
        }
 }
 
+unsigned long oprofile_get_cpu_buffer_size(void)
+{
+       return fs_cpu_buffer_size;
+}
+
+void oprofile_cpu_buffer_inc_smpl_lost(void)
+{
+       struct oprofile_cpu_buffer *cpu_buf
+               = &__get_cpu_var(cpu_buffer);
+
+       cpu_buf->sample_lost_overflow++;
+}
+
 int alloc_cpu_buffers(void)
 {
        int i;
+
        unsigned long buffer_size = fs_cpu_buffer_size;
-       for_each_online_cpu(i) {
+
+       for_each_possible_cpu(i) {
                struct oprofile_cpu_buffer *b = &per_cpu(cpu_buffer, i);
+
                b->buffer = vmalloc_node(sizeof(struct op_sample) * buffer_size,
                        cpu_to_node(i));
                if (!b->buffer)
                        goto fail;
+
                b->last_task = NULL;
                b->last_is_kernel = -1;
                b->tracing = 0;
@@ -112,7 +125,7 @@ void end_cpu_work(void)
 }
 
 /* Resets the cpu buffer to a sane state. */
-void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf)
+void cpu_buffer_reset(struct oprofile_cpu_buffer *cpu_buf)
 {
        /* reset these to invalid values; the next sample
         * collected will populate the buffer with proper
@@ -123,7 +136,7 @@ void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf)
 }
 
 /* compute number of available slots in cpu_buffer queue */
-static unsigned long nr_available_slots(struct oprofile_cpu_buffer const * b)
+static unsigned long nr_available_slots(struct oprofile_cpu_buffer const *b)
 {
        unsigned long head = b->head_pos;
        unsigned long tail = b->tail_pos;
@@ -134,7 +147,7 @@ static unsigned long nr_available_slots(struct oprofile_cpu_buffer const * b)
        return tail + (b->buffer_size - head) - 1;
 }
 
-static void increment_head(struct oprofile_cpu_buffer * b)
+static void increment_head(struct oprofile_cpu_buffer *b)
 {
        unsigned long new_head = b->head_pos + 1;
 
@@ -149,17 +162,17 @@ static void increment_head(struct oprofile_cpu_buffer * b)
 }
 
 static inline void
-add_sample(struct oprofile_cpu_buffer * cpu_buf,
-           unsigned long pc, unsigned long event)
+add_sample(struct oprofile_cpu_buffer *cpu_buf,
+          unsigned long pc, unsigned long event)
 {
-       struct op_sample * entry = &cpu_buf->buffer[cpu_buf->head_pos];
+       struct op_sample *entry = &cpu_buf->buffer[cpu_buf->head_pos];
        entry->eip = pc;
        entry->event = event;
        increment_head(cpu_buf);
 }
 
 static inline void
-add_code(struct oprofile_cpu_buffer * buffer, unsigned long value)
+add_code(struct oprofile_cpu_buffer *buffer, unsigned long value)
 {
        add_sample(buffer, ESCAPE_CODE, value);
 }
@@ -173,10 +186,10 @@ add_code(struct oprofile_cpu_buffer * buffer, unsigned long value)
  * pc. We tag this in the buffer by generating kernel enter/exit
  * events whenever is_kernel changes
  */
-static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc,
+static int log_sample(struct oprofile_cpu_buffer *cpu_buf, unsigned long pc,
                      int is_kernel, unsigned long event)
 {
-       struct task_struct * task;
+       struct task_struct *task;
 
        cpu_buf->sample_received++;
 
@@ -205,7 +218,7 @@ static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc,
                cpu_buf->last_task = task;
                add_code(cpu_buf, (unsigned long)task);
        }
+
        add_sample(cpu_buf, pc, event);
        return 1;
 }
@@ -222,7 +235,7 @@ static int oprofile_begin_trace(struct oprofile_cpu_buffer *cpu_buf)
        return 1;
 }
 
-static void oprofile_end_trace(struct oprofile_cpu_buffer * cpu_buf)
+static void oprofile_end_trace(struct oprofile_cpu_buffer *cpu_buf)
 {
        cpu_buf->tracing = 0;
 }
@@ -257,21 +270,23 @@ void oprofile_add_sample(struct pt_regs * const regs, unsigned long event)
 
 #ifdef CONFIG_OPROFILE_IBS
 
-#define MAX_IBS_SAMPLE_SIZE    14
-static int log_ibs_sample(struct oprofile_cpu_buffer *cpu_buf,
-       unsigned long pc, int is_kernel, unsigned  int *ibs, int ibs_code)
+#define MAX_IBS_SAMPLE_SIZE 14
+
+void oprofile_add_ibs_sample(struct pt_regs *const regs,
+                            unsigned int *const ibs_sample, int ibs_code)
 {
+       int is_kernel = !user_mode(regs);
+       struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(cpu_buffer);
        struct task_struct *task;
 
        cpu_buf->sample_received++;
 
        if (nr_available_slots(cpu_buf) < MAX_IBS_SAMPLE_SIZE) {
+               /* we can't backtrace since we lost the source of this event */
                cpu_buf->sample_lost_overflow++;
-               return 0;
+               return;
        }
 
-       is_kernel = !!is_kernel;
-
        /* notice a switch from user->kernel or vice versa */
        if (cpu_buf->last_is_kernel != is_kernel) {
                cpu_buf->last_is_kernel = is_kernel;
@@ -281,7 +296,6 @@ static int log_ibs_sample(struct oprofile_cpu_buffer *cpu_buf,
        /* notice a task switch */
        if (!is_kernel) {
                task = current;
-
                if (cpu_buf->last_task != task) {
                        cpu_buf->last_task = task;
                        add_code(cpu_buf, (unsigned long)task);
@@ -289,36 +303,17 @@ static int log_ibs_sample(struct oprofile_cpu_buffer *cpu_buf,
        }
 
        add_code(cpu_buf, ibs_code);
-       add_sample(cpu_buf, ibs[0], ibs[1]);
-       add_sample(cpu_buf, ibs[2], ibs[3]);
-       add_sample(cpu_buf, ibs[4], ibs[5]);
+       add_sample(cpu_buf, ibs_sample[0], ibs_sample[1]);
+       add_sample(cpu_buf, ibs_sample[2], ibs_sample[3]);
+       add_sample(cpu_buf, ibs_sample[4], ibs_sample[5]);
 
        if (ibs_code == IBS_OP_BEGIN) {
-       add_sample(cpu_buf, ibs[6], ibs[7]);
-       add_sample(cpu_buf, ibs[8], ibs[9]);
-       add_sample(cpu_buf, ibs[10], ibs[11]);
-       }
-
-       return 1;
-}
-
-void oprofile_add_ibs_sample(struct pt_regs *const regs,
-                               unsigned int * const ibs_sample, u8 code)
-{
-       int is_kernel = !user_mode(regs);
-       unsigned long pc = profile_pc(regs);
-
-       struct oprofile_cpu_buffer *cpu_buf =
-                        &per_cpu(cpu_buffer, smp_processor_id());
-
-       if (!backtrace_depth) {
-               log_ibs_sample(cpu_buf, pc, is_kernel, ibs_sample, code);
-               return;
+               add_sample(cpu_buf, ibs_sample[6], ibs_sample[7]);
+               add_sample(cpu_buf, ibs_sample[8], ibs_sample[9]);
+               add_sample(cpu_buf, ibs_sample[10], ibs_sample[11]);
        }
 
-       /* if log_sample() fails we can't backtrace since we lost the source
-       * of this event */
-       if (log_ibs_sample(cpu_buf, pc, is_kernel, ibs_sample, code))
+       if (backtrace_depth)
                oprofile_ops.backtrace(regs, backtrace_depth);
 }
 
@@ -363,11 +358,16 @@ void oprofile_add_trace(unsigned long pc)
  */
 static void wq_sync_buffer(struct work_struct *work)
 {
-       struct oprofile_cpu_buffer * b =
+       struct oprofile_cpu_buffer *b =
                container_of(work, struct oprofile_cpu_buffer, work.work);
        if (b->cpu != smp_processor_id()) {
                printk(KERN_DEBUG "WQ on CPU%d, prefer CPU%d\n",
                       smp_processor_id(), b->cpu);
+
+               if (!cpu_online(b->cpu)) {
+                       cancel_delayed_work(&b->work);
+                       return;
+               }
        }
        sync_buffer(b->cpu);
 
index 9c44d004da69c6a3747d5b9a4976be7f63c0d099..d3cc26264db55b60948a71b9f8500a236666a64d 100644 (file)
@@ -15,9 +15,9 @@
 #include <linux/workqueue.h>
 #include <linux/cache.h>
 #include <linux/sched.h>
+
 struct task_struct;
+
 int alloc_cpu_buffers(void);
 void free_cpu_buffers(void);
 
@@ -31,15 +31,15 @@ struct op_sample {
        unsigned long eip;
        unsigned long event;
 };
+
 struct oprofile_cpu_buffer {
        volatile unsigned long head_pos;
        volatile unsigned long tail_pos;
        unsigned long buffer_size;
-       struct task_struct * last_task;
+       struct task_struct *last_task;
        int last_is_kernel;
        int tracing;
-       struct op_sample * buffer;
+       struct op_sample *buffer;
        unsigned long sample_received;
        unsigned long sample_lost_overflow;
        unsigned long backtrace_aborted;
@@ -50,7 +50,7 @@ struct oprofile_cpu_buffer {
 
 DECLARE_PER_CPU(struct oprofile_cpu_buffer, cpu_buffer);
 
-void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf);
+void cpu_buffer_reset(struct oprofile_cpu_buffer *cpu_buf);
 
 /* transient events for the CPU buffer -> event buffer */
 #define CPU_IS_KERNEL 1
index 8d692a5c8e73f730fa5a5417f73e149768627bc1..d962ba0dd87a2f41188a85714df6b28366d34b59 100644 (file)
 #include <linux/dcookies.h>
 #include <linux/fs.h>
 #include <asm/uaccess.h>
+
 #include "oprof.h"
 #include "event_buffer.h"
 #include "oprofile_stats.h"
 
 DEFINE_MUTEX(buffer_mutex);
+
 static unsigned long buffer_opened;
 static DECLARE_WAIT_QUEUE_HEAD(buffer_wait);
-static unsigned long * event_buffer;
+static unsigned long *event_buffer;
 static unsigned long buffer_size;
 static unsigned long buffer_watershed;
 static size_t buffer_pos;
@@ -66,7 +66,7 @@ void wake_up_buffer_waiter(void)
        mutex_unlock(&buffer_mutex);
 }
 
+
 int alloc_event_buffer(void)
 {
        int err = -ENOMEM;
@@ -76,13 +76,13 @@ int alloc_event_buffer(void)
        buffer_size = fs_buffer_size;
        buffer_watershed = fs_buffer_watershed;
        spin_unlock_irqrestore(&oprofilefs_lock, flags);
+
        if (buffer_watershed >= buffer_size)
                return -EINVAL;
+
        event_buffer = vmalloc(sizeof(unsigned long) * buffer_size);
        if (!event_buffer)
-               goto out; 
+               goto out;
 
        err = 0;
 out:
@@ -97,8 +97,8 @@ void free_event_buffer(void)
        event_buffer = NULL;
 }
 
-static int event_buffer_open(struct inode * inode, struct file * file)
+
+static int event_buffer_open(struct inode *inode, struct file *file)
 {
        int err = -EPERM;
 
@@ -116,14 +116,14 @@ static int event_buffer_open(struct inode * inode, struct file * file)
        file->private_data = dcookie_register();
        if (!file->private_data)
                goto out;
-                
+
        if ((err = oprofile_setup()))
                goto fail;
 
        /* NB: the actual start happens from userspace
         * echo 1 >/dev/oprofile/enable
         */
+
        return 0;
 
 fail:
@@ -134,7 +134,7 @@ out:
 }
 
 
-static int event_buffer_release(struct inode * inode, struct file * file)
+static int event_buffer_release(struct inode *inode, struct file *file)
 {
        oprofile_stop();
        oprofile_shutdown();
@@ -146,8 +146,8 @@ static int event_buffer_release(struct inode * inode, struct file * file)
 }
 
 
-static ssize_t event_buffer_read(struct file * file, char __user * buf,
-                                size_t count, loff_t * offset)
+static ssize_t event_buffer_read(struct file *file, char __user *buf,
+                                size_t count, loff_t *offset)
 {
        int retval = -EINVAL;
        size_t const max = buffer_size * sizeof(unsigned long);
@@ -172,18 +172,18 @@ static ssize_t event_buffer_read(struct file * file, char __user * buf,
        retval = -EFAULT;
 
        count = buffer_pos * sizeof(unsigned long);
+
        if (copy_to_user(buf, event_buffer, count))
                goto out;
 
        retval = count;
        buffer_pos = 0;
+
 out:
        mutex_unlock(&buffer_mutex);
        return retval;
 }
+
 const struct file_operations event_buffer_fops = {
        .open           = event_buffer_open,
        .release        = event_buffer_release,
index 5076ed1ebd8feff23e3df134a808eb211e2cdfc7..4e70749f8d16e122a0fab36fa065889e018ef954 100644 (file)
 #ifndef EVENT_BUFFER_H
 #define EVENT_BUFFER_H
 
-#include <linux/types.h> 
+#include <linux/types.h>
 #include <asm/mutex.h>
+
 int alloc_event_buffer(void);
 
 void free_event_buffer(void);
+
+/**
+ * Add data to the event buffer.
+ * The data passed is free-form, but typically consists of
+ * file offsets, dcookies, context information, and ESCAPE codes.
+ */
+void add_event_entry(unsigned long data);
+
 /* wake up the process sleeping on the event file */
 void wake_up_buffer_waiter(void);
 
@@ -24,10 +31,10 @@ void wake_up_buffer_waiter(void);
 #define NO_COOKIE 0UL
 
 extern const struct file_operations event_buffer_fops;
+
 /* mutex between sync_cpu_buffers() and the
  * file reading code.
  */
 extern struct mutex buffer_mutex;
+
 #endif /* EVENT_BUFFER_H */
index 2c645170f06e49a80da62f740445fcea96592c62..cd375907f26fcd3cc452f021fa893e51870941f9 100644 (file)
@@ -19,7 +19,7 @@
 #include "cpu_buffer.h"
 #include "buffer_sync.h"
 #include "oprofile_stats.h"
+
 struct oprofile_operations oprofile_ops;
 
 unsigned long oprofile_started;
@@ -36,7 +36,7 @@ static int timer = 0;
 int oprofile_setup(void)
 {
        int err;
+
        mutex_lock(&start_mutex);
 
        if ((err = alloc_cpu_buffers()))
@@ -44,10 +44,10 @@ int oprofile_setup(void)
 
        if ((err = alloc_event_buffer()))
                goto out1;
+
        if (oprofile_ops.setup && (err = oprofile_ops.setup()))
                goto out2;
+
        /* Note even though this starts part of the
         * profiling overhead, it's necessary to prevent
         * us missing task deaths and eventually oopsing
@@ -74,7 +74,7 @@ post_sync:
        is_setup = 1;
        mutex_unlock(&start_mutex);
        return 0;
+
 out3:
        if (oprofile_ops.shutdown)
                oprofile_ops.shutdown();
@@ -92,17 +92,17 @@ out:
 int oprofile_start(void)
 {
        int err = -EINVAL;
+
        mutex_lock(&start_mutex);
+
        if (!is_setup)
                goto out;
 
-       err = 0; 
+       err = 0;
+
        if (oprofile_started)
                goto out;
+
        oprofile_reset_stats();
 
        if ((err = oprofile_ops.start()))
@@ -114,7 +114,7 @@ out:
        return err;
 }
 
+
 /* echo 0>/dev/oprofile/enable */
 void oprofile_stop(void)
 {
@@ -204,13 +204,13 @@ static void __exit oprofile_exit(void)
        oprofile_arch_exit();
 }
 
+
 module_init(oprofile_init);
 module_exit(oprofile_exit);
 
 module_param_named(timer, timer, int, 0644);
 MODULE_PARM_DESC(timer, "force use of timer interrupt");
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("John Levon <levon@movementarian.org>");
 MODULE_DESCRIPTION("OProfile system profiler");
index 18323650806e58013820984bbe69bd16aabbda4e..5df0c21a608ffbf48fa05b516fc9ff057509d148 100644 (file)
@@ -11,7 +11,7 @@
 #define OPROF_H
 
 int oprofile_setup(void);
-void oprofile_shutdown(void); 
+void oprofile_shutdown(void);
 
 int oprofilefs_register(void);
 void oprofilefs_unregister(void);
@@ -20,20 +20,20 @@ int oprofile_start(void);
 void oprofile_stop(void);
 
 struct oprofile_operations;
+
 extern unsigned long fs_buffer_size;
 extern unsigned long fs_cpu_buffer_size;
 extern unsigned long fs_buffer_watershed;
 extern struct oprofile_operations oprofile_ops;
 extern unsigned long oprofile_started;
 extern unsigned long backtrace_depth;
+
 struct super_block;
 struct dentry;
 
-void oprofile_create_files(struct super_block * sb, struct dentry * root);
-void oprofile_timer_init(struct oprofile_operations * ops);
+void oprofile_create_files(struct super_block *sb, struct dentry *root);
+void oprofile_timer_init(struct oprofile_operations *ops);
 
 int oprofile_set_backtrace(unsigned long depth);
+
 #endif /* OPROF_H */
index ef953ba5ab6b239d1b08d8ec4a423b2dca21d17a..cc106d503acec3cdb2917ba0ea316e267474f724 100644 (file)
 #include "event_buffer.h"
 #include "oprofile_stats.h"
 #include "oprof.h"
+
 unsigned long fs_buffer_size = 131072;
 unsigned long fs_cpu_buffer_size = 8192;
 unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
 
-static ssize_t depth_read(struct file * file, char __user * buf, size_t count, loff_t * offset)
+static ssize_t depth_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
 {
        return oprofilefs_ulong_to_user(backtrace_depth, buf, count, offset);
 }
 
 
-static ssize_t depth_write(struct file * file, char const __user * buf, size_t count, loff_t * offset)
+static ssize_t depth_write(struct file *file, char const __user *buf, size_t count, loff_t *offset)
 {
        unsigned long val;
        int retval;
@@ -49,8 +49,8 @@ static const struct file_operations depth_fops = {
        .write          = depth_write
 };
 
-static ssize_t pointer_size_read(struct file * file, char __user * buf, size_t count, loff_t * offset)
+
+static ssize_t pointer_size_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
 {
        return oprofilefs_ulong_to_user(sizeof(void *), buf, count, offset);
 }
@@ -61,24 +61,24 @@ static const struct file_operations pointer_size_fops = {
 };
 
 
-static ssize_t cpu_type_read(struct file * file, char __user * buf, size_t count, loff_t * offset)
+static ssize_t cpu_type_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
 {
        return oprofilefs_str_to_user(oprofile_ops.cpu_type, buf, count, offset);
 }
+
+
 static const struct file_operations cpu_type_fops = {
        .read           = cpu_type_read,
 };
-static ssize_t enable_read(struct file * file, char __user * buf, size_t count, loff_t * offset)
+
+
+static ssize_t enable_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
 {
        return oprofilefs_ulong_to_user(oprofile_started, buf, count, offset);
 }
 
 
-static ssize_t enable_write(struct file * file, char const __user * buf, size_t count, loff_t * offset)
+static ssize_t enable_write(struct file *file, char const __user *buf, size_t count, loff_t *offset)
 {
        unsigned long val;
        int retval;
@@ -89,7 +89,7 @@ static ssize_t enable_write(struct file * file, char const __user * buf, size_t
        retval = oprofilefs_ulong_from_user(&val, buf, count);
        if (retval)
                return retval;
+
        if (val)
                retval = oprofile_start();
        else
@@ -100,14 +100,14 @@ static ssize_t enable_write(struct file * file, char const __user * buf, size_t
        return count;
 }
 
+
 static const struct file_operations enable_fops = {
        .read           = enable_read,
        .write          = enable_write,
 };
 
 
-static ssize_t dump_write(struct file * file, char const __user * buf, size_t count, loff_t * offset)
+static ssize_t dump_write(struct file *file, char const __user *buf, size_t count, loff_t *offset)
 {
        wake_up_buffer_waiter();
        return count;
@@ -117,8 +117,8 @@ static ssize_t dump_write(struct file * file, char const __user * buf, size_t co
 static const struct file_operations dump_fops = {
        .write          = dump_write,
 };
-void oprofile_create_files(struct super_block * sb, struct dentry * root)
+
+void oprofile_create_files(struct super_block *sb, struct dentry *root)
 {
        oprofilefs_create_file(sb, root, "enable", &enable_fops);
        oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666);
@@ -126,7 +126,7 @@ void oprofile_create_files(struct super_block * sb, struct dentry * root)
        oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size);
        oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed);
        oprofilefs_create_ulong(sb, root, "cpu_buffer_size", &fs_cpu_buffer_size);
-       oprofilefs_create_file(sb, root, "cpu_type", &cpu_type_fops); 
+       oprofilefs_create_file(sb, root, "cpu_type", &cpu_type_fops);
        oprofilefs_create_file(sb, root, "backtrace_depth", &depth_fops);
        oprofilefs_create_file(sb, root, "pointer_size", &pointer_size_fops);
        oprofile_create_stats_files(sb, root);
index f99b28e7b79a424cb4aa52506f9ac6e0109e1391..e1f6ce03705ed915d94b77f1dde0a687e07e08f8 100644 (file)
 #include <linux/smp.h>
 #include <linux/cpumask.h>
 #include <linux/threads.h>
+
 #include "oprofile_stats.h"
 #include "cpu_buffer.h"
+
 struct oprofile_stat_struct oprofile_stats;
+
 void oprofile_reset_stats(void)
 {
-       struct oprofile_cpu_buffer * cpu_buf; 
+       struct oprofile_cpu_buffer *cpu_buf;
        int i;
+
        for_each_possible_cpu(i) {
                cpu_buf = &per_cpu(cpu_buffer, i);
                cpu_buf->sample_received = 0;
@@ -29,18 +29,18 @@ void oprofile_reset_stats(void)
                cpu_buf->backtrace_aborted = 0;
                cpu_buf->sample_invalid_eip = 0;
        }
+
        atomic_set(&oprofile_stats.sample_lost_no_mm, 0);
        atomic_set(&oprofile_stats.sample_lost_no_mapping, 0);
        atomic_set(&oprofile_stats.event_lost_overflow, 0);
 }
 
 
-void oprofile_create_stats_files(struct super_block * sb, struct dentry * root)
+void oprofile_create_stats_files(struct super_block *sb, struct dentry *root)
 {
-       struct oprofile_cpu_buffer * cpu_buf;
-       struct dentry * cpudir;
-       struct dentry * dir;
+       struct oprofile_cpu_buffer *cpu_buf;
+       struct dentry *cpudir;
+       struct dentry *dir;
        char buf[10];
        int i;
 
@@ -52,7 +52,7 @@ void oprofile_create_stats_files(struct super_block * sb, struct dentry * root)
                cpu_buf = &per_cpu(cpu_buffer, i);
                snprintf(buf, 10, "cpu%d", i);
                cpudir = oprofilefs_mkdir(sb, dir, buf);
+
                /* Strictly speaking access to these ulongs is racy,
                 * but we can't simply lock them, and they are
                 * informational only.
@@ -66,7 +66,7 @@ void oprofile_create_stats_files(struct super_block * sb, struct dentry * root)
                oprofilefs_create_ro_ulong(sb, cpudir, "sample_invalid_eip",
                        &cpu_buf->sample_invalid_eip);
        }
+
        oprofilefs_create_ro_atomic(sb, dir, "sample_lost_no_mm",
                &oprofile_stats.sample_lost_no_mm);
        oprofilefs_create_ro_atomic(sb, dir, "sample_lost_no_mapping",
index 6d755a633f15b58244bd6d23b4ac521bf12e0b2e..3da0d08dc1f980416867b0c25e1ef604e3430ca5 100644 (file)
@@ -11,7 +11,7 @@
 #define OPROFILE_STATS_H
 
 #include <asm/atomic.h>
+
 struct oprofile_stat_struct {
        atomic_t sample_lost_no_mm;
        atomic_t sample_lost_no_mapping;
@@ -20,14 +20,14 @@ struct oprofile_stat_struct {
 };
 
 extern struct oprofile_stat_struct oprofile_stats;
+
 /* reset all stats to zero */
 void oprofile_reset_stats(void);
+
 struct super_block;
 struct dentry;
+
 /* create the stats/ dir */
-void oprofile_create_stats_files(struct super_block * sb, struct dentry * root);
+void oprofile_create_stats_files(struct super_block *sb, struct dentry *root);
 
 #endif /* OPROFILE_STATS_H */
index 8543cb26cf34b8d8b861cb7cafd3388b5cf6a6f3..ddc4c59f02dca27adc42d187429543dea4f4da63 100644 (file)
@@ -23,9 +23,9 @@
 
 DEFINE_SPINLOCK(oprofilefs_lock);
 
-static struct inode * oprofilefs_get_inode(struct super_block * sb, int mode)
+static struct inode *oprofilefs_get_inode(struct super_block *sb, int mode)
 {
-       struct inode * inode = new_inode(sb);
+       struct inode *inode = new_inode(sb);
 
        if (inode) {
                inode->i_mode = mode;
@@ -44,7 +44,7 @@ static struct super_operations s_ops = {
 };
 
 
-ssize_t oprofilefs_str_to_user(char const * str, char __user * buf, size_t count, loff_t * offset)
+ssize_t oprofilefs_str_to_user(char const *str, char __user *buf, size_t count, loff_t *offset)
 {
        return simple_read_from_buffer(buf, count, offset, str, strlen(str));
 }
@@ -52,7 +52,7 @@ ssize_t oprofilefs_str_to_user(char const * str, char __user * buf, size_t count
 
 #define TMPBUFSIZE 50
 
-ssize_t oprofilefs_ulong_to_user(unsigned long val, char __user * buf, size_t count, loff_t * offset)
+ssize_t oprofilefs_ulong_to_user(unsigned long val, char __user *buf, size_t count, loff_t *offset)
 {
        char tmpbuf[TMPBUFSIZE];
        size_t maxlen = snprintf(tmpbuf, TMPBUFSIZE, "%lu\n", val);
@@ -62,7 +62,7 @@ ssize_t oprofilefs_ulong_to_user(unsigned long val, char __user * buf, size_t co
 }
 
 
-int oprofilefs_ulong_from_user(unsigned long * val, char const __user * buf, size_t count)
+int oprofilefs_ulong_from_user(unsigned long *val, char const __user *buf, size_t count)
 {
        char tmpbuf[TMPBUFSIZE];
        unsigned long flags;
@@ -85,16 +85,16 @@ int oprofilefs_ulong_from_user(unsigned long * val, char const __user * buf, siz
 }
 
 
-static ssize_t ulong_read_file(struct file * file, char __user * buf, size_t count, loff_t * offset)
+static ssize_t ulong_read_file(struct file *file, char __user *buf, size_t count, loff_t *offset)
 {
-       unsigned long * val = file->private_data;
+       unsigned long *val = file->private_data;
        return oprofilefs_ulong_to_user(*val, buf, count, offset);
 }
 
 
-static ssize_t ulong_write_file(struct file * file, char const __user * buf, size_t count, loff_t * offset)
+static ssize_t ulong_write_file(struct file *file, char const __user *buf, size_t count, loff_t *offset)
 {
-       unsigned long * value = file->private_data;
+       unsigned long *value = file->private_data;
        int retval;
 
        if (*offset)
@@ -108,7 +108,7 @@ static ssize_t ulong_write_file(struct file * file, char const __user * buf, siz
 }
 
 
-static int default_open(struct inode * inode, struct file * filp)
+static int default_open(struct inode *inode, struct file *filp)
 {
        if (inode->i_private)
                filp->private_data = inode->i_private;
@@ -129,12 +129,12 @@ static const struct file_operations ulong_ro_fops = {
 };
 
 
-static struct dentry * __oprofilefs_create_file(struct super_block * sb,
-       struct dentry * root, char const * name, const struct file_operations * fops,
+static struct dentry *__oprofilefs_create_file(struct super_block *sb,
+       struct dentry *root, char const *name, const struct file_operations *fops,
        int perm)
 {
-       struct dentry * dentry;
-       struct inode * inode;
+       struct dentry *dentry;
+       struct inode *inode;
 
        dentry = d_alloc_name(root, name);
        if (!dentry)
@@ -150,10 +150,10 @@ static struct dentry * __oprofilefs_create_file(struct super_block * sb,
 }
 
 
-int oprofilefs_create_ulong(struct super_block * sb, struct dentry * root,
-       char const * name, unsigned long * val)
+int oprofilefs_create_ulong(struct super_block *sb, struct dentry *root,
+       char const *name, unsigned long *val)
 {
-       struct dentry * d = __oprofilefs_create_file(sb, root, name,
+       struct dentry *d = __oprofilefs_create_file(sb, root, name,
                                                     &ulong_fops, 0644);
        if (!d)
                return -EFAULT;
@@ -163,10 +163,10 @@ int oprofilefs_create_ulong(struct super_block * sb, struct dentry * root,
 }
 
 
-int oprofilefs_create_ro_ulong(struct super_block * sb, struct dentry * root,
-       char const * name, unsigned long * val)
+int oprofilefs_create_ro_ulong(struct super_block *sb, struct dentry *root,
+       char const *name, unsigned long *val)
 {
-       struct dentry * d = __oprofilefs_create_file(sb, root, name,
+       struct dentry *d = __oprofilefs_create_file(sb, root, name,
                                                     &ulong_ro_fops, 0444);
        if (!d)
                return -EFAULT;
@@ -176,23 +176,23 @@ int oprofilefs_create_ro_ulong(struct super_block * sb, struct dentry * root,
 }
 
 
-static ssize_t atomic_read_file(struct file * file, char __user * buf, size_t count, loff_t * offset)
+static ssize_t atomic_read_file(struct file *file, char __user *buf, size_t count, loff_t *offset)
 {
-       atomic_t * val = file->private_data;
+       atomic_t *val = file->private_data;
        return oprofilefs_ulong_to_user(atomic_read(val), buf, count, offset);
 }
+
 
 static const struct file_operations atomic_ro_fops = {
        .read           = atomic_read_file,
        .open           = default_open,
 };
 
-int oprofilefs_create_ro_atomic(struct super_block * sb, struct dentry * root,
-       char const * name, atomic_t * val)
+
+int oprofilefs_create_ro_atomic(struct super_block *sb, struct dentry *root,
+       char const *name, atomic_t *val)
 {
-       struct dentry * d = __oprofilefs_create_file(sb, root, name,
+       struct dentry *d = __oprofilefs_create_file(sb, root, name,
                                                     &atomic_ro_fops, 0444);
        if (!d)
                return -EFAULT;
@@ -201,9 +201,9 @@ int oprofilefs_create_ro_atomic(struct super_block * sb, struct dentry * root,
        return 0;
 }
 
-int oprofilefs_create_file(struct super_block * sb, struct dentry * root,
-       char const * name, const struct file_operations * fops)
+
+int oprofilefs_create_file(struct super_block *sb, struct dentry *root,
+       char const *name, const struct file_operations *fops)
 {
        if (!__oprofilefs_create_file(sb, root, name, fops, 0644))
                return -EFAULT;
@@ -211,8 +211,8 @@ int oprofilefs_create_file(struct super_block * sb, struct dentry * root,
 }
 
 
-int oprofilefs_create_file_perm(struct super_block * sb, struct dentry * root,
-       char const * name, const struct file_operations * fops, int perm)
+int oprofilefs_create_file_perm(struct super_block *sb, struct dentry *root,
+       char const *name, const struct file_operations *fops, int perm)
 {
        if (!__oprofilefs_create_file(sb, root, name, fops, perm))
                return -EFAULT;
@@ -220,11 +220,11 @@ int oprofilefs_create_file_perm(struct super_block * sb, struct dentry * root,
 }
 
 
-struct dentry * oprofilefs_mkdir(struct super_block * sb,
-       struct dentry * root, char const * name)
+struct dentry *oprofilefs_mkdir(struct super_block *sb,
+       struct dentry *root, char const *name)
 {
-       struct dentry * dentry;
-       struct inode * inode;
+       struct dentry *dentry;
+       struct inode *inode;
 
        dentry = d_alloc_name(root, name);
        if (!dentry)
@@ -241,10 +241,10 @@ struct dentry * oprofilefs_mkdir(struct super_block * sb,
 }
 
 
-static int oprofilefs_fill_super(struct super_block * sb, void * data, int silent)
+static int oprofilefs_fill_super(struct super_block *sb, void *data, int silent)
 {
-       struct inode * root_inode;
-       struct dentry * root_dentry;
+       struct inode *root_inode;
+       struct dentry *root_dentry;
 
        sb->s_blocksize = PAGE_CACHE_SIZE;
        sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
index 710a45f0d734430871c21a8731108c483e07f2c5..333f915568c796683af2b49e51227e54914d97b2 100644 (file)
@@ -19,7 +19,7 @@
 
 static int timer_notify(struct pt_regs *regs)
 {
-       oprofile_add_sample(regs, 0);
+       oprofile_add_sample(regs, 0);
        return 0;
 }
 
@@ -35,7 +35,7 @@ static void timer_stop(void)
 }
 
 
-void __init oprofile_timer_init(struct oprofile_operations * ops)
+void __init oprofile_timer_init(struct oprofile_operations *ops)
 {
        ops->create_files = NULL;
        ops->setup = NULL;
index b30e38f3a50d736d95d591594c04f9aeae7c62ea..dcc1e9958d2f9bb0b0fd3625c43ed9eaf806bfd2 100644 (file)
 #undef DEBUG_CCIO_RUN_SG
 
 #ifdef CONFIG_PROC_FS
-/*
- * CCIO_SEARCH_TIME can help measure how fast the bitmap search is.
- * impacts performance though - ditch it if you don't use it.
- */
-#define CCIO_SEARCH_TIME
-#undef CCIO_MAP_STATS
-#else
-#undef CCIO_SEARCH_TIME
-#undef CCIO_MAP_STATS
+/* depends on proc fs support. But costs CPU performance. */
+#undef CCIO_COLLECT_STATS
 #endif
 
 #include <linux/proc_fs.h>
@@ -239,12 +232,10 @@ struct ioc {
        u32 res_size;                   /* size of resource map in bytes */
        spinlock_t res_lock;
 
-#ifdef CCIO_SEARCH_TIME
+#ifdef CCIO_COLLECT_STATS
 #define CCIO_SEARCH_SAMPLE 0x100
        unsigned long avg_search[CCIO_SEARCH_SAMPLE];
        unsigned long avg_idx;            /* current index into avg_search */
-#endif
-#ifdef CCIO_MAP_STATS
        unsigned long used_pages;
        unsigned long msingle_calls;
        unsigned long msingle_pages;
@@ -351,7 +342,7 @@ ccio_alloc_range(struct ioc *ioc, struct device *dev, size_t size)
        unsigned int pages_needed = size >> IOVP_SHIFT;
        unsigned int res_idx;
        unsigned long boundary_size;
-#ifdef CCIO_SEARCH_TIME
+#ifdef CCIO_COLLECT_STATS
        unsigned long cr_start = mfctl(16);
 #endif
        
@@ -406,7 +397,7 @@ resource_found:
        DBG_RES("%s() res_idx %d res_hint: %d\n",
                __func__, res_idx, ioc->res_hint);
 
-#ifdef CCIO_SEARCH_TIME
+#ifdef CCIO_COLLECT_STATS
        {
                unsigned long cr_end = mfctl(16);
                unsigned long tmp = cr_end - cr_start;
@@ -416,7 +407,7 @@ resource_found:
        ioc->avg_search[ioc->avg_idx++] = cr_start;
        ioc->avg_idx &= CCIO_SEARCH_SAMPLE - 1;
 #endif
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
        ioc->used_pages += pages_needed;
 #endif
        /* 
@@ -452,7 +443,7 @@ ccio_free_range(struct ioc *ioc, dma_addr_t iova, unsigned long pages_mapped)
        DBG_RES("%s():  res_idx: %d pages_mapped %d\n", 
                __func__, res_idx, pages_mapped);
 
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
        ioc->used_pages -= pages_mapped;
 #endif
 
@@ -764,7 +755,7 @@ ccio_map_single(struct device *dev, void *addr, size_t size,
        size = ALIGN(size + offset, IOVP_SIZE);
        spin_lock_irqsave(&ioc->res_lock, flags);
 
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
        ioc->msingle_calls++;
        ioc->msingle_pages += size >> IOVP_SHIFT;
 #endif
@@ -828,7 +819,7 @@ ccio_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
 
        spin_lock_irqsave(&ioc->res_lock, flags);
 
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
        ioc->usingle_calls++;
        ioc->usingle_pages += size >> IOVP_SHIFT;
 #endif
@@ -894,7 +885,7 @@ ccio_free_consistent(struct device *dev, size_t size, void *cpu_addr,
 */
 #define PIDE_FLAG 0x80000000UL
 
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
 #define IOMMU_MAP_STATS
 #endif
 #include "iommu-helpers.h"
@@ -938,7 +929,7 @@ ccio_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
        
        spin_lock_irqsave(&ioc->res_lock, flags);
 
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
        ioc->msg_calls++;
 #endif
 
@@ -997,13 +988,13 @@ ccio_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
        DBG_RUN_SG("%s() START %d entries,  %08lx,%x\n",
                __func__, nents, sg_virt_addr(sglist), sglist->length);
 
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
        ioc->usg_calls++;
 #endif
 
        while(sg_dma_len(sglist) && nents--) {
 
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
                ioc->usg_pages += sg_dma_len(sglist) >> PAGE_SHIFT;
 #endif
                ccio_unmap_single(dev, sg_dma_address(sglist),
@@ -1048,7 +1039,7 @@ static int ccio_proc_info(struct seq_file *m, void *p)
                len += seq_printf(m, "IO PDIR size    : %d bytes (%d entries)\n",
                               total_pages * 8, total_pages);
 
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
                len += seq_printf(m, "IO PDIR entries : %ld free  %ld used (%d%%)\n",
                                  total_pages - ioc->used_pages, ioc->used_pages,
                                  (int)(ioc->used_pages * 100 / total_pages));
@@ -1057,7 +1048,7 @@ static int ccio_proc_info(struct seq_file *m, void *p)
                len += seq_printf(m, "Resource bitmap : %d bytes (%d pages)\n", 
                                  ioc->res_size, total_pages);
 
-#ifdef CCIO_SEARCH_TIME
+#ifdef CCIO_COLLECT_STATS
                min = max = ioc->avg_search[0];
                for(j = 0; j < CCIO_SEARCH_SAMPLE; ++j) {
                        avg += ioc->avg_search[j];
@@ -1070,7 +1061,7 @@ static int ccio_proc_info(struct seq_file *m, void *p)
                len += seq_printf(m, "  Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
                                  min, avg, max);
 #endif
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
                len += seq_printf(m, "pci_map_single(): %8ld calls  %8ld pages (avg %d/1000)\n",
                                  ioc->msingle_calls, ioc->msingle_pages,
                                  (int)((ioc->msingle_pages * 1000)/ioc->msingle_calls));
@@ -1088,7 +1079,7 @@ static int ccio_proc_info(struct seq_file *m, void *p)
                len += seq_printf(m, "pci_unmap_sg()  : %8ld calls  %8ld pages (avg %d/1000)\n\n\n",
                                  ioc->usg_calls, ioc->usg_pages,
                                  (int)((ioc->usg_pages * 1000)/ioc->usg_calls));
-#endif /* CCIO_MAP_STATS */
+#endif /* CCIO_COLLECT_STATS */
 
                ioc = ioc->next;
        }
index fd56128525d1b11e01bc71624025258957da15dd..3bc54b30c3a18af9733718015e5370b7a3a79038 100644 (file)
@@ -298,7 +298,8 @@ struct pci_port_ops dino_port_ops = {
 
 static void dino_disable_irq(unsigned int irq)
 {
-       struct dino_device *dino_dev = irq_desc[irq].chip_data;
+       struct irq_desc *desc = irq_to_desc(irq);
+       struct dino_device *dino_dev = desc->chip_data;
        int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS);
 
        DBG(KERN_WARNING "%s(0x%p, %d)\n", __func__, dino_dev, irq);
@@ -310,7 +311,8 @@ static void dino_disable_irq(unsigned int irq)
 
 static void dino_enable_irq(unsigned int irq)
 {
-       struct dino_device *dino_dev = irq_desc[irq].chip_data;
+       struct irq_desc *desc = irq_to_desc(irq);
+       struct dino_device *dino_dev = desc->chip_data;
        int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS);
        u32 tmp;
 
index 771cef592542fd75182b69a1e6d324c8fdc63d7b..7891db50c483bc6e6def22133ae78e17cc97da50 100644 (file)
@@ -346,10 +346,10 @@ static int __init eisa_probe(struct parisc_device *dev)
        }
        
        /* Reserve IRQ2 */
-       irq_desc[2].action = &irq2_action;
+       irq_to_desc(2)->action = &irq2_action;
        
        for (i = 0; i < 16; i++) {
-               irq_desc[i].chip = &eisa_interrupt_type;
+               irq_to_desc(i)->chip = &eisa_interrupt_type;
        }
        
        EISA_bus = 1;
index 5ac207932fd7b755fa56418ec8745be6c9afd093..685d94e69d44e2b0791d0546736bef20c5d22806 100644 (file)
@@ -86,7 +86,7 @@ static int eisa_eeprom_open(struct inode *inode, struct file *file)
 {
        cycle_kernel_lock();
 
-       if (file->f_mode & 2)
+       if (file->f_mode & FMODE_WRITE)
                return -EINVAL;
    
        return 0;
index f7d088b897ee384f849081e92851ac08fd4ea164..e76db9e4d504968fd774ca6fc877d3b462dda33a 100644 (file)
@@ -108,7 +108,8 @@ int gsc_find_local_irq(unsigned int irq, int *global_irqs, int limit)
 
 static void gsc_asic_disable_irq(unsigned int irq)
 {
-       struct gsc_asic *irq_dev = irq_desc[irq].chip_data;
+       struct irq_desc *desc = irq_to_desc(irq);
+       struct gsc_asic *irq_dev = desc->chip_data;
        int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32);
        u32 imr;
 
@@ -123,7 +124,8 @@ static void gsc_asic_disable_irq(unsigned int irq)
 
 static void gsc_asic_enable_irq(unsigned int irq)
 {
-       struct gsc_asic *irq_dev = irq_desc[irq].chip_data;
+       struct irq_desc *desc = irq_to_desc(irq);
+       struct gsc_asic *irq_dev = desc->chip_data;
        int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32);
        u32 imr;
 
@@ -159,12 +161,14 @@ static struct hw_interrupt_type gsc_asic_interrupt_type = {
 int gsc_assign_irq(struct hw_interrupt_type *type, void *data)
 {
        static int irq = GSC_IRQ_BASE;
+       struct irq_desc *desc;
 
        if (irq > GSC_IRQ_MAX)
                return NO_IRQ;
 
-       irq_desc[irq].chip = type;
-       irq_desc[irq].chip_data = data;
+       desc = irq_to_desc(irq);
+       desc->chip = type;
+       desc->chip_data = data;
        return irq++;
 }
 
index 6fb3f7979f21b89043bb3cc90d16240d110c590d..7beffcab274548545c15673025cbd639ce563094 100644 (file)
@@ -619,7 +619,9 @@ iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1)
 
 static struct vector_info *iosapic_get_vector(unsigned int irq)
 {
-       return irq_desc[irq].chip_data;
+       struct irq_desc *desc = irq_to_desc(irq);
+
+       return desc->chip_data;
 }
 
 static void iosapic_disable_irq(unsigned int irq)
index 1e8d2d17f04c63d921fe827402ded98252affa87..1e93c837514f11fdf065ce80703ba57651276a2f 100644 (file)
@@ -363,7 +363,9 @@ int superio_fixup_irq(struct pci_dev *pcidev)
 #endif
 
        for (i = 0; i < 16; i++) {
-               irq_desc[i].chip = &superio_interrupt_type;
+               struct irq_desc *desc = irq_to_desc(i);
+
+               desc->chip = &superio_interrupt_type;
        }
 
        /*
index 8a846adf1dcf2cd2ac792693c3cb3b124b36ceb4..96f3bdf0ec4bd4a04aaad15647e48c005a31d2d3 100644 (file)
@@ -2791,6 +2791,7 @@ enum parport_pc_pci_cards {
        oxsemi_952,
        oxsemi_954,
        oxsemi_840,
+       oxsemi_pcie_pport,
        aks_0100,
        mobility_pp,
        netmos_9705,
@@ -2868,6 +2869,7 @@ static struct parport_pc_pci {
        /* oxsemi_952 */                { 1, { { 0, 1 }, } },
        /* oxsemi_954 */                { 1, { { 0, -1 }, } },
        /* oxsemi_840 */                { 1, { { 0, 1 }, } },
+       /* oxsemi_pcie_pport */         { 1, { { 0, 1 }, } },
        /* aks_0100 */                  { 1, { { 0, -1 }, } },
        /* mobility_pp */               { 1, { { 0, 1 }, } },
        /* netmos_9705 */               { 1, { { 0, -1 }, } }, /* untested */
@@ -2928,7 +2930,6 @@ static const struct pci_device_id parport_pc_pci_tbl[] = {
        { 0x1409, 0x7268, 0x1409, 0x0103, 0, 0, timedia_4008a },
        { 0x1409, 0x7268, 0x1409, 0x0104, 0, 0, timedia_4018 },
        { 0x1409, 0x7268, 0x1409, 0x9018, 0, 0, timedia_9018a },
-       { 0x14f2, 0x0121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, mobility_pp },
        { PCI_VENDOR_ID_SYBA, PCI_DEVICE_ID_SYBA_2P_EPP,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, syba_2p_epp },
        { PCI_VENDOR_ID_SYBA, PCI_DEVICE_ID_SYBA_1P_ECP,
@@ -2946,8 +2947,25 @@ static const struct pci_device_id parport_pc_pci_tbl[] = {
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_954 },
        { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_12PCI840,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_840 },
+       { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_PCIe840,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport },
+       { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_PCIe840_G,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport },
+       { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_PCIe952_0,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport },
+       { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_PCIe952_0_G,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport },
+       { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_PCIe952_1,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport },
+       { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_PCIe952_1_G,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport },
+       { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_PCIe952_1_U,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport },
+       { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_PCIe952_1_GU,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport },
        { PCI_VENDOR_ID_AKS, PCI_DEVICE_ID_AKS_ALADDINCARD,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, aks_0100 },
+       { 0x14f2, 0x0121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, mobility_pp },
        /* NetMos communication controllers */
        { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9705,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9705 },
index 529d9d7727b01d1ea857388cb0514f2703c8f5b3..999cc4088b5952beb76e018e573afff4b53fba04 100644 (file)
@@ -151,6 +151,13 @@ void pci_bus_add_devices(struct pci_bus *bus)
                        if (retval)
                                dev_err(&dev->dev, "Error creating cpuaffinity"
                                        " file, continuing...\n");
+
+                       retval = device_create_file(&child_bus->dev,
+                                               &dev_attr_cpulistaffinity);
+                       if (retval)
+                               dev_err(&dev->dev,
+                                       "Error creating cpulistaffinity"
+                                       " file, continuing...\n");
                }
        }
 }
index e842e756308a71c470e658164ec6c2163d5e8955..691b3adeb87057799841f112d8b77797e729e4ce 100644 (file)
@@ -188,12 +188,11 @@ dmar_parse_one_drhd(struct acpi_dmar_header *header)
        return 0;
 }
 
-static int __init
-dmar_parse_dev(struct dmar_drhd_unit *dmaru)
+static int __init dmar_parse_dev(struct dmar_drhd_unit *dmaru)
 {
        struct acpi_dmar_hardware_unit *drhd;
        static int include_all;
-       int ret;
+       int ret = 0;
 
        drhd = (struct acpi_dmar_hardware_unit *) dmaru->hdr;
 
@@ -212,7 +211,7 @@ dmar_parse_dev(struct dmar_drhd_unit *dmaru)
                include_all = 1;
        }
 
-       if (ret || (dmaru->devices_cnt == 0 && !dmaru->include_all)) {
+       if (ret) {
                list_del(&dmaru->list);
                kfree(dmaru);
        }
@@ -277,18 +276,37 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
                drhd = (struct acpi_dmar_hardware_unit *)header;
                printk (KERN_INFO PREFIX
                        "DRHD (flags: 0x%08x)base: 0x%016Lx\n",
-                       drhd->flags, drhd->address);
+                       drhd->flags, (unsigned long long)drhd->address);
                break;
        case ACPI_DMAR_TYPE_RESERVED_MEMORY:
                rmrr = (struct acpi_dmar_reserved_memory *)header;
 
                printk (KERN_INFO PREFIX
                        "RMRR base: 0x%016Lx end: 0x%016Lx\n",
-                       rmrr->base_address, rmrr->end_address);
+                       (unsigned long long)rmrr->base_address,
+                       (unsigned long long)rmrr->end_address);
                break;
        }
 }
 
+/**
+ * dmar_table_detect - checks to see if the platform supports DMAR devices
+ */
+static int __init dmar_table_detect(void)
+{
+       acpi_status status = AE_OK;
+
+       /* if we could find DMAR table, then there are DMAR devices */
+       status = acpi_get_table(ACPI_SIG_DMAR, 0,
+                               (struct acpi_table_header **)&dmar_tbl);
+
+       if (ACPI_SUCCESS(status) && !dmar_tbl) {
+               printk (KERN_WARNING PREFIX "Unable to map DMAR\n");
+               status = AE_NOT_FOUND;
+       }
+
+       return (ACPI_SUCCESS(status) ? 1 : 0);
+}
 
 /**
  * parse_dmar_table - parses the DMA reporting table
@@ -300,11 +318,17 @@ parse_dmar_table(void)
        struct acpi_dmar_header *entry_header;
        int ret = 0;
 
+       /*
+        * Do it again, earlier dmar_tbl mapping could be mapped with
+        * fixed map.
+        */
+       dmar_table_detect();
+
        dmar = (struct acpi_table_dmar *)dmar_tbl;
        if (!dmar)
                return -ENODEV;
 
-       if (dmar->width < PAGE_SHIFT_4K - 1) {
+       if (dmar->width < PAGE_SHIFT - 1) {
                printk(KERN_WARNING PREFIX "Invalid DMAR haw\n");
                return -EINVAL;
        }
@@ -373,10 +397,10 @@ dmar_find_matched_drhd_unit(struct pci_dev *dev)
 
 int __init dmar_dev_scope_init(void)
 {
-       struct dmar_drhd_unit *drhd;
+       struct dmar_drhd_unit *drhd, *drhd_n;
        int ret = -ENODEV;
 
-       for_each_drhd_unit(drhd) {
+       list_for_each_entry_safe(drhd, drhd_n, &dmar_drhd_units, list) {
                ret = dmar_parse_dev(drhd);
                if (ret)
                        return ret;
@@ -384,8 +408,8 @@ int __init dmar_dev_scope_init(void)
 
 #ifdef CONFIG_DMAR
        {
-               struct dmar_rmrr_unit *rmrr;
-               for_each_rmrr_units(rmrr) {
+               struct dmar_rmrr_unit *rmrr, *rmrr_n;
+               list_for_each_entry_safe(rmrr, rmrr_n, &dmar_rmrr_units, list) {
                        ret = rmrr_parse_dev(rmrr);
                        if (ret)
                                return ret;
@@ -430,33 +454,14 @@ int __init dmar_table_init(void)
        return 0;
 }
 
-/**
- * early_dmar_detect - checks to see if the platform supports DMAR devices
- */
-int __init early_dmar_detect(void)
-{
-       acpi_status status = AE_OK;
-
-       /* if we could find DMAR table, then there are DMAR devices */
-       status = acpi_get_table(ACPI_SIG_DMAR, 0,
-                               (struct acpi_table_header **)&dmar_tbl);
-
-       if (ACPI_SUCCESS(status) && !dmar_tbl) {
-               printk (KERN_WARNING PREFIX "Unable to map DMAR\n");
-               status = AE_NOT_FOUND;
-       }
-
-       return (ACPI_SUCCESS(status) ? 1 : 0);
-}
-
 void __init detect_intel_iommu(void)
 {
        int ret;
 
-       ret = early_dmar_detect();
+       ret = dmar_table_detect();
 
-#ifdef CONFIG_DMAR
        {
+#ifdef CONFIG_INTR_REMAP
                struct acpi_table_dmar *dmar;
                /*
                 * for now we will disable dma-remapping when interrupt
@@ -465,28 +470,18 @@ void __init detect_intel_iommu(void)
                 * is added, we will not need this any more.
                 */
                dmar = (struct acpi_table_dmar *) dmar_tbl;
-               if (ret && cpu_has_x2apic && dmar->flags & 0x1) {
+               if (ret && cpu_has_x2apic && dmar->flags & 0x1)
                        printk(KERN_INFO
                               "Queued invalidation will be enabled to support "
                               "x2apic and Intr-remapping.\n");
-                       printk(KERN_INFO
-                              "Disabling IOMMU detection, because of missing "
-                              "queued invalidation support for IOTLB "
-                              "invalidation\n");
-                       printk(KERN_INFO
-                              "Use \"nox2apic\", if you want to use Intel "
-                              " IOMMU for DMA-remapping and don't care about "
-                              " x2apic support\n");
-
-                       dmar_disabled = 1;
-                       return;
-               }
-
+#endif
+#ifdef CONFIG_DMAR
                if (ret && !no_iommu && !iommu_detected && !swiotlb &&
                    !dmar_disabled)
                        iommu_detected = 1;
-       }
 #endif
+       }
+       dmar_tbl = NULL;
 }
 
 
@@ -503,7 +498,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
 
        iommu->seq_id = iommu_allocated++;
 
-       iommu->reg = ioremap(drhd->reg_base_addr, PAGE_SIZE_4K);
+       iommu->reg = ioremap(drhd->reg_base_addr, VTD_PAGE_SIZE);
        if (!iommu->reg) {
                printk(KERN_ERR "IOMMU: can't map the region\n");
                goto error;
@@ -514,8 +509,8 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
        /* the registers might be more than one page */
        map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap),
                cap_max_fault_reg_offset(iommu->cap));
-       map_size = PAGE_ALIGN_4K(map_size);
-       if (map_size > PAGE_SIZE_4K) {
+       map_size = VTD_PAGE_ALIGN(map_size);
+       if (map_size > VTD_PAGE_SIZE) {
                iounmap(iommu->reg);
                iommu->reg = ioremap(drhd->reg_base_addr, map_size);
                if (!iommu->reg) {
@@ -526,8 +521,10 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
 
        ver = readl(iommu->reg + DMAR_VER_REG);
        pr_debug("IOMMU %llx: ver %d:%d cap %llx ecap %llx\n",
-               drhd->reg_base_addr, DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver),
-               iommu->cap, iommu->ecap);
+               (unsigned long long)drhd->reg_base_addr,
+               DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver),
+               (unsigned long long)iommu->cap,
+               (unsigned long long)iommu->ecap);
 
        spin_lock_init(&iommu->register_lock);
 
@@ -580,11 +577,11 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
 
        hw = qi->desc;
 
-       spin_lock(&qi->q_lock);
+       spin_lock_irqsave(&qi->q_lock, flags);
        while (qi->free_cnt < 3) {
-               spin_unlock(&qi->q_lock);
+               spin_unlock_irqrestore(&qi->q_lock, flags);
                cpu_relax();
-               spin_lock(&qi->q_lock);
+               spin_lock_irqsave(&qi->q_lock, flags);
        }
 
        index = qi->free_head;
@@ -605,15 +602,22 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
        qi->free_head = (qi->free_head + 2) % QI_LENGTH;
        qi->free_cnt -= 2;
 
-       spin_lock_irqsave(&iommu->register_lock, flags);
+       spin_lock(&iommu->register_lock);
        /*
         * update the HW tail register indicating the presence of
         * new descriptors.
         */
        writel(qi->free_head << 4, iommu->reg + DMAR_IQT_REG);
-       spin_unlock_irqrestore(&iommu->register_lock, flags);
+       spin_unlock(&iommu->register_lock);
 
        while (qi->desc_status[wait_index] != QI_DONE) {
+               /*
+                * We will leave the interrupts disabled, to prevent interrupt
+                * context to queue another cmd while a cmd is already submitted
+                * and waiting for completion on this cpu. This is to avoid
+                * a deadlock where the interrupt context can wait indefinitely
+                * for free slots in the queue.
+                */
                spin_unlock(&qi->q_lock);
                cpu_relax();
                spin_lock(&qi->q_lock);
@@ -622,7 +626,7 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
        qi->desc_status[index] = QI_DONE;
 
        reclaim_free_desc(qi);
-       spin_unlock(&qi->q_lock);
+       spin_unlock_irqrestore(&qi->q_lock, flags);
 }
 
 /*
@@ -638,6 +642,62 @@ void qi_global_iec(struct intel_iommu *iommu)
        qi_submit_sync(&desc, iommu);
 }
 
+int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm,
+                    u64 type, int non_present_entry_flush)
+{
+
+       struct qi_desc desc;
+
+       if (non_present_entry_flush) {
+               if (!cap_caching_mode(iommu->cap))
+                       return 1;
+               else
+                       did = 0;
+       }
+
+       desc.low = QI_CC_FM(fm) | QI_CC_SID(sid) | QI_CC_DID(did)
+                       | QI_CC_GRAN(type) | QI_CC_TYPE;
+       desc.high = 0;
+
+       qi_submit_sync(&desc, iommu);
+
+       return 0;
+
+}
+
+int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
+                  unsigned int size_order, u64 type,
+                  int non_present_entry_flush)
+{
+       u8 dw = 0, dr = 0;
+
+       struct qi_desc desc;
+       int ih = 0;
+
+       if (non_present_entry_flush) {
+               if (!cap_caching_mode(iommu->cap))
+                       return 1;
+               else
+                       did = 0;
+       }
+
+       if (cap_write_drain(iommu->cap))
+               dw = 1;
+
+       if (cap_read_drain(iommu->cap))
+               dr = 1;
+
+       desc.low = QI_IOTLB_DID(did) | QI_IOTLB_DR(dr) | QI_IOTLB_DW(dw)
+               | QI_IOTLB_GRAN(type) | QI_IOTLB_TYPE;
+       desc.high = QI_IOTLB_ADDR(addr) | QI_IOTLB_IH(ih)
+               | QI_IOTLB_AM(size_order);
+
+       qi_submit_sync(&desc, iommu);
+
+       return 0;
+
+}
+
 /*
  * Enable Queued Invalidation interface. This is a must to support
  * interrupt-remapping. Also used by DMA-remapping, which replaces
index 5a58b075dd8d0da2f7ae8ae451ded6ea241c0e06..f9e244da30aef9ea9e170c5cce58a524ab5f87a6 100644 (file)
@@ -50,9 +50,6 @@
 #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
 #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
 
-/* name size which is used for entries in pcihpfs */
-#define SLOT_NAME_SIZE 20              /* {_SUN} */
-
 struct acpiphp_bridge;
 struct acpiphp_slot;
 
@@ -63,9 +60,13 @@ struct slot {
        struct hotplug_slot     *hotplug_slot;
        struct acpiphp_slot     *acpi_slot;
        struct hotplug_slot_info info;
-       char name[SLOT_NAME_SIZE];
 };
 
+static inline const char *slot_name(struct slot *slot)
+{
+       return hotplug_slot_name(slot->hotplug_slot);
+}
+
 /*
  * struct acpiphp_bridge - PCI bridge information
  *
index 0e496e866a84dc51480d4cb3194e1ea6b62023c8..95b536a23d25d8d9f76d5aa757a411540017fef0 100644 (file)
@@ -44,6 +44,9 @@
 
 #define MY_NAME        "acpiphp"
 
+/* name size which is used for entries in pcihpfs */
+#define SLOT_NAME_SIZE  21              /* {_SUN} */
+
 static int debug;
 int acpiphp_debug;
 
@@ -84,7 +87,6 @@ static struct hotplug_slot_ops acpi_hotplug_slot_ops = {
        .get_adapter_status     = get_adapter_status,
 };
 
-
 /**
  * acpiphp_register_attention - set attention LED callback
  * @info: must be completely filled with LED callbacks
@@ -136,7 +138,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
 {
        struct slot *slot = hotplug_slot->private;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        /* enable the specified slot */
        return acpiphp_enable_slot(slot->acpi_slot);
@@ -154,7 +156,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
        struct slot *slot = hotplug_slot->private;
        int retval;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        /* disable the specified slot */
        retval = acpiphp_disable_slot(slot->acpi_slot);
@@ -177,7 +179,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
  {
        int retval = -ENODEV;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot_name(hotplug_slot));
  
        if (attention_info && try_module_get(attention_info->owner)) {
                retval = attention_info->set_attn(hotplug_slot, status);
@@ -200,7 +202,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
 {
        struct slot *slot = hotplug_slot->private;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        *value = acpiphp_get_power_status(slot->acpi_slot);
 
@@ -222,7 +224,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
 {
        int retval = -EINVAL;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot_name(hotplug_slot));
 
        if (attention_info && try_module_get(attention_info->owner)) {
                retval = attention_info->get_attn(hotplug_slot, value);
@@ -245,7 +247,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
 {
        struct slot *slot = hotplug_slot->private;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        *value = acpiphp_get_latch_status(slot->acpi_slot);
 
@@ -265,7 +267,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
 {
        struct slot *slot = hotplug_slot->private;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        *value = acpiphp_get_adapter_status(slot->acpi_slot);
 
@@ -299,7 +301,7 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
 {
        struct slot *slot = hotplug_slot->private;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        kfree(slot->hotplug_slot);
        kfree(slot);
@@ -310,6 +312,7 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot)
 {
        struct slot *slot;
        int retval = -ENOMEM;
+       char name[SLOT_NAME_SIZE];
 
        slot = kzalloc(sizeof(*slot), GFP_KERNEL);
        if (!slot)
@@ -321,8 +324,6 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot)
 
        slot->hotplug_slot->info = &slot->info;
 
-       slot->hotplug_slot->name = slot->name;
-
        slot->hotplug_slot->private = slot;
        slot->hotplug_slot->release = &release_slot;
        slot->hotplug_slot->ops = &acpi_hotplug_slot_ops;
@@ -336,11 +337,12 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot)
        slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN;
 
        acpiphp_slot->slot = slot;
-       snprintf(slot->name, sizeof(slot->name), "%u", slot->acpi_slot->sun);
+       snprintf(name, SLOT_NAME_SIZE, "%u", slot->acpi_slot->sun);
 
        retval = pci_hp_register(slot->hotplug_slot,
                                        acpiphp_slot->bridge->pci_bus,
-                                       acpiphp_slot->device);
+                                       acpiphp_slot->device,
+                                       name);
        if (retval == -EBUSY)
                goto error_hpslot;
        if (retval) {
@@ -348,7 +350,7 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot)
                goto error_hpslot;
        }
 
-       info("Slot [%s] registered\n", slot->hotplug_slot->name);
+       info("Slot [%s] registered\n", slot_name(slot));
 
        return 0;
 error_hpslot:
@@ -365,7 +367,7 @@ void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *acpiphp_slot)
        struct slot *slot = acpiphp_slot->slot;
        int retval = 0;
 
-       info ("Slot [%s] unregistered\n", slot->hotplug_slot->name);
+       info("Slot [%s] unregistered\n", slot_name(slot));
 
        retval = pci_hp_deregister(slot->hotplug_slot);
        if (retval)
index a3e4705dd8f0f11ef477ddfeaec284990780c87f..955aae4071f7a64eeb5cb716aaacf8ebb26c7a11 100644 (file)
@@ -169,7 +169,9 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val,
 }
 
 
-
+static struct acpi_dock_ops acpiphp_dock_ops = {
+       .handler = handle_hotplug_event_func,
+};
 
 /* callback routine to register each ACPI PCI slot object */
 static acpi_status
@@ -180,7 +182,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
        struct acpiphp_func *newfunc;
        acpi_handle tmp;
        acpi_status status = AE_OK;
-       unsigned long adr, sun;
+       unsigned long long adr, sun;
        int device, function, retval;
 
        status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
@@ -285,7 +287,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
                 */
                newfunc->flags &= ~FUNC_HAS_EJ0;
                if (register_hotplug_dock_device(handle,
-                       handle_hotplug_event_func, newfunc))
+                       &acpiphp_dock_ops, newfunc))
                        dbg("failed to register dock device\n");
 
                /* we need to be notified when dock events happen
@@ -528,7 +530,7 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
        acpi_status status;
        acpi_handle dummy_handle;
-       unsigned long tmp;
+       unsigned long long tmp;
        int device, function;
        struct pci_dev *dev;
        struct pci_bus *pci_bus = context;
@@ -573,7 +575,7 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
 static int add_bridge(acpi_handle handle)
 {
        acpi_status status;
-       unsigned long tmp;
+       unsigned long long tmp;
        int seg, bus;
        acpi_handle dummy_handle;
        struct pci_bus *pci_bus;
@@ -767,7 +769,7 @@ static int get_gsi_base(acpi_handle handle, u32 *gsi_base)
 {
        acpi_status status;
        int result = -1;
-       unsigned long gsb;
+       unsigned long long gsb;
        struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
        union acpi_object *obj;
        void *table;
@@ -808,7 +810,7 @@ static acpi_status
 ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
        acpi_status status;
-       unsigned long sta;
+       unsigned long long sta;
        acpi_handle tmp;
        struct pci_dev *pdev;
        u32 gsi_base;
@@ -872,7 +874,7 @@ static acpi_status
 ioapic_remove(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
        acpi_status status;
-       unsigned long sta;
+       unsigned long long sta;
        acpi_handle tmp;
        u32 gsi_base;
        struct acpiphp_ioapic *pos, *n, *ioapic = NULL;
@@ -1264,7 +1266,7 @@ static int disable_device(struct acpiphp_slot *slot)
 static unsigned int get_slot_status(struct acpiphp_slot *slot)
 {
        acpi_status status;
-       unsigned long sta = 0;
+       unsigned long long sta = 0;
        u32 dvid;
        struct list_head *l;
        struct acpiphp_func *func;
index 2b7c45e39370f1e42fa0546f30cf6e6c7e9356f8..b291ee68b4f16dbef4737753a15bb8596808c018 100644 (file)
@@ -183,7 +183,7 @@ static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status)
        union acpi_object args[2]; 
        struct acpi_object_list params = { .pointer = args, .count = 2 };
        acpi_status stat; 
-       unsigned long rc;
+       unsigned long long rc;
        union apci_descriptor *ibm_slot;
 
        ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot));
index d9769b30be9a6f175a89c68340b0526c885ec5f2..9fff878cf0268c0c0cd4d160edf80dec51e67dd1 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 
 /* PICMG 2.1 R2.0 HS CSR bits: */
 #define HS_CSR_INS     0x0080
@@ -69,6 +70,11 @@ struct cpci_hp_controller {
        struct cpci_hp_controller_ops *ops;
 };
 
+static inline const char *slot_name(struct slot *slot)
+{
+       return hotplug_slot_name(slot->hotplug_slot);
+}
+
 extern int cpci_hp_register_controller(struct cpci_hp_controller *controller);
 extern int cpci_hp_unregister_controller(struct cpci_hp_controller *controller);
 extern int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last);
index 935947991dc98649dfaa8794fb55604ee12cb895..de94f4feef8c58c30c4817957903a5db89d85323 100644 (file)
@@ -108,7 +108,7 @@ enable_slot(struct hotplug_slot *hotplug_slot)
        struct slot *slot = hotplug_slot->private;
        int retval = 0;
 
-       dbg("%s - physical_slot = %s", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s", __func__, slot_name(slot));
 
        if (controller->ops->set_power)
                retval = controller->ops->set_power(slot, 1);
@@ -121,25 +121,23 @@ disable_slot(struct hotplug_slot *hotplug_slot)
        struct slot *slot = hotplug_slot->private;
        int retval = 0;
 
-       dbg("%s - physical_slot = %s", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s", __func__, slot_name(slot));
 
        down_write(&list_rwsem);
 
        /* Unconfigure device */
-       dbg("%s - unconfiguring slot %s",
-           __func__, slot->hotplug_slot->name);
+       dbg("%s - unconfiguring slot %s", __func__, slot_name(slot));
        if ((retval = cpci_unconfigure_slot(slot))) {
                err("%s - could not unconfigure slot %s",
-                   __func__, slot->hotplug_slot->name);
+                   __func__, slot_name(slot));
                goto disable_error;
        }
-       dbg("%s - finished unconfiguring slot %s",
-           __func__, slot->hotplug_slot->name);
+       dbg("%s - finished unconfiguring slot %s", __func__, slot_name(slot));
 
        /* Clear EXT (by setting it) */
        if (cpci_clear_ext(slot)) {
                err("%s - could not clear EXT for slot %s",
-                   __func__, slot->hotplug_slot->name);
+                   __func__, slot_name(slot));
                retval = -ENODEV;
                goto disable_error;
        }
@@ -214,7 +212,6 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
        struct slot *slot = hotplug_slot->private;
 
        kfree(slot->hotplug_slot->info);
-       kfree(slot->hotplug_slot->name);
        kfree(slot->hotplug_slot);
        if (slot->dev)
                pci_dev_put(slot->dev);
@@ -222,12 +219,6 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
 }
 
 #define SLOT_NAME_SIZE 6
-static void
-make_slot_name(struct slot *slot)
-{
-       snprintf(slot->hotplug_slot->name,
-                SLOT_NAME_SIZE, "%02x:%02x", slot->bus->number, slot->number);
-}
 
 int
 cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
@@ -235,7 +226,7 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
        struct slot *slot;
        struct hotplug_slot *hotplug_slot;
        struct hotplug_slot_info *info;
-       char *name;
+       char name[SLOT_NAME_SIZE];
        int status = -ENOMEM;
        int i;
 
@@ -262,34 +253,31 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
                        goto error_hpslot;
                hotplug_slot->info = info;
 
-               name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
-               if (!name)
-                       goto error_info;
-               hotplug_slot->name = name;
-
                slot->bus = bus;
                slot->number = i;
                slot->devfn = PCI_DEVFN(i, 0);
 
+               snprintf(name, SLOT_NAME_SIZE, "%02x:%02x", bus->number, i);
+
                hotplug_slot->private = slot;
                hotplug_slot->release = &release_slot;
-               make_slot_name(slot);
                hotplug_slot->ops = &cpci_hotplug_slot_ops;
 
                /*
                 * Initialize the slot info structure with some known
                 * good values.
                 */
-               dbg("initializing slot %s", slot->hotplug_slot->name);
+               dbg("initializing slot %s", name);
                info->power_status = cpci_get_power_status(slot);
                info->attention_status = cpci_get_attention_status(slot);
 
-               dbg("registering slot %s", slot->hotplug_slot->name);
-               status = pci_hp_register(slot->hotplug_slot, bus, i);
+               dbg("registering slot %s", name);
+               status = pci_hp_register(slot->hotplug_slot, bus, i, name);
                if (status) {
                        err("pci_hp_register failed with error %d", status);
-                       goto error_name;
+                       goto error_info;
                }
+               dbg("slot registered with name: %s", slot_name(slot));
 
                /* Add slot to our internal list */
                down_write(&list_rwsem);
@@ -298,8 +286,6 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
                up_write(&list_rwsem);
        }
        return 0;
-error_name:
-       kfree(name);
 error_info:
        kfree(info);
 error_hpslot:
@@ -327,7 +313,7 @@ cpci_hp_unregister_bus(struct pci_bus *bus)
                        list_del(&slot->slot_list);
                        slots--;
 
-                       dbg("deregistering slot %s", slot->hotplug_slot->name);
+                       dbg("deregistering slot %s", slot_name(slot));
                        status = pci_hp_deregister(slot->hotplug_slot);
                        if (status) {
                                err("pci_hp_deregister failed with error %d",
@@ -379,11 +365,10 @@ init_slots(int clear_ins)
                return -1;
        }
        list_for_each_entry(slot, &slot_list, slot_list) {
-               dbg("%s - looking at slot %s",
-                   __func__, slot->hotplug_slot->name);
+               dbg("%s - looking at slot %s", __func__, slot_name(slot));
                if (clear_ins && cpci_check_and_clear_ins(slot))
                        dbg("%s - cleared INS for slot %s",
-                           __func__, slot->hotplug_slot->name);
+                           __func__, slot_name(slot));
                dev = pci_get_slot(slot->bus, PCI_DEVFN(slot->number, 0));
                if (dev) {
                        if (update_adapter_status(slot->hotplug_slot, 1))
@@ -414,8 +399,7 @@ check_slots(void)
        }
        extracted = inserted = 0;
        list_for_each_entry(slot, &slot_list, slot_list) {
-               dbg("%s - looking at slot %s",
-                   __func__, slot->hotplug_slot->name);
+               dbg("%s - looking at slot %s", __func__, slot_name(slot));
                if (cpci_check_and_clear_ins(slot)) {
                        /*
                         * Some broken hardware (e.g. PLX 9054AB) asserts
@@ -423,35 +407,34 @@ check_slots(void)
                         */
                        if (slot->dev) {
                                warn("slot %s already inserted",
-                                    slot->hotplug_slot->name);
+                                    slot_name(slot));
                                inserted++;
                                continue;
                        }
 
                        /* Process insertion */
-                       dbg("%s - slot %s inserted",
-                           __func__, slot->hotplug_slot->name);
+                       dbg("%s - slot %s inserted", __func__, slot_name(slot));
 
                        /* GSM, debug */
                        hs_csr = cpci_get_hs_csr(slot);
                        dbg("%s - slot %s HS_CSR (1) = %04x",
-                           __func__, slot->hotplug_slot->name, hs_csr);
+                           __func__, slot_name(slot), hs_csr);
 
                        /* Configure device */
                        dbg("%s - configuring slot %s",
-                           __func__, slot->hotplug_slot->name);
+                           __func__, slot_name(slot));
                        if (cpci_configure_slot(slot)) {
                                err("%s - could not configure slot %s",
-                                   __func__, slot->hotplug_slot->name);
+                                   __func__, slot_name(slot));
                                continue;
                        }
                        dbg("%s - finished configuring slot %s",
-                           __func__, slot->hotplug_slot->name);
+                           __func__, slot_name(slot));
 
                        /* GSM, debug */
                        hs_csr = cpci_get_hs_csr(slot);
                        dbg("%s - slot %s HS_CSR (2) = %04x",
-                           __func__, slot->hotplug_slot->name, hs_csr);
+                           __func__, slot_name(slot), hs_csr);
 
                        if (update_latch_status(slot->hotplug_slot, 1))
                                warn("failure to update latch file");
@@ -464,18 +447,18 @@ check_slots(void)
                        /* GSM, debug */
                        hs_csr = cpci_get_hs_csr(slot);
                        dbg("%s - slot %s HS_CSR (3) = %04x",
-                           __func__, slot->hotplug_slot->name, hs_csr);
+                           __func__, slot_name(slot), hs_csr);
 
                        inserted++;
                } else if (cpci_check_ext(slot)) {
                        /* Process extraction request */
                        dbg("%s - slot %s extracted",
-                           __func__, slot->hotplug_slot->name);
+                           __func__, slot_name(slot));
 
                        /* GSM, debug */
                        hs_csr = cpci_get_hs_csr(slot);
                        dbg("%s - slot %s HS_CSR = %04x",
-                           __func__, slot->hotplug_slot->name, hs_csr);
+                           __func__, slot_name(slot), hs_csr);
 
                        if (!slot->extracting) {
                                if (update_latch_status(slot->hotplug_slot, 0)) {
@@ -493,7 +476,7 @@ check_slots(void)
                                 * bother trying to tell the driver or not?
                                 */
                                err("card in slot %s was improperly removed",
-                                   slot->hotplug_slot->name);
+                                   slot_name(slot));
                                if (update_adapter_status(slot->hotplug_slot, 0))
                                        warn("failure to update adapter file");
                                slot->extracting = 0;
index df82b95e287486e0a3a9ee932ab5ea0ba262afd6..829c327cfb5e5780bf9cde69877cdec759c63549 100644 (file)
@@ -209,7 +209,7 @@ int cpci_led_on(struct slot* slot)
                                              hs_cap + 2,
                                              hs_csr)) {
                        err("Could not set LOO for slot %s",
-                           slot->hotplug_slot->name);
+                           hotplug_slot_name(slot->hotplug_slot));
                        return -ENODEV;
                }
        }
@@ -238,7 +238,7 @@ int cpci_led_off(struct slot* slot)
                                              hs_cap + 2,
                                              hs_csr)) {
                        err("Could not clear LOO for slot %s",
-                           slot->hotplug_slot->name);
+                           hotplug_slot_name(slot->hotplug_slot));
                        return -ENODEV;
                }
        }
index b1decfa88b7a1adfa7929395359d6f0737738f6b..afaf8f69f73ec0938f754f427822a929697b79b4 100644 (file)
@@ -449,6 +449,11 @@ extern u8 cpqhp_disk_irq;
 
 /* inline functions */
 
+static inline char *slot_name(struct slot *slot)
+{
+       return hotplug_slot_name(slot->hotplug_slot);
+}
+
 /*
  * return_resource
  *
@@ -696,14 +701,6 @@ static inline int get_presence_status(struct controller *ctrl, struct slot *slot
        return presence_save;
 }
 
-#define SLOT_NAME_SIZE 10
-
-static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
-{
-       snprintf(buffer, buffer_size, "%d", slot->number);
-}
-
-
 static inline int wait_for_ctrl_irq(struct controller *ctrl)
 {
         DECLARE_WAITQUEUE(wait, current);
index 54defec51d0895f7dd2136230fa56e87e8feac3b..724d42c4adbcbcd1b80edf6614d6df377ccbe8df 100644 (file)
@@ -315,14 +315,15 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
 {
        struct slot *slot = hotplug_slot->private;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        kfree(slot->hotplug_slot->info);
-       kfree(slot->hotplug_slot->name);
        kfree(slot->hotplug_slot);
        kfree(slot);
 }
 
+#define SLOT_NAME_SIZE 10
+
 static int ctrl_slot_setup(struct controller *ctrl,
                        void __iomem *smbios_start,
                        void __iomem *smbios_table)
@@ -335,6 +336,7 @@ static int ctrl_slot_setup(struct controller *ctrl,
        u8 slot_number;
        u8 ctrl_slot;
        u32 tempdword;
+       char name[SLOT_NAME_SIZE];
        void __iomem *slot_entry= NULL;
        int result = -ENOMEM;
 
@@ -363,16 +365,12 @@ static int ctrl_slot_setup(struct controller *ctrl,
                if (!hotplug_slot->info)
                        goto error_hpslot;
                hotplug_slot_info = hotplug_slot->info;
-               hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
-
-               if (!hotplug_slot->name)
-                       goto error_info;
 
                slot->ctrl = ctrl;
                slot->bus = ctrl->bus;
                slot->device = slot_device;
                slot->number = slot_number;
-               dbg("slot->number = %d\n", slot->number);
+               dbg("slot->number = %u\n", slot->number);
 
                slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9,
                                        slot_entry);
@@ -418,9 +416,9 @@ static int ctrl_slot_setup(struct controller *ctrl,
                /* register this slot with the hotplug pci core */
                hotplug_slot->release = &release_slot;
                hotplug_slot->private = slot;
-               make_slot_name(hotplug_slot->name, SLOT_NAME_SIZE, slot);
+               snprintf(name, SLOT_NAME_SIZE, "%u", slot->number);
                hotplug_slot->ops = &cpqphp_hotplug_slot_ops;
-               
+
                hotplug_slot_info->power_status = get_slot_enabled(ctrl, slot);
                hotplug_slot_info->attention_status =
                        cpq_get_attention_status(ctrl, slot);
@@ -436,10 +434,11 @@ static int ctrl_slot_setup(struct controller *ctrl,
                                slot_number);
                result = pci_hp_register(hotplug_slot,
                                         ctrl->pci_dev->subordinate,
-                                        slot->device);
+                                        slot->device,
+                                        name);
                if (result) {
                        err("pci_hp_register failed with error %d\n", result);
-                       goto error_name;
+                       goto error_info;
                }
                
                slot->next = ctrl->slot;
@@ -451,8 +450,6 @@ static int ctrl_slot_setup(struct controller *ctrl,
        }
 
        return 0;
-error_name:
-       kfree(hotplug_slot->name);
 error_info:
        kfree(hotplug_slot_info);
 error_hpslot:
@@ -638,7 +635,7 @@ static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
        u8 device;
        u8 function;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
                return -ENODEV;
@@ -665,7 +662,7 @@ static int process_SI(struct hotplug_slot *hotplug_slot)
        u8 device;
        u8 function;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
                return -ENODEV;
@@ -697,7 +694,7 @@ static int process_SS(struct hotplug_slot *hotplug_slot)
        u8 device;
        u8 function;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
                return -ENODEV;
@@ -720,7 +717,7 @@ static int hardware_test(struct hotplug_slot *hotplug_slot, u32 value)
        struct slot *slot = hotplug_slot->private;
        struct controller *ctrl = slot->ctrl;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        return cpqhp_hardware_test(ctrl, value);        
 }
@@ -731,7 +728,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
        struct slot *slot = hotplug_slot->private;
        struct controller *ctrl = slot->ctrl;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        *value = get_slot_enabled(ctrl, slot);
        return 0;
@@ -742,7 +739,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
        struct slot *slot = hotplug_slot->private;
        struct controller *ctrl = slot->ctrl;
        
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        *value = cpq_get_attention_status(ctrl, slot);
        return 0;
@@ -753,7 +750,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
        struct slot *slot = hotplug_slot->private;
        struct controller *ctrl = slot->ctrl;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        *value = cpq_get_latch_status(ctrl, slot);
 
@@ -765,7 +762,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
        struct slot *slot = hotplug_slot->private;
        struct controller *ctrl = slot->ctrl;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        *value = get_presence_status(ctrl, slot);
 
@@ -777,7 +774,7 @@ static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_sp
        struct slot *slot = hotplug_slot->private;
        struct controller *ctrl = slot->ctrl;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        *value = ctrl->speed_capability;
 
@@ -789,7 +786,7 @@ static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_sp
        struct slot *slot = hotplug_slot->private;
        struct controller *ctrl = slot->ctrl;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        *value = ctrl->speed;
 
index ef041ca91c275b4bc51360be9b1f251aad52b241..a60a25290995e5f2c267f6a2f4da65e9122d858a 100644 (file)
@@ -1139,7 +1139,7 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_
        for(slot = ctrl->slot; slot; slot = slot->next) {
                if (slot->device == (hp_slot + ctrl->slot_device_offset)) 
                        continue;
-               if (!slot->hotplug_slot && !slot->hotplug_slot->info) 
+               if (!slot->hotplug_slot || !slot->hotplug_slot->info)
                        continue;
                if (slot->hotplug_slot->info->adapter_status == 0) 
                        continue;
index 146ca9cd1567f20858b521dc1b552c1da3362f17..3a2637a00934014fbf96b3988815b16ac3621f41 100644 (file)
@@ -66,10 +66,10 @@ struct dummy_slot {
        struct pci_dev *dev;
        struct work_struct remove_work;
        unsigned long removed;
-       char name[8];
 };
 
 static int debug;
+static int dup_slots;
 static LIST_HEAD(slot_list);
 static struct workqueue_struct *dummyphp_wq;
 
@@ -96,10 +96,13 @@ static void dummy_release(struct hotplug_slot *slot)
        kfree(dslot);
 }
 
+#define SLOT_NAME_SIZE 8
+
 static int add_slot(struct pci_dev *dev)
 {
        struct dummy_slot *dslot;
        struct hotplug_slot *slot;
+       char name[SLOT_NAME_SIZE];
        int retval = -ENOMEM;
        static int count = 1;
 
@@ -119,19 +122,22 @@ static int add_slot(struct pci_dev *dev)
        if (!dslot)
                goto error_info;
 
-       slot->name = dslot->name;
-       snprintf(slot->name, sizeof(dslot->name), "fake%d", count++);
-       dbg("slot->name = %s\n", slot->name);
+       if (dup_slots)
+               snprintf(name, SLOT_NAME_SIZE, "fake");
+       else
+               snprintf(name, SLOT_NAME_SIZE, "fake%d", count++);
+       dbg("slot->name = %s\n", name);
        slot->ops = &dummy_hotplug_slot_ops;
        slot->release = &dummy_release;
        slot->private = dslot;
 
-       retval = pci_hp_register(slot, dev->bus, PCI_SLOT(dev->devfn));
+       retval = pci_hp_register(slot, dev->bus, PCI_SLOT(dev->devfn), name);
        if (retval) {
                err("pci_hp_register failed with error %d\n", retval);
                goto error_dslot;
        }
 
+       dbg("slot->name = %s\n", hotplug_slot_name(slot));
        dslot->slot = slot;
        dslot->dev = pci_dev_get(dev);
        list_add (&dslot->node, &slot_list);
@@ -167,10 +173,11 @@ static void remove_slot(struct dummy_slot *dslot)
 {
        int retval;
 
-       dbg("removing slot %s\n", dslot->slot->name);
+       dbg("removing slot %s\n", hotplug_slot_name(dslot->slot));
        retval = pci_hp_deregister(dslot->slot);
        if (retval)
-               err("Problem unregistering a slot %s\n", dslot->slot->name);
+               err("Problem unregistering a slot %s\n",
+                       hotplug_slot_name(dslot->slot));
 }
 
 /* called from the single-threaded workqueue handler to remove a slot */
@@ -308,7 +315,7 @@ static int disable_slot(struct hotplug_slot *slot)
                return -ENODEV;
        dslot = slot->private;
 
-       dbg("%s - physical_slot = %s\n", __func__, slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot_name(slot));
 
        for (func = 7; func >= 0; func--) {
                dev = pci_get_slot(dslot->dev->bus, dslot->dev->devfn + func);
@@ -373,4 +380,5 @@ MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
-
+module_param(dup_slots, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(dup_slots, "Force duplicate slot names for debugging");
index 612d96301509c8e9d2fbb003d1a751b46e339cd7..a8d391a4957db86ccd7bd41dd02ccfa67831e8e7 100644 (file)
@@ -707,17 +707,16 @@ struct slot {
        u8 device;
        u8 number;
        u8 real_physical_slot_num;
-       char name[100];
        u32 capabilities;
        u8 supported_speed;
        u8 supported_bus_mode;
+       u8 flag;                /* this is for disable slot and polling */
+       u8 ctlr_index;
        struct hotplug_slot *hotplug_slot;
        struct controller *ctrl;
        struct pci_func *func;
        u8 irq[4];
-       u8 flag;                /* this is for disable slot and polling */
        int bit_mode;           /* 0 = 32, 1 = 64 */
-       u8 ctlr_index;
        struct bus_info *bus_on;
        struct list_head ibm_slot_list;
        u8 status;
index 7d27631e6e627bba3202633d68ff5578dd84e663..c1abac8ab5c326847ca8cca0c2eb33b1fcae4e1e 100644 (file)
@@ -123,10 +123,8 @@ static struct ebda_pci_rsrc *alloc_ebda_pci_rsrc (void)
 static void __init print_bus_info (void)
 {
        struct bus_info *ptr;
-       struct list_head *ptr1;
        
-       list_for_each (ptr1, &bus_info_head) {
-               ptr = list_entry (ptr1, struct bus_info, bus_info_list);
+       list_for_each_entry(ptr, &bus_info_head, bus_info_list) {
                debug ("%s - slot_min = %x\n", __func__, ptr->slot_min);
                debug ("%s - slot_max = %x\n", __func__, ptr->slot_max);
                debug ("%s - slot_count = %x\n", __func__, ptr->slot_count);
@@ -146,10 +144,8 @@ static void __init print_bus_info (void)
 static void print_lo_info (void)
 {
        struct rio_detail *ptr;
-       struct list_head *ptr1;
        debug ("print_lo_info ----\n"); 
-       list_for_each (ptr1, &rio_lo_head) {
-               ptr = list_entry (ptr1, struct rio_detail, rio_detail_list);
+       list_for_each_entry(ptr, &rio_lo_head, rio_detail_list) {
                debug ("%s - rio_node_id = %x\n", __func__, ptr->rio_node_id);
                debug ("%s - rio_type = %x\n", __func__, ptr->rio_type);
                debug ("%s - owner_id = %x\n", __func__, ptr->owner_id);
@@ -163,10 +159,8 @@ static void print_lo_info (void)
 static void print_vg_info (void)
 {
        struct rio_detail *ptr;
-       struct list_head *ptr1;
        debug ("%s ---\n", __func__);
-       list_for_each (ptr1, &rio_vg_head) {
-               ptr = list_entry (ptr1, struct rio_detail, rio_detail_list);
+       list_for_each_entry(ptr, &rio_vg_head, rio_detail_list) {
                debug ("%s - rio_node_id = %x\n", __func__, ptr->rio_node_id);
                debug ("%s - rio_type = %x\n", __func__, ptr->rio_type);
                debug ("%s - owner_id = %x\n", __func__, ptr->owner_id);
@@ -180,10 +174,8 @@ static void print_vg_info (void)
 static void __init print_ebda_pci_rsrc (void)
 {
        struct ebda_pci_rsrc *ptr;
-       struct list_head *ptr1;
 
-       list_for_each (ptr1, &ibmphp_ebda_pci_rsrc_head) {
-               ptr = list_entry (ptr1, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
+       list_for_each_entry(ptr, &ibmphp_ebda_pci_rsrc_head, ebda_pci_rsrc_list) {
                debug ("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n", 
                        __func__, ptr->rsrc_type ,ptr->bus_num, ptr->dev_fun,ptr->start_addr, ptr->end_addr);
        }
@@ -192,10 +184,8 @@ static void __init print_ebda_pci_rsrc (void)
 static void __init print_ibm_slot (void)
 {
        struct slot *ptr;
-       struct list_head *ptr1;
 
-       list_for_each (ptr1, &ibmphp_slot_head) {
-               ptr = list_entry (ptr1, struct slot, ibm_slot_list);
+       list_for_each_entry(ptr, &ibmphp_slot_head, ibm_slot_list) {
                debug ("%s - slot_number: %x\n", __func__, ptr->number);
        }
 }
@@ -203,10 +193,8 @@ static void __init print_ibm_slot (void)
 static void __init print_opt_vg (void)
 {
        struct opt_rio *ptr;
-       struct list_head *ptr1;
        debug ("%s ---\n", __func__);
-       list_for_each (ptr1, &opt_vg_head) {
-               ptr = list_entry (ptr1, struct opt_rio, opt_rio_list);
+       list_for_each_entry(ptr, &opt_vg_head, opt_rio_list) {
                debug ("%s - rio_type %x\n", __func__, ptr->rio_type);
                debug ("%s - chassis_num: %x\n", __func__, ptr->chassis_num);
                debug ("%s - first_slot_num: %x\n", __func__, ptr->first_slot_num);
@@ -217,13 +205,9 @@ static void __init print_opt_vg (void)
 static void __init print_ebda_hpc (void)
 {
        struct controller *hpc_ptr;
-       struct list_head *ptr1;
        u16 index;
 
-       list_for_each (ptr1, &ebda_hpc_head) {
-
-               hpc_ptr = list_entry (ptr1, struct controller, ebda_hpc_list); 
-
+       list_for_each_entry(hpc_ptr, &ebda_hpc_head, ebda_hpc_list) {
                for (index = 0; index < hpc_ptr->slot_count; index++) {
                        debug ("%s - physical slot#: %x\n", __func__, hpc_ptr->slots[index].slot_num);
                        debug ("%s - pci bus# of the slot: %x\n", __func__, hpc_ptr->slots[index].slot_bus_num);
@@ -460,9 +444,7 @@ static int __init ebda_rio_table (void)
 static struct opt_rio *search_opt_vg (u8 chassis_num)
 {
        struct opt_rio *ptr;
-       struct list_head *ptr1;
-       list_for_each (ptr1, &opt_vg_head) {
-               ptr = list_entry (ptr1, struct opt_rio, opt_rio_list);
+       list_for_each_entry(ptr, &opt_vg_head, opt_rio_list) {
                if (ptr->chassis_num == chassis_num)
                        return ptr;
        }               
@@ -473,10 +455,8 @@ static int __init combine_wpg_for_chassis (void)
 {
        struct opt_rio *opt_rio_ptr = NULL;
        struct rio_detail *rio_detail_ptr = NULL;
-       struct list_head *list_head_ptr = NULL;
        
-       list_for_each (list_head_ptr, &rio_vg_head) {
-               rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
+       list_for_each_entry(rio_detail_ptr, &rio_vg_head, rio_detail_list) {
                opt_rio_ptr = search_opt_vg (rio_detail_ptr->chassis_num);
                if (!opt_rio_ptr) {
                        opt_rio_ptr = kzalloc(sizeof(struct opt_rio), GFP_KERNEL);
@@ -497,14 +477,12 @@ static int __init combine_wpg_for_chassis (void)
 }      
 
 /*
- * reorgnizing linked list of expansion box     
+ * reorganizing linked list of expansion box
  */
 static struct opt_rio_lo *search_opt_lo (u8 chassis_num)
 {
        struct opt_rio_lo *ptr;
-       struct list_head *ptr1;
-       list_for_each (ptr1, &opt_lo_head) {
-               ptr = list_entry (ptr1, struct opt_rio_lo, opt_rio_lo_list);
+       list_for_each_entry(ptr, &opt_lo_head, opt_rio_lo_list) {
                if (ptr->chassis_num == chassis_num)
                        return ptr;
        }               
@@ -515,10 +493,8 @@ static int combine_wpg_for_expansion (void)
 {
        struct opt_rio_lo *opt_rio_lo_ptr = NULL;
        struct rio_detail *rio_detail_ptr = NULL;
-       struct list_head *list_head_ptr = NULL;
        
-       list_for_each (list_head_ptr, &rio_lo_head) {
-               rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
+       list_for_each_entry(rio_detail_ptr, &rio_lo_head, rio_detail_list) {
                opt_rio_lo_ptr = search_opt_lo (rio_detail_ptr->chassis_num);
                if (!opt_rio_lo_ptr) {
                        opt_rio_lo_ptr = kzalloc(sizeof(struct opt_rio_lo), GFP_KERNEL);
@@ -550,20 +526,17 @@ static int first_slot_num (u8 slot_num, u8 first_slot, u8 var)
 {
        struct opt_rio *opt_vg_ptr = NULL;
        struct opt_rio_lo *opt_lo_ptr = NULL;
-       struct list_head *ptr = NULL;
        int rc = 0;
 
        if (!var) {
-               list_for_each (ptr, &opt_vg_head) {
-                       opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list);
+               list_for_each_entry(opt_vg_ptr, &opt_vg_head, opt_rio_list) {
                        if ((first_slot < opt_vg_ptr->first_slot_num) && (slot_num >= opt_vg_ptr->first_slot_num)) { 
                                rc = -ENODEV;
                                break;
                        }
                }
        } else {
-               list_for_each (ptr, &opt_lo_head) {
-                       opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list);
+               list_for_each_entry(opt_lo_ptr, &opt_lo_head, opt_rio_lo_list) {
                        if ((first_slot < opt_lo_ptr->first_slot_num) && (slot_num >= opt_lo_ptr->first_slot_num)) {
                                rc = -ENODEV;
                                break;
@@ -576,10 +549,8 @@ static int first_slot_num (u8 slot_num, u8 first_slot, u8 var)
 static struct opt_rio_lo * find_rxe_num (u8 slot_num)
 {
        struct opt_rio_lo *opt_lo_ptr;
-       struct list_head *ptr;
 
-       list_for_each (ptr, &opt_lo_head) {
-               opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list);
+       list_for_each_entry(opt_lo_ptr, &opt_lo_head, opt_rio_lo_list) {
                //check to see if this slot_num belongs to expansion box
                if ((slot_num >= opt_lo_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_lo_ptr->first_slot_num, 1))) 
                        return opt_lo_ptr;
@@ -590,10 +561,8 @@ static struct opt_rio_lo * find_rxe_num (u8 slot_num)
 static struct opt_rio * find_chassis_num (u8 slot_num)
 {
        struct opt_rio *opt_vg_ptr;
-       struct list_head *ptr;
 
-       list_for_each (ptr, &opt_vg_head) {
-               opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list);
+       list_for_each_entry(opt_vg_ptr, &opt_vg_head, opt_rio_list) {
                //check to see if this slot_num belongs to chassis 
                if ((slot_num >= opt_vg_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_vg_ptr->first_slot_num, 0))) 
                        return opt_vg_ptr;
@@ -607,11 +576,9 @@ static struct opt_rio * find_chassis_num (u8 slot_num)
 static u8 calculate_first_slot (u8 slot_num)
 {
        u8 first_slot = 1;
-       struct list_head * list;
        struct slot * slot_cur;
        
-       list_for_each (list, &ibmphp_slot_head) {
-               slot_cur = list_entry (list, struct slot, ibm_slot_list);
+       list_for_each_entry(slot_cur, &ibmphp_slot_head, ibm_slot_list) {
                if (slot_cur->ctrl) {
                        if ((slot_cur->ctrl->ctlr_type != 4) && (slot_cur->ctrl->ending_slot_num > first_slot) && (slot_num > slot_cur->ctrl->ending_slot_num)) 
                                first_slot = slot_cur->ctrl->ending_slot_num;
@@ -620,11 +587,14 @@ static u8 calculate_first_slot (u8 slot_num)
        return first_slot + 1;
 
 }
+
+#define SLOT_NAME_SIZE 30
+
 static char *create_file_name (struct slot * slot_cur)
 {
        struct opt_rio *opt_vg_ptr = NULL;
        struct opt_rio_lo *opt_lo_ptr = NULL;
-       static char str[30];
+       static char str[SLOT_NAME_SIZE];
        int which = 0; /* rxe = 1, chassis = 0 */
        u8 number = 1; /* either chassis or rxe # */
        u8 first_slot = 1;
@@ -736,7 +706,6 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
 
        slot = hotplug_slot->private;
        kfree(slot->hotplug_slot->info);
-       kfree(slot->hotplug_slot->name);
        kfree(slot->hotplug_slot);
        slot->ctrl = NULL;
        slot->bus_on = NULL;
@@ -767,7 +736,7 @@ static int __init ebda_rsrc_controller (void)
        struct bus_info *bus_info_ptr1, *bus_info_ptr2;
        int rc;
        struct slot *tmp_slot;
-       struct list_head *list;
+       char name[SLOT_NAME_SIZE];
 
        addr = hpc_list_ptr->phys_addr;
        for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) {
@@ -931,12 +900,6 @@ static int __init ebda_rsrc_controller (void)
                                goto error_no_hp_info;
                        }
 
-                       hp_slot_ptr->name = kmalloc(30, GFP_KERNEL);
-                       if (!hp_slot_ptr->name) {
-                               rc = -ENOMEM;
-                               goto error_no_hp_name;
-                       }
-
                        tmp_slot = kzalloc(sizeof(*tmp_slot), GFP_KERNEL);
                        if (!tmp_slot) {
                                rc = -ENOMEM;
@@ -997,12 +960,10 @@ static int __init ebda_rsrc_controller (void)
 
        }                       /* each hpc  */
 
-       list_for_each (list, &ibmphp_slot_head) {
-               tmp_slot = list_entry (list, struct slot, ibm_slot_list);
-
-               snprintf (tmp_slot->hotplug_slot->name, 30, "%s", create_file_name (tmp_slot));
+       list_for_each_entry(tmp_slot, &ibmphp_slot_head, ibm_slot_list) {
+               snprintf(name, SLOT_NAME_SIZE, "%s", create_file_name(tmp_slot));
                pci_hp_register(tmp_slot->hotplug_slot,
-                       pci_find_bus(0, tmp_slot->bus), tmp_slot->device);
+                       pci_find_bus(0, tmp_slot->bus), tmp_slot->device, name);
        }
 
        print_ebda_hpc ();
@@ -1012,8 +973,6 @@ static int __init ebda_rsrc_controller (void)
 error:
        kfree (hp_slot_ptr->private);
 error_no_slot:
-       kfree (hp_slot_ptr->name);
-error_no_hp_name:
        kfree (hp_slot_ptr->info);
 error_no_hp_info:
        kfree (hp_slot_ptr);
@@ -1101,10 +1060,8 @@ u16 ibmphp_get_total_controllers (void)
 struct slot *ibmphp_get_slot_from_physical_num (u8 physical_num)
 {
        struct slot *slot;
-       struct list_head *list;
 
-       list_for_each (list, &ibmphp_slot_head) {
-               slot = list_entry (list, struct slot, ibm_slot_list);
+       list_for_each_entry(slot, &ibmphp_slot_head, ibm_slot_list) {
                if (slot->number == physical_num)
                        return slot;
        }
@@ -1120,10 +1077,8 @@ struct slot *ibmphp_get_slot_from_physical_num (u8 physical_num)
 struct bus_info *ibmphp_find_same_bus_num (u32 num)
 {
        struct bus_info *ptr;
-       struct list_head  *ptr1;
 
-       list_for_each (ptr1, &bus_info_head) {
-               ptr = list_entry (ptr1, struct bus_info, bus_info_list); 
+       list_for_each_entry(ptr, &bus_info_head, bus_info_list) {
                if (ptr->busno == num) 
                         return ptr;
        }
@@ -1136,10 +1091,8 @@ struct bus_info *ibmphp_find_same_bus_num (u32 num)
 int ibmphp_get_bus_index (u8 num)
 {
        struct bus_info *ptr;
-       struct list_head  *ptr1;
 
-       list_for_each (ptr1, &bus_info_head) {
-               ptr = list_entry (ptr1, struct bus_info, bus_info_list);
+       list_for_each_entry(ptr, &bus_info_head, bus_info_list) {
                if (ptr->busno == num)  
                        return ptr->index;
        }
@@ -1212,11 +1165,9 @@ static struct pci_driver ibmphp_driver = {
 int ibmphp_register_pci (void)
 {
        struct controller *ctrl;
-       struct list_head *tmp;
        int rc = 0;
 
-       list_for_each (tmp, &ebda_hpc_head) {
-               ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
+       list_for_each_entry(ctrl, &ebda_hpc_head, ebda_hpc_list) {
                if (ctrl->ctlr_type == 1) {
                        rc = pci_register_driver(&ibmphp_driver);
                        break;
@@ -1227,12 +1178,10 @@ int ibmphp_register_pci (void)
 static int ibmphp_probe (struct pci_dev * dev, const struct pci_device_id *ids)
 {
        struct controller *ctrl;
-       struct list_head *tmp;
 
        debug ("inside ibmphp_probe\n");
        
-       list_for_each (tmp, &ebda_hpc_head) {
-               ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
+       list_for_each_entry(ctrl, &ebda_hpc_head, ebda_hpc_list) {
                if (ctrl->ctlr_type == 1) {
                        if ((dev->devfn == ctrl->u.pci_ctlr.dev_fun) && (dev->bus->number == ctrl->u.pci_ctlr.bus)) {
                                ctrl->ctrl_dev = dev;
index 5f85b1b120e3ddc12c350e2b821c18946ec90e27..535fce0f07f964edd1ecebc019a4347ec71cb549 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/init.h>
 #include <linux/mount.h>
 #include <linux/namei.h>
+#include <linux/mutex.h>
 #include <linux/pci.h>
 #include <linux/pci_hotplug.h>
 #include <asm/uaccess.h>
@@ -61,7 +62,7 @@ static int debug;
 //////////////////////////////////////////////////////////////////
 
 static LIST_HEAD(pci_hotplug_slot_list);
-static DEFINE_SPINLOCK(pci_hotplug_slot_list_lock);
+static DEFINE_MUTEX(pci_hp_mutex);
 
 /* these strings match up with the values in pci_bus_speed */
 static char *pci_bus_speed_strings[] = {
@@ -102,13 +103,13 @@ static int get_##name (struct hotplug_slot *slot, type *value)            \
 {                                                                      \
        struct hotplug_slot_ops *ops = slot->ops;                       \
        int retval = 0;                                                 \
-       if (try_module_get(ops->owner)) {                               \
-               if (ops->get_##name)                                    \
-                       retval = ops->get_##name(slot, value);          \
-               else                                                    \
-                       *value = slot->info->name;                      \
-               module_put(ops->owner);                                 \
-       }                                                               \
+       if (!try_module_get(ops->owner))                                \
+               return -ENODEV;                                         \
+       if (ops->get_##name)                                            \
+               retval = ops->get_##name(slot, value);                  \
+       else                                                            \
+               *value = slot->info->name;                              \
+       module_put(ops->owner);                                         \
        return retval;                                                  \
 }
 
@@ -530,16 +531,12 @@ static struct hotplug_slot *get_slot_from_name (const char *name)
        struct hotplug_slot *slot;
        struct list_head *tmp;
 
-       spin_lock(&pci_hotplug_slot_list_lock);
        list_for_each (tmp, &pci_hotplug_slot_list) {
                slot = list_entry (tmp, struct hotplug_slot, slot_list);
-               if (strcmp(slot->name, name) == 0)
-                       goto out;
+               if (strcmp(hotplug_slot_name(slot), name) == 0)
+                       return slot;
        }
-       slot = NULL;
-out:
-       spin_unlock(&pci_hotplug_slot_list_lock);
-       return slot;
+       return NULL;
 }
 
 /**
@@ -547,13 +544,15 @@ out:
  * @bus: bus this slot is on
  * @slot: pointer to the &struct hotplug_slot to register
  * @slot_nr: slot number
+ * @name: name registered with kobject core
  *
  * Registers a hotplug slot with the pci hotplug subsystem, which will allow
  * userspace interaction to the slot.
  *
  * Returns 0 if successful, anything else for an error.
  */
-int pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, int slot_nr)
+int pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, int slot_nr,
+                       const char *name)
 {
        int result;
        struct pci_slot *pci_slot;
@@ -568,48 +567,29 @@ int pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, int slot_nr)
                return -EINVAL;
        }
 
-       /* Check if we have already registered a slot with the same name. */
-       if (get_slot_from_name(slot->name))
-               return -EEXIST;
+       mutex_lock(&pci_hp_mutex);
 
        /*
         * No problems if we call this interface from both ACPI_PCI_SLOT
         * driver and call it here again. If we've already created the
         * pci_slot, the interface will simply bump the refcount.
         */
-       pci_slot = pci_create_slot(bus, slot_nr, slot->name);
-       if (IS_ERR(pci_slot))
-               return PTR_ERR(pci_slot);
-
-       if (pci_slot->hotplug) {
-               dbg("%s: already claimed\n", __func__);
-               pci_destroy_slot(pci_slot);
-               return -EBUSY;
+       pci_slot = pci_create_slot(bus, slot_nr, name, slot);
+       if (IS_ERR(pci_slot)) {
+               result = PTR_ERR(pci_slot);
+               goto out;
        }
 
        slot->pci_slot = pci_slot;
        pci_slot->hotplug = slot;
 
-       /*
-        * Allow pcihp drivers to override the ACPI_PCI_SLOT name.
-        */
-       if (strcmp(kobject_name(&pci_slot->kobj), slot->name)) {
-               result = kobject_rename(&pci_slot->kobj, slot->name);
-               if (result) {
-                       pci_destroy_slot(pci_slot);
-                       return result;
-               }
-       }
-
-       spin_lock(&pci_hotplug_slot_list_lock);
        list_add(&slot->slot_list, &pci_hotplug_slot_list);
-       spin_unlock(&pci_hotplug_slot_list_lock);
 
        result = fs_add_slot(pci_slot);
        kobject_uevent(&pci_slot->kobj, KOBJ_ADD);
-       dbg("Added slot %s to the list\n", slot->name);
-
-
+       dbg("Added slot %s to the list\n", name);
+out:
+       mutex_unlock(&pci_hp_mutex);
        return result;
 }
 
@@ -630,21 +610,23 @@ int pci_hp_deregister(struct hotplug_slot *hotplug)
        if (!hotplug)
                return -ENODEV;
 
-       temp = get_slot_from_name(hotplug->name);
-       if (temp != hotplug)
+       mutex_lock(&pci_hp_mutex);
+       temp = get_slot_from_name(hotplug_slot_name(hotplug));
+       if (temp != hotplug) {
+               mutex_unlock(&pci_hp_mutex);
                return -ENODEV;
+       }
 
-       spin_lock(&pci_hotplug_slot_list_lock);
        list_del(&hotplug->slot_list);
-       spin_unlock(&pci_hotplug_slot_list_lock);
 
        slot = hotplug->pci_slot;
        fs_remove_slot(slot);
-       dbg("Removed slot %s from the list\n", hotplug->name);
+       dbg("Removed slot %s from the list\n", hotplug_slot_name(hotplug));
 
        hotplug->release(hotplug);
        slot->hotplug = NULL;
        pci_destroy_slot(slot);
+       mutex_unlock(&pci_hp_mutex);
 
        return 0;
 }
index 9e6cec67e1cc33d62690e8a3ebcf462c706956ca..a4817a841faea5f6c3e148fd1991d50fa77b5aa0 100644 (file)
@@ -57,19 +57,30 @@ extern struct workqueue_struct *pciehp_wq;
 #define warn(format, arg...)                                           \
        printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
 
+#define ctrl_dbg(ctrl, format, arg...)                                 \
+       do {                                                            \
+               if (pciehp_debug)                                       \
+                       dev_printk(, &ctrl->pcie->device,               \
+                                       format, ## arg);                \
+       } while (0)
+#define ctrl_err(ctrl, format, arg...)                                 \
+       dev_err(&ctrl->pcie->device, format, ## arg)
+#define ctrl_info(ctrl, format, arg...)                                        \
+       dev_info(&ctrl->pcie->device, format, ## arg)
+#define ctrl_warn(ctrl, format, arg...)                                        \
+       dev_warn(&ctrl->pcie->device, format, ## arg)
+
 #define SLOT_NAME_SIZE 10
 struct slot {
        u8 bus;
        u8 device;
-       u32 number;
        u8 state;
-       struct timer_list task_event;
        u8 hp_slot;
+       u32 number;
        struct controller *ctrl;
        struct hpc_ops *hpc_ops;
        struct hotplug_slot *hotplug_slot;
        struct list_head        slot_list;
-       char name[SLOT_NAME_SIZE];
        unsigned long last_emi_toggle;
        struct delayed_work work;       /* work for button event */
        struct mutex lock;
@@ -87,6 +98,7 @@ struct controller {
        int num_slots;                  /* Number of slots on ctlr */
        int slot_num_inc;               /* 1 or -1 */
        struct pci_dev *pci_dev;
+       struct pcie_device *pcie;       /* PCI Express port service */
        struct list_head slot_list;
        struct hpc_ops *hpc_ops;
        wait_queue_head_t queue;        /* sleep & wake process */
@@ -98,6 +110,7 @@ struct controller {
        struct timer_list poll_timer;
        int cmd_busy;
        unsigned int no_cmd_complete:1;
+       unsigned int link_active_reporting:1;
 };
 
 #define INT_BUTTON_IGNORE              0
@@ -161,6 +174,11 @@ int pciehp_enable_slot(struct slot *p_slot);
 int pciehp_disable_slot(struct slot *p_slot);
 int pcie_enable_notification(struct controller *ctrl);
 
+static inline const char *slot_name(struct slot *slot)
+{
+       return hotplug_slot_name(slot->hotplug_slot);
+}
+
 static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device)
 {
        struct slot *slot;
@@ -170,7 +188,7 @@ static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device)
                        return slot;
        }
 
-       err("%s: slot (device=0x%x) not found\n", __func__, device);
+       ctrl_err(ctrl, "%s: slot (device=0x%x) not found\n", __func__, device);
        return NULL;
 }
 
index 4fd5355bc3b55a6c957f2d0b031b2a5dd9d2d7d3..62be1b59c74b0843ed0c9c599e145a0b51dedba8 100644 (file)
@@ -144,9 +144,10 @@ set_lock_exit:
  * sysfs interface which allows the user to toggle the Electro Mechanical
  * Interlock.  Valid values are either 0 or 1.  0 == unlock, 1 == lock
  */
-static ssize_t lock_write_file(struct hotplug_slot *slot, const char *buf,
-               size_t count)
+static ssize_t lock_write_file(struct hotplug_slot *hotplug_slot,
+               const char *buf, size_t count)
 {
+       struct slot *slot = hotplug_slot->private;
        unsigned long llock;
        u8 lock;
        int retval = 0;
@@ -157,10 +158,11 @@ static ssize_t lock_write_file(struct hotplug_slot *slot, const char *buf,
        switch (lock) {
                case 0:
                case 1:
-                       retval = set_lock_status(slot, lock);
+                       retval = set_lock_status(hotplug_slot, lock);
                        break;
                default:
-                       err ("%d is an invalid lock value\n", lock);
+                       ctrl_err(slot->ctrl, "%d is an invalid lock value\n",
+                                lock);
                        retval = -EINVAL;
        }
        if (retval)
@@ -180,7 +182,10 @@ static struct hotplug_slot_attribute hotplug_slot_attr_lock = {
  */
 static void release_slot(struct hotplug_slot *hotplug_slot)
 {
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       struct slot *slot = hotplug_slot->private;
+
+       ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
+                __func__, hotplug_slot_name(hotplug_slot));
 
        kfree(hotplug_slot->info);
        kfree(hotplug_slot);
@@ -191,7 +196,7 @@ static int init_slots(struct controller *ctrl)
        struct slot *slot;
        struct hotplug_slot *hotplug_slot;
        struct hotplug_slot_info *info;
-       int len, dup = 1;
+       char name[SLOT_NAME_SIZE];
        int retval = -ENOMEM;
 
        list_for_each_entry(slot, &ctrl->slot_list, slot_list) {
@@ -205,46 +210,36 @@ static int init_slots(struct controller *ctrl)
 
                /* register this slot with the hotplug pci core */
                hotplug_slot->info = info;
-               hotplug_slot->name = slot->name;
                hotplug_slot->private = slot;
                hotplug_slot->release = &release_slot;
                hotplug_slot->ops = &pciehp_hotplug_slot_ops;
-               get_power_status(hotplug_slot, &info->power_status);
-               get_attention_status(hotplug_slot, &info->attention_status);
-               get_latch_status(hotplug_slot, &info->latch_status);
-               get_adapter_status(hotplug_slot, &info->adapter_status);
                slot->hotplug_slot = hotplug_slot;
+               snprintf(name, SLOT_NAME_SIZE, "%u", slot->number);
 
-               dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x "
-                   "slot_device_offset=%x\n", slot->bus, slot->device,
-                   slot->hp_slot, slot->number, ctrl->slot_device_offset);
-duplicate_name:
+               ctrl_dbg(ctrl, "Registering bus=%x dev=%x hp_slot=%x sun=%x "
+                        "slot_device_offset=%x\n", slot->bus, slot->device,
+                        slot->hp_slot, slot->number, ctrl->slot_device_offset);
                retval = pci_hp_register(hotplug_slot,
                                         ctrl->pci_dev->subordinate,
-                                        slot->device);
+                                        slot->device,
+                                        name);
                if (retval) {
-                       /*
-                        * If slot N already exists, we'll try to create
-                        * slot N-1, N-2 ... N-M, until we overflow.
-                        */
-                       if (retval == -EEXIST) {
-                               len = snprintf(slot->name, SLOT_NAME_SIZE,
-                                              "%d-%d", slot->number, dup++);
-                               if (len < SLOT_NAME_SIZE)
-                                       goto duplicate_name;
-                               else
-                                       err("duplicate slot name overflow\n");
-                       }
-                       err("pci_hp_register failed with error %d\n", retval);
+                       ctrl_err(ctrl, "pci_hp_register failed with error %d\n",
+                                retval);
                        goto error_info;
                }
+               get_power_status(hotplug_slot, &info->power_status);
+               get_attention_status(hotplug_slot, &info->attention_status);
+               get_latch_status(hotplug_slot, &info->latch_status);
+               get_adapter_status(hotplug_slot, &info->adapter_status);
                /* create additional sysfs entries */
                if (EMI(ctrl)) {
                        retval = sysfs_create_file(&hotplug_slot->pci_slot->kobj,
                                &hotplug_slot_attr_lock.attr);
                        if (retval) {
                                pci_hp_deregister(hotplug_slot);
-                               err("cannot create additional sysfs entries\n");
+                               ctrl_err(ctrl, "cannot create additional sysfs "
+                                        "entries\n");
                                goto error_info;
                        }
                }
@@ -278,7 +273,8 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
 {
        struct slot *slot = hotplug_slot->private;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
+                 __func__, slot_name(slot));
 
        hotplug_slot->info->attention_status = status;
 
@@ -293,7 +289,8 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
 {
        struct slot *slot = hotplug_slot->private;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
+                __func__, slot_name(slot));
 
        return pciehp_sysfs_enable_slot(slot);
 }
@@ -303,7 +300,8 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
 {
        struct slot *slot = hotplug_slot->private;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
+                 __func__, slot_name(slot));
 
        return pciehp_sysfs_disable_slot(slot);
 }
@@ -313,7 +311,8 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
        struct slot *slot = hotplug_slot->private;
        int retval;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
+                 __func__, slot_name(slot));
 
        retval = slot->hpc_ops->get_power_status(slot, value);
        if (retval < 0)
@@ -327,7 +326,8 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
        struct slot *slot = hotplug_slot->private;
        int retval;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
+                 __func__, slot_name(slot));
 
        retval = slot->hpc_ops->get_attention_status(slot, value);
        if (retval < 0)
@@ -341,7 +341,8 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
        struct slot *slot = hotplug_slot->private;
        int retval;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
+                __func__, slot_name(slot));
 
        retval = slot->hpc_ops->get_latch_status(slot, value);
        if (retval < 0)
@@ -355,7 +356,8 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
        struct slot *slot = hotplug_slot->private;
        int retval;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
+                __func__, slot_name(slot));
 
        retval = slot->hpc_ops->get_adapter_status(slot, value);
        if (retval < 0)
@@ -370,7 +372,8 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot,
        struct slot *slot = hotplug_slot->private;
        int retval;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
+                __func__, slot_name(slot));
 
        retval = slot->hpc_ops->get_max_bus_speed(slot, value);
        if (retval < 0)
@@ -384,7 +387,8 @@ static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe
        struct slot *slot = hotplug_slot->private;
        int retval;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
+                __func__, slot_name(slot));
 
        retval = slot->hpc_ops->get_cur_bus_speed(slot, value);
        if (retval < 0)
@@ -402,14 +406,15 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
        struct pci_dev *pdev = dev->port;
 
        if (pciehp_force)
-               dbg("Bypassing BIOS check for pciehp use on %s\n",
-                   pci_name(pdev));
+               dev_info(&dev->device,
+                        "Bypassing BIOS check for pciehp use on %s\n",
+                        pci_name(pdev));
        else if (pciehp_get_hp_hw_control_from_firmware(pdev))
                goto err_out_none;
 
        ctrl = pcie_init(dev);
        if (!ctrl) {
-               dbg("%s: controller initialization failed\n", PCIE_MODULE_NAME);
+               dev_err(&dev->device, "controller initialization failed\n");
                goto err_out_none;
        }
        set_service_data(dev, ctrl);
@@ -418,11 +423,10 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
        rc = init_slots(ctrl);
        if (rc) {
                if (rc == -EBUSY)
-                       warn("%s: slot already registered by another "
-                               "hotplug driver\n", PCIE_MODULE_NAME);
+                       ctrl_warn(ctrl, "slot already registered by another "
+                                 "hotplug driver\n");
                else
-                       err("%s: slot initialization failed\n",
-                               PCIE_MODULE_NAME);
+                       ctrl_err(ctrl, "slot initialization failed\n");
                goto err_out_release_ctlr;
        }
 
@@ -461,13 +465,13 @@ static void pciehp_remove (struct pcie_device *dev)
 #ifdef CONFIG_PM
 static int pciehp_suspend (struct pcie_device *dev, pm_message_t state)
 {
-       printk("%s ENTRY\n", __func__);
+       dev_info(&dev->device, "%s ENTRY\n", __func__);
        return 0;
 }
 
 static int pciehp_resume (struct pcie_device *dev)
 {
-       printk("%s ENTRY\n", __func__);
+       dev_info(&dev->device, "%s ENTRY\n", __func__);
        if (pciehp_force) {
                struct controller *ctrl = get_service_data(dev);
                struct slot *t_slot;
@@ -497,10 +501,9 @@ static struct pcie_port_service_id port_pci_ids[] = { {
        .driver_data =  0,
        }, { /* end: all zeroes */ }
 };
-static const char device_name[] = "hpdriver";
 
 static struct pcie_port_service_driver hpdriver_portdrv = {
-       .name           = (char *)device_name,
+       .name           = PCIE_MODULE_NAME,
        .id_table       = &port_pci_ids[0],
 
        .probe          = pciehp_probe,
index 96a5d55a49835e43caadb3b2b0cd52210fd2fce9..d6c5eb2977530f34e18b51001f4fa3285353f641 100644 (file)
@@ -58,14 +58,15 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type)
 u8 pciehp_handle_attention_button(struct slot *p_slot)
 {
        u32 event_type;
+       struct controller *ctrl = p_slot->ctrl;
 
        /* Attention Button Change */
-       dbg("pciehp:  Attention button interrupt received.\n");
+       ctrl_dbg(ctrl, "Attention button interrupt received.\n");
 
        /*
         *  Button pressed - See if need to TAKE ACTION!!!
         */
-       info("Button pressed on Slot(%s)\n", p_slot->name);
+       ctrl_info(ctrl, "Button pressed on Slot(%s)\n", slot_name(p_slot));
        event_type = INT_BUTTON_PRESS;
 
        queue_interrupt_event(p_slot, event_type);
@@ -77,22 +78,23 @@ u8 pciehp_handle_switch_change(struct slot *p_slot)
 {
        u8 getstatus;
        u32 event_type;
+       struct controller *ctrl = p_slot->ctrl;
 
        /* Switch Change */
-       dbg("pciehp:  Switch interrupt received.\n");
+       ctrl_dbg(ctrl, "Switch interrupt received.\n");
 
        p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
        if (getstatus) {
                /*
                 * Switch opened
                 */
-               info("Latch open on Slot(%s)\n", p_slot->name);
+               ctrl_info(ctrl, "Latch open on Slot(%s)\n", slot_name(p_slot));
                event_type = INT_SWITCH_OPEN;
        } else {
                /*
                 *  Switch closed
                 */
-               info("Latch close on Slot(%s)\n", p_slot->name);
+               ctrl_info(ctrl, "Latch close on Slot(%s)\n", slot_name(p_slot));
                event_type = INT_SWITCH_CLOSE;
        }
 
@@ -105,9 +107,10 @@ u8 pciehp_handle_presence_change(struct slot *p_slot)
 {
        u32 event_type;
        u8 presence_save;
+       struct controller *ctrl = p_slot->ctrl;
 
        /* Presence Change */
-       dbg("pciehp:  Presence/Notify input change.\n");
+       ctrl_dbg(ctrl, "Presence/Notify input change.\n");
 
        /* Switch is open, assume a presence change
         * Save the presence state
@@ -117,13 +120,14 @@ u8 pciehp_handle_presence_change(struct slot *p_slot)
                /*
                 * Card Present
                 */
-               info("Card present on Slot(%s)\n", p_slot->name);
+               ctrl_info(ctrl, "Card present on Slot(%s)\n", slot_name(p_slot));
                event_type = INT_PRESENCE_ON;
        } else {
                /*
                 * Not Present
                 */
-               info("Card not present on Slot(%s)\n", p_slot->name);
+               ctrl_info(ctrl, "Card not present on Slot(%s)\n",
+                         slot_name(p_slot));
                event_type = INT_PRESENCE_OFF;
        }
 
@@ -135,23 +139,25 @@ u8 pciehp_handle_presence_change(struct slot *p_slot)
 u8 pciehp_handle_power_fault(struct slot *p_slot)
 {
        u32 event_type;
+       struct controller *ctrl = p_slot->ctrl;
 
        /* power fault */
-       dbg("pciehp:  Power fault interrupt received.\n");
+       ctrl_dbg(ctrl, "Power fault interrupt received.\n");
 
        if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) {
                /*
                 * power fault Cleared
                 */
-               info("Power fault cleared on Slot(%s)\n", p_slot->name);
+               ctrl_info(ctrl, "Power fault cleared on Slot(%s)\n",
+                         slot_name(p_slot));
                event_type = INT_POWER_FAULT_CLEAR;
        } else {
                /*
                 *   power fault
                 */
-               info("Power fault on Slot(%s)\n", p_slot->name);
+               ctrl_info(ctrl, "Power fault on Slot(%s)\n", slot_name(p_slot));
                event_type = INT_POWER_FAULT;
-               info("power fault bit %x set\n", 0);
+               ctrl_info(ctrl, "power fault bit %x set\n", 0);
        }
 
        queue_interrupt_event(p_slot, event_type);
@@ -168,8 +174,9 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
        /* turn off slot, turn on Amber LED, turn off Green LED if supported*/
        if (POWER_CTRL(ctrl)) {
                if (pslot->hpc_ops->power_off_slot(pslot)) {
-                       err("%s: Issue of Slot Power Off command failed\n",
-                           __func__);
+                       ctrl_err(ctrl,
+                                "%s: Issue of Slot Power Off command failed\n",
+                                __func__);
                        return;
                }
        }
@@ -186,8 +193,8 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
 
        if (ATTN_LED(ctrl)) {
                if (pslot->hpc_ops->set_attention_status(pslot, 1)) {
-                       err("%s: Issue of Set Attention Led command failed\n",
-                           __func__);
+                       ctrl_err(ctrl, "%s: Issue of Set Attention "
+                                "Led command failed\n", __func__);
                        return;
                }
        }
@@ -205,9 +212,9 @@ static int board_added(struct slot *p_slot)
        int retval = 0;
        struct controller *ctrl = p_slot->ctrl;
 
-       dbg("%s: slot device, slot offset, hp slot = %d, %d ,%d\n",
-                       __func__, p_slot->device,
-                       ctrl->slot_device_offset, p_slot->hp_slot);
+       ctrl_dbg(ctrl, "%s: slot device, slot offset, hp slot = %d, %d ,%d\n",
+                __func__, p_slot->device, ctrl->slot_device_offset,
+                p_slot->hp_slot);
 
        if (POWER_CTRL(ctrl)) {
                /* Power on slot */
@@ -219,28 +226,25 @@ static int board_added(struct slot *p_slot)
        if (PWR_LED(ctrl))
                p_slot->hpc_ops->green_led_blink(p_slot);
 
-       /* Wait for ~1 second */
-       msleep(1000);
-
        /* Check link training status */
        retval = p_slot->hpc_ops->check_lnk_status(ctrl);
        if (retval) {
-               err("%s: Failed to check link status\n", __func__);
+               ctrl_err(ctrl, "%s: Failed to check link status\n", __func__);
                set_slot_off(ctrl, p_slot);
                return retval;
        }
 
        /* Check for a power fault */
        if (p_slot->hpc_ops->query_power_fault(p_slot)) {
-               dbg("%s: power fault detected\n", __func__);
+               ctrl_dbg(ctrl, "%s: power fault detected\n", __func__);
                retval = POWER_FAILURE;
                goto err_exit;
        }
 
        retval = pciehp_configure_device(p_slot);
        if (retval) {
-               err("Cannot add device 0x%x:%x\n", p_slot->bus,
-                   p_slot->device);
+               ctrl_err(ctrl, "Cannot add device 0x%x:%x\n",
+                        p_slot->bus, p_slot->device);
                goto err_exit;
        }
 
@@ -272,14 +276,14 @@ static int remove_board(struct slot *p_slot)
        if (retval)
                return retval;
 
-       dbg("In %s, hp_slot = %d\n", __func__, p_slot->hp_slot);
+       ctrl_dbg(ctrl, "In %s, hp_slot = %d\n", __func__, p_slot->hp_slot);
 
        if (POWER_CTRL(ctrl)) {
                /* power off slot */
                retval = p_slot->hpc_ops->power_off_slot(p_slot);
                if (retval) {
-                       err("%s: Issue of Slot Disable command failed\n",
-                           __func__);
+                       ctrl_err(ctrl, "%s: Issue of Slot Disable command "
+                                "failed\n", __func__);
                        return retval;
                }
        }
@@ -320,8 +324,8 @@ static void pciehp_power_thread(struct work_struct *work)
        switch (p_slot->state) {
        case POWEROFF_STATE:
                mutex_unlock(&p_slot->lock);
-               dbg("%s: disabling bus:device(%x:%x)\n",
-                   __func__, p_slot->bus, p_slot->device);
+               ctrl_dbg(p_slot->ctrl, "%s: disabling bus:device(%x:%x)\n",
+                        __func__, p_slot->bus, p_slot->device);
                pciehp_disable_slot(p_slot);
                mutex_lock(&p_slot->lock);
                p_slot->state = STATIC_STATE;
@@ -349,7 +353,8 @@ void pciehp_queue_pushbutton_work(struct work_struct *work)
 
        info = kmalloc(sizeof(*info), GFP_KERNEL);
        if (!info) {
-               err("%s: Cannot allocate memory\n", __func__);
+               ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n",
+                        __func__);
                return;
        }
        info->p_slot = p_slot;
@@ -403,12 +408,14 @@ static void handle_button_press_event(struct slot *p_slot)
                p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
                if (getstatus) {
                        p_slot->state = BLINKINGOFF_STATE;
-                       info("PCI slot #%s - powering off due to button "
-                            "press.\n", p_slot->name);
+                       ctrl_info(ctrl,
+                                 "PCI slot #%s - powering off due to button "
+                                 "press.\n", slot_name(p_slot));
                } else {
                        p_slot->state = BLINKINGON_STATE;
-                       info("PCI slot #%s - powering on due to button "
-                            "press.\n", p_slot->name);
+                       ctrl_info(ctrl,
+                                 "PCI slot #%s - powering on due to button "
+                                 "press.\n", slot_name(p_slot));
                }
                /* blink green LED and turn off amber */
                if (PWR_LED(ctrl))
@@ -425,8 +432,8 @@ static void handle_button_press_event(struct slot *p_slot)
                 * press the attention again before the 5 sec. limit
                 * expires to cancel hot-add or hot-remove
                 */
-               info("Button cancel on Slot(%s)\n", p_slot->name);
-               dbg("%s: button cancel\n", __func__);
+               ctrl_info(ctrl, "Button cancel on Slot(%s)\n", slot_name(p_slot));
+               ctrl_dbg(ctrl, "%s: button cancel\n", __func__);
                cancel_delayed_work(&p_slot->work);
                if (p_slot->state == BLINKINGOFF_STATE) {
                        if (PWR_LED(ctrl))
@@ -437,8 +444,8 @@ static void handle_button_press_event(struct slot *p_slot)
                }
                if (ATTN_LED(ctrl))
                        p_slot->hpc_ops->set_attention_status(p_slot, 0);
-               info("PCI slot #%s - action canceled due to button press\n",
-                    p_slot->name);
+               ctrl_info(ctrl, "PCI slot #%s - action canceled "
+                         "due to button press\n", slot_name(p_slot));
                p_slot->state = STATIC_STATE;
                break;
        case POWEROFF_STATE:
@@ -448,11 +455,11 @@ static void handle_button_press_event(struct slot *p_slot)
                 * this means that the previous attention button action
                 * to hot-add or hot-remove is undergoing
                 */
-               info("Button ignore on Slot(%s)\n", p_slot->name);
+               ctrl_info(ctrl, "Button ignore on Slot(%s)\n", slot_name(p_slot));
                update_slot_info(p_slot);
                break;
        default:
-               warn("Not a valid state\n");
+               ctrl_warn(ctrl, "Not a valid state\n");
                break;
        }
 }
@@ -467,7 +474,8 @@ static void handle_surprise_event(struct slot *p_slot)
 
        info = kmalloc(sizeof(*info), GFP_KERNEL);
        if (!info) {
-               err("%s: Cannot allocate memory\n", __func__);
+               ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n",
+                        __func__);
                return;
        }
        info->p_slot = p_slot;
@@ -505,7 +513,7 @@ static void interrupt_event_handler(struct work_struct *work)
        case INT_PRESENCE_OFF:
                if (!HP_SUPR_RM(ctrl))
                        break;
-               dbg("Surprise Removal\n");
+               ctrl_dbg(ctrl, "Surprise Removal\n");
                update_slot_info(p_slot);
                handle_surprise_event(p_slot);
                break;
@@ -522,22 +530,23 @@ int pciehp_enable_slot(struct slot *p_slot)
 {
        u8 getstatus = 0;
        int rc;
+       struct controller *ctrl = p_slot->ctrl;
 
        /* Check to see if (latch closed, card present, power off) */
        mutex_lock(&p_slot->ctrl->crit_sect);
 
        rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
        if (rc || !getstatus) {
-               info("%s: no adapter on slot(%s)\n", __func__,
-                    p_slot->name);
+               ctrl_info(ctrl, "%s: no adapter on slot(%s)\n",
+                         __func__, slot_name(p_slot));
                mutex_unlock(&p_slot->ctrl->crit_sect);
                return -ENODEV;
        }
        if (MRL_SENS(p_slot->ctrl)) {
                rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
                if (rc || getstatus) {
-                       info("%s: latch open on slot(%s)\n", __func__,
-                            p_slot->name);
+                       ctrl_info(ctrl, "%s: latch open on slot(%s)\n",
+                                 __func__, slot_name(p_slot));
                        mutex_unlock(&p_slot->ctrl->crit_sect);
                        return -ENODEV;
                }
@@ -546,8 +555,8 @@ int pciehp_enable_slot(struct slot *p_slot)
        if (POWER_CTRL(p_slot->ctrl)) {
                rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
                if (rc || getstatus) {
-                       info("%s: already enabled on slot(%s)\n", __func__,
-                            p_slot->name);
+                       ctrl_info(ctrl, "%s: already enabled on slot(%s)\n",
+                                 __func__, slot_name(p_slot));
                        mutex_unlock(&p_slot->ctrl->crit_sect);
                        return -EINVAL;
                }
@@ -571,6 +580,7 @@ int pciehp_disable_slot(struct slot *p_slot)
 {
        u8 getstatus = 0;
        int ret = 0;
+       struct controller *ctrl = p_slot->ctrl;
 
        if (!p_slot->ctrl)
                return 1;
@@ -581,8 +591,8 @@ int pciehp_disable_slot(struct slot *p_slot)
        if (!HP_SUPR_RM(p_slot->ctrl)) {
                ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
                if (ret || !getstatus) {
-                       info("%s: no adapter on slot(%s)\n", __func__,
-                            p_slot->name);
+                       ctrl_info(ctrl, "%s: no adapter on slot(%s)\n",
+                                 __func__, slot_name(p_slot));
                        mutex_unlock(&p_slot->ctrl->crit_sect);
                        return -ENODEV;
                }
@@ -591,8 +601,8 @@ int pciehp_disable_slot(struct slot *p_slot)
        if (MRL_SENS(p_slot->ctrl)) {
                ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
                if (ret || getstatus) {
-                       info("%s: latch open on slot(%s)\n", __func__,
-                            p_slot->name);
+                       ctrl_info(ctrl, "%s: latch open on slot(%s)\n",
+                                 __func__, slot_name(p_slot));
                        mutex_unlock(&p_slot->ctrl->crit_sect);
                        return -ENODEV;
                }
@@ -601,8 +611,8 @@ int pciehp_disable_slot(struct slot *p_slot)
        if (POWER_CTRL(p_slot->ctrl)) {
                ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
                if (ret || !getstatus) {
-                       info("%s: already disabled slot(%s)\n", __func__,
-                            p_slot->name);
+                       ctrl_info(ctrl, "%s: already disabled slot(%s)\n",
+                                 __func__, slot_name(p_slot));
                        mutex_unlock(&p_slot->ctrl->crit_sect);
                        return -EINVAL;
                }
@@ -618,6 +628,7 @@ int pciehp_disable_slot(struct slot *p_slot)
 int pciehp_sysfs_enable_slot(struct slot *p_slot)
 {
        int retval = -ENODEV;
+       struct controller *ctrl = p_slot->ctrl;
 
        mutex_lock(&p_slot->lock);
        switch (p_slot->state) {
@@ -631,15 +642,17 @@ int pciehp_sysfs_enable_slot(struct slot *p_slot)
                p_slot->state = STATIC_STATE;
                break;
        case POWERON_STATE:
-               info("Slot %s is already in powering on state\n",
-                    p_slot->name);
+               ctrl_info(ctrl, "Slot %s is already in powering on state\n",
+                         slot_name(p_slot));
                break;
        case BLINKINGOFF_STATE:
        case POWEROFF_STATE:
-               info("Already enabled on slot %s\n", p_slot->name);
+               ctrl_info(ctrl, "Already enabled on slot %s\n",
+                         slot_name(p_slot));
                break;
        default:
-               err("Not a valid state on slot %s\n", p_slot->name);
+               ctrl_err(ctrl, "Not a valid state on slot %s\n",
+                        slot_name(p_slot));
                break;
        }
        mutex_unlock(&p_slot->lock);
@@ -650,6 +663,7 @@ int pciehp_sysfs_enable_slot(struct slot *p_slot)
 int pciehp_sysfs_disable_slot(struct slot *p_slot)
 {
        int retval = -ENODEV;
+       struct controller *ctrl = p_slot->ctrl;
 
        mutex_lock(&p_slot->lock);
        switch (p_slot->state) {
@@ -663,15 +677,17 @@ int pciehp_sysfs_disable_slot(struct slot *p_slot)
                p_slot->state = STATIC_STATE;
                break;
        case POWEROFF_STATE:
-               info("Slot %s is already in powering off state\n",
-                    p_slot->name);
+               ctrl_info(ctrl, "Slot %s is already in powering off state\n",
+                         slot_name(p_slot));
                break;
        case BLINKINGON_STATE:
        case POWERON_STATE:
-               info("Already disabled on slot %s\n", p_slot->name);
+               ctrl_info(ctrl, "Already disabled on slot %s\n",
+                         slot_name(p_slot));
                break;
        default:
-               err("Not a valid state on slot %s\n", p_slot->name);
+               ctrl_err(ctrl, "Not a valid state on slot %s\n",
+                        slot_name(p_slot));
                break;
        }
        mutex_unlock(&p_slot->lock);
index 9d934ddee95661b76c133864591c545bdba571cc..58c72d2cc2179b4039911050158cc5a5074c4a8f 100644 (file)
@@ -125,6 +125,7 @@ static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value)
 /* Field definitions in Link Capabilities Register */
 #define MAX_LNK_SPEED          0x000F
 #define MAX_LNK_WIDTH          0x03F0
+#define LINK_ACTIVE_REPORTING  0x00100000
 
 /* Link Width Encoding */
 #define LNK_X1         0x01
@@ -141,6 +142,7 @@ static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value)
 #define LNK_TRN_ERR    0x0400
 #define        LNK_TRN         0x0800
 #define SLOT_CLK_CONF  0x1000
+#define LINK_ACTIVE    0x2000
 
 /* Field definitions in Slot Capabilities Register */
 #define ATTN_BUTTN_PRSN        0x00000001
@@ -223,7 +225,7 @@ static void start_int_poll_timer(struct controller *ctrl, int sec)
 
 static inline int pciehp_request_irq(struct controller *ctrl)
 {
-       int retval, irq = ctrl->pci_dev->irq;
+       int retval, irq = ctrl->pcie->irq;
 
        /* Install interrupt polling timer. Start with 10 sec delay */
        if (pciehp_poll_mode) {
@@ -235,7 +237,8 @@ static inline int pciehp_request_irq(struct controller *ctrl)
        /* Installs the interrupt handler */
        retval = request_irq(irq, pcie_isr, IRQF_SHARED, MY_NAME, ctrl);
        if (retval)
-               err("Cannot get irq %d for the hotplug controller\n", irq);
+               ctrl_err(ctrl, "Cannot get irq %d for the hotplug controller\n",
+                        irq);
        return retval;
 }
 
@@ -244,7 +247,7 @@ static inline void pciehp_free_irq(struct controller *ctrl)
        if (pciehp_poll_mode)
                del_timer_sync(&ctrl->poll_timer);
        else
-               free_irq(ctrl->pci_dev->irq, ctrl);
+               free_irq(ctrl->pcie->irq, ctrl);
 }
 
 static int pcie_poll_cmd(struct controller *ctrl)
@@ -282,7 +285,7 @@ static void pcie_wait_cmd(struct controller *ctrl, int poll)
        else
                rc = wait_event_timeout(ctrl->queue, !ctrl->cmd_busy, timeout);
        if (!rc)
-               dbg("Command not completed in 1000 msec\n");
+               ctrl_dbg(ctrl, "Command not completed in 1000 msec\n");
 }
 
 /**
@@ -301,7 +304,8 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
 
        retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
        if (retval) {
-               err("%s: Cannot read SLOTSTATUS register\n", __func__);
+               ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n",
+                        __func__);
                goto out;
        }
 
@@ -312,26 +316,28 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
                         * proceed forward to issue the next command according
                         * to spec. Just print out the error message.
                         */
-                       dbg("%s: CMD_COMPLETED not clear after 1 sec.\n",
-                           __func__);
+                       ctrl_dbg(ctrl,
+                                "%s: CMD_COMPLETED not clear after 1 sec.\n",
+                                __func__);
                } else if (!NO_CMD_CMPL(ctrl)) {
                        /*
                         * This controller semms to notify of command completed
                         * event even though it supports none of power
                         * controller, attention led, power led and EMI.
                         */
-                       dbg("%s: Unexpected CMD_COMPLETED. Need to wait for "
-                           "command completed event.\n", __func__);
+                       ctrl_dbg(ctrl, "%s: Unexpected CMD_COMPLETED. Need to "
+                                "wait for command completed event.\n",
+                                __func__);
                        ctrl->no_cmd_complete = 0;
                } else {
-                       dbg("%s: Unexpected CMD_COMPLETED. Maybe the "
-                           "controller is broken.\n", __func__);
+                       ctrl_dbg(ctrl, "%s: Unexpected CMD_COMPLETED. Maybe "
+                                "the controller is broken.\n", __func__);
                }
        }
 
        retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
        if (retval) {
-               err("%s: Cannot read SLOTCTRL register\n", __func__);
+               ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__);
                goto out;
        }
 
@@ -341,7 +347,8 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
        smp_mb();
        retval = pciehp_writew(ctrl, SLOTCTRL, slot_ctrl);
        if (retval)
-               err("%s: Cannot write to SLOTCTRL register\n", __func__);
+               ctrl_err(ctrl, "%s: Cannot write to SLOTCTRL register\n",
+                        __func__);
 
        /*
         * Wait for command completion.
@@ -363,21 +370,63 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
        return retval;
 }
 
+static inline int check_link_active(struct controller *ctrl)
+{
+       u16 link_status;
+
+       if (pciehp_readw(ctrl, LNKSTATUS, &link_status))
+               return 0;
+       return !!(link_status & LINK_ACTIVE);
+}
+
+static void pcie_wait_link_active(struct controller *ctrl)
+{
+       int timeout = 1000;
+
+       if (check_link_active(ctrl))
+               return;
+       while (timeout > 0) {
+               msleep(10);
+               timeout -= 10;
+               if (check_link_active(ctrl))
+                       return;
+       }
+       ctrl_dbg(ctrl, "Data Link Layer Link Active not set in 1000 msec\n");
+}
+
 static int hpc_check_lnk_status(struct controller *ctrl)
 {
        u16 lnk_status;
        int retval = 0;
 
+        /*
+         * Data Link Layer Link Active Reporting must be capable for
+         * hot-plug capable downstream port. But old controller might
+         * not implement it. In this case, we wait for 1000 ms.
+         */
+        if (ctrl->link_active_reporting){
+                /* Wait for Data Link Layer Link Active bit to be set */
+                pcie_wait_link_active(ctrl);
+                /*
+                 * We must wait for 100 ms after the Data Link Layer
+                 * Link Active bit reads 1b before initiating a
+                 * configuration access to the hot added device.
+                 */
+                msleep(100);
+        } else
+                msleep(1000);
+
        retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status);
        if (retval) {
-               err("%s: Cannot read LNKSTATUS register\n", __func__);
+               ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n",
+                        __func__);
                return retval;
        }
 
-       dbg("%s: lnk_status = %x\n", __func__, lnk_status);
+       ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status);
        if ( (lnk_status & LNK_TRN) || (lnk_status & LNK_TRN_ERR) ||
                !(lnk_status & NEG_LINK_WD)) {
-               err("%s : Link Training Error occurs \n", __func__);
+               ctrl_err(ctrl, "%s : Link Training Error occurs \n", __func__);
                retval = -1;
                return retval;
        }
@@ -394,12 +443,12 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status)
 
        retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
        if (retval) {
-               err("%s: Cannot read SLOTCTRL register\n", __func__);
+               ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__);
                return retval;
        }
 
-       dbg("%s: SLOTCTRL %x, value read %x\n",
-           __func__, ctrl->cap_base + SLOTCTRL, slot_ctrl);
+       ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n",
+                __func__, ctrl->cap_base + SLOTCTRL, slot_ctrl);
 
        atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6;
 
@@ -433,11 +482,11 @@ static int hpc_get_power_status(struct slot *slot, u8 *status)
 
        retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
        if (retval) {
-               err("%s: Cannot read SLOTCTRL register\n", __func__);
+               ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__);
                return retval;
        }
-       dbg("%s: SLOTCTRL %x value read %x\n",
-           __func__, ctrl->cap_base + SLOTCTRL, slot_ctrl);
+       ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n",
+                __func__, ctrl->cap_base + SLOTCTRL, slot_ctrl);
 
        pwr_state = (slot_ctrl & PWR_CTRL) >> 10;
 
@@ -464,7 +513,8 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status)
 
        retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
        if (retval) {
-               err("%s: Cannot read SLOTSTATUS register\n", __func__);
+               ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n",
+                        __func__);
                return retval;
        }
 
@@ -482,7 +532,8 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status)
 
        retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
        if (retval) {
-               err("%s: Cannot read SLOTSTATUS register\n", __func__);
+               ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n",
+                        __func__);
                return retval;
        }
        card_state = (u8)((slot_status & PRSN_STATE) >> 6);
@@ -500,7 +551,7 @@ static int hpc_query_power_fault(struct slot *slot)
 
        retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
        if (retval) {
-               err("%s: Cannot check for power fault\n", __func__);
+               ctrl_err(ctrl, "%s: Cannot check for power fault\n", __func__);
                return retval;
        }
        pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1);
@@ -516,7 +567,7 @@ static int hpc_get_emi_status(struct slot *slot, u8 *status)
 
        retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
        if (retval) {
-               err("%s : Cannot check EMI status\n", __func__);
+               ctrl_err(ctrl, "%s : Cannot check EMI status\n", __func__);
                return retval;
        }
        *status = (slot_status & EMI_STATE) >> EMI_STATUS_BIT;
@@ -560,8 +611,8 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
                        return -1;
        }
        rc = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
-       dbg("%s: SLOTCTRL %x write cmd %x\n",
-           __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
+       ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
+                __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
 
        return rc;
 }
@@ -575,8 +626,8 @@ static void hpc_set_green_led_on(struct slot *slot)
        slot_cmd = 0x0100;
        cmd_mask = PWR_LED_CTRL;
        pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
-       dbg("%s: SLOTCTRL %x write cmd %x\n",
-           __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
+       ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
+                __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
 }
 
 static void hpc_set_green_led_off(struct slot *slot)
@@ -588,8 +639,8 @@ static void hpc_set_green_led_off(struct slot *slot)
        slot_cmd = 0x0300;
        cmd_mask = PWR_LED_CTRL;
        pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
-       dbg("%s: SLOTCTRL %x write cmd %x\n",
-           __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
+       ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
+                __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
 }
 
 static void hpc_set_green_led_blink(struct slot *slot)
@@ -601,8 +652,8 @@ static void hpc_set_green_led_blink(struct slot *slot)
        slot_cmd = 0x0200;
        cmd_mask = PWR_LED_CTRL;
        pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
-       dbg("%s: SLOTCTRL %x write cmd %x\n",
-           __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
+       ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
+                __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
 }
 
 static int hpc_power_on_slot(struct slot * slot)
@@ -613,20 +664,22 @@ static int hpc_power_on_slot(struct slot * slot)
        u16 slot_status;
        int retval = 0;
 
-       dbg("%s: slot->hp_slot %x\n", __func__, slot->hp_slot);
+       ctrl_dbg(ctrl, "%s: slot->hp_slot %x\n", __func__, slot->hp_slot);
 
        /* Clear sticky power-fault bit from previous power failures */
        retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
        if (retval) {
-               err("%s: Cannot read SLOTSTATUS register\n", __func__);
+               ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n",
+                        __func__);
                return retval;
        }
        slot_status &= PWR_FAULT_DETECTED;
        if (slot_status) {
                retval = pciehp_writew(ctrl, SLOTSTATUS, slot_status);
                if (retval) {
-                       err("%s: Cannot write to SLOTSTATUS register\n",
-                           __func__);
+                       ctrl_err(ctrl,
+                                "%s: Cannot write to SLOTSTATUS register\n",
+                                __func__);
                        return retval;
                }
        }
@@ -644,11 +697,12 @@ static int hpc_power_on_slot(struct slot * slot)
        retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
 
        if (retval) {
-               err("%s: Write %x command failed!\n", __func__, slot_cmd);
+               ctrl_err(ctrl, "%s: Write %x command failed!\n",
+                        __func__, slot_cmd);
                return -1;
        }
-       dbg("%s: SLOTCTRL %x write cmd %x\n",
-           __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
+       ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
+                __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
 
        return retval;
 }
@@ -694,7 +748,7 @@ static int hpc_power_off_slot(struct slot * slot)
        int retval = 0;
        int changed;
 
-       dbg("%s: slot->hp_slot %x\n", __func__, slot->hp_slot);
+       ctrl_dbg(ctrl, "%s: slot->hp_slot %x\n", __func__, slot->hp_slot);
 
        /*
         * Set Bad DLLP Mask bit in Correctable Error Mask
@@ -722,12 +776,12 @@ static int hpc_power_off_slot(struct slot * slot)
 
        retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
        if (retval) {
-               err("%s: Write command failed!\n", __func__);
+               ctrl_err(ctrl, "%s: Write command failed!\n", __func__);
                retval = -1;
                goto out;
        }
-       dbg("%s: SLOTCTRL %x write cmd %x\n",
-           __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
+       ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
+                __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
  out:
        if (changed)
                pcie_unmask_bad_dllp(ctrl);
@@ -749,7 +803,8 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
        intr_loc = 0;
        do {
                if (pciehp_readw(ctrl, SLOTSTATUS, &detected)) {
-                       err("%s: Cannot read SLOTSTATUS\n", __func__);
+                       ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS\n",
+                                __func__);
                        return IRQ_NONE;
                }
 
@@ -760,12 +815,13 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
                if (!intr_loc)
                        return IRQ_NONE;
                if (detected && pciehp_writew(ctrl, SLOTSTATUS, detected)) {
-                       err("%s: Cannot write to SLOTSTATUS\n", __func__);
+                       ctrl_err(ctrl, "%s: Cannot write to SLOTSTATUS\n",
+                                __func__);
                        return IRQ_NONE;
                }
        } while (detected);
 
-       dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc);
+       ctrl_dbg(ctrl, "%s: intr_loc %x\n", __func__, intr_loc);
 
        /* Check Command Complete Interrupt Pending */
        if (intr_loc & CMD_COMPLETED) {
@@ -807,7 +863,7 @@ static int hpc_get_max_lnk_speed(struct slot *slot, enum pci_bus_speed *value)
 
        retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap);
        if (retval) {
-               err("%s: Cannot read LNKCAP register\n", __func__);
+               ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__);
                return retval;
        }
 
@@ -821,7 +877,7 @@ static int hpc_get_max_lnk_speed(struct slot *slot, enum pci_bus_speed *value)
        }
 
        *value = lnk_speed;
-       dbg("Max link speed = %d\n", lnk_speed);
+       ctrl_dbg(ctrl, "Max link speed = %d\n", lnk_speed);
 
        return retval;
 }
@@ -836,7 +892,7 @@ static int hpc_get_max_lnk_width(struct slot *slot,
 
        retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap);
        if (retval) {
-               err("%s: Cannot read LNKCAP register\n", __func__);
+               ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__);
                return retval;
        }
 
@@ -871,7 +927,7 @@ static int hpc_get_max_lnk_width(struct slot *slot,
        }
 
        *value = lnk_wdth;
-       dbg("Max link width = %d\n", lnk_wdth);
+       ctrl_dbg(ctrl, "Max link width = %d\n", lnk_wdth);
 
        return retval;
 }
@@ -885,7 +941,8 @@ static int hpc_get_cur_lnk_speed(struct slot *slot, enum pci_bus_speed *value)
 
        retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status);
        if (retval) {
-               err("%s: Cannot read LNKSTATUS register\n", __func__);
+               ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n",
+                        __func__);
                return retval;
        }
 
@@ -899,7 +956,7 @@ static int hpc_get_cur_lnk_speed(struct slot *slot, enum pci_bus_speed *value)
        }
 
        *value = lnk_speed;
-       dbg("Current link speed = %d\n", lnk_speed);
+       ctrl_dbg(ctrl, "Current link speed = %d\n", lnk_speed);
 
        return retval;
 }
@@ -914,7 +971,8 @@ static int hpc_get_cur_lnk_width(struct slot *slot,
 
        retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status);
        if (retval) {
-               err("%s: Cannot read LNKSTATUS register\n", __func__);
+               ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n",
+                        __func__);
                return retval;
        }
 
@@ -949,7 +1007,7 @@ static int hpc_get_cur_lnk_width(struct slot *slot,
        }
 
        *value = lnk_wdth;
-       dbg("Current link width = %d\n", lnk_wdth);
+       ctrl_dbg(ctrl, "Current link width = %d\n", lnk_wdth);
 
        return retval;
 }
@@ -998,7 +1056,8 @@ int pcie_enable_notification(struct controller *ctrl)
               PWR_FAULT_DETECT_ENABLE | HP_INTR_ENABLE | CMD_CMPL_INTR_ENABLE;
 
        if (pcie_write_cmd(ctrl, cmd, mask)) {
-               err("%s: Cannot enable software notification\n", __func__);
+               ctrl_err(ctrl, "%s: Cannot enable software notification\n",
+                        __func__);
                return -1;
        }
        return 0;
@@ -1010,7 +1069,8 @@ static void pcie_disable_notification(struct controller *ctrl)
        mask = PRSN_DETECT_ENABLE | ATTN_BUTTN_ENABLE | MRL_DETECT_ENABLE |
               PWR_FAULT_DETECT_ENABLE | HP_INTR_ENABLE | CMD_CMPL_INTR_ENABLE;
        if (pcie_write_cmd(ctrl, 0, mask))
-               warn("%s: Cannot disable software notification\n", __func__);
+               ctrl_warn(ctrl, "%s: Cannot disable software notification\n",
+                         __func__);
 }
 
 static int pcie_init_notification(struct controller *ctrl)
@@ -1044,7 +1104,6 @@ static int pcie_init_slot(struct controller *ctrl)
        slot->device = ctrl->slot_device_offset + slot->hp_slot;
        slot->hpc_ops = ctrl->hpc_ops;
        slot->number = ctrl->first_slot;
-       snprintf(slot->name, SLOT_NAME_SIZE, "%d", slot->number);
        mutex_init(&slot->lock);
        INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work);
        list_add(&slot->slot_list, &ctrl->slot_list);
@@ -1071,58 +1130,71 @@ static inline void dbg_ctrl(struct controller *ctrl)
        if (!pciehp_debug)
                return;
 
-       dbg("Hotplug Controller:\n");
-       dbg("  Seg/Bus/Dev/Func/IRQ : %s IRQ %d\n", pci_name(pdev), pdev->irq);
-       dbg("  Vendor ID            : 0x%04x\n", pdev->vendor);
-       dbg("  Device ID            : 0x%04x\n", pdev->device);
-       dbg("  Subsystem ID         : 0x%04x\n", pdev->subsystem_device);
-       dbg("  Subsystem Vendor ID  : 0x%04x\n", pdev->subsystem_vendor);
-       dbg("  PCIe Cap offset      : 0x%02x\n", ctrl->cap_base);
+       ctrl_info(ctrl, "Hotplug Controller:\n");
+       ctrl_info(ctrl, "  Seg/Bus/Dev/Func/IRQ : %s IRQ %d\n",
+                 pci_name(pdev), pdev->irq);
+       ctrl_info(ctrl, "  Vendor ID            : 0x%04x\n", pdev->vendor);
+       ctrl_info(ctrl, "  Device ID            : 0x%04x\n", pdev->device);
+       ctrl_info(ctrl, "  Subsystem ID         : 0x%04x\n",
+                 pdev->subsystem_device);
+       ctrl_info(ctrl, "  Subsystem Vendor ID  : 0x%04x\n",
+                 pdev->subsystem_vendor);
+       ctrl_info(ctrl, "  PCIe Cap offset      : 0x%02x\n", ctrl->cap_base);
        for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
                if (!pci_resource_len(pdev, i))
                        continue;
-               dbg("  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]     : 0x%llx@0x%llx\n",
+                         i, (unsigned long long)pci_resource_len(pdev, i),
+                         (unsigned long long)pci_resource_start(pdev, i));
        }
-       dbg("Slot Capabilities      : 0x%08x\n", ctrl->slot_cap);
-       dbg("  Physical Slot Number : %d\n", ctrl->first_slot);
-       dbg("  Attention Button     : %3s\n", ATTN_BUTTN(ctrl) ? "yes" : "no");
-       dbg("  Power Controller     : %3s\n", POWER_CTRL(ctrl) ? "yes" : "no");
-       dbg("  MRL Sensor           : %3s\n", MRL_SENS(ctrl)   ? "yes" : "no");
-       dbg("  Attention Indicator  : %3s\n", ATTN_LED(ctrl)   ? "yes" : "no");
-       dbg("  Power Indicator      : %3s\n", PWR_LED(ctrl)    ? "yes" : "no");
-       dbg("  Hot-Plug Surprise    : %3s\n", HP_SUPR_RM(ctrl) ? "yes" : "no");
-       dbg("  EMI Present          : %3s\n", EMI(ctrl)        ? "yes" : "no");
-       dbg("  Command Completed    : %3s\n", NO_CMD_CMPL(ctrl)? "no" : "yes");
+       ctrl_info(ctrl, "Slot Capabilities      : 0x%08x\n", ctrl->slot_cap);
+       ctrl_info(ctrl, "  Physical Slot Number : %d\n", ctrl->first_slot);
+       ctrl_info(ctrl, "  Attention Button     : %3s\n",
+                 ATTN_BUTTN(ctrl) ? "yes" : "no");
+       ctrl_info(ctrl, "  Power Controller     : %3s\n",
+                 POWER_CTRL(ctrl) ? "yes" : "no");
+       ctrl_info(ctrl, "  MRL Sensor           : %3s\n",
+                 MRL_SENS(ctrl)   ? "yes" : "no");
+       ctrl_info(ctrl, "  Attention Indicator  : %3s\n",
+                 ATTN_LED(ctrl)   ? "yes" : "no");
+       ctrl_info(ctrl, "  Power Indicator      : %3s\n",
+                 PWR_LED(ctrl)    ? "yes" : "no");
+       ctrl_info(ctrl, "  Hot-Plug Surprise    : %3s\n",
+                 HP_SUPR_RM(ctrl) ? "yes" : "no");
+       ctrl_info(ctrl, "  EMI Present          : %3s\n",
+                 EMI(ctrl)        ? "yes" : "no");
+       ctrl_info(ctrl, "  Command Completed    : %3s\n",
+                 NO_CMD_CMPL(ctrl) ? "no" : "yes");
        pciehp_readw(ctrl, SLOTSTATUS, &reg16);
-       dbg("Slot Status            : 0x%04x\n", reg16);
+       ctrl_info(ctrl, "Slot Status            : 0x%04x\n", reg16);
        pciehp_readw(ctrl, SLOTCTRL, &reg16);
-       dbg("Slot Control           : 0x%04x\n", reg16);
+       ctrl_info(ctrl, "Slot Control           : 0x%04x\n", reg16);
 }
 
 struct controller *pcie_init(struct pcie_device *dev)
 {
        struct controller *ctrl;
-       u32 slot_cap;
+       u32 slot_cap, link_cap;
        struct pci_dev *pdev = dev->port;
 
        ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
        if (!ctrl) {
-               err("%s : out of memory\n", __func__);
+               dev_err(&dev->device, "%s : out of memory\n", __func__);
                goto abort;
        }
        INIT_LIST_HEAD(&ctrl->slot_list);
 
+       ctrl->pcie = dev;
        ctrl->pci_dev = pdev;
        ctrl->cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP);
        if (!ctrl->cap_base) {
-               err("%s: Cannot find PCI Express capability\n", __func__);
-               goto abort;
+               ctrl_err(ctrl, "%s: Cannot find PCI Express capability\n",
+                        __func__);
+               goto abort_ctrl;
        }
        if (pciehp_readl(ctrl, SLOTCAP, &slot_cap)) {
-               err("%s: Cannot read SLOTCAP register\n", __func__);
-               goto abort;
+               ctrl_err(ctrl, "%s: Cannot read SLOTCAP register\n", __func__);
+               goto abort_ctrl;
        }
 
        ctrl->slot_cap = slot_cap;
@@ -1144,6 +1216,16 @@ struct controller *pcie_init(struct pcie_device *dev)
            !(POWER_CTRL(ctrl) | ATTN_LED(ctrl) | PWR_LED(ctrl) | EMI(ctrl)))
            ctrl->no_cmd_complete = 1;
 
+        /* Check if Data Link Layer Link Active Reporting is implemented */
+        if (pciehp_readl(ctrl, LNKCAP, &link_cap)) {
+                ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__);
+                goto abort_ctrl;
+        }
+        if (link_cap & LINK_ACTIVE_REPORTING) {
+                ctrl_dbg(ctrl, "Link Active Reporting supported\n");
+                ctrl->link_active_reporting = 1;
+        }
+
        /* Clear all remaining event bits in Slot Status register */
        if (pciehp_writew(ctrl, SLOTSTATUS, 0x1f))
                goto abort_ctrl;
@@ -1161,9 +1243,9 @@ struct controller *pcie_init(struct pcie_device *dev)
                        goto abort_ctrl;
        }
 
-       info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n",
-            pdev->vendor, pdev->device,
-            pdev->subsystem_vendor, pdev->subsystem_device);
+       ctrl_info(ctrl, "HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n",
+                 pdev->vendor, pdev->device, pdev->subsystem_vendor,
+                 pdev->subsystem_device);
 
        if (pcie_init_slot(ctrl))
                goto abort_ctrl;
index 6040dcceb256388285e1db7a10d64b62fd3925e5..ffd11148fbe21416149b5e600834f4ff5f8c054b 100644 (file)
@@ -198,18 +198,20 @@ int pciehp_configure_device(struct slot *p_slot)
        struct pci_dev *dev;
        struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
        int num, fn;
+       struct controller *ctrl = p_slot->ctrl;
 
        dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0));
        if (dev) {
-               err("Device %s already exists at %x:%x, cannot hot-add\n",
-                               pci_name(dev), p_slot->bus, p_slot->device);
+               ctrl_err(ctrl,
+                        "Device %s already exists at %x:%x, cannot hot-add\n",
+                        pci_name(dev), p_slot->bus, p_slot->device);
                pci_dev_put(dev);
                return -EINVAL;
        }
 
        num = pci_scan_slot(parent, PCI_DEVFN(p_slot->device, 0));
        if (num == 0) {
-               err("No new device found\n");
+               ctrl_err(ctrl, "No new device found\n");
                return -ENODEV;
        }
 
@@ -218,8 +220,8 @@ int pciehp_configure_device(struct slot *p_slot)
                if (!dev)
                        continue;
                if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
-                       err("Cannot hot-add display device %s\n",
-                                       pci_name(dev));
+                       ctrl_err(ctrl, "Cannot hot-add display device %s\n",
+                                pci_name(dev));
                        pci_dev_put(dev);
                        continue;
                }
@@ -244,9 +246,10 @@ int pciehp_unconfigure_device(struct slot *p_slot)
        u8 presence = 0;
        struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
        u16 command;
+       struct controller *ctrl = p_slot->ctrl;
 
-       dbg("%s: bus/dev = %x/%x\n", __func__, p_slot->bus,
-                               p_slot->device);
+       ctrl_dbg(ctrl, "%s: bus/dev = %x/%x\n", __func__,
+                p_slot->bus, p_slot->device);
        ret = p_slot->hpc_ops->get_adapter_status(p_slot, &presence);
        if (ret)
                presence = 0;
@@ -257,16 +260,17 @@ int pciehp_unconfigure_device(struct slot *p_slot)
                if (!temp)
                        continue;
                if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
-                       err("Cannot remove display device %s\n",
-                                       pci_name(temp));
+                       ctrl_err(ctrl, "Cannot remove display device %s\n",
+                                pci_name(temp));
                        pci_dev_put(temp);
                        continue;
                }
                if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) {
                        pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl);
                        if (bctl & PCI_BRIDGE_CTL_VGA) {
-                               err("Cannot remove display device %s\n",
-                                   pci_name(temp));
+                               ctrl_err(ctrl,
+                                        "Cannot remove display device %s\n",
+                                        pci_name(temp));
                                pci_dev_put(temp);
                                continue;
                        }
index 7d5921b1ee7820960afcc6b2b0ae9d711172ea49..419919a87b0fa1d923898728964de310ae4bedb2 100644 (file)
 #define PRESENT         1      /* Card in slot */
 
 #define MY_NAME "rpaphp"
-extern int debug;
+extern int rpaphp_debug;
 #define dbg(format, arg...)                                    \
        do {                                                    \
-               if (debug)                                      \
+               if (rpaphp_debug)                                       \
                        printk(KERN_DEBUG "%s: " format,        \
                                MY_NAME , ## arg);              \
        } while (0)
index 1f84f402acdbdfbffad7ac13cb56597690a0561f..95d02a08fdc7f1a1558a96583043133da5f5071c 100644 (file)
@@ -37,7 +37,7 @@
                                /* and pci_do_scan_bus */
 #include "rpaphp.h"
 
-int debug;
+int rpaphp_debug;
 LIST_HEAD(rpaphp_slot_head);
 
 #define DRIVER_VERSION "0.1"
@@ -50,7 +50,7 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
-module_param(debug, bool, 0644);
+module_param_named(debug, rpaphp_debug, bool, 0644);
 
 /**
  * set_attention_status - set attention LED
index 5acfd4f3d4cb81fb48eb5c4897aa6d840c5b77a6..513e1e2823914dddf71b7ecc7f5d58ac13010459 100644 (file)
@@ -123,7 +123,7 @@ int rpaphp_enable_slot(struct slot *slot)
                        slot->state = CONFIGURED;
                }
 
-               if (debug) {
+               if (rpaphp_debug) {
                        struct pci_dev *dev;
                        dbg("%s: pci_devs of slot[%s]\n", __func__, slot->dn->full_name);
                        list_for_each_entry (dev, &bus->devices, bus_list)
index 50884507b8be5005cd4767c65407edb7b4599db8..2ea9cf1a8d02ec2fa2785f9493610f392a6b7be4 100644 (file)
@@ -43,7 +43,7 @@ static void rpaphp_release_slot(struct hotplug_slot *hotplug_slot)
 void dealloc_slot_struct(struct slot *slot)
 {
        kfree(slot->hotplug_slot->info);
-       kfree(slot->hotplug_slot->name);
+       kfree(slot->name);
        kfree(slot->hotplug_slot);
        kfree(slot);
 }
@@ -63,11 +63,9 @@ struct slot *alloc_slot_struct(struct device_node *dn,
                                           GFP_KERNEL);
        if (!slot->hotplug_slot->info)
                goto error_hpslot;
-       slot->hotplug_slot->name = kmalloc(strlen(drc_name) + 1, GFP_KERNEL);
-       if (!slot->hotplug_slot->name)
+       slot->name = kstrdup(drc_name, GFP_KERNEL);
+       if (!slot->name)
                goto error_info;        
-       slot->name = slot->hotplug_slot->name;
-       strcpy(slot->name, drc_name);
        slot->dn = dn;
        slot->index = drc_index;
        slot->power_domain = power_domain;
@@ -137,7 +135,7 @@ int rpaphp_register_slot(struct slot *slot)
                slotno = PCI_SLOT(PCI_DN(slot->dn->child)->devfn);
        else
                slotno = -1;
-       retval = pci_hp_register(php_slot, slot->bus, slotno);
+       retval = pci_hp_register(php_slot, slot->bus, slotno, slot->name);
        if (retval) {
                err("pci_hp_register failed with error %d\n", retval);
                return retval;
index 410fe0394a8ea63fb8de8542654d514d2ec36992..3eee70928d4581e6a77cb4d804611123f6bcf38d 100644 (file)
@@ -161,7 +161,8 @@ static int sn_pci_bus_valid(struct pci_bus *pci_bus)
 }
 
 static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
-                                   struct pci_bus *pci_bus, int device)
+                                   struct pci_bus *pci_bus, int device,
+                                   char *name)
 {
        struct pcibus_info *pcibus_info;
        struct slot *slot;
@@ -173,15 +174,9 @@ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
                return -ENOMEM;
        bss_hotplug_slot->private = slot;
 
-       bss_hotplug_slot->name = kmalloc(SN_SLOT_NAME_SIZE, GFP_KERNEL);
-       if (!bss_hotplug_slot->name) {
-               kfree(bss_hotplug_slot->private);
-               return -ENOMEM;
-       }
-
        slot->device_num = device;
        slot->pci_bus = pci_bus;
-       sprintf(bss_hotplug_slot->name, "%04x:%02x:%02x",
+       sprintf(name, "%04x:%02x:%02x",
                pci_domain_nr(pci_bus),
                ((u16)pcibus_info->pbi_buscommon.bs_persist_busnum),
                device + 1);
@@ -418,7 +413,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
        /*
         * Add the slot's devices to the ACPI infrastructure */
        if (SN_ACPI_BASE_SUPPORT() && ssdt) {
-               unsigned long adr;
+               unsigned long long adr;
                struct acpi_device *pdevice;
                struct acpi_device *device;
                acpi_handle phandle;
@@ -510,7 +505,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
        /* free the ACPI resources for the slot */
        if (SN_ACPI_BASE_SUPPORT() &&
             PCI_CONTROLLER(slot->pci_bus)->acpi_handle) {
-               unsigned long adr;
+               unsigned long long adr;
                struct acpi_device *device;
                acpi_handle phandle;
                acpi_handle chandle = NULL;
@@ -608,7 +603,6 @@ static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot,
 static void sn_release_slot(struct hotplug_slot *bss_hotplug_slot)
 {
        kfree(bss_hotplug_slot->info);
-       kfree(bss_hotplug_slot->name);
        kfree(bss_hotplug_slot->private);
        kfree(bss_hotplug_slot);
 }
@@ -618,6 +612,7 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
        int device;
        struct pci_slot *pci_slot;
        struct hotplug_slot *bss_hotplug_slot;
+       char name[SN_SLOT_NAME_SIZE];
        int rc = 0;
 
        /*
@@ -645,15 +640,14 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
                }
 
                if (sn_hp_slot_private_alloc(bss_hotplug_slot,
-                                            pci_bus, device)) {
+                                            pci_bus, device, name)) {
                        rc = -ENOMEM;
                        goto alloc_err;
                }
-
                bss_hotplug_slot->ops = &sn_hotplug_slot_ops;
                bss_hotplug_slot->release = &sn_release_slot;
 
-               rc = pci_hp_register(bss_hotplug_slot, pci_bus, device);
+               rc = pci_hp_register(bss_hotplug_slot, pci_bus, device, name);
                if (rc)
                        goto register_err;
 
index 8a026f750deb65f64831f50a603c32d761e6c5ff..4d9fed00e1d0ecd671af290015566e8d82e23b9e 100644 (file)
@@ -69,15 +69,13 @@ struct slot {
        u8 state;
        u8 presence_save;
        u8 pwr_save;
-       struct timer_list task_event;
-       u8 hp_slot;
        struct controller *ctrl;
        struct hpc_ops *hpc_ops;
        struct hotplug_slot *hotplug_slot;
        struct list_head        slot_list;
-       char name[SLOT_NAME_SIZE];
        struct delayed_work work;       /* work for button event */
        struct mutex lock;
+       u8 hp_slot;
 };
 
 struct event_info {
@@ -169,6 +167,11 @@ extern void cleanup_slots(struct controller *ctrl);
 extern void shpchp_queue_pushbutton_work(struct work_struct *work);
 extern int shpc_init( struct controller *ctrl, struct pci_dev *pdev);
 
+static inline const char *slot_name(struct slot *slot)
+{
+       return hotplug_slot_name(slot->hotplug_slot);
+}
+
 #ifdef CONFIG_ACPI
 #include <linux/pci-acpi.h>
 static inline int get_hp_params_from_firmware(struct pci_dev *dev,
index cc38615395f1087f10a07764fe8d402524a9830b..7af9191df4d6dd0947d816492edea5a5d61b1ccc 100644 (file)
@@ -89,7 +89,7 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
 {
        struct slot *slot = hotplug_slot->private;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        kfree(slot->hotplug_slot->info);
        kfree(slot->hotplug_slot);
@@ -101,8 +101,9 @@ static int init_slots(struct controller *ctrl)
        struct slot *slot;
        struct hotplug_slot *hotplug_slot;
        struct hotplug_slot_info *info;
+       char name[SLOT_NAME_SIZE];
        int retval = -ENOMEM;
-       int i, len, dup = 1;
+       int i;
 
        for (i = 0; i < ctrl->num_slots; i++) {
                slot = kzalloc(sizeof(*slot), GFP_KERNEL);
@@ -119,8 +120,6 @@ static int init_slots(struct controller *ctrl)
                        goto error_hpslot;
                hotplug_slot->info = info;
 
-               hotplug_slot->name = slot->name;
-
                slot->hp_slot = i;
                slot->ctrl = ctrl;
                slot->bus = ctrl->pci_dev->subordinate->number;
@@ -133,37 +132,24 @@ static int init_slots(struct controller *ctrl)
                /* register this slot with the hotplug pci core */
                hotplug_slot->private = slot;
                hotplug_slot->release = &release_slot;
-               snprintf(slot->name, SLOT_NAME_SIZE, "%d", slot->number);
+               snprintf(name, SLOT_NAME_SIZE, "%d", slot->number);
                hotplug_slot->ops = &shpchp_hotplug_slot_ops;
 
-               get_power_status(hotplug_slot, &info->power_status);
-               get_attention_status(hotplug_slot, &info->attention_status);
-               get_latch_status(hotplug_slot, &info->latch_status);
-               get_adapter_status(hotplug_slot, &info->adapter_status);
-
                dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x "
                    "slot_device_offset=%x\n", slot->bus, slot->device,
                    slot->hp_slot, slot->number, ctrl->slot_device_offset);
-duplicate_name:
                retval = pci_hp_register(slot->hotplug_slot,
-                               ctrl->pci_dev->subordinate, slot->device);
+                               ctrl->pci_dev->subordinate, slot->device, name);
                if (retval) {
-                       /*
-                        * If slot N already exists, we'll try to create
-                        * slot N-1, N-2 ... N-M, until we overflow.
-                        */
-                       if (retval == -EEXIST) {
-                               len = snprintf(slot->name, SLOT_NAME_SIZE,
-                                              "%d-%d", slot->number, dup++);
-                               if (len < SLOT_NAME_SIZE)
-                                       goto duplicate_name;
-                               else
-                                       err("duplicate slot name overflow\n");
-                       }
                        err("pci_hp_register failed with error %d\n", retval);
                        goto error_info;
                }
 
+               get_power_status(hotplug_slot, &info->power_status);
+               get_attention_status(hotplug_slot, &info->attention_status);
+               get_latch_status(hotplug_slot, &info->latch_status);
+               get_adapter_status(hotplug_slot, &info->adapter_status);
+
                list_add(&slot->slot_list, &ctrl->slot_list);
        }
 
@@ -201,7 +187,7 @@ static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
 {
        struct slot *slot = get_slot(hotplug_slot);
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        hotplug_slot->info->attention_status = status;
        slot->hpc_ops->set_attention_status(slot, status);
@@ -213,7 +199,7 @@ static int enable_slot (struct hotplug_slot *hotplug_slot)
 {
        struct slot *slot = get_slot(hotplug_slot);
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        return shpchp_sysfs_enable_slot(slot);
 }
@@ -222,7 +208,7 @@ static int disable_slot (struct hotplug_slot *hotplug_slot)
 {
        struct slot *slot = get_slot(hotplug_slot);
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        return shpchp_sysfs_disable_slot(slot);
 }
@@ -232,7 +218,7 @@ static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
        struct slot *slot = get_slot(hotplug_slot);
        int retval;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        retval = slot->hpc_ops->get_power_status(slot, value);
        if (retval < 0)
@@ -246,7 +232,7 @@ static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
        struct slot *slot = get_slot(hotplug_slot);
        int retval;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        retval = slot->hpc_ops->get_attention_status(slot, value);
        if (retval < 0)
@@ -260,7 +246,7 @@ static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
        struct slot *slot = get_slot(hotplug_slot);
        int retval;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        retval = slot->hpc_ops->get_latch_status(slot, value);
        if (retval < 0)
@@ -274,7 +260,7 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
        struct slot *slot = get_slot(hotplug_slot);
        int retval;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        retval = slot->hpc_ops->get_adapter_status(slot, value);
        if (retval < 0)
@@ -289,7 +275,7 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot,
        struct slot *slot = get_slot(hotplug_slot);
        int retval;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        retval = slot->hpc_ops->get_max_bus_speed(slot, value);
        if (retval < 0)
@@ -303,7 +289,7 @@ static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_sp
        struct slot *slot = get_slot(hotplug_slot);
        int retval;
 
-       dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
        retval = slot->hpc_ops->get_cur_bus_speed(slot, value);
        if (retval < 0)
index dfb53932dfbce43c51d715e738d9536a1b759eb6..919b1ee4431305a886c8a8e9c63d5d7442a1390a 100644 (file)
@@ -70,7 +70,7 @@ u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl)
        /*
         *  Button pressed - See if need to TAKE ACTION!!!
         */
-       info("Button pressed on Slot(%s)\n", p_slot->name);
+       info("Button pressed on Slot(%s)\n", slot_name(p_slot));
        event_type = INT_BUTTON_PRESS;
 
        queue_interrupt_event(p_slot, event_type);
@@ -98,7 +98,7 @@ u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl)
                /*
                 * Switch opened
                 */
-               info("Latch open on Slot(%s)\n", p_slot->name);
+               info("Latch open on Slot(%s)\n", slot_name(p_slot));
                event_type = INT_SWITCH_OPEN;
                if (p_slot->pwr_save && p_slot->presence_save) {
                        event_type = INT_POWER_FAULT;
@@ -108,7 +108,7 @@ u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl)
                /*
                 *  Switch closed
                 */
-               info("Latch close on Slot(%s)\n", p_slot->name);
+               info("Latch close on Slot(%s)\n", slot_name(p_slot));
                event_type = INT_SWITCH_CLOSE;
        }
 
@@ -135,13 +135,13 @@ u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl)
                /*
                 * Card Present
                 */
-               info("Card present on Slot(%s)\n", p_slot->name);
+               info("Card present on Slot(%s)\n", slot_name(p_slot));
                event_type = INT_PRESENCE_ON;
        } else {
                /*
                 * Not Present
                 */
-               info("Card not present on Slot(%s)\n", p_slot->name);
+               info("Card not present on Slot(%s)\n", slot_name(p_slot));
                event_type = INT_PRESENCE_OFF;
        }
 
@@ -164,14 +164,14 @@ u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl)
                /*
                 * Power fault Cleared
                 */
-               info("Power fault cleared on Slot(%s)\n", p_slot->name);
+               info("Power fault cleared on Slot(%s)\n", slot_name(p_slot));
                p_slot->status = 0x00;
                event_type = INT_POWER_FAULT_CLEAR;
        } else {
                /*
                 *   Power fault
                 */
-               info("Power fault on Slot(%s)\n", p_slot->name);
+               info("Power fault on Slot(%s)\n", slot_name(p_slot));
                event_type = INT_POWER_FAULT;
                /* set power fault status for this board */
                p_slot->status = 0xFF;
@@ -493,11 +493,11 @@ static void handle_button_press_event(struct slot *p_slot)
                if (getstatus) {
                        p_slot->state = BLINKINGOFF_STATE;
                        info("PCI slot #%s - powering off due to button "
-                            "press.\n", p_slot->name);
+                            "press.\n", slot_name(p_slot));
                } else {
                        p_slot->state = BLINKINGON_STATE;
                        info("PCI slot #%s - powering on due to button "
-                            "press.\n", p_slot->name);
+                            "press.\n", slot_name(p_slot));
                }
                /* blink green LED and turn off amber */
                p_slot->hpc_ops->green_led_blink(p_slot);
@@ -512,7 +512,7 @@ static void handle_button_press_event(struct slot *p_slot)
                 * press the attention again before the 5 sec. limit
                 * expires to cancel hot-add or hot-remove
                 */
-               info("Button cancel on Slot(%s)\n", p_slot->name);
+               info("Button cancel on Slot(%s)\n", slot_name(p_slot));
                dbg("%s: button cancel\n", __func__);
                cancel_delayed_work(&p_slot->work);
                if (p_slot->state == BLINKINGOFF_STATE)
@@ -521,7 +521,7 @@ static void handle_button_press_event(struct slot *p_slot)
                        p_slot->hpc_ops->green_led_off(p_slot);
                p_slot->hpc_ops->set_attention_status(p_slot, 0);
                info("PCI slot #%s - action canceled due to button press\n",
-                    p_slot->name);
+                    slot_name(p_slot));
                p_slot->state = STATIC_STATE;
                break;
        case POWEROFF_STATE:
@@ -531,7 +531,7 @@ static void handle_button_press_event(struct slot *p_slot)
                 * this means that the previous attention button action
                 * to hot-add or hot-remove is undergoing
                 */
-               info("Button ignore on Slot(%s)\n", p_slot->name);
+               info("Button ignore on Slot(%s)\n", slot_name(p_slot));
                update_slot_info(p_slot);
                break;
        default:
@@ -574,17 +574,17 @@ static int shpchp_enable_slot (struct slot *p_slot)
        mutex_lock(&p_slot->ctrl->crit_sect);
        rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
        if (rc || !getstatus) {
-               info("No adapter on slot(%s)\n", p_slot->name);
+               info("No adapter on slot(%s)\n", slot_name(p_slot));
                goto out;
        }
        rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
        if (rc || getstatus) {
-               info("Latch open on slot(%s)\n", p_slot->name);
+               info("Latch open on slot(%s)\n", slot_name(p_slot));
                goto out;
        }
        rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
        if (rc || getstatus) {
-               info("Already enabled on slot(%s)\n", p_slot->name);
+               info("Already enabled on slot(%s)\n", slot_name(p_slot));
                goto out;
        }
 
@@ -633,17 +633,17 @@ static int shpchp_disable_slot (struct slot *p_slot)
 
        rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
        if (rc || !getstatus) {
-               info("No adapter on slot(%s)\n", p_slot->name);
+               info("No adapter on slot(%s)\n", slot_name(p_slot));
                goto out;
        }
        rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
        if (rc || getstatus) {
-               info("Latch open on slot(%s)\n", p_slot->name);
+               info("Latch open on slot(%s)\n", slot_name(p_slot));
                goto out;
        }
        rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
        if (rc || !getstatus) {
-               info("Already disabled slot(%s)\n", p_slot->name);
+               info("Already disabled slot(%s)\n", slot_name(p_slot));
                goto out;
        }
 
@@ -671,14 +671,14 @@ int shpchp_sysfs_enable_slot(struct slot *p_slot)
                break;
        case POWERON_STATE:
                info("Slot %s is already in powering on state\n",
-                    p_slot->name);
+                    slot_name(p_slot));
                break;
        case BLINKINGOFF_STATE:
        case POWEROFF_STATE:
-               info("Already enabled on slot %s\n", p_slot->name);
+               info("Already enabled on slot %s\n", slot_name(p_slot));
                break;
        default:
-               err("Not a valid state on slot %s\n", p_slot->name);
+               err("Not a valid state on slot %s\n", slot_name(p_slot));
                break;
        }
        mutex_unlock(&p_slot->lock);
@@ -703,14 +703,14 @@ int shpchp_sysfs_disable_slot(struct slot *p_slot)
                break;
        case POWEROFF_STATE:
                info("Slot %s is already in powering off state\n",
-                    p_slot->name);
+                    slot_name(p_slot));
                break;
        case BLINKINGON_STATE:
        case POWERON_STATE:
-               info("Already disabled on slot %s\n", p_slot->name);
+               info("Already disabled on slot %s\n", slot_name(p_slot));
                break;
        default:
-               err("Not a valid state on slot %s\n", p_slot->name);
+               err("Not a valid state on slot %s\n", slot_name(p_slot));
                break;
        }
        mutex_unlock(&p_slot->lock);
index 279c940a00397444a8d49e03e1ec68386f78fc3c..bf7d6ce9bbb3e764621caa96db426509003e2d46 100644 (file)
@@ -126,7 +126,8 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update)
        cfg->msg.address_hi = 0xffffffff;
 
        irq = create_irq();
-       if (irq < 0) {
+
+       if (irq <= 0) {
                kfree(cfg);
                return -EBUSY;
        }
index 8b51e10b7783d589b1d7893bb6febd052b3ee23b..a2692724b68ffe04382bdd8a2d15c4774511c47d 100644 (file)
@@ -18,6 +18,7 @@
  * Author: Ashok Raj <ashok.raj@intel.com>
  * Author: Shaohua Li <shaohua.li@intel.com>
  * Author: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ * Author: Fenghua Yu <fenghua.yu@intel.com>
  */
 
 #include <linux/init.h>
 #include <linux/timer.h>
 #include <linux/iova.h>
 #include <linux/intel-iommu.h>
-#include <asm/proto.h> /* force_iommu in this header in x86-64*/
 #include <asm/cacheflush.h>
 #include <asm/iommu.h>
 #include "pci.h"
 
+#define ROOT_SIZE              VTD_PAGE_SIZE
+#define CONTEXT_SIZE           VTD_PAGE_SIZE
+
 #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
 #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
 
@@ -199,7 +202,7 @@ static struct context_entry * device_to_context_entry(struct intel_iommu *iommu,
                        spin_unlock_irqrestore(&iommu->lock, flags);
                        return NULL;
                }
-               __iommu_flush_cache(iommu, (void *)context, PAGE_SIZE_4K);
+               __iommu_flush_cache(iommu, (void *)context, CONTEXT_SIZE);
                phy_addr = virt_to_phys((void *)context);
                set_root_value(root, phy_addr);
                set_root_present(root);
@@ -345,7 +348,7 @@ static struct dma_pte * addr_to_dma_pte(struct dmar_domain *domain, u64 addr)
                                return NULL;
                        }
                        __iommu_flush_cache(domain->iommu, tmp_page,
-                                       PAGE_SIZE_4K);
+                                       PAGE_SIZE);
                        dma_set_pte_addr(*pte, virt_to_phys(tmp_page));
                        /*
                         * high level table always sets r/w, last level page
@@ -408,13 +411,13 @@ static void dma_pte_clear_range(struct dmar_domain *domain, u64 start, u64 end)
        start &= (((u64)1) << addr_width) - 1;
        end &= (((u64)1) << addr_width) - 1;
        /* in case it's partial page */
-       start = PAGE_ALIGN_4K(start);
-       end &= PAGE_MASK_4K;
+       start = PAGE_ALIGN(start);
+       end &= PAGE_MASK;
 
        /* we don't need lock here, nobody else touches the iova range */
        while (start < end) {
                dma_pte_clear_one(domain, start);
-               start += PAGE_SIZE_4K;
+               start += VTD_PAGE_SIZE;
        }
 }
 
@@ -468,7 +471,7 @@ static int iommu_alloc_root_entry(struct intel_iommu *iommu)
        if (!root)
                return -ENOMEM;
 
-       __iommu_flush_cache(iommu, root, PAGE_SIZE_4K);
+       __iommu_flush_cache(iommu, root, ROOT_SIZE);
 
        spin_lock_irqsave(&iommu->lock, flags);
        iommu->root_entry = root;
@@ -567,27 +570,6 @@ static int __iommu_flush_context(struct intel_iommu *iommu,
        return 0;
 }
 
-static int inline iommu_flush_context_global(struct intel_iommu *iommu,
-       int non_present_entry_flush)
-{
-       return __iommu_flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL,
-               non_present_entry_flush);
-}
-
-static int inline iommu_flush_context_domain(struct intel_iommu *iommu, u16 did,
-       int non_present_entry_flush)
-{
-       return __iommu_flush_context(iommu, did, 0, 0, DMA_CCMD_DOMAIN_INVL,
-               non_present_entry_flush);
-}
-
-static int inline iommu_flush_context_device(struct intel_iommu *iommu,
-       u16 did, u16 source_id, u8 function_mask, int non_present_entry_flush)
-{
-       return __iommu_flush_context(iommu, did, source_id, function_mask,
-               DMA_CCMD_DEVICE_INVL, non_present_entry_flush);
-}
-
 /* return value determine if we need a write buffer flush */
 static int __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
        u64 addr, unsigned int size_order, u64 type,
@@ -655,37 +637,25 @@ static int __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
                printk(KERN_ERR"IOMMU: flush IOTLB failed\n");
        if (DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type))
                pr_debug("IOMMU: tlb flush request %Lx, actual %Lx\n",
-                       DMA_TLB_IIRG(type), DMA_TLB_IAIG(val));
+                       (unsigned long long)DMA_TLB_IIRG(type),
+                       (unsigned long long)DMA_TLB_IAIG(val));
        /* flush iotlb entry will implicitly flush write buffer */
        return 0;
 }
 
-static int inline iommu_flush_iotlb_global(struct intel_iommu *iommu,
-       int non_present_entry_flush)
-{
-       return __iommu_flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH,
-               non_present_entry_flush);
-}
-
-static int inline iommu_flush_iotlb_dsi(struct intel_iommu *iommu, u16 did,
-       int non_present_entry_flush)
-{
-       return __iommu_flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH,
-               non_present_entry_flush);
-}
-
 static int iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did,
        u64 addr, unsigned int pages, int non_present_entry_flush)
 {
        unsigned int mask;
 
-       BUG_ON(addr & (~PAGE_MASK_4K));
+       BUG_ON(addr & (~VTD_PAGE_MASK));
        BUG_ON(pages == 0);
 
        /* Fallback to domain selective flush if no PSI support */
        if (!cap_pgsel_inv(iommu->cap))
-               return iommu_flush_iotlb_dsi(iommu, did,
-                       non_present_entry_flush);
+               return iommu->flush.flush_iotlb(iommu, did, 0, 0,
+                                               DMA_TLB_DSI_FLUSH,
+                                               non_present_entry_flush);
 
        /*
         * PSI requires page size to be 2 ^ x, and the base address is naturally
@@ -694,11 +664,12 @@ static int iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did,
        mask = ilog2(__roundup_pow_of_two(pages));
        /* Fallback to domain selective flush if size is too big */
        if (mask > cap_max_amask_val(iommu->cap))
-               return iommu_flush_iotlb_dsi(iommu, did,
-                       non_present_entry_flush);
+               return iommu->flush.flush_iotlb(iommu, did, 0, 0,
+                       DMA_TLB_DSI_FLUSH, non_present_entry_flush);
 
-       return __iommu_flush_iotlb(iommu, did, addr, mask,
-               DMA_TLB_PSI_FLUSH, non_present_entry_flush);
+       return iommu->flush.flush_iotlb(iommu, did, addr, mask,
+                                       DMA_TLB_PSI_FLUSH,
+                                       non_present_entry_flush);
 }
 
 static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
@@ -831,7 +802,7 @@ void dmar_msi_read(int irq, struct msi_msg *msg)
 }
 
 static int iommu_page_fault_do_one(struct intel_iommu *iommu, int type,
-               u8 fault_reason, u16 source_id, u64 addr)
+               u8 fault_reason, u16 source_id, unsigned long long addr)
 {
        const char *reason;
 
@@ -1084,9 +1055,9 @@ static void dmar_init_reserved_ranges(void)
                        if (!r->flags || !(r->flags & IORESOURCE_MEM))
                                continue;
                        addr = r->start;
-                       addr &= PAGE_MASK_4K;
+                       addr &= PAGE_MASK;
                        size = r->end - addr;
-                       size = PAGE_ALIGN_4K(size);
+                       size = PAGE_ALIGN(size);
                        iova = reserve_iova(&reserved_iova_list, IOVA_PFN(addr),
                                IOVA_PFN(size + addr) - 1);
                        if (!iova)
@@ -1148,7 +1119,7 @@ static int domain_init(struct dmar_domain *domain, int guest_width)
        domain->pgd = (struct dma_pte *)alloc_pgtable_page();
        if (!domain->pgd)
                return -ENOMEM;
-       __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE_4K);
+       __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE);
        return 0;
 }
 
@@ -1164,7 +1135,7 @@ static void domain_exit(struct dmar_domain *domain)
        /* destroy iovas */
        put_iova_domain(&domain->iovad);
        end = DOMAIN_MAX_ADDR(domain->gaw);
-       end = end & (~PAGE_MASK_4K);
+       end = end & (~PAGE_MASK);
 
        /* clear ptes */
        dma_pte_clear_range(domain, 0, end);
@@ -1204,11 +1175,13 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
        __iommu_flush_cache(iommu, context, sizeof(*context));
 
        /* it's a non-present to present mapping */
-       if (iommu_flush_context_device(iommu, domain->id,
-                       (((u16)bus) << 8) | devfn, DMA_CCMD_MASK_NOBIT, 1))
+       if (iommu->flush.flush_context(iommu, domain->id,
+               (((u16)bus) << 8) | devfn, DMA_CCMD_MASK_NOBIT,
+               DMA_CCMD_DEVICE_INVL, 1))
                iommu_flush_write_buffer(iommu);
        else
-               iommu_flush_iotlb_dsi(iommu, 0, 0);
+               iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_DSI_FLUSH, 0);
+
        spin_unlock_irqrestore(&iommu->lock, flags);
        return 0;
 }
@@ -1283,22 +1256,25 @@ domain_page_mapping(struct dmar_domain *domain, dma_addr_t iova,
        u64 start_pfn, end_pfn;
        struct dma_pte *pte;
        int index;
+       int addr_width = agaw_to_width(domain->agaw);
+
+       hpa &= (((u64)1) << addr_width) - 1;
 
        if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
                return -EINVAL;
-       iova &= PAGE_MASK_4K;
-       start_pfn = ((u64)hpa) >> PAGE_SHIFT_4K;
-       end_pfn = (PAGE_ALIGN_4K(((u64)hpa) + size)) >> PAGE_SHIFT_4K;
+       iova &= PAGE_MASK;
+       start_pfn = ((u64)hpa) >> VTD_PAGE_SHIFT;
+       end_pfn = (VTD_PAGE_ALIGN(((u64)hpa) + size)) >> VTD_PAGE_SHIFT;
        index = 0;
        while (start_pfn < end_pfn) {
-               pte = addr_to_dma_pte(domain, iova + PAGE_SIZE_4K * index);
+               pte = addr_to_dma_pte(domain, iova + VTD_PAGE_SIZE * index);
                if (!pte)
                        return -ENOMEM;
                /* We don't need lock here, nobody else
                 * touches the iova range
                 */
                BUG_ON(dma_pte_addr(*pte));
-               dma_set_pte_addr(*pte, start_pfn << PAGE_SHIFT_4K);
+               dma_set_pte_addr(*pte, start_pfn << VTD_PAGE_SHIFT);
                dma_set_pte_prot(*pte, prot);
                __iommu_flush_cache(domain->iommu, pte, sizeof(*pte));
                start_pfn++;
@@ -1310,8 +1286,10 @@ domain_page_mapping(struct dmar_domain *domain, dma_addr_t iova,
 static void detach_domain_for_dev(struct dmar_domain *domain, u8 bus, u8 devfn)
 {
        clear_context_table(domain->iommu, bus, devfn);
-       iommu_flush_context_global(domain->iommu, 0);
-       iommu_flush_iotlb_global(domain->iommu, 0);
+       domain->iommu->flush.flush_context(domain->iommu, 0, 0, 0,
+                                          DMA_CCMD_GLOBAL_INVL, 0);
+       domain->iommu->flush.flush_iotlb(domain->iommu, 0, 0, 0,
+                                        DMA_TLB_GLOBAL_FLUSH, 0);
 }
 
 static void domain_remove_dev_info(struct dmar_domain *domain)
@@ -1474,11 +1452,13 @@ error:
        return find_domain(pdev);
 }
 
-static int iommu_prepare_identity_map(struct pci_dev *pdev, u64 start, u64 end)
+static int iommu_prepare_identity_map(struct pci_dev *pdev,
+                                     unsigned long long start,
+                                     unsigned long long end)
 {
        struct dmar_domain *domain;
        unsigned long size;
-       u64 base;
+       unsigned long long base;
        int ret;
 
        printk(KERN_INFO
@@ -1490,9 +1470,9 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev, u64 start, u64 end)
                return -ENOMEM;
 
        /* The address might not be aligned */
-       base = start & PAGE_MASK_4K;
+       base = start & PAGE_MASK;
        size = end - base;
-       size = PAGE_ALIGN_4K(size);
+       size = PAGE_ALIGN(size);
        if (!reserve_iova(&domain->iovad, IOVA_PFN(base),
                        IOVA_PFN(base + size) - 1)) {
                printk(KERN_ERR "IOMMU: reserve iova failed\n");
@@ -1662,6 +1642,28 @@ int __init init_dmars(void)
                }
        }
 
+       for_each_drhd_unit(drhd) {
+               if (drhd->ignored)
+                       continue;
+
+               iommu = drhd->iommu;
+               if (dmar_enable_qi(iommu)) {
+                       /*
+                        * Queued Invalidate not enabled, use Register Based
+                        * Invalidate
+                        */
+                       iommu->flush.flush_context = __iommu_flush_context;
+                       iommu->flush.flush_iotlb = __iommu_flush_iotlb;
+                       printk(KERN_INFO "IOMMU 0x%Lx: using Register based "
+                              "invalidation\n", drhd->reg_base_addr);
+               } else {
+                       iommu->flush.flush_context = qi_flush_context;
+                       iommu->flush.flush_iotlb = qi_flush_iotlb;
+                       printk(KERN_INFO "IOMMU 0x%Lx: using Queued "
+                              "invalidation\n", drhd->reg_base_addr);
+               }
+       }
+
        /*
         * For each rmrr
         *   for each dev attached to rmrr
@@ -1714,9 +1716,10 @@ int __init init_dmars(void)
 
                iommu_set_root_entry(iommu);
 
-               iommu_flush_context_global(iommu, 0);
-               iommu_flush_iotlb_global(iommu, 0);
-
+               iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL,
+                                          0);
+               iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH,
+                                        0);
                iommu_disable_protect_mem_regions(iommu);
 
                ret = iommu_enable_translation(iommu);
@@ -1738,8 +1741,8 @@ error:
 static inline u64 aligned_size(u64 host_addr, size_t size)
 {
        u64 addr;
-       addr = (host_addr & (~PAGE_MASK_4K)) + size;
-       return PAGE_ALIGN_4K(addr);
+       addr = (host_addr & (~PAGE_MASK)) + size;
+       return PAGE_ALIGN(addr);
 }
 
 struct iova *
@@ -1753,20 +1756,20 @@ iommu_alloc_iova(struct dmar_domain *domain, size_t size, u64 end)
                return NULL;
 
        piova = alloc_iova(&domain->iovad,
-                       size >> PAGE_SHIFT_4K, IOVA_PFN(end), 1);
+                       size >> PAGE_SHIFT, IOVA_PFN(end), 1);
        return piova;
 }
 
 static struct iova *
 __intel_alloc_iova(struct device *dev, struct dmar_domain *domain,
-               size_t size)
+                  size_t size, u64 dma_mask)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
        struct iova *iova = NULL;
 
-       if ((pdev->dma_mask <= DMA_32BIT_MASK) || (dmar_forcedac)) {
-               iova = iommu_alloc_iova(domain, size, pdev->dma_mask);
-       } else  {
+       if (dma_mask <= DMA_32BIT_MASK || dmar_forcedac)
+               iova = iommu_alloc_iova(domain, size, dma_mask);
+       else {
                /*
                 * First try to allocate an io virtual address in
                 * DMA_32BIT_MASK and if that fails then try allocating
@@ -1774,7 +1777,7 @@ __intel_alloc_iova(struct device *dev, struct dmar_domain *domain,
                 */
                iova = iommu_alloc_iova(domain, size, DMA_32BIT_MASK);
                if (!iova)
-                       iova = iommu_alloc_iova(domain, size, pdev->dma_mask);
+                       iova = iommu_alloc_iova(domain, size, dma_mask);
        }
 
        if (!iova) {
@@ -1813,12 +1816,12 @@ get_valid_domain_for_dev(struct pci_dev *pdev)
        return domain;
 }
 
-static dma_addr_t
-intel_map_single(struct device *hwdev, phys_addr_t paddr, size_t size, int dir)
+static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr,
+                                    size_t size, int dir, u64 dma_mask)
 {
        struct pci_dev *pdev = to_pci_dev(hwdev);
        struct dmar_domain *domain;
-       unsigned long start_paddr;
+       phys_addr_t start_paddr;
        struct iova *iova;
        int prot = 0;
        int ret;
@@ -1833,11 +1836,11 @@ intel_map_single(struct device *hwdev, phys_addr_t paddr, size_t size, int dir)
 
        size = aligned_size((u64)paddr, size);
 
-       iova = __intel_alloc_iova(hwdev, domain, size);
+       iova = __intel_alloc_iova(hwdev, domain, size, pdev->dma_mask);
        if (!iova)
                goto error;
 
-       start_paddr = iova->pfn_lo << PAGE_SHIFT_4K;
+       start_paddr = (phys_addr_t)iova->pfn_lo << PAGE_SHIFT;
 
        /*
         * Check if DMAR supports zero-length reads on write only
@@ -1855,30 +1858,33 @@ intel_map_single(struct device *hwdev, phys_addr_t paddr, size_t size, int dir)
         * is not a big problem
         */
        ret = domain_page_mapping(domain, start_paddr,
-               ((u64)paddr) & PAGE_MASK_4K, size, prot);
+               ((u64)paddr) & PAGE_MASK, size, prot);
        if (ret)
                goto error;
 
-       pr_debug("Device %s request: %lx@%llx mapping: %lx@%llx, dir %d\n",
-               pci_name(pdev), size, (u64)paddr,
-               size, (u64)start_paddr, dir);
-
        /* it's a non-present to present mapping */
        ret = iommu_flush_iotlb_psi(domain->iommu, domain->id,
-                       start_paddr, size >> PAGE_SHIFT_4K, 1);
+                       start_paddr, size >> VTD_PAGE_SHIFT, 1);
        if (ret)
                iommu_flush_write_buffer(domain->iommu);
 
-       return (start_paddr + ((u64)paddr & (~PAGE_MASK_4K)));
+       return start_paddr + ((u64)paddr & (~PAGE_MASK));
 
 error:
        if (iova)
                __free_iova(&domain->iovad, iova);
        printk(KERN_ERR"Device %s request: %lx@%llx dir %d --- failed\n",
-               pci_name(pdev), size, (u64)paddr, dir);
+               pci_name(pdev), size, (unsigned long long)paddr, dir);
        return 0;
 }
 
+dma_addr_t intel_map_single(struct device *hwdev, phys_addr_t paddr,
+                           size_t size, int dir)
+{
+       return __intel_map_single(hwdev, paddr, size, dir,
+                                 to_pci_dev(hwdev)->dma_mask);
+}
+
 static void flush_unmaps(void)
 {
        int i, j;
@@ -1891,7 +1897,8 @@ static void flush_unmaps(void)
                        struct intel_iommu *iommu =
                                deferred_flush[i].domain[0]->iommu;
 
-                       iommu_flush_iotlb_global(iommu, 0);
+                       iommu->flush.flush_iotlb(iommu, 0, 0, 0,
+                                                DMA_TLB_GLOBAL_FLUSH, 0);
                        for (j = 0; j < deferred_flush[i].next; j++) {
                                __free_iova(&deferred_flush[i].domain[j]->iovad,
                                                deferred_flush[i].iova[j]);
@@ -1936,8 +1943,8 @@ static void add_unmap(struct dmar_domain *dom, struct iova *iova)
        spin_unlock_irqrestore(&async_umap_flush_lock, flags);
 }
 
-static void intel_unmap_single(struct device *dev, dma_addr_t dev_addr,
-       size_t size, int dir)
+void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size,
+                       int dir)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
        struct dmar_domain *domain;
@@ -1953,11 +1960,11 @@ static void intel_unmap_single(struct device *dev, dma_addr_t dev_addr,
        if (!iova)
                return;
 
-       start_addr = iova->pfn_lo << PAGE_SHIFT_4K;
+       start_addr = iova->pfn_lo << PAGE_SHIFT;
        size = aligned_size((u64)dev_addr, size);
 
        pr_debug("Device %s unmapping: %lx@%llx\n",
-               pci_name(pdev), size, (u64)start_addr);
+               pci_name(pdev), size, (unsigned long long)start_addr);
 
        /*  clear the whole page */
        dma_pte_clear_range(domain, start_addr, start_addr + size);
@@ -1965,7 +1972,7 @@ static void intel_unmap_single(struct device *dev, dma_addr_t dev_addr,
        dma_pte_free_pagetable(domain, start_addr, start_addr + size);
        if (intel_iommu_strict) {
                if (iommu_flush_iotlb_psi(domain->iommu,
-                       domain->id, start_addr, size >> PAGE_SHIFT_4K, 0))
+                       domain->id, start_addr, size >> VTD_PAGE_SHIFT, 0))
                        iommu_flush_write_buffer(domain->iommu);
                /* free iova */
                __free_iova(&domain->iovad, iova);
@@ -1978,13 +1985,13 @@ static void intel_unmap_single(struct device *dev, dma_addr_t dev_addr,
        }
 }
 
-static void * intel_alloc_coherent(struct device *hwdev, size_t size,
-                      dma_addr_t *dma_handle, gfp_t flags)
+void *intel_alloc_coherent(struct device *hwdev, size_t size,
+                          dma_addr_t *dma_handle, gfp_t flags)
 {
        void *vaddr;
        int order;
 
-       size = PAGE_ALIGN_4K(size);
+       size = PAGE_ALIGN(size);
        order = get_order(size);
        flags &= ~(GFP_DMA | GFP_DMA32);
 
@@ -1993,19 +2000,21 @@ static void * intel_alloc_coherent(struct device *hwdev, size_t size,
                return NULL;
        memset(vaddr, 0, size);
 
-       *dma_handle = intel_map_single(hwdev, virt_to_bus(vaddr), size, DMA_BIDIRECTIONAL);
+       *dma_handle = __intel_map_single(hwdev, virt_to_bus(vaddr), size,
+                                        DMA_BIDIRECTIONAL,
+                                        hwdev->coherent_dma_mask);
        if (*dma_handle)
                return vaddr;
        free_pages((unsigned long)vaddr, order);
        return NULL;
 }
 
-static void intel_free_coherent(struct device *hwdev, size_t size,
-       void *vaddr, dma_addr_t dma_handle)
+void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
+                        dma_addr_t dma_handle)
 {
        int order;
 
-       size = PAGE_ALIGN_4K(size);
+       size = PAGE_ALIGN(size);
        order = get_order(size);
 
        intel_unmap_single(hwdev, dma_handle, size, DMA_BIDIRECTIONAL);
@@ -2013,8 +2022,9 @@ static void intel_free_coherent(struct device *hwdev, size_t size,
 }
 
 #define SG_ENT_VIRT_ADDRESS(sg)        (sg_virt((sg)))
-static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
-       int nelems, int dir)
+
+void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
+                   int nelems, int dir)
 {
        int i;
        struct pci_dev *pdev = to_pci_dev(hwdev);
@@ -2038,7 +2048,7 @@ static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
                size += aligned_size((u64)addr, sg->length);
        }
 
-       start_addr = iova->pfn_lo << PAGE_SHIFT_4K;
+       start_addr = iova->pfn_lo << PAGE_SHIFT;
 
        /*  clear the whole page */
        dma_pte_clear_range(domain, start_addr, start_addr + size);
@@ -2046,7 +2056,7 @@ static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
        dma_pte_free_pagetable(domain, start_addr, start_addr + size);
 
        if (iommu_flush_iotlb_psi(domain->iommu, domain->id, start_addr,
-                       size >> PAGE_SHIFT_4K, 0))
+                       size >> VTD_PAGE_SHIFT, 0))
                iommu_flush_write_buffer(domain->iommu);
 
        /* free iova */
@@ -2067,8 +2077,8 @@ static int intel_nontranslate_map_sg(struct device *hddev,
        return nelems;
 }
 
-static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist,
-                               int nelems, int dir)
+int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
+                int dir)
 {
        void *addr;
        int i;
@@ -2096,7 +2106,7 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist,
                size += aligned_size((u64)addr, sg->length);
        }
 
-       iova = __intel_alloc_iova(hwdev, domain, size);
+       iova = __intel_alloc_iova(hwdev, domain, size, pdev->dma_mask);
        if (!iova) {
                sglist->dma_length = 0;
                return 0;
@@ -2112,14 +2122,14 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist,
        if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
                prot |= DMA_PTE_WRITE;
 
-       start_addr = iova->pfn_lo << PAGE_SHIFT_4K;
+       start_addr = iova->pfn_lo << PAGE_SHIFT;
        offset = 0;
        for_each_sg(sglist, sg, nelems, i) {
                addr = SG_ENT_VIRT_ADDRESS(sg);
                addr = (void *)virt_to_phys(addr);
                size = aligned_size((u64)addr, sg->length);
                ret = domain_page_mapping(domain, start_addr + offset,
-                       ((u64)addr) & PAGE_MASK_4K,
+                       ((u64)addr) & PAGE_MASK,
                        size, prot);
                if (ret) {
                        /*  clear the page */
@@ -2133,14 +2143,14 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist,
                        return 0;
                }
                sg->dma_address = start_addr + offset +
-                               ((u64)addr & (~PAGE_MASK_4K));
+                               ((u64)addr & (~PAGE_MASK));
                sg->dma_length = sg->length;
                offset += size;
        }
 
        /* it's a non-present to present mapping */
        if (iommu_flush_iotlb_psi(domain->iommu, domain->id,
-                       start_addr, offset >> PAGE_SHIFT_4K, 1))
+                       start_addr, offset >> VTD_PAGE_SHIFT, 1))
                iommu_flush_write_buffer(domain->iommu);
        return nelems;
 }
@@ -2180,7 +2190,6 @@ static inline int iommu_devinfo_cache_init(void)
                                         sizeof(struct device_domain_info),
                                         0,
                                         SLAB_HWCACHE_ALIGN,
-
                                         NULL);
        if (!iommu_devinfo_cache) {
                printk(KERN_ERR "Couldn't create devinfo cache\n");
@@ -2198,7 +2207,6 @@ static inline int iommu_iova_cache_init(void)
                                         sizeof(struct iova),
                                         0,
                                         SLAB_HWCACHE_ALIGN,
-
                                         NULL);
        if (!iommu_iova_cache) {
                printk(KERN_ERR "Couldn't create iova cache\n");
@@ -2327,7 +2335,7 @@ void intel_iommu_domain_exit(struct dmar_domain *domain)
                return;
 
        end = DOMAIN_MAX_ADDR(domain->gaw);
-       end = end & (~PAGE_MASK_4K);
+       end = end & (~VTD_PAGE_MASK);
 
        /* clear ptes */
        dma_pte_clear_range(domain, 0, end);
@@ -2423,6 +2431,6 @@ u64 intel_iommu_iova_to_pfn(struct dmar_domain *domain, u64 iova)
        if (pte)
                pfn = dma_pte_addr(*pte);
 
-       return pfn >> PAGE_SHIFT_4K;
+       return pfn >> VTD_PAGE_SHIFT;
 }
 EXPORT_SYMBOL_GPL(intel_iommu_iova_to_pfn);
index 738d4c89581cc7a41f5c2746add5dca767ad81be..2de5a3238c947be89213119d9cf468d2fa59e11d 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/interrupt.h>
 #include <linux/dmar.h>
 #include <linux/spinlock.h>
 #include <linux/jiffies.h>
@@ -11,41 +12,64 @@ static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
 static int ir_ioapic_num;
 int intr_remapping_enabled;
 
-static struct {
+struct irq_2_iommu {
        struct intel_iommu *iommu;
        u16 irte_index;
        u16 sub_handle;
        u8  irte_mask;
-} irq_2_iommu[NR_IRQS];
+};
+
+static struct irq_2_iommu irq_2_iommuX[NR_IRQS];
+
+static struct irq_2_iommu *irq_2_iommu(unsigned int irq)
+{
+       return (irq < nr_irqs) ? irq_2_iommuX + irq : NULL;
+}
+
+static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq)
+{
+       return irq_2_iommu(irq);
+}
 
 static DEFINE_SPINLOCK(irq_2_ir_lock);
 
-int irq_remapped(int irq)
+static struct irq_2_iommu *valid_irq_2_iommu(unsigned int irq)
 {
-       if (irq > NR_IRQS)
-               return 0;
+       struct irq_2_iommu *irq_iommu;
+
+       irq_iommu = irq_2_iommu(irq);
+
+       if (!irq_iommu)
+               return NULL;
+
+       if (!irq_iommu->iommu)
+               return NULL;
 
-       if (!irq_2_iommu[irq].iommu)
-               return 0;
+       return irq_iommu;
+}
 
-       return 1;
+int irq_remapped(int irq)
+{
+       return valid_irq_2_iommu(irq) != NULL;
 }
 
 int get_irte(int irq, struct irte *entry)
 {
        int index;
+       struct irq_2_iommu *irq_iommu;
 
-       if (!entry || irq > NR_IRQS)
+       if (!entry)
                return -1;
 
        spin_lock(&irq_2_ir_lock);
-       if (!irq_2_iommu[irq].iommu) {
+       irq_iommu = valid_irq_2_iommu(irq);
+       if (!irq_iommu) {
                spin_unlock(&irq_2_ir_lock);
                return -1;
        }
 
-       index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle;
-       *entry = *(irq_2_iommu[irq].iommu->ir_table->base + index);
+       index = irq_iommu->irte_index + irq_iommu->sub_handle;
+       *entry = *(irq_iommu->iommu->ir_table->base + index);
 
        spin_unlock(&irq_2_ir_lock);
        return 0;
@@ -54,6 +78,7 @@ int get_irte(int irq, struct irte *entry)
 int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
 {
        struct ir_table *table = iommu->ir_table;
+       struct irq_2_iommu *irq_iommu;
        u16 index, start_index;
        unsigned int mask = 0;
        int i;
@@ -61,6 +86,10 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
        if (!count)
                return -1;
 
+       /* protect irq_2_iommu_alloc later */
+       if (irq >= nr_irqs)
+               return -1;
+
        /*
         * start the IRTE search from index 0.
         */
@@ -100,10 +129,11 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
        for (i = index; i < index + count; i++)
                table->base[i].present = 1;
 
-       irq_2_iommu[irq].iommu = iommu;
-       irq_2_iommu[irq].irte_index =  index;
-       irq_2_iommu[irq].sub_handle = 0;
-       irq_2_iommu[irq].irte_mask = mask;
+       irq_iommu = irq_2_iommu_alloc(irq);
+       irq_iommu->iommu = iommu;
+       irq_iommu->irte_index =  index;
+       irq_iommu->sub_handle = 0;
+       irq_iommu->irte_mask = mask;
 
        spin_unlock(&irq_2_ir_lock);
 
@@ -124,31 +154,33 @@ static void qi_flush_iec(struct intel_iommu *iommu, int index, int mask)
 int map_irq_to_irte_handle(int irq, u16 *sub_handle)
 {
        int index;
+       struct irq_2_iommu *irq_iommu;
 
        spin_lock(&irq_2_ir_lock);
-       if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) {
+       irq_iommu = valid_irq_2_iommu(irq);
+       if (!irq_iommu) {
                spin_unlock(&irq_2_ir_lock);
                return -1;
        }
 
-       *sub_handle = irq_2_iommu[irq].sub_handle;
-       index = irq_2_iommu[irq].irte_index;
+       *sub_handle = irq_iommu->sub_handle;
+       index = irq_iommu->irte_index;
        spin_unlock(&irq_2_ir_lock);
        return index;
 }
 
 int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
 {
+       struct irq_2_iommu *irq_iommu;
+
        spin_lock(&irq_2_ir_lock);
-       if (irq >= NR_IRQS || irq_2_iommu[irq].iommu) {
-               spin_unlock(&irq_2_ir_lock);
-               return -1;
-       }
 
-       irq_2_iommu[irq].iommu = iommu;
-       irq_2_iommu[irq].irte_index = index;
-       irq_2_iommu[irq].sub_handle = subhandle;
-       irq_2_iommu[irq].irte_mask = 0;
+       irq_iommu = irq_2_iommu_alloc(irq);
+
+       irq_iommu->iommu = iommu;
+       irq_iommu->irte_index = index;
+       irq_iommu->sub_handle = subhandle;
+       irq_iommu->irte_mask = 0;
 
        spin_unlock(&irq_2_ir_lock);
 
@@ -157,16 +189,19 @@ int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
 
 int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index)
 {
+       struct irq_2_iommu *irq_iommu;
+
        spin_lock(&irq_2_ir_lock);
-       if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) {
+       irq_iommu = valid_irq_2_iommu(irq);
+       if (!irq_iommu) {
                spin_unlock(&irq_2_ir_lock);
                return -1;
        }
 
-       irq_2_iommu[irq].iommu = NULL;
-       irq_2_iommu[irq].irte_index = 0;
-       irq_2_iommu[irq].sub_handle = 0;
-       irq_2_iommu[irq].irte_mask = 0;
+       irq_iommu->iommu = NULL;
+       irq_iommu->irte_index = 0;
+       irq_iommu->sub_handle = 0;
+       irq_2_iommu(irq)->irte_mask = 0;
 
        spin_unlock(&irq_2_ir_lock);
 
@@ -178,16 +213,18 @@ int modify_irte(int irq, struct irte *irte_modified)
        int index;
        struct irte *irte;
        struct intel_iommu *iommu;
+       struct irq_2_iommu *irq_iommu;
 
        spin_lock(&irq_2_ir_lock);
-       if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) {
+       irq_iommu = valid_irq_2_iommu(irq);
+       if (!irq_iommu) {
                spin_unlock(&irq_2_ir_lock);
                return -1;
        }
 
-       iommu = irq_2_iommu[irq].iommu;
+       iommu = irq_iommu->iommu;
 
-       index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle;
+       index = irq_iommu->irte_index + irq_iommu->sub_handle;
        irte = &iommu->ir_table->base[index];
 
        set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1));
@@ -203,18 +240,20 @@ int flush_irte(int irq)
 {
        int index;
        struct intel_iommu *iommu;
+       struct irq_2_iommu *irq_iommu;
 
        spin_lock(&irq_2_ir_lock);
-       if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) {
+       irq_iommu = valid_irq_2_iommu(irq);
+       if (!irq_iommu) {
                spin_unlock(&irq_2_ir_lock);
                return -1;
        }
 
-       iommu = irq_2_iommu[irq].iommu;
+       iommu = irq_iommu->iommu;
 
-       index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle;
+       index = irq_iommu->irte_index + irq_iommu->sub_handle;
 
-       qi_flush_iec(iommu, index, irq_2_iommu[irq].irte_mask);
+       qi_flush_iec(iommu, index, irq_iommu->irte_mask);
        spin_unlock(&irq_2_ir_lock);
 
        return 0;
@@ -246,28 +285,30 @@ int free_irte(int irq)
        int index, i;
        struct irte *irte;
        struct intel_iommu *iommu;
+       struct irq_2_iommu *irq_iommu;
 
        spin_lock(&irq_2_ir_lock);
-       if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) {
+       irq_iommu = valid_irq_2_iommu(irq);
+       if (!irq_iommu) {
                spin_unlock(&irq_2_ir_lock);
                return -1;
        }
 
-       iommu = irq_2_iommu[irq].iommu;
+       iommu = irq_iommu->iommu;
 
-       index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle;
+       index = irq_iommu->irte_index + irq_iommu->sub_handle;
        irte = &iommu->ir_table->base[index];
 
-       if (!irq_2_iommu[irq].sub_handle) {
-               for (i = 0; i < (1 << irq_2_iommu[irq].irte_mask); i++)
+       if (!irq_iommu->sub_handle) {
+               for (i = 0; i < (1 << irq_iommu->irte_mask); i++)
                        set_64bit((unsigned long *)irte, 0);
-               qi_flush_iec(iommu, index, irq_2_iommu[irq].irte_mask);
+               qi_flush_iec(iommu, index, irq_iommu->irte_mask);
        }
 
-       irq_2_iommu[irq].iommu = NULL;
-       irq_2_iommu[irq].irte_index = 0;
-       irq_2_iommu[irq].sub_handle = 0;
-       irq_2_iommu[irq].irte_mask = 0;
+       irq_iommu->iommu = NULL;
+       irq_iommu->irte_index = 0;
+       irq_iommu->sub_handle = 0;
+       irq_iommu->irte_mask = 0;
 
        spin_unlock(&irq_2_ir_lock);
 
index 4a10b5624f728f49c0cc8977cb48a4bbf47b2bd2..74801f7df9c901ad21017ce2a831e0cd61c8af1c 100644 (file)
@@ -378,23 +378,21 @@ static int msi_capability_init(struct pci_dev *dev)
        entry->msi_attrib.masked = 1;
        entry->msi_attrib.default_irq = dev->irq;       /* Save IOAPIC IRQ */
        entry->msi_attrib.pos = pos;
-       if (is_mask_bit_support(control)) {
+       if (entry->msi_attrib.maskbit) {
                entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos,
-                               is_64bit_address(control));
+                               entry->msi_attrib.is_64);
        }
        entry->dev = dev;
        if (entry->msi_attrib.maskbit) {
                unsigned int maskbits, temp;
                /* All MSIs are unmasked by default, Mask them all */
                pci_read_config_dword(dev,
-                       msi_mask_bits_reg(pos, is_64bit_address(control)),
+                       msi_mask_bits_reg(pos, entry->msi_attrib.is_64),
                        &maskbits);
                temp = (1 << multi_msi_capable(control));
                temp = ((temp - 1) & ~temp);
                maskbits |= temp;
-               pci_write_config_dword(dev,
-                       msi_mask_bits_reg(pos, is_64bit_address(control)),
-                       maskbits);
+               pci_write_config_dword(dev, entry->msi_attrib.is_64, maskbits);
                entry->msi_attrib.maskbits_mask = temp;
        }
        list_add_tail(&entry->list, &dev->msi_list);
@@ -761,3 +759,24 @@ void pci_msi_init_pci_dev(struct pci_dev *dev)
 {
        INIT_LIST_HEAD(&dev->msi_list);
 }
+
+#ifdef CONFIG_ACPI
+#include <linux/acpi.h>
+#include <linux/pci-acpi.h>
+static void __devinit msi_acpi_init(void)
+{
+       if (acpi_pci_disabled)
+               return;
+       pci_osc_support_set(OSC_MSI_SUPPORT);
+       pcie_osc_support_set(OSC_MSI_SUPPORT);
+}
+#else
+static inline void msi_acpi_init(void) { }
+#endif /* CONFIG_ACPI */
+
+void __devinit msi_init(void)
+{
+       if (!pci_msi_enable)
+               return;
+       msi_acpi_init();
+}
index 89a2f0fa10f91d79b216bc78da9d19eb0fbd3941..dfe7c8e1b18586fa9da406cd365bbfb14188ec97 100644 (file)
@@ -24,17 +24,17 @@ struct acpi_osc_data {
        acpi_handle handle;
        u32 support_set;
        u32 control_set;
-       int is_queried;
-       u32 query_result;
        struct list_head sibiling;
 };
 static LIST_HEAD(acpi_osc_data_list);
 
 struct acpi_osc_args {
        u32 capbuf[3];
-       u32 query_result;
+       u32 ctrl_result;
 };
 
+static DEFINE_MUTEX(pci_acpi_lock);
+
 static struct acpi_osc_data *acpi_get_osc_data(acpi_handle handle)
 {
        struct acpi_osc_data *data;
@@ -108,9 +108,8 @@ static acpi_status acpi_run_osc(acpi_handle handle,
                goto out_kfree;
        }
 out_success:
-       if (flags & OSC_QUERY_ENABLE)
-               osc_args->query_result =
-                       *((u32 *)(out_obj->buffer.pointer + 8));
+       osc_args->ctrl_result =
+               *((u32 *)(out_obj->buffer.pointer + 8));
        status = AE_OK;
 
 out_kfree:
@@ -118,41 +117,53 @@ out_kfree:
        return status;
 }
 
-static acpi_status acpi_query_osc(acpi_handle handle,
-                                 u32 level, void *context, void **retval)
+static acpi_status __acpi_query_osc(u32 flags, struct acpi_osc_data *osc_data,
+                                   u32 *result)
 {
        acpi_status status;
-       struct acpi_osc_data *osc_data;
-       u32 flags = (unsigned long)context, support_set;
-       acpi_handle tmp;
+       u32 support_set;
        struct acpi_osc_args osc_args;
 
-       status = acpi_get_handle(handle, "_OSC", &tmp);
-       if (ACPI_FAILURE(status))
-               return status;
-
-       osc_data = acpi_get_osc_data(handle);
-       if (!osc_data) {
-               printk(KERN_ERR "acpi osc data array is full\n");
-               return AE_ERROR;
-       }
-
        /* do _OSC query for all possible controls */
        support_set = osc_data->support_set | (flags & OSC_SUPPORT_MASKS);
        osc_args.capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
        osc_args.capbuf[OSC_SUPPORT_TYPE] = support_set;
        osc_args.capbuf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
 
-       status = acpi_run_osc(handle, &osc_args);
+       status = acpi_run_osc(osc_data->handle, &osc_args);
        if (ACPI_SUCCESS(status)) {
                osc_data->support_set = support_set;
-               osc_data->query_result = osc_args.query_result;
-               osc_data->is_queried = 1;
+               *result = osc_args.ctrl_result;
        }
 
        return status;
 }
 
+static acpi_status acpi_query_osc(acpi_handle handle,
+                                 u32 level, void *context, void **retval)
+{
+       acpi_status status;
+       struct acpi_osc_data *osc_data;
+       u32 flags = (unsigned long)context, dummy;
+       acpi_handle tmp;
+
+       status = acpi_get_handle(handle, "_OSC", &tmp);
+       if (ACPI_FAILURE(status))
+               return AE_OK;
+
+       mutex_lock(&pci_acpi_lock);
+       osc_data = acpi_get_osc_data(handle);
+       if (!osc_data) {
+               printk(KERN_ERR "acpi osc data array is full\n");
+               goto out;
+       }
+
+       __acpi_query_osc(flags, osc_data, &dummy);
+out:
+       mutex_unlock(&pci_acpi_lock);
+       return AE_OK;
+}
+
 /**
  * __pci_osc_support_set - register OS support to Firmware
  * @flags: OS support bits
@@ -181,7 +192,7 @@ acpi_status __pci_osc_support_set(u32 flags, const char *hid)
 acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
 {
        acpi_status status;
-       u32 ctrlset, control_set;
+       u32 ctrlset, control_set, result;
        acpi_handle tmp;
        struct acpi_osc_data *osc_data;
        struct acpi_osc_args osc_args;
@@ -190,19 +201,28 @@ acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
        if (ACPI_FAILURE(status))
                return status;
 
+       mutex_lock(&pci_acpi_lock);
        osc_data = acpi_get_osc_data(handle);
        if (!osc_data) {
                printk(KERN_ERR "acpi osc data array is full\n");
-               return AE_ERROR;
+               status = AE_ERROR;
+               goto out;
        }
 
        ctrlset = (flags & OSC_CONTROL_MASKS);
-       if (!ctrlset)
-               return AE_TYPE;
+       if (!ctrlset) {
+               status = AE_TYPE;
+               goto out;
+       }
 
-       if (osc_data->is_queried &&
-           ((osc_data->query_result & ctrlset) != ctrlset))
-               return AE_SUPPORT;
+       status = __acpi_query_osc(osc_data->support_set, osc_data, &result);
+       if (ACPI_FAILURE(status))
+               goto out;
+
+       if ((result & ctrlset) != ctrlset) {
+               status = AE_SUPPORT;
+               goto out;
+       }
 
        control_set = osc_data->control_set | ctrlset;
        osc_args.capbuf[OSC_QUERY_TYPE] = 0;
@@ -211,7 +231,8 @@ acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
        status = acpi_run_osc(handle, &osc_args);
        if (ACPI_SUCCESS(status))
                osc_data->control_set = control_set;
-
+out:
+       mutex_unlock(&pci_acpi_lock);
        return status;
 }
 EXPORT_SYMBOL(pci_osc_control_set);
index a13f53486114fe27e665bfc7451933d823465ca1..b4cdd690ae71ca9d05811a6ce6cd9bcd0de15b20 100644 (file)
@@ -43,18 +43,32 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count)
 {
        struct pci_dynid *dynid;
        struct pci_driver *pdrv = to_pci_driver(driver);
+       const struct pci_device_id *ids = pdrv->id_table;
        __u32 vendor, device, subvendor=PCI_ANY_ID,
                subdevice=PCI_ANY_ID, class=0, class_mask=0;
        unsigned long driver_data=0;
        int fields=0;
-       int retval = 0;
+       int retval;
 
-       fields = sscanf(buf, "%x %x %x %x %x %x %lux",
+       fields = sscanf(buf, "%x %x %x %x %x %x %lx",
                        &vendor, &device, &subvendor, &subdevice,
                        &class, &class_mask, &driver_data);
        if (fields < 2)
                return -EINVAL;
 
+       /* Only accept driver_data values that match an existing id_table
+          entry */
+       retval = -EINVAL;
+       while (ids->vendor || ids->subvendor || ids->class_mask) {
+               if (driver_data == ids->driver_data) {
+                       retval = 0;
+                       break;
+               }
+               ids++;
+       }
+       if (retval)     /* No match */
+               return retval;
+
        dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
        if (!dynid)
                return -ENOMEM;
@@ -65,8 +79,7 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count)
        dynid->id.subdevice = subdevice;
        dynid->id.class = class;
        dynid->id.class_mask = class_mask;
-       dynid->id.driver_data = pdrv->dynids.use_driver_data ?
-               driver_data : 0UL;
+       dynid->id.driver_data = driver_data;
 
        spin_lock(&pdrv->dynids.lock);
        list_add_tail(&dynid->node, &pdrv->dynids.list);
index 77baff022f71b85259e1e064a06531b03a9bb727..110022d7868976a5bf2885737f5bdddf175aa372 100644 (file)
@@ -423,7 +423,7 @@ pci_write_vpd(struct kobject *kobj, struct bin_attribute *bin_attr,
  * Reads 1, 2, or 4 bytes from legacy I/O port space using an arch specific
  * callback routine (pci_legacy_read).
  */
-ssize_t
+static ssize_t
 pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
                   char *buf, loff_t off, size_t count)
 {
@@ -448,7 +448,7 @@ pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
  * Writes 1, 2, or 4 bytes from legacy I/O port space using an arch specific
  * callback routine (pci_legacy_write).
  */
-ssize_t
+static ssize_t
 pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
                    char *buf, loff_t off, size_t count)
 {
@@ -468,11 +468,11 @@ pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
  * @attr: struct bin_attribute for this file
  * @vma: struct vm_area_struct passed to mmap
  *
- * Uses an arch specific callback, pci_mmap_legacy_page_range, to mmap
+ * Uses an arch specific callback, pci_mmap_legacy_mem_page_range, to mmap
  * legacy memory space (first meg of bus space) into application virtual
  * memory space.
  */
-int
+static int
 pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr,
                     struct vm_area_struct *vma)
 {
@@ -480,7 +480,90 @@ pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr,
                                                       struct device,
                                                      kobj));
 
-        return pci_mmap_legacy_page_range(bus, vma);
+        return pci_mmap_legacy_page_range(bus, vma, pci_mmap_mem);
+}
+
+/**
+ * pci_mmap_legacy_io - map legacy PCI IO into user memory space
+ * @kobj: kobject corresponding to device to be mapped
+ * @attr: struct bin_attribute for this file
+ * @vma: struct vm_area_struct passed to mmap
+ *
+ * Uses an arch specific callback, pci_mmap_legacy_io_page_range, to mmap
+ * legacy IO space (first meg of bus space) into application virtual
+ * memory space. Returns -ENOSYS if the operation isn't supported
+ */
+static int
+pci_mmap_legacy_io(struct kobject *kobj, struct bin_attribute *attr,
+                  struct vm_area_struct *vma)
+{
+        struct pci_bus *bus = to_pci_bus(container_of(kobj,
+                                                      struct device,
+                                                     kobj));
+
+        return pci_mmap_legacy_page_range(bus, vma, pci_mmap_io);
+}
+
+/**
+ * pci_create_legacy_files - create legacy I/O port and memory files
+ * @b: bus to create files under
+ *
+ * Some platforms allow access to legacy I/O port and ISA memory space on
+ * a per-bus basis.  This routine creates the files and ties them into
+ * their associated read, write and mmap files from pci-sysfs.c
+ *
+ * On error unwind, but don't propogate the error to the caller
+ * as it is ok to set up the PCI bus without these files.
+ */
+void pci_create_legacy_files(struct pci_bus *b)
+{
+       int error;
+
+       b->legacy_io = kzalloc(sizeof(struct bin_attribute) * 2,
+                              GFP_ATOMIC);
+       if (!b->legacy_io)
+               goto kzalloc_err;
+
+       b->legacy_io->attr.name = "legacy_io";
+       b->legacy_io->size = 0xffff;
+       b->legacy_io->attr.mode = S_IRUSR | S_IWUSR;
+       b->legacy_io->read = pci_read_legacy_io;
+       b->legacy_io->write = pci_write_legacy_io;
+       b->legacy_io->mmap = pci_mmap_legacy_io;
+       error = device_create_bin_file(&b->dev, b->legacy_io);
+       if (error)
+               goto legacy_io_err;
+
+       /* Allocated above after the legacy_io struct */
+       b->legacy_mem = b->legacy_io + 1;
+       b->legacy_mem->attr.name = "legacy_mem";
+       b->legacy_mem->size = 1024*1024;
+       b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
+       b->legacy_mem->mmap = pci_mmap_legacy_mem;
+       error = device_create_bin_file(&b->dev, b->legacy_mem);
+       if (error)
+               goto legacy_mem_err;
+
+       return;
+
+legacy_mem_err:
+       device_remove_bin_file(&b->dev, b->legacy_io);
+legacy_io_err:
+       kfree(b->legacy_io);
+       b->legacy_io = NULL;
+kzalloc_err:
+       printk(KERN_WARNING "pci: warning: could not create legacy I/O port "
+              "and ISA memory resources to sysfs\n");
+       return;
+}
+
+void pci_remove_legacy_files(struct pci_bus *b)
+{
+       if (b->legacy_io) {
+               device_remove_bin_file(&b->dev, b->legacy_io);
+               device_remove_bin_file(&b->dev, b->legacy_mem);
+               kfree(b->legacy_io); /* both are allocated here */
+       }
 }
 #endif /* HAVE_PCI_LEGACY */
 
@@ -715,7 +798,7 @@ static struct bin_attribute pci_config_attr = {
                .name = "config",
                .mode = S_IRUGO | S_IWUSR,
        },
-       .size = 256,
+       .size = PCI_CFG_SPACE_SIZE,
        .read = pci_read_config,
        .write = pci_write_config,
 };
@@ -725,7 +808,7 @@ static struct bin_attribute pcie_config_attr = {
                .name = "config",
                .mode = S_IRUGO | S_IWUSR,
        },
-       .size = 4096,
+       .size = PCI_CFG_SPACE_EXP_SIZE,
        .read = pci_read_config,
        .write = pci_write_config,
 };
@@ -735,86 +818,103 @@ int __attribute__ ((weak)) pcibios_add_platform_entries(struct pci_dev *dev)
        return 0;
 }
 
+static int pci_create_capabilities_sysfs(struct pci_dev *dev)
+{
+       int retval;
+       struct bin_attribute *attr;
+
+       /* If the device has VPD, try to expose it in sysfs. */
+       if (dev->vpd) {
+               attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
+               if (!attr)
+                       return -ENOMEM;
+
+               attr->size = dev->vpd->len;
+               attr->attr.name = "vpd";
+               attr->attr.mode = S_IRUSR | S_IWUSR;
+               attr->read = pci_read_vpd;
+               attr->write = pci_write_vpd;
+               retval = sysfs_create_bin_file(&dev->dev.kobj, attr);
+               if (retval) {
+                       kfree(dev->vpd->attr);
+                       return retval;
+               }
+               dev->vpd->attr = attr;
+       }
+
+       /* Active State Power Management */
+       pcie_aspm_create_sysfs_dev_files(dev);
+
+       return 0;
+}
+
 int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
 {
-       struct bin_attribute *attr = NULL;
        int retval;
+       int rom_size = 0;
+       struct bin_attribute *attr;
 
        if (!sysfs_initialized)
                return -EACCES;
 
-       if (pdev->cfg_size < 4096)
+       if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
                retval = sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
        else
                retval = sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
        if (retval)
                goto err;
 
-       /* If the device has VPD, try to expose it in sysfs. */
-       if (pdev->vpd) {
-               attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
-               if (attr) {
-                       pdev->vpd->attr = attr;
-                       attr->size = pdev->vpd->len;
-                       attr->attr.name = "vpd";
-                       attr->attr.mode = S_IRUSR | S_IWUSR;
-                       attr->read = pci_read_vpd;
-                       attr->write = pci_write_vpd;
-                       retval = sysfs_create_bin_file(&pdev->dev.kobj, attr);
-                       if (retval)
-                               goto err_vpd;
-               } else {
-                       retval = -ENOMEM;
-                       goto err_config_file;
-               }
-       }
-
        retval = pci_create_resource_files(pdev);
        if (retval)
-               goto err_vpd_file;
+               goto err_config_file;
+
+       if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
+               rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
+       else if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)
+               rom_size = 0x20000;
 
        /* If the device has a ROM, try to expose it in sysfs. */
-       if (pci_resource_len(pdev, PCI_ROM_RESOURCE) ||
-           (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)) {
+       if (rom_size) {
                attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
-               if (attr) {
-                       pdev->rom_attr = attr;
-                       attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
-                       attr->attr.name = "rom";
-                       attr->attr.mode = S_IRUSR;
-                       attr->read = pci_read_rom;
-                       attr->write = pci_write_rom;
-                       retval = sysfs_create_bin_file(&pdev->dev.kobj, attr);
-                       if (retval)
-                               goto err_rom;
-               } else {
+               if (!attr) {
                        retval = -ENOMEM;
                        goto err_resource_files;
                }
+               attr->size = rom_size;
+               attr->attr.name = "rom";
+               attr->attr.mode = S_IRUSR;
+               attr->read = pci_read_rom;
+               attr->write = pci_write_rom;
+               retval = sysfs_create_bin_file(&pdev->dev.kobj, attr);
+               if (retval) {
+                       kfree(attr);
+                       goto err_resource_files;
+               }
+               pdev->rom_attr = attr;
        }
+
        /* add platform-specific attributes */
-       if (pcibios_add_platform_entries(pdev))
+       retval = pcibios_add_platform_entries(pdev);
+       if (retval)
                goto err_rom_file;
 
-       pcie_aspm_create_sysfs_dev_files(pdev);
+       /* add sysfs entries for various capabilities */
+       retval = pci_create_capabilities_sysfs(pdev);
+       if (retval)
+               goto err_rom_file;
 
        return 0;
 
 err_rom_file:
-       if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
+       if (rom_size) {
                sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
-err_rom:
-       kfree(pdev->rom_attr);
+               kfree(pdev->rom_attr);
+               pdev->rom_attr = NULL;
+       }
 err_resource_files:
        pci_remove_resource_files(pdev);
-err_vpd_file:
-       if (pdev->vpd) {
-               sysfs_remove_bin_file(&pdev->dev.kobj, pdev->vpd->attr);
-err_vpd:
-               kfree(pdev->vpd->attr);
-       }
 err_config_file:
-       if (pdev->cfg_size < 4096)
+       if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
                sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
        else
                sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
@@ -822,6 +922,16 @@ err:
        return retval;
 }
 
+static void pci_remove_capabilities_sysfs(struct pci_dev *dev)
+{
+       if (dev->vpd && dev->vpd->attr) {
+               sysfs_remove_bin_file(&dev->dev.kobj, dev->vpd->attr);
+               kfree(dev->vpd->attr);
+       }
+
+       pcie_aspm_remove_sysfs_dev_files(dev);
+}
+
 /**
  * pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files
  * @pdev: device whose entries we should free
@@ -830,27 +940,28 @@ err:
  */
 void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
 {
+       int rom_size = 0;
+
        if (!sysfs_initialized)
                return;
 
-       pcie_aspm_remove_sysfs_dev_files(pdev);
+       pci_remove_capabilities_sysfs(pdev);
 
-       if (pdev->vpd) {
-               sysfs_remove_bin_file(&pdev->dev.kobj, pdev->vpd->attr);
-               kfree(pdev->vpd->attr);
-       }
-       if (pdev->cfg_size < 4096)
+       if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
                sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
        else
                sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
 
        pci_remove_resource_files(pdev);
 
-       if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
-               if (pdev->rom_attr) {
-                       sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
-                       kfree(pdev->rom_attr);
-               }
+       if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
+               rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
+       else if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)
+               rom_size = 0x20000;
+
+       if (rom_size && pdev->rom_attr) {
+               sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
+               kfree(pdev->rom_attr);
        }
 }
 
index dbe9f39f44363b3eb50d9cc7bcac0a50bd701315..533aeb5fcbe4512cb97c6244e7d41ba35cc9c4ed 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/log2.h>
 #include <linux/pci-aspm.h>
 #include <linux/pm_wakeup.h>
+#include <linux/interrupt.h>
 #include <asm/dma.h>   /* isa_dma_bridge_buggy */
 #include "pci.h"
 
@@ -213,10 +214,13 @@ int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap)
 int pci_find_ext_capability(struct pci_dev *dev, int cap)
 {
        u32 header;
-       int ttl = 480; /* 3840 bytes, minimum 8 bytes per capability */
-       int pos = 0x100;
+       int ttl;
+       int pos = PCI_CFG_SPACE_SIZE;
 
-       if (dev->cfg_size <= 256)
+       /* minimum 8 bytes per capability */
+       ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
+
+       if (dev->cfg_size <= PCI_CFG_SPACE_SIZE)
                return 0;
 
        if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
@@ -234,7 +238,7 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap)
                        return pos;
 
                pos = PCI_EXT_CAP_NEXT(header);
-               if (pos < 0x100)
+               if (pos < PCI_CFG_SPACE_SIZE)
                        break;
 
                if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
@@ -1126,6 +1130,27 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable)
        return pme_done ? 0 : error;
 }
 
+/**
+ * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold
+ * @dev: PCI device to prepare
+ * @enable: True to enable wake-up event generation; false to disable
+ *
+ * Many drivers want the device to wake up the system from D3_hot or D3_cold
+ * and this function allows them to set that up cleanly - pci_enable_wake()
+ * should not be called twice in a row to enable wake-up due to PCI PM vs ACPI
+ * ordering constraints.
+ *
+ * This function only returns error code if the device is not capable of
+ * generating PME# from both D3_hot and D3_cold, and the platform is unable to
+ * enable wake-up power for it.
+ */
+int pci_wake_from_d3(struct pci_dev *dev, bool enable)
+{
+       return pci_pme_capable(dev, PCI_D3cold) ?
+                       pci_enable_wake(dev, PCI_D3cold, enable) :
+                       pci_enable_wake(dev, PCI_D3hot, enable);
+}
+
 /**
  * pci_target_state - find an appropriate low power state for a given PCI dev
  * @dev: PCI device
@@ -1242,25 +1267,25 @@ void pci_pm_init(struct pci_dev *dev)
        dev->d1_support = false;
        dev->d2_support = false;
        if (!pci_no_d1d2(dev)) {
-               if (pmc & PCI_PM_CAP_D1) {
-                       dev_printk(KERN_DEBUG, &dev->dev, "supports D1\n");
+               if (pmc & PCI_PM_CAP_D1)
                        dev->d1_support = true;
-               }
-               if (pmc & PCI_PM_CAP_D2) {
-                       dev_printk(KERN_DEBUG, &dev->dev, "supports D2\n");
+               if (pmc & PCI_PM_CAP_D2)
                        dev->d2_support = true;
-               }
+
+               if (dev->d1_support || dev->d2_support)
+                       dev_printk(KERN_DEBUG, &dev->dev, "supports%s%s\n",
+                                  dev->d1_support ? " D1" : "",
+                                  dev->d2_support ? " D2" : "");
        }
 
        pmc &= PCI_PM_CAP_PME_MASK;
        if (pmc) {
-               dev_printk(KERN_INFO, &dev->dev,
-                       "PME# supported from%s%s%s%s%s\n",
-                       (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "",
-                       (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "",
-                       (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "",
-                       (pmc & PCI_PM_CAP_PME_D3) ? " D3hot" : "",
-                       (pmc & PCI_PM_CAP_PME_D3cold) ? " D3cold" : "");
+               dev_info(&dev->dev, "PME# supported from%s%s%s%s%s\n",
+                        (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "",
+                        (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "",
+                        (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "",
+                        (pmc & PCI_PM_CAP_PME_D3) ? " D3hot" : "",
+                        (pmc & PCI_PM_CAP_PME_D3cold) ? " D3cold" : "");
                dev->pme_support = pmc >> PCI_PM_CAP_PME_SHIFT;
                /*
                 * Make device's PM flags reflect the wake-up capability, but
@@ -1275,6 +1300,38 @@ void pci_pm_init(struct pci_dev *dev)
        }
 }
 
+/**
+ * pci_enable_ari - enable ARI forwarding if hardware support it
+ * @dev: the PCI device
+ */
+void pci_enable_ari(struct pci_dev *dev)
+{
+       int pos;
+       u32 cap;
+       u16 ctrl;
+
+       if (!dev->is_pcie)
+               return;
+
+       if (dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
+           dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
+               return;
+
+       pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+       if (!pos)
+               return;
+
+       pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap);
+       if (!(cap & PCI_EXP_DEVCAP2_ARI))
+               return;
+
+       pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
+       ctrl |= PCI_EXP_DEVCTL2_ARI;
+       pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
+
+       dev->ari_enabled = 1;
+}
+
 int
 pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge)
 {
@@ -1689,6 +1746,103 @@ int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask)
 EXPORT_SYMBOL(pci_set_dma_seg_boundary);
 #endif
 
+/**
+ * pci_execute_reset_function() - Reset a PCI device function
+ * @dev: Device function to reset
+ *
+ * Some devices allow an individual function to be reset without affecting
+ * other functions in the same device.  The PCI device must be responsive
+ * to PCI config space in order to use this function.
+ *
+ * The device function is presumed to be unused when this function is called.
+ * Resetting the device will make the contents of PCI configuration space
+ * random, so any caller of this must be prepared to reinitialise the
+ * device including MSI, bus mastering, BARs, decoding IO and memory spaces,
+ * etc.
+ *
+ * Returns 0 if the device function was successfully reset or -ENOTTY if the
+ * device doesn't support resetting a single function.
+ */
+int pci_execute_reset_function(struct pci_dev *dev)
+{
+       u16 status;
+       u32 cap;
+       int exppos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+
+       if (!exppos)
+               return -ENOTTY;
+       pci_read_config_dword(dev, exppos + PCI_EXP_DEVCAP, &cap);
+       if (!(cap & PCI_EXP_DEVCAP_FLR))
+               return -ENOTTY;
+
+       pci_block_user_cfg_access(dev);
+
+       /* Wait for Transaction Pending bit clean */
+       msleep(100);
+       pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
+       if (status & PCI_EXP_DEVSTA_TRPND) {
+               dev_info(&dev->dev, "Busy after 100ms while trying to reset; "
+                       "sleeping for 1 second\n");
+               ssleep(1);
+               pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
+               if (status & PCI_EXP_DEVSTA_TRPND)
+                       dev_info(&dev->dev, "Still busy after 1s; "
+                               "proceeding with reset anyway\n");
+       }
+
+       pci_write_config_word(dev, exppos + PCI_EXP_DEVCTL,
+                               PCI_EXP_DEVCTL_BCR_FLR);
+       mdelay(100);
+
+       pci_unblock_user_cfg_access(dev);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(pci_execute_reset_function);
+
+/**
+ * pci_reset_function() - quiesce and reset a PCI device function
+ * @dev: Device function to reset
+ *
+ * Some devices allow an individual function to be reset without affecting
+ * other functions in the same device.  The PCI device must be responsive
+ * to PCI config space in order to use this function.
+ *
+ * This function does not just reset the PCI portion of a device, but
+ * clears all the state associated with the device.  This function differs
+ * from pci_execute_reset_function in that it saves and restores device state
+ * over the reset.
+ *
+ * Returns 0 if the device function was successfully reset or -ENOTTY if the
+ * device doesn't support resetting a single function.
+ */
+int pci_reset_function(struct pci_dev *dev)
+{
+       u32 cap;
+       int exppos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+       int r;
+
+       if (!exppos)
+               return -ENOTTY;
+       pci_read_config_dword(dev, exppos + PCI_EXP_DEVCAP, &cap);
+       if (!(cap & PCI_EXP_DEVCAP_FLR))
+               return -ENOTTY;
+
+       if (!dev->msi_enabled && !dev->msix_enabled)
+               disable_irq(dev->irq);
+       pci_save_state(dev);
+
+       pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE);
+
+       r = pci_execute_reset_function(dev);
+
+       pci_restore_state(dev);
+       if (!dev->msi_enabled && !dev->msix_enabled)
+               enable_irq(dev->irq);
+
+       return r;
+}
+EXPORT_SYMBOL_GPL(pci_reset_function);
+
 /**
  * pcix_get_max_mmrbc - get PCI-X maximum designed memory read byte count
  * @dev: PCI device to query
@@ -1877,6 +2031,9 @@ static int __devinit pci_init(void)
        while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
                pci_fixup_device(pci_fixup_final, dev);
        }
+
+       msi_init();
+
        return 0;
 }
 
@@ -1942,6 +2099,7 @@ EXPORT_SYMBOL(pci_restore_state);
 EXPORT_SYMBOL(pci_pme_capable);
 EXPORT_SYMBOL(pci_pme_active);
 EXPORT_SYMBOL(pci_enable_wake);
+EXPORT_SYMBOL(pci_wake_from_d3);
 EXPORT_SYMBOL(pci_target_state);
 EXPORT_SYMBOL(pci_prepare_to_sleep);
 EXPORT_SYMBOL(pci_back_from_sleep);
index d807cd786f20a18419105df88d8cf816019cab48..9de87e9f98f5ad5d7327a000474eef6b54da689d 100644 (file)
@@ -1,3 +1,9 @@
+#ifndef DRIVERS_PCI_H
+#define DRIVERS_PCI_H
+
+#define PCI_CFG_SPACE_SIZE     256
+#define PCI_CFG_SPACE_EXP_SIZE 4096
+
 /* Functions internal to the PCI core code */
 
 extern int pci_uevent(struct device *dev, struct kobj_uevent_env *env);
@@ -76,7 +82,13 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; }
 /* Functions for PCI Hotplug drivers to use */
 extern unsigned int pci_do_scan_bus(struct pci_bus *bus);
 
+#ifdef HAVE_PCI_LEGACY
+extern void pci_create_legacy_files(struct pci_bus *bus);
 extern void pci_remove_legacy_files(struct pci_bus *bus);
+#else
+static inline void pci_create_legacy_files(struct pci_bus *bus) { return; }
+static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; }
+#endif
 
 /* Lock for read/write access to pci device and bus lists */
 extern struct rw_semaphore pci_bus_sem;
@@ -86,9 +98,11 @@ extern unsigned int pci_pm_d3_delay;
 #ifdef CONFIG_PCI_MSI
 void pci_no_msi(void);
 extern void pci_msi_init_pci_dev(struct pci_dev *dev);
+extern void __devinit msi_init(void);
 #else
 static inline void pci_no_msi(void) { }
 static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { }
+static inline void msi_init(void) { }
 #endif
 
 #ifdef CONFIG_PCIEAER
@@ -109,6 +123,7 @@ static inline int pci_no_d1d2(struct pci_dev *dev)
 extern int pcie_mch_quirk;
 extern struct device_attribute pci_dev_attrs[];
 extern struct device_attribute dev_attr_cpuaffinity;
+extern struct device_attribute dev_attr_cpulistaffinity;
 
 /**
  * pci_match_one_device - Tell if a PCI device structure has a matching
@@ -144,3 +159,16 @@ struct pci_slot_attribute {
 };
 #define to_pci_slot_attr(s) container_of(s, struct pci_slot_attribute, attr)
 
+extern void pci_enable_ari(struct pci_dev *dev);
+/**
+ * pci_ari_enabled - query ARI forwarding status
+ * @dev: the PCI device
+ *
+ * Returns 1 if ARI forwarding is enabled, or 0 if not enabled;
+ */
+static inline int pci_ari_enabled(struct pci_dev *dev)
+{
+       return dev->ari_enabled;
+}
+
+#endif /* DRIVERS_PCI_H */
index 77036f46acfe22e1cfdebeb3613cb6f3527b6df2..e390707661dde323e8beafc4bf96e651a843dd06 100644 (file)
@@ -105,7 +105,7 @@ static irqreturn_t aer_irq(int irq, void *context)
        unsigned long flags;
        int pos;
 
-       pos = pci_find_aer_capability(pdev->port);
+       pos = pci_find_ext_capability(pdev->port, PCI_EXT_CAP_ID_ERR);
        /*
         * Must lock access to Root Error Status Reg, Root Error ID Reg,
         * and Root error producer/consumer index
@@ -252,7 +252,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
        u32 status;
        int pos;
 
-       pos = pci_find_aer_capability(dev);
+       pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
 
        /* Disable Root's interrupt in response to error messages */
        pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, 0);
@@ -316,7 +316,7 @@ static void aer_error_resume(struct pci_dev *dev)
        pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16);
 
        /* Clean AER Root Error Status */
-       pos = pci_find_aer_capability(dev);
+       pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
        pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
        pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask);
        if (dev->error_state == pci_channel_io_normal)
index ee5e7b5176d0f5d0986fbcb04050e37ff8b324ee..dfc63d01f20a0a7c072f9a65039f2776537b3e8e 100644 (file)
 static int forceload;
 module_param(forceload, bool, 0);
 
-#define PCI_CFG_SPACE_SIZE     (0x100)
-int pci_find_aer_capability(struct pci_dev *dev)
-{
-       int pos;
-       u32 reg32 = 0;
-
-       /* Check if it's a pci-express device */
-       pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
-       if (!pos)
-               return 0;
-
-       /* Check if it supports pci-express AER */
-       pos = PCI_CFG_SPACE_SIZE;
-       while (pos) {
-               if (pci_read_config_dword(dev, pos, &reg32))
-                       return 0;
-
-               /* some broken boards return ~0 */
-               if (reg32 == 0xffffffff)
-                       return 0;
-
-               if (PCI_EXT_CAP_ID(reg32) == PCI_EXT_CAP_ID_ERR)
-                       break;
-
-               pos = reg32 >> 20;
-       }
-
-       return pos;
-}
-
 int pci_enable_pcie_error_reporting(struct pci_dev *dev)
 {
        u16 reg16 = 0;
        int pos;
 
+       pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+       if (!pos)
+               return -EIO;
+
        pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
        if (!pos)
                return -EIO;
@@ -102,7 +76,7 @@ int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
        int pos;
        u32 status, mask;
 
-       pos = pci_find_aer_capability(dev);
+       pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
        if (!pos)
                return -EIO;
 
@@ -123,7 +97,7 @@ int pci_cleanup_aer_correct_error_status(struct pci_dev *dev)
        int pos;
        u32 status;
 
-       pos = pci_find_aer_capability(dev);
+       pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
        if (!pos)
                return -EIO;
 
@@ -502,7 +476,7 @@ static void handle_error_source(struct pcie_device * aerdev,
                 * Correctable error does not need software intevention.
                 * No need to go through error recovery process.
                 */
-               pos = pci_find_aer_capability(dev);
+               pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
                if (pos)
                        pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS,
                                        info.status);
@@ -542,7 +516,7 @@ void aer_enable_rootport(struct aer_rpc *rpc)
        reg16 &= ~(SYSTEM_ERROR_INTR_ON_MESG_MASK);
        pci_write_config_word(pdev, pos + PCI_EXP_RTCTL, reg16);
 
-       aer_pos = pci_find_aer_capability(pdev);
+       aer_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
        /* Clear error status */
        pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, &reg32);
        pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32);
@@ -579,7 +553,7 @@ static void disable_root_aer(struct aer_rpc *rpc)
        u32 reg32;
        int pos;
 
-       pos = pci_find_aer_capability(pdev);
+       pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
        /* Disable Root's interrupt in response to error messages */
        pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0);
 
@@ -618,7 +592,7 @@ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
 {
        int pos;
 
-       pos = pci_find_aer_capability(dev);
+       pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
 
        /* The device might not support AER */
        if (!pos)
@@ -755,7 +729,6 @@ int aer_init(struct pcie_device *dev)
        return AER_SUCCESS;
 }
 
-EXPORT_SYMBOL_GPL(pci_find_aer_capability);
 EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting);
 EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting);
 EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status);
index 851f5b83cdbc3f62f352627d0ee91848fc9923c0..8f63f4c6b85f64e3f4d91d76ca7da90ac142c51e 100644 (file)
@@ -528,9 +528,9 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
                pci_read_config_dword(child_dev, child_pos + PCI_EXP_DEVCAP,
                        &reg32);
                if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) {
-                       printk("Pre-1.1 PCIe device detected, "
-                               "disable ASPM for %s. It can be enabled forcedly"
-                               " with 'pcie_aspm=force'\n", pci_name(pdev));
+                       dev_printk(KERN_INFO, &child_dev->dev, "disabling ASPM"
+                               " on pre-1.1 PCIe device.  You can enable it"
+                               " with 'pcie_aspm=force'\n");
                        return -EINVAL;
                }
        }
index 3656e0349dd1d6ee4c6917203298b0d3b635d486..2529f3f2ea5a246ad3134307eb0e50d4c73d00a6 100644 (file)
@@ -25,7 +25,6 @@
 #define PCIE_CAPABILITIES_REG          0x2
 #define PCIE_SLOT_CAPABILITIES_REG     0x14
 #define PCIE_PORT_DEVICE_MAXSERVICES   4
-#define PCI_CFG_SPACE_SIZE             256
 
 #define get_descriptor_id(type, service) (((type - 4) << 4) | service)
 
index 890f0d2b370af7003625326075073f7641e549ce..2e091e014829e61366ec69b1267d8d9f05e58111 100644 (file)
@@ -195,24 +195,11 @@ static int get_port_device_capability(struct pci_dev *dev)
        /* PME Capable - root port capability */
        if (((reg16 >> 4) & PORT_TYPE_MASK) == PCIE_RC_PORT)
                services |= PCIE_PORT_SERVICE_PME;
-       
-       pos = PCI_CFG_SPACE_SIZE;
-       while (pos) {
-               pci_read_config_dword(dev, pos, &reg32);
-               switch (reg32 & 0xffff) {
-               case PCI_EXT_CAP_ID_ERR:
-                       services |= PCIE_PORT_SERVICE_AER;
-                       pos = reg32 >> 20;
-                       break;
-               case PCI_EXT_CAP_ID_VC:
-                       services |= PCIE_PORT_SERVICE_VC;
-                       pos = reg32 >> 20;
-                       break;
-               default:
-                       pos = 0;
-                       break;
-               }
-       }
+
+       if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR))
+               services |= PCIE_PORT_SERVICE_AER;
+       if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC))
+               services |= PCIE_PORT_SERVICE_VC;
 
        return services;
 }
index 367c9c20000dd59dfdd8e1130be182ed2b3fde51..584422da8d8b3e013934edfd1b5b255f2b2775a2 100644 (file)
@@ -91,7 +91,7 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev,
        
        pci_set_master(dev);
         if (!dev->irq && dev->pin) {
-               dev_warn(&dev->dev, "device [%04x/%04x] has invalid IRQ; "
+               dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; "
                         "check vendor BIOS\n", dev->vendor, dev->device);
        }
        if (pcie_port_device_register(dev)) {
index d3db8b24972995750eef5043b2ca700e779dedeb..6f1e51d77bce010b53ec7a4f55069fe6302ebf78 100644 (file)
@@ -14,8 +14,6 @@
 
 #define CARDBUS_LATENCY_TIMER  176     /* secondary latency timer */
 #define CARDBUS_RESERVE_BUSNR  3
-#define PCI_CFG_SPACE_SIZE     256
-#define PCI_CFG_SPACE_EXP_SIZE 4096
 
 /* Ugh.  Need to stop exporting this to modules. */
 LIST_HEAD(pci_root_buses);
@@ -44,72 +42,6 @@ int no_pci_devices(void)
 }
 EXPORT_SYMBOL(no_pci_devices);
 
-#ifdef HAVE_PCI_LEGACY
-/**
- * pci_create_legacy_files - create legacy I/O port and memory files
- * @b: bus to create files under
- *
- * Some platforms allow access to legacy I/O port and ISA memory space on
- * a per-bus basis.  This routine creates the files and ties them into
- * their associated read, write and mmap files from pci-sysfs.c
- *
- * On error unwind, but don't propogate the error to the caller
- * as it is ok to set up the PCI bus without these files.
- */
-static void pci_create_legacy_files(struct pci_bus *b)
-{
-       int error;
-
-       b->legacy_io = kzalloc(sizeof(struct bin_attribute) * 2,
-                              GFP_ATOMIC);
-       if (!b->legacy_io)
-               goto kzalloc_err;
-
-       b->legacy_io->attr.name = "legacy_io";
-       b->legacy_io->size = 0xffff;
-       b->legacy_io->attr.mode = S_IRUSR | S_IWUSR;
-       b->legacy_io->read = pci_read_legacy_io;
-       b->legacy_io->write = pci_write_legacy_io;
-       error = device_create_bin_file(&b->dev, b->legacy_io);
-       if (error)
-               goto legacy_io_err;
-
-       /* Allocated above after the legacy_io struct */
-       b->legacy_mem = b->legacy_io + 1;
-       b->legacy_mem->attr.name = "legacy_mem";
-       b->legacy_mem->size = 1024*1024;
-       b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
-       b->legacy_mem->mmap = pci_mmap_legacy_mem;
-       error = device_create_bin_file(&b->dev, b->legacy_mem);
-       if (error)
-               goto legacy_mem_err;
-
-       return;
-
-legacy_mem_err:
-       device_remove_bin_file(&b->dev, b->legacy_io);
-legacy_io_err:
-       kfree(b->legacy_io);
-       b->legacy_io = NULL;
-kzalloc_err:
-       printk(KERN_WARNING "pci: warning: could not create legacy I/O port "
-              "and ISA memory resources to sysfs\n");
-       return;
-}
-
-void pci_remove_legacy_files(struct pci_bus *b)
-{
-       if (b->legacy_io) {
-               device_remove_bin_file(&b->dev, b->legacy_io);
-               device_remove_bin_file(&b->dev, b->legacy_mem);
-               kfree(b->legacy_io); /* both are allocated here */
-       }
-}
-#else /* !HAVE_PCI_LEGACY */
-static inline void pci_create_legacy_files(struct pci_bus *bus) { return; }
-void pci_remove_legacy_files(struct pci_bus *bus) { return; }
-#endif /* HAVE_PCI_LEGACY */
-
 /*
  * PCI Bus Class Devices
  */
@@ -219,7 +151,7 @@ static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar)
 
        res->flags = bar & ~PCI_BASE_ADDRESS_MEM_MASK;
 
-       if (res->flags == PCI_BASE_ADDRESS_MEM_TYPE_64)
+       if (res->flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
                return pci_bar_mem64;
        return pci_bar_mem32;
 }
@@ -304,8 +236,8 @@ static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
                } else {
                        res->start = l64;
                        res->end = l64 + sz64;
-                       printk(KERN_DEBUG "PCI: %s reg %x 64bit mmio: %pR\n",
-                               pci_name(dev), pos, res);
+                       dev_printk(KERN_DEBUG, &dev->dev,
+                               "reg %x 64bit mmio: %pR\n", pos, res);
                }
        } else {
                sz = pci_size(l, sz, mask);
@@ -315,10 +247,10 @@ static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 
                res->start = l;
                res->end = l + sz;
-               printk(KERN_DEBUG "PCI: %s reg %x %s: %pR\n",
-                      pci_name(dev), pos,
-                      (res->flags & IORESOURCE_IO) ? "io port":"32bit mmio",
-                      res);
+
+               dev_printk(KERN_DEBUG, &dev->dev, "reg %x %s: %pR\n", pos,
+                       (res->flags & IORESOURCE_IO) ? "io port" : "32bit mmio",
+                       res);
        }
 
  out:
@@ -389,8 +321,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
                        res->start = base;
                if (!res->end)
                        res->end = limit + 0xfff;
-               printk(KERN_DEBUG "PCI: bridge %s io port: %pR\n",
-                      pci_name(dev), res);
+               dev_printk(KERN_DEBUG, &dev->dev, "bridge io port: %pR\n", res);
        }
 
        res = child->resource[1];
@@ -402,8 +333,8 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
                res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
                res->start = base;
                res->end = limit + 0xfffff;
-               printk(KERN_DEBUG "PCI: bridge %s 32bit mmio: %pR\n",
-                      pci_name(dev), res);
+               dev_printk(KERN_DEBUG, &dev->dev, "bridge 32bit mmio: %pR\n",
+                       res);
        }
 
        res = child->resource[2];
@@ -439,9 +370,9 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
                res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
                res->start = base;
                res->end = limit + 0xfffff;
-               printk(KERN_DEBUG "PCI: bridge %s %sbit mmio pref: %pR\n",
-                      pci_name(dev),
-                      (res->flags & PCI_PREF_RANGE_TYPE_64) ? "64":"32", res);
+               dev_printk(KERN_DEBUG, &dev->dev, "bridge %sbit mmio pref: %pR\n",
+                       (res->flags & PCI_PREF_RANGE_TYPE_64) ? "64" : "32",
+                       res);
        }
 }
 
@@ -549,19 +480,27 @@ 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;
+       int broken = 0;
 
        pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
 
        dev_dbg(&dev->dev, "scanning behind bridge, config %06x, pass %d\n",
                buses & 0xffffff, pass);
 
+       /* Check if setup is sensible at all */
+       if (!pass &&
+           ((buses & 0xff) != bus->number || ((buses >> 8) & 0xff) <= bus->number)) {
+               dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n");
+               broken = 1;
+       }
+
        /* Disable MasterAbortMode during probing to avoid reporting
           of bus errors (in some architectures) */ 
        pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bctl);
        pci_write_config_word(dev, PCI_BRIDGE_CONTROL,
                              bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT);
 
-       if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus) {
+       if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus && !broken) {
                unsigned int cmax, busnr;
                /*
                 * Bus already configured by firmware, process it in the first
@@ -599,7 +538,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
                 * do in the second pass.
                 */
                if (!pass) {
-                       if (pcibios_assign_all_busses())
+                       if (pcibios_assign_all_busses() || broken)
                                /* Temporarily disable forwarding of the
                                   configuration cycles on all bridges in
                                   this bus segment to avoid possible
@@ -762,7 +701,7 @@ static int pci_setup_device(struct pci_dev * dev)
        dev->class = class;
        class >>= 8;
 
-       dev_dbg(&dev->dev, "found [%04x/%04x] class %06x header type %02x\n",
+       dev_dbg(&dev->dev, "found [%04x:%04x] class %06x header type %02x\n",
                 dev->vendor, dev->device, class, dev->hdr_type);
 
        /* "Unknown power state" */
@@ -844,6 +783,11 @@ static int pci_setup_device(struct pci_dev * dev)
        return 0;
 }
 
+static void pci_release_capabilities(struct pci_dev *dev)
+{
+       pci_vpd_release(dev);
+}
+
 /**
  * pci_release_dev - free a pci device structure when all users of it are finished.
  * @dev: device that's been disconnected
@@ -856,7 +800,7 @@ static void pci_release_dev(struct device *dev)
        struct pci_dev *pci_dev;
 
        pci_dev = to_pci_dev(dev);
-       pci_vpd_release(pci_dev);
+       pci_release_capabilities(pci_dev);
        kfree(pci_dev);
 }
 
@@ -887,8 +831,9 @@ static void set_pcie_port_type(struct pci_dev *pdev)
 int pci_cfg_space_size_ext(struct pci_dev *dev)
 {
        u32 status;
+       int pos = PCI_CFG_SPACE_SIZE;
 
-       if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL)
+       if (pci_read_config_dword(dev, pos, &status) != PCIBIOS_SUCCESSFUL)
                goto fail;
        if (status == 0xffffffff)
                goto fail;
@@ -936,8 +881,6 @@ struct pci_dev *alloc_pci_dev(void)
 
        INIT_LIST_HEAD(&dev->bus_list);
 
-       pci_msi_init_pci_dev(dev);
-
        return dev;
 }
 EXPORT_SYMBOL(alloc_pci_dev);
@@ -949,6 +892,7 @@ EXPORT_SYMBOL(alloc_pci_dev);
 static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
 {
        struct pci_dev *dev;
+       struct pci_slot *slot;
        u32 l;
        u8 hdr_type;
        int delay = 1;
@@ -997,6 +941,10 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
        dev->error_state = pci_channel_io_normal;
        set_pcie_port_type(dev);
 
+       list_for_each_entry(slot, &bus->slots, list)
+               if (PCI_SLOT(devfn) == slot->number)
+                       dev->slot = slot;
+
        /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
           set this higher, assuming the system even supports it.  */
        dev->dma_mask = 0xffffffff;
@@ -1005,9 +953,22 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
                return NULL;
        }
 
+       return dev;
+}
+
+static void pci_init_capabilities(struct pci_dev *dev)
+{
+       /* MSI/MSI-X list */
+       pci_msi_init_pci_dev(dev);
+
+       /* Power Management */
+       pci_pm_init(dev);
+
+       /* Vital Product Data */
        pci_vpd_pci22_init(dev);
 
-       return dev;
+       /* Alternative Routing-ID Forwarding */
+       pci_enable_ari(dev);
 }
 
 void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
@@ -1026,8 +987,8 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
        /* Fix up broken headers */
        pci_fixup_device(pci_fixup_header, dev);
 
-       /* Initialize power management of the device */
-       pci_pm_init(dev);
+       /* Initialize various capabilities */
+       pci_init_capabilities(dev);
 
        /*
         * Add the device to our list of discovered devices
index e872ac925b4b3479cc06e5699973edbf65128881..96cf8ecd04ce7b40ea60fc9e1a077607a8c46d77 100644 (file)
 #include <linux/kallsyms.h>
 #include "pci.h"
 
+int isa_dma_bridge_buggy;
+EXPORT_SYMBOL(isa_dma_bridge_buggy);
+int pci_pci_problems;
+EXPORT_SYMBOL(pci_pci_problems);
+int pcie_mch_quirk;
+EXPORT_SYMBOL(pcie_mch_quirk);
+
+#ifdef CONFIG_PCI_QUIRKS
 /* The Mellanox Tavor device gives false positive parity errors
  * Mark this device with a broken_parity_status, to allow
  * PCI scanning code to "skip" this now blacklisted device.
@@ -35,6 +43,20 @@ static void __devinit quirk_mellanox_tavor(struct pci_dev *dev)
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR,quirk_mellanox_tavor);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR_BRIDGE,quirk_mellanox_tavor);
 
+/* Many VIA bridges seem to corrupt data for DAC. Disable it here */
+int forbid_dac __read_mostly;
+EXPORT_SYMBOL(forbid_dac);
+
+static __devinit void via_no_dac(struct pci_dev *dev)
+{
+       if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) {
+               dev_info(&dev->dev,
+                       "VIA PCI bridge detected. Disabling DAC.\n");
+               forbid_dac = 1;
+       }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, via_no_dac);
+
 /* Deal with broken BIOS'es that neglect to enable passive release,
    which can cause problems in combination with the 82441FX/PPro MTRRs */
 static void quirk_passive_release(struct pci_dev *dev)
@@ -62,8 +84,6 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441,      quirk_p
     
     This appears to be BIOS not version dependent. So presumably there is a 
     chipset level fix */
-int isa_dma_bridge_buggy;
-EXPORT_SYMBOL(isa_dma_bridge_buggy);
     
 static void __devinit quirk_isa_dma_hangs(struct pci_dev *dev)
 {
@@ -84,9 +104,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC,   PCI_DEVICE_ID_NEC_CBUS_1,       quirk_isa_d
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC,     PCI_DEVICE_ID_NEC_CBUS_2,       quirk_isa_dma_hangs);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC,     PCI_DEVICE_ID_NEC_CBUS_3,       quirk_isa_dma_hangs);
 
-int pci_pci_problems;
-EXPORT_SYMBOL(pci_pci_problems);
-
 /*
  *     Chipsets where PCI->PCI transfers vanish or hang
  */
@@ -1362,9 +1379,6 @@ static void __init quirk_alder_ioapic(struct pci_dev *pdev)
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_EESSC,      quirk_alder_ioapic);
 #endif
 
-int pcie_mch_quirk;
-EXPORT_SYMBOL(pcie_mch_quirk);
-
 static void __devinit quirk_pcie_mch(struct pci_dev *pdev)
 {
        pcie_mch_quirk = 1;
@@ -1555,84 +1569,6 @@ static void __devinit fixup_rev1_53c810(struct pci_dev* dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
 
-static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end)
-{
-       while (f < end) {
-               if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) &&
-                   (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) {
-#ifdef DEBUG
-                       dev_dbg(&dev->dev, "calling %pF\n", f->hook);
-#endif
-                       f->hook(dev);
-               }
-               f++;
-       }
-}
-
-extern struct pci_fixup __start_pci_fixups_early[];
-extern struct pci_fixup __end_pci_fixups_early[];
-extern struct pci_fixup __start_pci_fixups_header[];
-extern struct pci_fixup __end_pci_fixups_header[];
-extern struct pci_fixup __start_pci_fixups_final[];
-extern struct pci_fixup __end_pci_fixups_final[];
-extern struct pci_fixup __start_pci_fixups_enable[];
-extern struct pci_fixup __end_pci_fixups_enable[];
-extern struct pci_fixup __start_pci_fixups_resume[];
-extern struct pci_fixup __end_pci_fixups_resume[];
-extern struct pci_fixup __start_pci_fixups_resume_early[];
-extern struct pci_fixup __end_pci_fixups_resume_early[];
-extern struct pci_fixup __start_pci_fixups_suspend[];
-extern struct pci_fixup __end_pci_fixups_suspend[];
-
-
-void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
-{
-       struct pci_fixup *start, *end;
-
-       switch(pass) {
-       case pci_fixup_early:
-               start = __start_pci_fixups_early;
-               end = __end_pci_fixups_early;
-               break;
-
-       case pci_fixup_header:
-               start = __start_pci_fixups_header;
-               end = __end_pci_fixups_header;
-               break;
-
-       case pci_fixup_final:
-               start = __start_pci_fixups_final;
-               end = __end_pci_fixups_final;
-               break;
-
-       case pci_fixup_enable:
-               start = __start_pci_fixups_enable;
-               end = __end_pci_fixups_enable;
-               break;
-
-       case pci_fixup_resume:
-               start = __start_pci_fixups_resume;
-               end = __end_pci_fixups_resume;
-               break;
-
-       case pci_fixup_resume_early:
-               start = __start_pci_fixups_resume_early;
-               end = __end_pci_fixups_resume_early;
-               break;
-
-       case pci_fixup_suspend:
-               start = __start_pci_fixups_suspend;
-               end = __end_pci_fixups_suspend;
-               break;
-
-       default:
-               /* stupid compiler warning, you would think with an enum... */
-               return;
-       }
-       pci_do_fixups(dev, start, end);
-}
-EXPORT_SYMBOL(pci_fixup_device);
-
 /* Enable 1k I/O space granularity on the Intel P64H2 */
 static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev)
 {
@@ -2006,3 +1942,82 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4375,
                        quirk_msi_intx_disable_bug);
 
 #endif /* CONFIG_PCI_MSI */
+
+static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end)
+{
+       while (f < end) {
+               if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) &&
+                   (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) {
+                       dev_dbg(&dev->dev, "calling %pF\n", f->hook);
+                       f->hook(dev);
+               }
+               f++;
+       }
+}
+
+extern struct pci_fixup __start_pci_fixups_early[];
+extern struct pci_fixup __end_pci_fixups_early[];
+extern struct pci_fixup __start_pci_fixups_header[];
+extern struct pci_fixup __end_pci_fixups_header[];
+extern struct pci_fixup __start_pci_fixups_final[];
+extern struct pci_fixup __end_pci_fixups_final[];
+extern struct pci_fixup __start_pci_fixups_enable[];
+extern struct pci_fixup __end_pci_fixups_enable[];
+extern struct pci_fixup __start_pci_fixups_resume[];
+extern struct pci_fixup __end_pci_fixups_resume[];
+extern struct pci_fixup __start_pci_fixups_resume_early[];
+extern struct pci_fixup __end_pci_fixups_resume_early[];
+extern struct pci_fixup __start_pci_fixups_suspend[];
+extern struct pci_fixup __end_pci_fixups_suspend[];
+
+
+void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
+{
+       struct pci_fixup *start, *end;
+
+       switch(pass) {
+       case pci_fixup_early:
+               start = __start_pci_fixups_early;
+               end = __end_pci_fixups_early;
+               break;
+
+       case pci_fixup_header:
+               start = __start_pci_fixups_header;
+               end = __end_pci_fixups_header;
+               break;
+
+       case pci_fixup_final:
+               start = __start_pci_fixups_final;
+               end = __end_pci_fixups_final;
+               break;
+
+       case pci_fixup_enable:
+               start = __start_pci_fixups_enable;
+               end = __end_pci_fixups_enable;
+               break;
+
+       case pci_fixup_resume:
+               start = __start_pci_fixups_resume;
+               end = __end_pci_fixups_resume;
+               break;
+
+       case pci_fixup_resume_early:
+               start = __start_pci_fixups_resume_early;
+               end = __end_pci_fixups_resume_early;
+               break;
+
+       case pci_fixup_suspend:
+               start = __start_pci_fixups_suspend;
+               end = __end_pci_fixups_suspend;
+               break;
+
+       default:
+               /* stupid compiler warning, you would think with an enum... */
+               return;
+       }
+       pci_do_fixups(dev, start, end);
+}
+#else
+void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) {}
+#endif
+EXPORT_SYMBOL(pci_fixup_device);
index bdc2a44d68e1dbc4859c7d1628a24411ca0802ee..042e08924421bbd8d3c773a1ee40dfb50d9a2a1e 100644 (file)
@@ -73,6 +73,7 @@ void pci_remove_bus(struct pci_bus *pci_bus)
        up_write(&pci_bus_sem);
        pci_remove_legacy_files(pci_bus);
        device_remove_file(&pci_bus->dev, &dev_attr_cpuaffinity);
+       device_remove_file(&pci_bus->dev, &dev_attr_cpulistaffinity);
        device_unregister(&pci_bus->dev);
 }
 EXPORT_SYMBOL(pci_remove_bus);
@@ -114,13 +115,9 @@ void pci_remove_behind_bridge(struct pci_dev *dev)
 {
        struct list_head *l, *n;
 
-       if (dev->subordinate) {
-               list_for_each_safe(l, n, &dev->subordinate->devices) {
-                       struct pci_dev *dev = pci_dev_b(l);
-
-                       pci_remove_bus_device(dev);
-               }
-       }
+       if (dev->subordinate)
+               list_for_each_safe(l, n, &dev->subordinate->devices)
+                       pci_remove_bus_device(pci_dev_b(l));
 }
 
 static void pci_stop_bus_devices(struct pci_bus *bus)
index 4edfc4731bd4296f3b33081d2f9f66946f1f231f..5af8bd5381497656291ec61de58e678e8b874dd6 100644 (file)
@@ -166,6 +166,7 @@ struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device,
 {
        struct pci_dev *pdev;
 
+       pci_dev_get(from);
        pdev = pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from);
        pci_dev_put(pdev);
        return pdev;
@@ -270,12 +271,8 @@ static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id,
        struct pci_dev *pdev = NULL;
 
        WARN_ON(in_interrupt());
-       if (from) {
-               /* FIXME
-                * take the cast off, when bus_find_device is made const.
-                */
-               dev_start = (struct device *)&from->dev;
-       }
+       if (from)
+               dev_start = &from->dev;
        dev = bus_find_device(&pci_bus_type, dev_start, (void *)id,
                              match_pci_dev_by_id);
        if (dev)
index 471a429d7a20fec7b116537ed5e90c912da8b7b7..ea979f2bc6db0ecdc6f6c355e9926c59f908cfd7 100644 (file)
@@ -299,7 +299,7 @@ static void pbus_size_io(struct pci_bus *bus)
 
                        if (r->parent || !(r->flags & IORESOURCE_IO))
                                continue;
-                       r_size = r->end - r->start + 1;
+                       r_size = resource_size(r);
 
                        if (r_size < 0x400)
                                /* Might be re-aligned for ISA */
@@ -350,7 +350,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
 
                        if (r->parent || (r->flags & mask) != type)
                                continue;
-                       r_size = r->end - r->start + 1;
+                       r_size = resource_size(r);
                        /* For bridges size != alignment */
                        align = resource_alignment(r);
                        order = __ffs(align) - 20;
index d4b5c690eaa776112c46cc8f9ca993a49e233d50..2dbd96cce2d8469e82198ec3d29ae3604ef104de 100644 (file)
@@ -129,7 +129,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
        resource_size_t size, min, align;
        int ret;
 
-       size = res->end - res->start + 1;
+       size = resource_size(res);
        min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
 
        align = resource_alignment(res);
index 7e5b85cbd9488936b9ecbd10928dde86618f842c..4dd1c3e157aec6d6c136c02255faed19d46c3dc1 100644 (file)
@@ -49,11 +49,16 @@ static ssize_t address_read_file(struct pci_slot *slot, char *buf)
 
 static void pci_slot_release(struct kobject *kobj)
 {
+       struct pci_dev *dev;
        struct pci_slot *slot = to_pci_slot(kobj);
 
        pr_debug("%s: releasing pci_slot on %x:%d\n", __func__,
                 slot->bus->number, slot->number);
 
+       list_for_each_entry(dev, &slot->bus->devices, bus_list)
+               if (PCI_SLOT(dev->devfn) == slot->number)
+                       dev->slot = NULL;
+
        list_del(&slot->list);
 
        kfree(slot);
@@ -73,18 +78,100 @@ static struct kobj_type pci_slot_ktype = {
        .default_attrs = pci_slot_default_attrs,
 };
 
+static char *make_slot_name(const char *name)
+{
+       char *new_name;
+       int len, max, dup;
+
+       new_name = kstrdup(name, GFP_KERNEL);
+       if (!new_name)
+               return NULL;
+
+       /*
+        * Make sure we hit the realloc case the first time through the
+        * loop.  'len' will be strlen(name) + 3 at that point which is
+        * enough space for "name-X" and the trailing NUL.
+        */
+       len = strlen(name) + 2;
+       max = 1;
+       dup = 1;
+
+       for (;;) {
+               struct kobject *dup_slot;
+               dup_slot = kset_find_obj(pci_slots_kset, new_name);
+               if (!dup_slot)
+                       break;
+               kobject_put(dup_slot);
+               if (dup == max) {
+                       len++;
+                       max *= 10;
+                       kfree(new_name);
+                       new_name = kmalloc(len, GFP_KERNEL);
+                       if (!new_name)
+                               break;
+               }
+               sprintf(new_name, "%s-%d", name, dup++);
+       }
+
+       return new_name;
+}
+
+static int rename_slot(struct pci_slot *slot, const char *name)
+{
+       int result = 0;
+       char *slot_name;
+
+       if (strcmp(pci_slot_name(slot), name) == 0)
+               return result;
+
+       slot_name = make_slot_name(name);
+       if (!slot_name)
+               return -ENOMEM;
+
+       result = kobject_rename(&slot->kobj, slot_name);
+       kfree(slot_name);
+
+       return result;
+}
+
+static struct pci_slot *get_slot(struct pci_bus *parent, int slot_nr)
+{
+       struct pci_slot *slot;
+       /*
+        * We already hold pci_bus_sem so don't worry
+        */
+       list_for_each_entry(slot, &parent->slots, list)
+               if (slot->number == slot_nr) {
+                       kobject_get(&slot->kobj);
+                       return slot;
+               }
+
+       return NULL;
+}
+
 /**
  * pci_create_slot - create or increment refcount for physical PCI slot
  * @parent: struct pci_bus of parent bridge
  * @slot_nr: PCI_SLOT(pci_dev->devfn) or -1 for placeholder
  * @name: user visible string presented in /sys/bus/pci/slots/<name>
+ * @hotplug: set if caller is hotplug driver, NULL otherwise
  *
  * PCI slots have first class attributes such as address, speed, width,
  * and a &struct pci_slot is used to manage them. This interface will
  * either return a new &struct pci_slot to the caller, or if the pci_slot
  * already exists, its refcount will be incremented.
  *
- * Slots are uniquely identified by a @pci_bus, @slot_nr, @name tuple.
+ * Slots are uniquely identified by a @pci_bus, @slot_nr tuple.
+ *
+ * There are known platforms with broken firmware that assign the same
+ * name to multiple slots. Workaround these broken platforms by renaming
+ * the slots on behalf of the caller. If firmware assigns name N to
+ * multiple slots:
+ *
+ * The first slot is assigned N
+ * The second slot is assigned N-1
+ * The third slot is assigned N-2
+ * etc.
  *
  * Placeholder slots:
  * In most cases, @pci_bus, @slot_nr will be sufficient to uniquely identify
@@ -93,71 +180,82 @@ static struct kobj_type pci_slot_ktype = {
  * the slot. In this scenario, the caller may pass -1 for @slot_nr.
  *
  * The following semantics are imposed when the caller passes @slot_nr ==
- * -1. First, the check for existing %struct pci_slot is skipped, as the
- * caller may know about several unpopulated slots on a given %struct
- * pci_bus, and each slot would have a @slot_nr of -1.  Uniqueness for
- * these slots is then determined by the @name parameter. We expect
- * kobject_init_and_add() to warn us if the caller attempts to create
- * multiple slots with the same name. The other change in semantics is
+ * -1. First, we no longer check for an existing %struct pci_slot, as there
+ * may be many slots with @slot_nr of -1.  The other change in semantics is
  * user-visible, which is the 'address' parameter presented in sysfs will
  * consist solely of a dddd:bb tuple, where dddd is the PCI domain of the
  * %struct pci_bus and bb is the bus number. In other words, the devfn of
  * the 'placeholder' slot will not be displayed.
  */
-
 struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
-                                const char *name)
+                                const char *name,
+                                struct hotplug_slot *hotplug)
 {
+       struct pci_dev *dev;
        struct pci_slot *slot;
-       int err;
+       int err = 0;
+       char *slot_name = NULL;
 
        down_write(&pci_bus_sem);
 
        if (slot_nr == -1)
                goto placeholder;
 
-       /* If we've already created this slot, bump refcount and return. */
-       list_for_each_entry(slot, &parent->slots, list) {
-               if (slot->number == slot_nr) {
-                       kobject_get(&slot->kobj);
-                       pr_debug("%s: inc refcount to %d on %04x:%02x:%02x\n",
-                                __func__,
-                                atomic_read(&slot->kobj.kref.refcount),
-                                pci_domain_nr(parent), parent->number,
-                                slot_nr);
-                       goto out;
+       /*
+        * Hotplug drivers are allowed to rename an existing slot,
+        * but only if not already claimed.
+        */
+       slot = get_slot(parent, slot_nr);
+       if (slot) {
+               if (hotplug) {
+                       if ((err = slot->hotplug ? -EBUSY : 0)
+                            || (err = rename_slot(slot, name))) {
+                               kobject_put(&slot->kobj);
+                               slot = NULL;
+                               goto err;
+                       }
                }
+               goto out;
        }
 
 placeholder:
        slot = kzalloc(sizeof(*slot), GFP_KERNEL);
        if (!slot) {
-               slot = ERR_PTR(-ENOMEM);
-               goto out;
+               err = -ENOMEM;
+               goto err;
        }
 
        slot->bus = parent;
        slot->number = slot_nr;
 
        slot->kobj.kset = pci_slots_kset;
-       err = kobject_init_and_add(&slot->kobj, &pci_slot_ktype, NULL,
-                                  "%s", name);
-       if (err) {
-               printk(KERN_ERR "Unable to register kobject %s\n", name);
+
+       slot_name = make_slot_name(name);
+       if (!slot_name) {
+               err = -ENOMEM;
                goto err;
        }
 
+       err = kobject_init_and_add(&slot->kobj, &pci_slot_ktype, NULL,
+                                  "%s", slot_name);
+       if (err)
+               goto err;
+
        INIT_LIST_HEAD(&slot->list);
        list_add(&slot->list, &parent->slots);
 
+       list_for_each_entry(dev, &parent->devices, bus_list)
+               if (PCI_SLOT(dev->devfn) == slot_nr)
+                       dev->slot = slot;
+
        /* Don't care if debug printk has a -1 for slot_nr */
        pr_debug("%s: created pci_slot on %04x:%02x:%02x\n",
                 __func__, pci_domain_nr(parent), parent->number, slot_nr);
 
- out:
+out:
        up_write(&pci_bus_sem);
        return slot;
- err:
+err:
        kfree(slot);
        slot = ERR_PTR(err);
        goto out;
@@ -165,7 +263,7 @@ placeholder:
 EXPORT_SYMBOL_GPL(pci_create_slot);
 
 /**
- * pci_update_slot_number - update %struct pci_slot -> number
+ * pci_renumber_slot - update %struct pci_slot -> number
  * @slot - %struct pci_slot to update
  * @slot_nr - new number for slot
  *
@@ -173,27 +271,22 @@ EXPORT_SYMBOL_GPL(pci_create_slot);
  * created a placeholder slot in pci_create_slot() by passing a -1 as
  * slot_nr, to update their %struct pci_slot with the correct @slot_nr.
  */
-
-void pci_update_slot_number(struct pci_slot *slot, int slot_nr)
+void pci_renumber_slot(struct pci_slot *slot, int slot_nr)
 {
-       int name_count = 0;
        struct pci_slot *tmp;
 
        down_write(&pci_bus_sem);
 
        list_for_each_entry(tmp, &slot->bus->slots, list) {
                WARN_ON(tmp->number == slot_nr);
-               if (!strcmp(kobject_name(&tmp->kobj), kobject_name(&slot->kobj)))
-                       name_count++;
+               goto out;
        }
 
-       if (name_count > 1)
-               printk(KERN_WARNING "pci_update_slot_number found %d slots with the same name: %s\n", name_count, kobject_name(&slot->kobj));
-
        slot->number = slot_nr;
+out:
        up_write(&pci_bus_sem);
 }
-EXPORT_SYMBOL_GPL(pci_update_slot_number);
+EXPORT_SYMBOL_GPL(pci_renumber_slot);
 
 /**
  * pci_destroy_slot - decrement refcount for physical PCI slot
@@ -203,7 +296,6 @@ EXPORT_SYMBOL_GPL(pci_update_slot_number);
  * just call kobject_put on its kobj and let our release methods do the
  * rest.
  */
-
 void pci_destroy_slot(struct pci_slot *slot)
 {
        pr_debug("%s: dec refcount to %d on %04x:%02x:%02x\n", __func__,
index b46c60b7270842fcbaef50f7bd9eb8136e0d50f0..23e492bf75cfaa0eda763cf8354b398d2edab8e0 100644 (file)
@@ -70,7 +70,7 @@ pxa2xx-obj-$(CONFIG_MACH_MAINSTONE)           += pxa2xx_mainstone.o
 pxa2xx-obj-$(CONFIG_PXA_SHARPSL)               += pxa2xx_sharpsl.o
 pxa2xx-obj-$(CONFIG_MACH_ARMCORE)              += pxa2xx_cm_x2xx_cs.o
 pxa2xx-obj-$(CONFIG_ARCH_VIPER)                        += pxa2xx_viper.o
-pxa2xx-obj-$(CONFIG_TRIZEPS_PCMCIA)            += pxa2xx_trizeps.o
+pxa2xx-obj-$(CONFIG_TRIZEPS_PCMCIA)            += pxa2xx_trizeps4.o
 pxa2xx-obj-$(CONFIG_MACH_PALMTX)               += pxa2xx_palmtx.o
 pxa2xx-obj-$(CONFIG_MACH_PALMLD)               += pxa2xx_palmld.o
 
index a0ffb8ebfe00765cdf6fcf84e94f5dd5662844ee..9e1140f085fdfb70adca24d75e33d2a5b007b8e7 100644 (file)
@@ -273,7 +273,7 @@ static int __init at91_cf_probe(struct platform_device *pdev)
                        goto fail0d;
                cf->socket.pci_irq = board->irq_pin;
        } else
-               cf->socket.pci_irq = NR_IRQS + 1;
+               cf->socket.pci_irq = nr_irqs + 1;
 
        /* pcmcia layer only remaps "real" memory not iospace */
        cf->socket.io_offset = (unsigned long)
index 117dc12ab4380060889814b4ca0b1d8fffb317d0..9ef69cdb3183b1af1a2c40ddf53ef497fdcf7cb0 100644 (file)
@@ -233,15 +233,18 @@ static struct hw_interrupt_type hd64465_ss_irq_type = {
  */
 static void hs_map_irq(hs_socket_t *sp, unsigned int irq)
 {
+       struct irq_desc *desc;
+
        DPRINTK("hs_map_irq(sock=%d irq=%d)\n", sp->number, irq);
        
        if (irq >= HS_NUM_MAPPED_IRQS)
            return;
 
+       desc = irq_to_desc(irq);
        hs_mapped_irq[irq].sock = sp;
        /* insert ourselves as the irq controller */
-       hs_mapped_irq[irq].old_handler = irq_desc[irq].chip;
-       irq_desc[irq].chip = &hd64465_ss_irq_type;
+       hs_mapped_irq[irq].old_handler = desc->chip;
+       desc->chip = &hd64465_ss_irq_type;
 }
 
 
@@ -250,13 +253,16 @@ static void hs_map_irq(hs_socket_t *sp, unsigned int irq)
  */
 static void hs_unmap_irq(hs_socket_t *sp, unsigned int irq)
 {
+       struct irq_desc *desc;
+
        DPRINTK("hs_unmap_irq(sock=%d irq=%d)\n", sp->number, irq);
        
        if (irq >= HS_NUM_MAPPED_IRQS)
            return;
                
+       desc = irq_to_desc(irq);
        /* restore the original irq controller */
-       irq_desc[irq].chip = hs_mapped_irq[irq].old_handler;
+       desc->chip = hs_mapped_irq[irq].old_handler;
 }
 
 /*============================================================*/
index eee2f1cb213c76e35726b6c09df0eed9d6db060e..b2c412419059f9f5d03117305323378e784fb266 100644 (file)
@@ -639,7 +639,7 @@ static int __devinit vrc4171_card_setup(char *options)
                int irq;
                options += 4;
                irq = simple_strtoul(options, &options, 0);
-               if (irq >= 0 && irq < NR_IRQS)
+               if (irq >= 0 && irq < nr_irqs)
                        vrc4171_irq = irq;
 
                if (*options != ',')
index 821933f9aa57dc84825301e8b45504ad711aa3c5..2a37b3fedb8e619d203c1a277c5a9e831da389cc 100644 (file)
@@ -20,13 +20,21 @@ menuconfig PNP
 
          If unsure, say Y.
 
-if PNP
-
-config PNP_DEBUG
-       bool "PnP Debug Messages"
+config PNP_DEBUG_MESSAGES
+       default y
+       bool "PNP debugging messages"
+       depends on PNP
        help
-         Say Y if you want the Plug and Play Layer to print debug messages.
-         This is useful if you are developing a PnP driver or troubleshooting.
+         Say Y here if you want the PNP layer to be able to produce debugging
+         messages if needed.  The messages can be enabled at boot-time with
+         the pnp.debug kernel parameter.
+
+         This option allows you to save a bit of space if you do not want
+         the messages to even be built into the kernel.
+
+         If you have any doubts about this, say Y here.
+
+if PNP
 
 comment "Protocols"
 
index e83f34f1b5bada1207cb4bf8e77badaac623e2e1..8de3775ec2429b79ef70abe211663419eb2bc871 100644 (file)
@@ -10,7 +10,3 @@ obj-$(CONFIG_ISAPNP)          += isapnp/
 
 # pnp_system_init goes after pnpacpi/pnpbios init
 obj-y                          += system.o
-
-ifeq ($(CONFIG_PNP_DEBUG),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
index 3b8b9d3cb03d6cc2f8738e67abd145ff09a4285f..0b8d14050efaf2e424b11c5a07515d1c2eb1f6c1 100644 (file)
@@ -166,3 +166,13 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
 struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
                                          resource_size_t start,
                                          resource_size_t end, int flags);
+
+extern int pnp_debug;
+
+#if defined(CONFIG_PNP_DEBUG_MESSAGES)
+#define pnp_dbg(dev, format, arg...)                                   \
+       ({ if (pnp_debug) dev_printk(KERN_DEBUG, dev, format, ## arg); 0; })
+#else
+#define pnp_dbg(dev, format, arg...)                                   \
+       ({ if (0) dev_printk(KERN_DEBUG, dev, format, ## arg); 0; })
+#endif
index 817fe626e15b2d78a5cfa32ab7f26e761ee37009..16c01c6fa7c589b92e0b827cd36d65fb5fbccad7 100644 (file)
@@ -177,6 +177,9 @@ int __pnp_add_device(struct pnp_dev *dev)
 int pnp_add_device(struct pnp_dev *dev)
 {
        int ret;
+       char buf[128];
+       int len = 0;
+       struct pnp_id *id;
 
        if (dev->card)
                return -EINVAL;
@@ -185,17 +188,12 @@ int pnp_add_device(struct pnp_dev *dev)
        if (ret)
                return ret;
 
-#ifdef CONFIG_PNP_DEBUG
-       {
-               struct pnp_id *id;
+       buf[0] = '\0';
+       for (id = dev->id; id; id = id->next)
+               len += scnprintf(buf + len, sizeof(buf) - len, " %s", id->id);
 
-               dev_printk(KERN_DEBUG, &dev->dev, "%s device, IDs",
-                       dev->protocol->name);
-               for (id = dev->id; id; id = id->next)
-                       printk(" %s", id->id);
-               printk(" (%s)\n", dev->active ? "active" : "disabled");
-       }
-#endif
+       pnp_dbg(&dev->dev, "%s device, IDs%s (%s)\n",
+               dev->protocol->name, buf, dev->active ? "active" : "disabled");
        return 0;
 }
 
@@ -214,3 +212,14 @@ static int __init pnp_init(void)
 }
 
 subsys_initcall(pnp_init);
+
+int pnp_debug;
+
+#if defined(CONFIG_PNP_DEBUG_MESSAGES)
+static int __init pnp_debug_setup(char *__unused)
+{
+       pnp_debug = 1;
+       return 1;
+}
+__setup("pnp.debug", pnp_debug_setup);
+#endif
index e3f7e89c4dfb29a794a86a40a8bcf088550c032f..527ee764c93f54264cfd7f60e4facf4462cd8c80 100644 (file)
@@ -114,7 +114,6 @@ static int pnp_device_probe(struct device *dev)
        } else
                goto fail;
 
-       dev_dbg(dev, "driver attached\n");
        return error;
 
 fail:
@@ -211,8 +210,6 @@ struct bus_type pnp_bus_type = {
 
 int pnp_register_driver(struct pnp_driver *drv)
 {
-       pnp_dbg("the driver '%s' has been registered", drv->name);
-
        drv->driver.name = drv->name;
        drv->driver.bus = &pnp_bus_type;
 
@@ -222,7 +219,6 @@ int pnp_register_driver(struct pnp_driver *drv)
 void pnp_unregister_driver(struct pnp_driver *drv)
 {
        driver_unregister(&drv->driver);
-       pnp_dbg("the driver '%s' has been unregistered", drv->name);
 }
 
 /**
index 3e38f06f8d785b64d77a76a392d78c2593e44205..cac18bbfb817b1e042d820fbf7eace2adbdc6f9f 100644 (file)
@@ -5,7 +5,3 @@
 isapnp-proc-$(CONFIG_PROC_FS) = proc.o
 
 obj-y := core.o compat.o $(isapnp-proc-y)
-
-ifeq ($(CONFIG_PNP_DEBUG),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
index 46455fbab6d51f6dae89b6b68da5a4b2f34f4851..e851160e14f06e6d98179f19716ac04b51e7a598 100644 (file)
@@ -901,7 +901,7 @@ static int isapnp_get_resources(struct pnp_dev *dev)
 {
        int i, ret;
 
-       dev_dbg(&dev->dev, "get resources\n");
+       pnp_dbg(&dev->dev, "get resources\n");
        pnp_init_resources(dev);
        isapnp_cfg_begin(dev->card->number, dev->number);
        dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE);
@@ -939,13 +939,13 @@ static int isapnp_set_resources(struct pnp_dev *dev)
        struct resource *res;
        int tmp;
 
-       dev_dbg(&dev->dev, "set resources\n");
+       pnp_dbg(&dev->dev, "set resources\n");
        isapnp_cfg_begin(dev->card->number, dev->number);
        dev->active = 1;
        for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) {
                res = pnp_get_resource(dev, IORESOURCE_IO, tmp);
                if (pnp_resource_enabled(res)) {
-                       dev_dbg(&dev->dev, "  set io  %d to %#llx\n",
+                       pnp_dbg(&dev->dev, "  set io  %d to %#llx\n",
                                tmp, (unsigned long long) res->start);
                        isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1),
                                          res->start);
@@ -957,14 +957,14 @@ static int isapnp_set_resources(struct pnp_dev *dev)
                        int irq = res->start;
                        if (irq == 2)
                                irq = 9;
-                       dev_dbg(&dev->dev, "  set irq %d to %d\n", tmp, irq);
+                       pnp_dbg(&dev->dev, "  set irq %d to %d\n", tmp, irq);
                        isapnp_write_byte(ISAPNP_CFG_IRQ + (tmp << 1), irq);
                }
        }
        for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) {
                res = pnp_get_resource(dev, IORESOURCE_DMA, tmp);
                if (pnp_resource_enabled(res)) {
-                       dev_dbg(&dev->dev, "  set dma %d to %lld\n",
+                       pnp_dbg(&dev->dev, "  set dma %d to %lld\n",
                                tmp, (unsigned long long) res->start);
                        isapnp_write_byte(ISAPNP_CFG_DMA + tmp, res->start);
                }
@@ -972,7 +972,7 @@ static int isapnp_set_resources(struct pnp_dev *dev)
        for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) {
                res = pnp_get_resource(dev, IORESOURCE_MEM, tmp);
                if (pnp_resource_enabled(res)) {
-                       dev_dbg(&dev->dev, "  set mem %d to %#llx\n",
+                       pnp_dbg(&dev->dev, "  set mem %d to %#llx\n",
                                tmp, (unsigned long long) res->start);
                        isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3),
                                          (res->start >> 8) & 0xffff);
index b526eaad3f6c4e069360b9167b83ae786ccf511b..00fd3577b98575abb218972a4e35d1d62f6366c2 100644 (file)
@@ -25,7 +25,7 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
 
        res = pnp_get_resource(dev, IORESOURCE_IO, idx);
        if (res) {
-               dev_dbg(&dev->dev, "  io %d already set to %#llx-%#llx "
+               pnp_dbg(&dev->dev, "  io %d already set to %#llx-%#llx "
                        "flags %#lx\n", idx, (unsigned long long) res->start,
                        (unsigned long long) res->end, res->flags);
                return 0;
@@ -38,7 +38,7 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
 
        if (!rule->size) {
                res->flags |= IORESOURCE_DISABLED;
-               dev_dbg(&dev->dev, "  io %d disabled\n", idx);
+               pnp_dbg(&dev->dev, "  io %d disabled\n", idx);
                goto __add;
        }
 
@@ -49,7 +49,7 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
                res->start += rule->align;
                res->end = res->start + rule->size - 1;
                if (res->start > rule->max || !rule->align) {
-                       dev_dbg(&dev->dev, "  couldn't assign io %d "
+                       pnp_dbg(&dev->dev, "  couldn't assign io %d "
                                "(min %#llx max %#llx)\n", idx,
                                (unsigned long long) rule->min,
                                (unsigned long long) rule->max);
@@ -68,7 +68,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
 
        res = pnp_get_resource(dev, IORESOURCE_MEM, idx);
        if (res) {
-               dev_dbg(&dev->dev, "  mem %d already set to %#llx-%#llx "
+               pnp_dbg(&dev->dev, "  mem %d already set to %#llx-%#llx "
                        "flags %#lx\n", idx, (unsigned long long) res->start,
                        (unsigned long long) res->end, res->flags);
                return 0;
@@ -90,7 +90,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
 
        if (!rule->size) {
                res->flags |= IORESOURCE_DISABLED;
-               dev_dbg(&dev->dev, "  mem %d disabled\n", idx);
+               pnp_dbg(&dev->dev, "  mem %d disabled\n", idx);
                goto __add;
        }
 
@@ -101,7 +101,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
                res->start += rule->align;
                res->end = res->start + rule->size - 1;
                if (res->start > rule->max || !rule->align) {
-                       dev_dbg(&dev->dev, "  couldn't assign mem %d "
+                       pnp_dbg(&dev->dev, "  couldn't assign mem %d "
                                "(min %#llx max %#llx)\n", idx,
                                (unsigned long long) rule->min,
                                (unsigned long long) rule->max);
@@ -126,7 +126,7 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
 
        res = pnp_get_resource(dev, IORESOURCE_IRQ, idx);
        if (res) {
-               dev_dbg(&dev->dev, "  irq %d already set to %d flags %#lx\n",
+               pnp_dbg(&dev->dev, "  irq %d already set to %d flags %#lx\n",
                        idx, (int) res->start, res->flags);
                return 0;
        }
@@ -138,7 +138,7 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
 
        if (bitmap_empty(rule->map.bits, PNP_IRQ_NR)) {
                res->flags |= IORESOURCE_DISABLED;
-               dev_dbg(&dev->dev, "  irq %d disabled\n", idx);
+               pnp_dbg(&dev->dev, "  irq %d disabled\n", idx);
                goto __add;
        }
 
@@ -160,11 +160,11 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
                res->start = -1;
                res->end = -1;
                res->flags |= IORESOURCE_DISABLED;
-               dev_dbg(&dev->dev, "  irq %d disabled (optional)\n", idx);
+               pnp_dbg(&dev->dev, "  irq %d disabled (optional)\n", idx);
                goto __add;
        }
 
-       dev_dbg(&dev->dev, "  couldn't assign irq %d\n", idx);
+       pnp_dbg(&dev->dev, "  couldn't assign irq %d\n", idx);
        return -EBUSY;
 
 __add:
@@ -184,7 +184,7 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
 
        res = pnp_get_resource(dev, IORESOURCE_DMA, idx);
        if (res) {
-               dev_dbg(&dev->dev, "  dma %d already set to %d flags %#lx\n",
+               pnp_dbg(&dev->dev, "  dma %d already set to %d flags %#lx\n",
                        idx, (int) res->start, res->flags);
                return 0;
        }
@@ -205,7 +205,7 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
        res->start = res->end = MAX_DMA_CHANNELS;
 #endif
        res->flags |= IORESOURCE_DISABLED;
-       dev_dbg(&dev->dev, "  disable dma %d\n", idx);
+       pnp_dbg(&dev->dev, "  disable dma %d\n", idx);
 
 __add:
        pnp_add_dma_resource(dev, res->start, res->flags);
@@ -238,7 +238,7 @@ static int pnp_assign_resources(struct pnp_dev *dev, int set)
        int nport = 0, nmem = 0, nirq = 0, ndma = 0;
        int ret = 0;
 
-       dev_dbg(&dev->dev, "pnp_assign_resources, try dependent set %d\n", set);
+       pnp_dbg(&dev->dev, "pnp_assign_resources, try dependent set %d\n", set);
        mutex_lock(&pnp_res_mutex);
        pnp_clean_resource_table(dev);
 
@@ -270,7 +270,7 @@ static int pnp_assign_resources(struct pnp_dev *dev, int set)
 
        mutex_unlock(&pnp_res_mutex);
        if (ret < 0) {
-               dev_dbg(&dev->dev, "pnp_assign_resources failed (%d)\n", ret);
+               pnp_dbg(&dev->dev, "pnp_assign_resources failed (%d)\n", ret);
                pnp_clean_resource_table(dev);
        } else
                dbg_pnp_show_resources(dev, "pnp_assign_resources succeeded");
@@ -286,7 +286,7 @@ int pnp_auto_config_dev(struct pnp_dev *dev)
        int i, ret;
 
        if (!pnp_can_configure(dev)) {
-               dev_dbg(&dev->dev, "configuration not supported\n");
+               pnp_dbg(&dev->dev, "configuration not supported\n");
                return -ENODEV;
        }
 
@@ -313,7 +313,7 @@ int pnp_auto_config_dev(struct pnp_dev *dev)
 int pnp_start_dev(struct pnp_dev *dev)
 {
        if (!pnp_can_write(dev)) {
-               dev_dbg(&dev->dev, "activation not supported\n");
+               pnp_dbg(&dev->dev, "activation not supported\n");
                return -EINVAL;
        }
 
@@ -336,7 +336,7 @@ int pnp_start_dev(struct pnp_dev *dev)
 int pnp_stop_dev(struct pnp_dev *dev)
 {
        if (!pnp_can_disable(dev)) {
-               dev_dbg(&dev->dev, "disabling not supported\n");
+               pnp_dbg(&dev->dev, "disabling not supported\n");
                return -EINVAL;
        }
        if (dev->protocol->disable(dev) < 0) {
index 2d7a1e6908be7df6ba535fb8e18ad7c3701e4816..905326fcca85021bd14083aee684610527c7f8b0 100644 (file)
@@ -3,7 +3,3 @@
 #
 
 obj-y := core.o rsparser.o
-
-ifeq ($(CONFIG_PNP_DEBUG),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
index 53561d72b4eef0795e41054476060093d1053dbe..383e47c392a4c8ea69fe7459e302e6d76ee77cff 100644 (file)
@@ -75,7 +75,7 @@ static int __init ispnpidacpi(char *id)
 
 static int pnpacpi_get_resources(struct pnp_dev *dev)
 {
-       dev_dbg(&dev->dev, "get resources\n");
+       pnp_dbg(&dev->dev, "get resources\n");
        return pnpacpi_parse_allocated_resource(dev);
 }
 
@@ -86,7 +86,7 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
        int ret;
        acpi_status status;
 
-       dev_dbg(&dev->dev, "set resources\n");
+       pnp_dbg(&dev->dev, "set resources\n");
        ret = pnpacpi_build_resource_template(dev, &buffer);
        if (ret)
                return ret;
@@ -148,9 +148,13 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
        acpi_status status;
        struct pnp_dev *dev;
 
+       /*
+        * If a PnPacpi device is not present , the device
+        * driver should not be loaded.
+        */
        status = acpi_get_handle(device->handle, "_CRS", &temp);
        if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) ||
-           is_exclusive_device(device))
+           is_exclusive_device(device) || (!device->status.present))
                return 0;
 
        dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device));
@@ -255,14 +259,14 @@ int pnpacpi_disabled __initdata;
 static int __init pnpacpi_init(void)
 {
        if (acpi_disabled || pnpacpi_disabled) {
-               pnp_info("PnP ACPI: disabled");
+               printk(KERN_INFO "pnp: PnP ACPI: disabled\n");
                return 0;
        }
-       pnp_info("PnP ACPI init");
+       printk(KERN_INFO "pnp: PnP ACPI init\n");
        pnp_register_protocol(&pnpacpi_protocol);
        register_acpi_bus_type(&acpi_pnp_bus);
        acpi_get_devices(NULL, pnpacpi_add_device_handler, NULL, NULL);
-       pnp_info("PnP ACPI: found %d devices", num);
+       printk(KERN_INFO "pnp: PnP ACPI: found %d devices\n", num);
        unregister_acpi_bus_type(&acpi_pnp_bus);
        pnp_platform_devices = 1;
        return 0;
index 95015cbfd33f47bbfbb729b48aada46bd6d8d27e..adf17856bacc187a8216af9ded5ec3cf2ed2662b 100644 (file)
@@ -132,7 +132,8 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev,
        pnp_add_irq_resource(dev, irq, flags);
 }
 
-static int dma_flags(int type, int bus_master, int transfer)
+static int dma_flags(struct pnp_dev *dev, int type, int bus_master,
+                    int transfer)
 {
        int flags = 0;
 
@@ -154,7 +155,7 @@ static int dma_flags(int type, int bus_master, int transfer)
        default:
                /* Set a default value ? */
                flags |= IORESOURCE_DMA_COMPATIBLE;
-               pnp_err("Invalid DMA type");
+               dev_err(&dev->dev, "invalid DMA type %d\n", type);
        }
        switch (transfer) {
        case ACPI_TRANSFER_8:
@@ -169,7 +170,7 @@ static int dma_flags(int type, int bus_master, int transfer)
        default:
                /* Set a default value ? */
                flags |= IORESOURCE_DMA_8AND16BIT;
-               pnp_err("Invalid DMA transfer type");
+               dev_err(&dev->dev, "invalid DMA transfer type %d\n", transfer);
        }
 
        return flags;
@@ -336,7 +337,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
        case ACPI_RESOURCE_TYPE_DMA:
                dma = &res->data.dma;
                if (dma->channel_count > 0 && dma->channels[0] != (u8) -1)
-                       flags = dma_flags(dma->type, dma->bus_master,
+                       flags = dma_flags(dev, dma->type, dma->bus_master,
                                          dma->transfer);
                else
                        flags = IORESOURCE_DISABLED;
@@ -449,7 +450,7 @@ int pnpacpi_parse_allocated_resource(struct pnp_dev *dev)
        acpi_handle handle = dev->data;
        acpi_status status;
 
-       dev_dbg(&dev->dev, "parse allocated resources\n");
+       pnp_dbg(&dev->dev, "parse allocated resources\n");
 
        pnp_init_resources(dev);
 
@@ -477,7 +478,7 @@ static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
        for (i = 0; i < p->channel_count; i++)
                map |= 1 << p->channels[i];
 
-       flags = dma_flags(p->type, p->bus_master, p->transfer);
+       flags = dma_flags(dev, p->type, p->bus_master, p->transfer);
        pnp_register_dma_resource(dev, option_flags, map, flags);
 }
 
@@ -608,8 +609,8 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
        unsigned char flags = 0;
 
        status = acpi_resource_to_address64(r, p);
-       if (!ACPI_SUCCESS(status)) {
-               pnp_warn("PnPACPI: failed to convert resource type %d",
+       if (ACPI_FAILURE(status)) {
+               dev_warn(&dev->dev, "can't convert resource type %d\n",
                         r->type);
                return;
        }
@@ -735,7 +736,7 @@ int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev)
        acpi_status status;
        struct acpipnp_parse_option_s parse_data;
 
-       dev_dbg(&dev->dev, "parse resource options\n");
+       pnp_dbg(&dev->dev, "parse resource options\n");
 
        parse_data.dev = dev;
        parse_data.option_flags = 0;
@@ -843,7 +844,7 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev,
 
        if (!pnp_resource_enabled(p)) {
                irq->interrupt_count = 0;
-               dev_dbg(&dev->dev, "  encode irq (%s)\n",
+               pnp_dbg(&dev->dev, "  encode irq (%s)\n",
                        p ? "disabled" : "missing");
                return;
        }
@@ -855,7 +856,7 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev,
        irq->interrupt_count = 1;
        irq->interrupts[0] = p->start;
 
-       dev_dbg(&dev->dev, "  encode irq %d %s %s %s (%d-byte descriptor)\n",
+       pnp_dbg(&dev->dev, "  encode irq %d %s %s %s (%d-byte descriptor)\n",
                (int) p->start,
                triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge",
                polarity == ACPI_ACTIVE_LOW ? "low" : "high",
@@ -872,7 +873,7 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,
 
        if (!pnp_resource_enabled(p)) {
                extended_irq->interrupt_count = 0;
-               dev_dbg(&dev->dev, "  encode extended irq (%s)\n",
+               pnp_dbg(&dev->dev, "  encode extended irq (%s)\n",
                        p ? "disabled" : "missing");
                return;
        }
@@ -885,7 +886,7 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,
        extended_irq->interrupt_count = 1;
        extended_irq->interrupts[0] = p->start;
 
-       dev_dbg(&dev->dev, "  encode irq %d %s %s %s\n", (int) p->start,
+       pnp_dbg(&dev->dev, "  encode irq %d %s %s %s\n", (int) p->start,
                triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge",
                polarity == ACPI_ACTIVE_LOW ? "low" : "high",
                extended_irq->sharable == ACPI_SHARED ? "shared" : "exclusive");
@@ -899,7 +900,7 @@ static void pnpacpi_encode_dma(struct pnp_dev *dev,
 
        if (!pnp_resource_enabled(p)) {
                dma->channel_count = 0;
-               dev_dbg(&dev->dev, "  encode dma (%s)\n",
+               pnp_dbg(&dev->dev, "  encode dma (%s)\n",
                        p ? "disabled" : "missing");
                return;
        }
@@ -934,7 +935,7 @@ static void pnpacpi_encode_dma(struct pnp_dev *dev,
        dma->channel_count = 1;
        dma->channels[0] = p->start;
 
-       dev_dbg(&dev->dev, "  encode dma %d "
+       pnp_dbg(&dev->dev, "  encode dma %d "
                "type %#x transfer %#x master %d\n",
                (int) p->start, dma->type, dma->transfer, dma->bus_master);
 }
@@ -958,7 +959,7 @@ static void pnpacpi_encode_io(struct pnp_dev *dev,
                io->address_length = 0;
        }
 
-       dev_dbg(&dev->dev, "  encode io %#x-%#x decode %#x\n", io->minimum,
+       pnp_dbg(&dev->dev, "  encode io %#x-%#x decode %#x\n", io->minimum,
                io->minimum + io->address_length - 1, io->io_decode);
 }
 
@@ -976,7 +977,7 @@ static void pnpacpi_encode_fixed_io(struct pnp_dev *dev,
                fixed_io->address_length = 0;
        }
 
-       dev_dbg(&dev->dev, "  encode fixed_io %#x-%#x\n", fixed_io->address,
+       pnp_dbg(&dev->dev, "  encode fixed_io %#x-%#x\n", fixed_io->address,
                fixed_io->address + fixed_io->address_length - 1);
 }
 
@@ -999,7 +1000,7 @@ static void pnpacpi_encode_mem24(struct pnp_dev *dev,
                memory24->address_length = 0;
        }
 
-       dev_dbg(&dev->dev, "  encode mem24 %#x-%#x write_protect %#x\n",
+       pnp_dbg(&dev->dev, "  encode mem24 %#x-%#x write_protect %#x\n",
                memory24->minimum,
                memory24->minimum + memory24->address_length - 1,
                memory24->write_protect);
@@ -1023,7 +1024,7 @@ static void pnpacpi_encode_mem32(struct pnp_dev *dev,
                memory32->alignment = 0;
        }
 
-       dev_dbg(&dev->dev, "  encode mem32 %#x-%#x write_protect %#x\n",
+       pnp_dbg(&dev->dev, "  encode mem32 %#x-%#x write_protect %#x\n",
                memory32->minimum,
                memory32->minimum + memory32->address_length - 1,
                memory32->write_protect);
@@ -1046,7 +1047,7 @@ static void pnpacpi_encode_fixed_mem32(struct pnp_dev *dev,
                fixed_memory32->address_length = 0;
        }
 
-       dev_dbg(&dev->dev, "  encode fixed_mem32 %#x-%#x write_protect %#x\n",
+       pnp_dbg(&dev->dev, "  encode fixed_mem32 %#x-%#x write_protect %#x\n",
                fixed_memory32->address,
                fixed_memory32->address + fixed_memory32->address_length - 1,
                fixed_memory32->write_protect);
@@ -1060,7 +1061,7 @@ int pnpacpi_encode_resources(struct pnp_dev *dev, struct acpi_buffer *buffer)
        struct acpi_resource *resource = buffer->pointer;
        int port = 0, irq = 0, dma = 0, mem = 0;
 
-       dev_dbg(&dev->dev, "encode %d resources\n", res_cnt);
+       pnp_dbg(&dev->dev, "encode %d resources\n", res_cnt);
        while (i < res_cnt) {
                switch (resource->type) {
                case ACPI_RESOURCE_TYPE_IRQ:
index 310e2b3a7710458e4e25518bfdb6f89ff713e9dd..3cd3ed760605fbc7c6f5046bc4f714345aa3b01c 100644 (file)
@@ -5,7 +5,3 @@
 pnpbios-proc-$(CONFIG_PNPBIOS_PROC_FS) = proc.o
 
 obj-y := core.o bioscalls.o rsparser.o $(pnpbios-proc-y)
-
-ifeq ($(CONFIG_PNP_DEBUG),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
index 2bfe13369df5e75d36d58bb1674646bc424bcfac..996f6483807909b3c773e6bbbace9997135cbcd9 100644 (file)
@@ -211,7 +211,7 @@ static int pnpbios_get_resources(struct pnp_dev *dev)
        if (!pnpbios_is_dynamic(dev))
                return -EPERM;
 
-       dev_dbg(&dev->dev, "get resources\n");
+       pnp_dbg(&dev->dev, "get resources\n");
        node = kzalloc(node_info.max_node_size, GFP_KERNEL);
        if (!node)
                return -1;
@@ -234,7 +234,7 @@ static int pnpbios_set_resources(struct pnp_dev *dev)
        if (!pnpbios_is_dynamic(dev))
                return -EPERM;
 
-       dev_dbg(&dev->dev, "set resources\n");
+       pnp_dbg(&dev->dev, "set resources\n");
        node = kzalloc(node_info.max_node_size, GFP_KERNEL);
        if (!node)
                return -1;
index ca567671379e73985863538650f37609b360fc32..87b4f49a5251b561ceaf23117ddad71f09f81c14 100644 (file)
@@ -87,7 +87,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(struct pnp_dev *dev,
        if (!p)
                return NULL;
 
-       dev_dbg(&dev->dev, "parse allocated resources\n");
+       pnp_dbg(&dev->dev, "parse allocated resources\n");
 
        pnp_init_resources(dev);
 
@@ -324,7 +324,7 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
        if (!p)
                return NULL;
 
-       dev_dbg(&dev->dev, "parse resource options\n");
+       pnp_dbg(&dev->dev, "parse resource options\n");
        option_flags = 0;
        while ((char *)p < (char *)end) {
 
@@ -519,7 +519,7 @@ static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p,
        p[10] = (len >> 8) & 0xff;
        p[11] = ((len >> 8) >> 8) & 0xff;
 
-       dev_dbg(&dev->dev, "  encode mem %#lx-%#lx\n", base, base + len - 1);
+       pnp_dbg(&dev->dev, "  encode mem %#lx-%#lx\n", base, base + len - 1);
 }
 
 static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p,
@@ -549,7 +549,7 @@ static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p,
        p[18] = (len >> 16) & 0xff;
        p[19] = (len >> 24) & 0xff;
 
-       dev_dbg(&dev->dev, "  encode mem32 %#lx-%#lx\n", base, base + len - 1);
+       pnp_dbg(&dev->dev, "  encode mem32 %#lx-%#lx\n", base, base + len - 1);
 }
 
 static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p,
@@ -575,7 +575,7 @@ static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p,
        p[10] = (len >> 16) & 0xff;
        p[11] = (len >> 24) & 0xff;
 
-       dev_dbg(&dev->dev, "  encode fixed_mem32 %#lx-%#lx\n", base,
+       pnp_dbg(&dev->dev, "  encode fixed_mem32 %#lx-%#lx\n", base,
                base + len - 1);
 }
 
@@ -592,7 +592,7 @@ static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p,
        p[1] = map & 0xff;
        p[2] = (map >> 8) & 0xff;
 
-       dev_dbg(&dev->dev, "  encode irq mask %#lx\n", map);
+       pnp_dbg(&dev->dev, "  encode irq mask %#lx\n", map);
 }
 
 static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p,
@@ -607,7 +607,7 @@ static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p,
 
        p[1] = map & 0xff;
 
-       dev_dbg(&dev->dev, "  encode dma mask %#lx\n", map);
+       pnp_dbg(&dev->dev, "  encode dma mask %#lx\n", map);
 }
 
 static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
@@ -630,7 +630,7 @@ static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
        p[5] = (base >> 8) & 0xff;
        p[7] = len & 0xff;
 
-       dev_dbg(&dev->dev, "  encode io %#lx-%#lx\n", base, base + len - 1);
+       pnp_dbg(&dev->dev, "  encode io %#lx-%#lx\n", base, base + len - 1);
 }
 
 static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p,
@@ -651,7 +651,7 @@ static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p,
        p[2] = (base >> 8) & 0xff;
        p[3] = len & 0xff;
 
-       dev_dbg(&dev->dev, "  encode fixed_io %#lx-%#lx\n", base,
+       pnp_dbg(&dev->dev, "  encode fixed_io %#lx-%#lx\n", base,
                base + len - 1);
 }
 
index c144bd575611f300249923264f065741957e9bb3..8473fe5ed7ffe79d190cffcc42b3b2b383e4cf58 100644 (file)
@@ -337,9 +337,8 @@ void pnp_fixup_device(struct pnp_dev *dev)
        for (f = pnp_fixups; *f->id; f++) {
                if (!compare_pnp_id(dev->id, f->id))
                        continue;
-#ifdef DEBUG
-               dev_dbg(&dev->dev, "%s: calling %pF\n", f->id, f->quirk_function);
-#endif
+               pnp_dbg(&dev->dev, "%s: calling %pF\n", f->id,
+                       f->quirk_function);
                f->quirk_function(dev);
        }
 }
index dbae23acdd5b12e1df4a83164dbec01a4c6d7a54..f604061d2bb0334981540e592b3aeee02320489c 100644 (file)
@@ -294,7 +294,7 @@ static int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci,
        u8 progif;
 
        if (pci->irq == irq) {
-               dev_dbg(&pnp->dev, "device %s using irq %d\n",
+               pnp_dbg(&pnp->dev, "  device %s using irq %d\n",
                        pci_name(pci), irq);
                return 1;
        }
@@ -316,7 +316,7 @@ static int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci,
                if ((progif & 0x5) != 0x5)
                        if (pci_get_legacy_ide_irq(pci, 0) == irq ||
                            pci_get_legacy_ide_irq(pci, 1) == irq) {
-                               dev_dbg(&pnp->dev, "legacy IDE device %s "
+                               pnp_dbg(&pnp->dev, "  legacy IDE device %s "
                                        "using irq %d\n", pci_name(pci), irq);
                                return 1;
                        }
@@ -517,7 +517,7 @@ struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
        res->start = irq;
        res->end = irq;
 
-       dev_dbg(&dev->dev, "  add irq %d flags %#x\n", irq, flags);
+       pnp_dbg(&dev->dev, "  add irq %d flags %#x\n", irq, flags);
        return pnp_res;
 }
 
@@ -538,7 +538,7 @@ struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
        res->start = dma;
        res->end = dma;
 
-       dev_dbg(&dev->dev, "  add dma %d flags %#x\n", dma, flags);
+       pnp_dbg(&dev->dev, "  add dma %d flags %#x\n", dma, flags);
        return pnp_res;
 }
 
@@ -562,7 +562,7 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
        res->start = start;
        res->end = end;
 
-       dev_dbg(&dev->dev, "  add io  %#llx-%#llx flags %#x\n",
+       pnp_dbg(&dev->dev, "  add io  %#llx-%#llx flags %#x\n",
                (unsigned long long) start, (unsigned long long) end, flags);
        return pnp_res;
 }
@@ -587,7 +587,7 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
        res->start = start;
        res->end = end;
 
-       dev_dbg(&dev->dev, "  add mem %#llx-%#llx flags %#x\n",
+       pnp_dbg(&dev->dev, "  add mem %#llx-%#llx flags %#x\n",
                (unsigned long long) start, (unsigned long long) end, flags);
        return pnp_res;
 }
index b42df1620718556a21345c7646abbe902ecd6399..63087d5ce609a189ca0b564ffa546e15e7b0c176 100644 (file)
@@ -75,18 +75,17 @@ char *pnp_resource_type_name(struct resource *res)
 
 void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
 {
-#ifdef DEBUG
        char buf[128];
        int len;
        struct pnp_resource *pnp_res;
        struct resource *res;
 
        if (list_empty(&dev->resources)) {
-               dev_dbg(&dev->dev, "%s: no current resources\n", desc);
+               pnp_dbg(&dev->dev, "%s: no current resources\n", desc);
                return;
        }
 
-       dev_dbg(&dev->dev, "%s: current resources:\n", desc);
+       pnp_dbg(&dev->dev, "%s: current resources:\n", desc);
        list_for_each_entry(pnp_res, &dev->resources, list) {
                res = &pnp_res->res;
                len = 0;
@@ -95,7 +94,7 @@ void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
                                 pnp_resource_type_name(res));
 
                if (res->flags & IORESOURCE_DISABLED) {
-                       dev_dbg(&dev->dev, "%sdisabled\n", buf);
+                       pnp_dbg(&dev->dev, "%sdisabled\n", buf);
                        continue;
                }
 
@@ -116,9 +115,8 @@ void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
                                         res->flags);
                        break;
                }
-               dev_dbg(&dev->dev, "%s\n", buf);
+               pnp_dbg(&dev->dev, "%s\n", buf);
        }
-#endif
 }
 
 char *pnp_option_priority_name(struct pnp_option *option)
@@ -136,7 +134,6 @@ char *pnp_option_priority_name(struct pnp_option *option)
 
 void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option)
 {
-#ifdef DEBUG
        char buf[128];
        int len = 0, i;
        struct pnp_port *port;
@@ -208,6 +205,5 @@ void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option)
                                 "flags %#x", dma->map, dma->flags);
                break;
        }
-       dev_dbg(&dev->dev, "%s\n", buf);
-#endif
+       pnp_dbg(&dev->dev, "%s\n", buf);
 }
index f660ef3e5b29e801f205eb06358cf54f26490e25..8abbb2020af9c0d6b238d16cf81c4277de31dc3d 100644 (file)
@@ -171,10 +171,10 @@ config RTC_DRV_MAX6900
          will be called rtc-max6900.
 
 config RTC_DRV_RS5C372
-       tristate "Ricoh RS5C372A/B, RV5C386, RV5C387A"
+       tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A"
        help
          If you say yes here you get support for the
-         Ricoh RS5C372A, RS5C372B, RV5C386, and RV5C387A RTC chips.
+         Ricoh R2025S/D, RS5C372A, RS5C372B, RV5C386, and RV5C387A RTC chips.
 
          This driver can also be built as a module. If so, the module
          will be called rtc-rs5c372.
@@ -246,6 +246,16 @@ config RTC_DRV_TWL92330
          platforms.  The support is integrated with the rest of
          the Menelaus driver; it's not separate module.
 
+config RTC_DRV_TWL4030
+       tristate "TI TWL4030/TWL5030/TPS659x0"
+       depends on RTC_CLASS && TWL4030_CORE
+       help
+         If you say yes here you get support for the RTC on the
+         TWL4030 family chips, used mostly with OMAP3 platforms.
+
+         This driver can also be built as a module. If so, the module
+         will be called rtc-twl4030.
+
 config RTC_DRV_S35390A
        tristate "Seiko Instruments S-35390A"
        select BITREVERSE
@@ -610,6 +620,14 @@ config RTC_DRV_RS5C313
        help
          If you say yes here you get support for the Ricoh RS5C313 RTC chips.
 
+config RTC_DRV_PARISC
+       tristate "PA-RISC firmware RTC support"
+       depends on PARISC
+       help
+         Say Y or M here to enable RTC support on PA-RISC systems using
+         firmware calls. If you do not know what you are doing, you should
+         just say Y.
+
 config RTC_DRV_PPC
        tristate "PowerPC machine dependent RTC support"
        depends on PPC
index d05928b3ca9466b7402a2392f555e32f3051ad31..e9e8474cc8fea8fb11ff77f31df46e30d8c7dbba 100644 (file)
@@ -51,6 +51,7 @@ obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
 obj-$(CONFIG_RTC_DRV_PCF8583)  += rtc-pcf8583.o
 obj-$(CONFIG_RTC_DRV_PL030)    += rtc-pl030.o
 obj-$(CONFIG_RTC_DRV_PL031)    += rtc-pl031.o
+obj-$(CONFIG_RTC_DRV_PARISC)   += rtc-parisc.o
 obj-$(CONFIG_RTC_DRV_PPC)      += rtc-ppc.o
 obj-$(CONFIG_RTC_DRV_R9701)    += rtc-r9701.o
 obj-$(CONFIG_RTC_DRV_RS5C313)  += rtc-rs5c313.o
@@ -62,6 +63,7 @@ obj-$(CONFIG_RTC_DRV_SA1100)  += rtc-sa1100.o
 obj-$(CONFIG_RTC_DRV_SH)       += rtc-sh.o
 obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o
 obj-$(CONFIG_RTC_DRV_TEST)     += rtc-test.o
+obj-$(CONFIG_RTC_DRV_TWL4030)  += rtc-twl4030.o
 obj-$(CONFIG_RTC_DRV_V3020)    += rtc-v3020.o
 obj-$(CONFIG_RTC_DRV_VR41XX)   += rtc-vr41xx.o
 obj-$(CONFIG_RTC_DRV_X1205)    += rtc-x1205.o
diff --git a/drivers/rtc/rtc-parisc.c b/drivers/rtc/rtc-parisc.c
new file mode 100644 (file)
index 0000000..346d633
--- /dev/null
@@ -0,0 +1,111 @@
+/* rtc-parisc: RTC for HP PA-RISC firmware
+ *
+ * Copyright (C) 2008 Kyle McMartin <kyle@mcmartin.ca>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/time.h>
+#include <linux/platform_device.h>
+
+#include <asm/rtc.h>
+
+/* as simple as can be, and no simpler. */
+struct parisc_rtc {
+       struct rtc_device *rtc;
+       spinlock_t lock;
+};
+
+static int parisc_get_time(struct device *dev, struct rtc_time *tm)
+{
+       struct parisc_rtc *p = dev_get_drvdata(dev);
+       unsigned long flags, ret;
+
+       spin_lock_irqsave(&p->lock, flags);
+       ret = get_rtc_time(tm);
+       spin_unlock_irqrestore(&p->lock, flags);
+
+       if (ret & RTC_BATT_BAD)
+               return -EOPNOTSUPP;
+
+       return 0;
+}
+
+static int parisc_set_time(struct device *dev, struct rtc_time *tm)
+{
+       struct parisc_rtc *p = dev_get_drvdata(dev);
+       unsigned long flags, ret;
+
+       spin_lock_irqsave(&p->lock, flags);
+       ret = set_rtc_time(tm);
+       spin_unlock_irqrestore(&p->lock, flags);
+
+       if (ret < 0)
+               return -EOPNOTSUPP;
+
+       return 0;
+}
+
+static const struct rtc_class_ops parisc_rtc_ops = {
+       .read_time = parisc_get_time,
+       .set_time = parisc_set_time,
+};
+
+static int __devinit parisc_rtc_probe(struct platform_device *dev)
+{
+       struct parisc_rtc *p;
+
+       p = kzalloc(sizeof (*p), GFP_KERNEL);
+       if (!p)
+               return -ENOMEM;
+
+       spin_lock_init(&p->lock);
+
+       p->rtc = rtc_device_register("rtc-parisc", &dev->dev, &parisc_rtc_ops,
+                                       THIS_MODULE);
+       if (IS_ERR(p->rtc)) {
+               int err = PTR_ERR(p->rtc);
+               kfree(p);
+               return err;
+       }
+
+       platform_set_drvdata(dev, p);
+
+       return 0;
+}
+
+static int __devexit parisc_rtc_remove(struct platform_device *dev)
+{
+       struct parisc_rtc *p = platform_get_drvdata(dev);
+
+       rtc_device_unregister(p->rtc);
+       kfree(p);
+
+       return 0;
+}
+
+static struct platform_driver parisc_rtc_driver = {
+       .driver = {
+               .name = "rtc-parisc",
+               .owner = THIS_MODULE,
+       },
+       .probe = parisc_rtc_probe,
+       .remove = __devexit_p(parisc_rtc_remove),
+};
+
+static int __init parisc_rtc_init(void)
+{
+       return platform_driver_register(&parisc_rtc_driver);
+}
+
+static void __exit parisc_rtc_fini(void)
+{
+       platform_driver_unregister(&parisc_rtc_driver);
+}
+
+module_init(parisc_rtc_init);
+module_exit(parisc_rtc_fini);
+
+MODULE_AUTHOR("Kyle McMartin <kyle@mcmartin.ca>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("HP PA-RISC RTC driver");
diff --git a/drivers/rtc/rtc-twl4030.c b/drivers/rtc/rtc-twl4030.c
new file mode 100644 (file)
index 0000000..abe87a4
--- /dev/null
@@ -0,0 +1,564 @@
+/*
+ * rtc-twl4030.c -- TWL4030 Real Time Clock interface
+ *
+ * Copyright (C) 2007 MontaVista Software, Inc
+ * Author: Alexandre Rusev <source@mvista.com>
+ *
+ * Based on original TI driver twl4030-rtc.c
+ *   Copyright (C) 2006 Texas Instruments, Inc.
+ *
+ * Based on rtc-omap.c
+ *   Copyright (C) 2003 MontaVista Software, Inc.
+ *   Author: George G. Davis <gdavis@mvista.com> or <source@mvista.com>
+ *   Copyright (C) 2006 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+
+#include <linux/i2c/twl4030.h>
+
+
+/*
+ * RTC block register offsets (use TWL_MODULE_RTC)
+ */
+#define REG_SECONDS_REG                          0x00
+#define REG_MINUTES_REG                          0x01
+#define REG_HOURS_REG                            0x02
+#define REG_DAYS_REG                             0x03
+#define REG_MONTHS_REG                           0x04
+#define REG_YEARS_REG                            0x05
+#define REG_WEEKS_REG                            0x06
+
+#define REG_ALARM_SECONDS_REG                    0x07
+#define REG_ALARM_MINUTES_REG                    0x08
+#define REG_ALARM_HOURS_REG                      0x09
+#define REG_ALARM_DAYS_REG                       0x0A
+#define REG_ALARM_MONTHS_REG                     0x0B
+#define REG_ALARM_YEARS_REG                      0x0C
+
+#define REG_RTC_CTRL_REG                         0x0D
+#define REG_RTC_STATUS_REG                       0x0E
+#define REG_RTC_INTERRUPTS_REG                   0x0F
+
+#define REG_RTC_COMP_LSB_REG                     0x10
+#define REG_RTC_COMP_MSB_REG                     0x11
+
+/* RTC_CTRL_REG bitfields */
+#define BIT_RTC_CTRL_REG_STOP_RTC_M              0x01
+#define BIT_RTC_CTRL_REG_ROUND_30S_M             0x02
+#define BIT_RTC_CTRL_REG_AUTO_COMP_M             0x04
+#define BIT_RTC_CTRL_REG_MODE_12_24_M            0x08
+#define BIT_RTC_CTRL_REG_TEST_MODE_M             0x10
+#define BIT_RTC_CTRL_REG_SET_32_COUNTER_M        0x20
+#define BIT_RTC_CTRL_REG_GET_TIME_M              0x40
+
+/* RTC_STATUS_REG bitfields */
+#define BIT_RTC_STATUS_REG_RUN_M                 0x02
+#define BIT_RTC_STATUS_REG_1S_EVENT_M            0x04
+#define BIT_RTC_STATUS_REG_1M_EVENT_M            0x08
+#define BIT_RTC_STATUS_REG_1H_EVENT_M            0x10
+#define BIT_RTC_STATUS_REG_1D_EVENT_M            0x20
+#define BIT_RTC_STATUS_REG_ALARM_M               0x40
+#define BIT_RTC_STATUS_REG_POWER_UP_M            0x80
+
+/* RTC_INTERRUPTS_REG bitfields */
+#define BIT_RTC_INTERRUPTS_REG_EVERY_M           0x03
+#define BIT_RTC_INTERRUPTS_REG_IT_TIMER_M        0x04
+#define BIT_RTC_INTERRUPTS_REG_IT_ALARM_M        0x08
+
+
+/* REG_SECONDS_REG through REG_YEARS_REG is how many registers? */
+#define ALL_TIME_REGS          6
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Supports 1 byte read from TWL4030 RTC register.
+ */
+static int twl4030_rtc_read_u8(u8 *data, u8 reg)
+{
+       int ret;
+
+       ret = twl4030_i2c_read_u8(TWL4030_MODULE_RTC, data, reg);
+       if (ret < 0)
+               pr_err("twl4030_rtc: Could not read TWL4030"
+                      "register %X - error %d\n", reg, ret);
+       return ret;
+}
+
+/*
+ * Supports 1 byte write to TWL4030 RTC registers.
+ */
+static int twl4030_rtc_write_u8(u8 data, u8 reg)
+{
+       int ret;
+
+       ret = twl4030_i2c_write_u8(TWL4030_MODULE_RTC, data, reg);
+       if (ret < 0)
+               pr_err("twl4030_rtc: Could not write TWL4030"
+                      "register %X - error %d\n", reg, ret);
+       return ret;
+}
+
+/*
+ * Cache the value for timer/alarm interrupts register; this is
+ * only changed by callers holding rtc ops lock (or resume).
+ */
+static unsigned char rtc_irq_bits;
+
+/*
+ * Enable timer and/or alarm interrupts.
+ */
+static int set_rtc_irq_bit(unsigned char bit)
+{
+       unsigned char val;
+       int ret;
+
+       val = rtc_irq_bits | bit;
+       ret = twl4030_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
+       if (ret == 0)
+               rtc_irq_bits = val;
+
+       return ret;
+}
+
+/*
+ * Disable timer and/or alarm interrupts.
+ */
+static int mask_rtc_irq_bit(unsigned char bit)
+{
+       unsigned char val;
+       int ret;
+
+       val = rtc_irq_bits & ~bit;
+       ret = twl4030_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
+       if (ret == 0)
+               rtc_irq_bits = val;
+
+       return ret;
+}
+
+static inline int twl4030_rtc_alarm_irq_set_state(int enabled)
+{
+       int ret;
+
+       if (enabled)
+               ret = set_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+       else
+               ret = mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+
+       return ret;
+}
+
+static inline int twl4030_rtc_irq_set_state(int enabled)
+{
+       int ret;
+
+       if (enabled)
+               ret = set_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
+       else
+               ret = mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
+
+       return ret;
+}
+
+/*
+ * Gets current TWL4030 RTC time and date parameters.
+ *
+ * The RTC's time/alarm representation is not what gmtime(3) requires
+ * Linux to use:
+ *
+ *  - Months are 1..12 vs Linux 0-11
+ *  - Years are 0..99 vs Linux 1900..N (we assume 21st century)
+ */
+static int twl4030_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+       unsigned char rtc_data[ALL_TIME_REGS + 1];
+       int ret;
+       u8 save_control;
+
+       ret = twl4030_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
+       if (ret < 0)
+               return ret;
+
+       save_control |= BIT_RTC_CTRL_REG_GET_TIME_M;
+
+       ret = twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
+       if (ret < 0)
+               return ret;
+
+       ret = twl4030_i2c_read(TWL4030_MODULE_RTC, rtc_data,
+                              REG_SECONDS_REG, ALL_TIME_REGS);
+
+       if (ret < 0) {
+               dev_err(dev, "rtc_read_time error %d\n", ret);
+               return ret;
+       }
+
+       tm->tm_sec = bcd2bin(rtc_data[0]);
+       tm->tm_min = bcd2bin(rtc_data[1]);
+       tm->tm_hour = bcd2bin(rtc_data[2]);
+       tm->tm_mday = bcd2bin(rtc_data[3]);
+       tm->tm_mon = bcd2bin(rtc_data[4]) - 1;
+       tm->tm_year = bcd2bin(rtc_data[5]) + 100;
+
+       return ret;
+}
+
+static int twl4030_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+       unsigned char save_control;
+       unsigned char rtc_data[ALL_TIME_REGS + 1];
+       int ret;
+
+       rtc_data[1] = bin2bcd(tm->tm_sec);
+       rtc_data[2] = bin2bcd(tm->tm_min);
+       rtc_data[3] = bin2bcd(tm->tm_hour);
+       rtc_data[4] = bin2bcd(tm->tm_mday);
+       rtc_data[5] = bin2bcd(tm->tm_mon + 1);
+       rtc_data[6] = bin2bcd(tm->tm_year - 100);
+
+       /* Stop RTC while updating the TC registers */
+       ret = twl4030_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
+       if (ret < 0)
+               goto out;
+
+       save_control &= ~BIT_RTC_CTRL_REG_STOP_RTC_M;
+       twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
+       if (ret < 0)
+               goto out;
+
+       /* update all the time registers in one shot */
+       ret = twl4030_i2c_write(TWL4030_MODULE_RTC, rtc_data,
+                       REG_SECONDS_REG, ALL_TIME_REGS);
+       if (ret < 0) {
+               dev_err(dev, "rtc_set_time error %d\n", ret);
+               goto out;
+       }
+
+       /* Start back RTC */
+       save_control |= BIT_RTC_CTRL_REG_STOP_RTC_M;
+       ret = twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
+
+out:
+       return ret;
+}
+
+/*
+ * Gets current TWL4030 RTC alarm time.
+ */
+static int twl4030_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+       unsigned char rtc_data[ALL_TIME_REGS + 1];
+       int ret;
+
+       ret = twl4030_i2c_read(TWL4030_MODULE_RTC, rtc_data,
+                              REG_ALARM_SECONDS_REG, ALL_TIME_REGS);
+       if (ret < 0) {
+               dev_err(dev, "rtc_read_alarm error %d\n", ret);
+               return ret;
+       }
+
+       /* some of these fields may be wildcard/"match all" */
+       alm->time.tm_sec = bcd2bin(rtc_data[0]);
+       alm->time.tm_min = bcd2bin(rtc_data[1]);
+       alm->time.tm_hour = bcd2bin(rtc_data[2]);
+       alm->time.tm_mday = bcd2bin(rtc_data[3]);
+       alm->time.tm_mon = bcd2bin(rtc_data[4]) - 1;
+       alm->time.tm_year = bcd2bin(rtc_data[5]) + 100;
+
+       /* report cached alarm enable state */
+       if (rtc_irq_bits & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M)
+               alm->enabled = 1;
+
+       return ret;
+}
+
+static int twl4030_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+       unsigned char alarm_data[ALL_TIME_REGS + 1];
+       int ret;
+
+       ret = twl4030_rtc_alarm_irq_set_state(0);
+       if (ret)
+               goto out;
+
+       alarm_data[1] = bin2bcd(alm->time.tm_sec);
+       alarm_data[2] = bin2bcd(alm->time.tm_min);
+       alarm_data[3] = bin2bcd(alm->time.tm_hour);
+       alarm_data[4] = bin2bcd(alm->time.tm_mday);
+       alarm_data[5] = bin2bcd(alm->time.tm_mon + 1);
+       alarm_data[6] = bin2bcd(alm->time.tm_year - 100);
+
+       /* update all the alarm registers in one shot */
+       ret = twl4030_i2c_write(TWL4030_MODULE_RTC, alarm_data,
+                       REG_ALARM_SECONDS_REG, ALL_TIME_REGS);
+       if (ret) {
+               dev_err(dev, "rtc_set_alarm error %d\n", ret);
+               goto out;
+       }
+
+       if (alm->enabled)
+               ret = twl4030_rtc_alarm_irq_set_state(1);
+out:
+       return ret;
+}
+
+#ifdef CONFIG_RTC_INTF_DEV
+
+static int twl4030_rtc_ioctl(struct device *dev, unsigned int cmd,
+                            unsigned long arg)
+{
+       switch (cmd) {
+       case RTC_AIE_OFF:
+               return twl4030_rtc_alarm_irq_set_state(0);
+       case RTC_AIE_ON:
+               return twl4030_rtc_alarm_irq_set_state(1);
+       case RTC_UIE_OFF:
+               return twl4030_rtc_irq_set_state(0);
+       case RTC_UIE_ON:
+               return twl4030_rtc_irq_set_state(1);
+
+       default:
+               return -ENOIOCTLCMD;
+       }
+}
+
+#else
+#define        omap_rtc_ioctl  NULL
+#endif
+
+static irqreturn_t twl4030_rtc_interrupt(int irq, void *rtc)
+{
+       unsigned long events = 0;
+       int ret = IRQ_NONE;
+       int res;
+       u8 rd_reg;
+
+#ifdef CONFIG_LOCKDEP
+       /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
+        * we don't want and can't tolerate.  Although it might be
+        * friendlier not to borrow this thread context...
+        */
+       local_irq_enable();
+#endif
+
+       res = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
+       if (res)
+               goto out;
+       /*
+        * Figure out source of interrupt: ALARM or TIMER in RTC_STATUS_REG.
+        * only one (ALARM or RTC) interrupt source may be enabled
+        * at time, we also could check our results
+        * by reading RTS_INTERRUPTS_REGISTER[IT_TIMER,IT_ALARM]
+        */
+       if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
+               events |= RTC_IRQF | RTC_AF;
+       else
+               events |= RTC_IRQF | RTC_UF;
+
+       res = twl4030_rtc_write_u8(rd_reg | BIT_RTC_STATUS_REG_ALARM_M,
+                                  REG_RTC_STATUS_REG);
+       if (res)
+               goto out;
+
+       /* Clear on Read enabled. RTC_IT bit of TWL4030_INT_PWR_ISR1
+        * needs 2 reads to clear the interrupt. One read is done in
+        * do_twl4030_pwrirq(). Doing the second read, to clear
+        * the bit.
+        *
+        * FIXME the reason PWR_ISR1 needs an extra read is that
+        * RTC_IF retriggered until we cleared REG_ALARM_M above.
+        * But re-reading like this is a bad hack; by doing so we
+        * risk wrongly clearing status for some other IRQ (losing
+        * the interrupt).  Be smarter about handling RTC_UF ...
+        */
+       res = twl4030_i2c_read_u8(TWL4030_MODULE_INT,
+                       &rd_reg, TWL4030_INT_PWR_ISR1);
+       if (res)
+               goto out;
+
+       /* Notify RTC core on event */
+       rtc_update_irq(rtc, 1, events);
+
+       ret = IRQ_HANDLED;
+out:
+       return ret;
+}
+
+static struct rtc_class_ops twl4030_rtc_ops = {
+       .ioctl          = twl4030_rtc_ioctl,
+       .read_time      = twl4030_rtc_read_time,
+       .set_time       = twl4030_rtc_set_time,
+       .read_alarm     = twl4030_rtc_read_alarm,
+       .set_alarm      = twl4030_rtc_set_alarm,
+};
+
+/*----------------------------------------------------------------------*/
+
+static int __devinit twl4030_rtc_probe(struct platform_device *pdev)
+{
+       struct rtc_device *rtc;
+       int ret = 0;
+       int irq = platform_get_irq(pdev, 0);
+       u8 rd_reg;
+
+       if (irq < 0)
+               return irq;
+
+       rtc = rtc_device_register(pdev->name,
+                                 &pdev->dev, &twl4030_rtc_ops, THIS_MODULE);
+       if (IS_ERR(rtc)) {
+               ret = -EINVAL;
+               dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
+                       PTR_ERR(rtc));
+               goto out0;
+
+       }
+
+       platform_set_drvdata(pdev, rtc);
+
+       ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
+
+       if (ret < 0)
+               goto out1;
+
+       if (rd_reg & BIT_RTC_STATUS_REG_POWER_UP_M)
+               dev_warn(&pdev->dev, "Power up reset detected.\n");
+
+       if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
+               dev_warn(&pdev->dev, "Pending Alarm interrupt detected.\n");
+
+       /* Clear RTC Power up reset and pending alarm interrupts */
+       ret = twl4030_rtc_write_u8(rd_reg, REG_RTC_STATUS_REG);
+       if (ret < 0)
+               goto out1;
+
+       ret = request_irq(irq, twl4030_rtc_interrupt,
+                               IRQF_TRIGGER_RISING,
+                               rtc->dev.bus_id, rtc);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "IRQ is not free.\n");
+               goto out1;
+       }
+
+       /* Check RTC module status, Enable if it is off */
+       ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG);
+       if (ret < 0)
+               goto out2;
+
+       if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) {
+               dev_info(&pdev->dev, "Enabling TWL4030-RTC.\n");
+               rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M;
+               ret = twl4030_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG);
+               if (ret < 0)
+                       goto out2;
+       }
+
+       /* init cached IRQ enable bits */
+       ret = twl4030_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
+       if (ret < 0)
+               goto out2;
+
+       return ret;
+
+
+out2:
+       free_irq(irq, rtc);
+out1:
+       rtc_device_unregister(rtc);
+out0:
+       return ret;
+}
+
+/*
+ * Disable all TWL4030 RTC module interrupts.
+ * Sets status flag to free.
+ */
+static int __devexit twl4030_rtc_remove(struct platform_device *pdev)
+{
+       /* leave rtc running, but disable irqs */
+       struct rtc_device *rtc = platform_get_drvdata(pdev);
+       int irq = platform_get_irq(pdev, 0);
+
+       mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+       mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
+
+       free_irq(irq, rtc);
+
+       rtc_device_unregister(rtc);
+       platform_set_drvdata(pdev, NULL);
+       return 0;
+}
+
+static void twl4030_rtc_shutdown(struct platform_device *pdev)
+{
+       mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M |
+                        BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+}
+
+#ifdef CONFIG_PM
+
+static unsigned char irqstat;
+
+static int twl4030_rtc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       irqstat = rtc_irq_bits;
+
+       /* REVISIT alarm may need to wake us from sleep */
+       mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M |
+                        BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+       return 0;
+}
+
+static int twl4030_rtc_resume(struct platform_device *pdev)
+{
+       set_rtc_irq_bit(irqstat);
+       return 0;
+}
+
+#else
+#define twl4030_rtc_suspend NULL
+#define twl4030_rtc_resume  NULL
+#endif
+
+MODULE_ALIAS("platform:twl4030_rtc");
+
+static struct platform_driver twl4030rtc_driver = {
+       .probe          = twl4030_rtc_probe,
+       .remove         = __devexit_p(twl4030_rtc_remove),
+       .shutdown       = twl4030_rtc_shutdown,
+       .suspend        = twl4030_rtc_suspend,
+       .resume         = twl4030_rtc_resume,
+       .driver         = {
+               .owner  = THIS_MODULE,
+               .name   = "twl4030_rtc",
+       },
+};
+
+static int __init twl4030_rtc_init(void)
+{
+       return platform_driver_register(&twl4030rtc_driver);
+}
+module_init(twl4030_rtc_init);
+
+static void __exit twl4030_rtc_exit(void)
+{
+       platform_driver_unregister(&twl4030rtc_driver);
+}
+module_exit(twl4030_rtc_exit);
+
+MODULE_AUTHOR("Texas Instruments, MontaVista Software");
+MODULE_LICENSE("GPL");
index 884b635f028b792ee9b9afef8954345b4375e24a..834dcc6d785f899a7a4d43985388da3724da6afe 100644 (file)
@@ -360,7 +360,7 @@ static int __devinit rtc_probe(struct platform_device *pdev)
        spin_unlock_irq(&rtc_lock);
 
        aie_irq = platform_get_irq(pdev, 0);
-       if (aie_irq < 0 || aie_irq >= NR_IRQS) {
+       if (aie_irq < 0 || aie_irq >= nr_irqs) {
                retval = -EBUSY;
                goto err_device_unregister;
        }
@@ -371,7 +371,7 @@ static int __devinit rtc_probe(struct platform_device *pdev)
                goto err_device_unregister;
 
        pie_irq = platform_get_irq(pdev, 1);
-       if (pie_irq < 0 || pie_irq >= NR_IRQS)
+       if (pie_irq < 0 || pie_irq >= nr_irqs)
                goto err_free_irq;
 
        retval = request_irq(pie_irq, rtclong1_interrupt, IRQF_DISABLED,
index 0a225ccda026017773e1a619fc07c651c7223aef..4b76fca64a6f1bf5538c8babc8595b15a234aa8e 100644 (file)
@@ -2011,10 +2011,9 @@ static void dasd_flush_request_queue(struct dasd_block *block)
        spin_unlock_irq(&block->request_queue_lock);
 }
 
-static int dasd_open(struct inode *inp, struct file *filp)
+static int dasd_open(struct block_device *bdev, fmode_t mode)
 {
-       struct gendisk *disk = inp->i_bdev->bd_disk;
-       struct dasd_block *block = disk->private_data;
+       struct dasd_block *block = bdev->bd_disk->private_data;
        struct dasd_device *base = block->base;
        int rc;
 
@@ -2052,9 +2051,8 @@ unlock:
        return rc;
 }
 
-static int dasd_release(struct inode *inp, struct file *filp)
+static int dasd_release(struct gendisk *disk, fmode_t mode)
 {
-       struct gendisk *disk = inp->i_bdev->bd_disk;
        struct dasd_block *block = disk->private_data;
 
        atomic_dec(&block->open_count);
@@ -2089,8 +2087,7 @@ dasd_device_operations = {
        .owner          = THIS_MODULE,
        .open           = dasd_open,
        .release        = dasd_release,
-       .ioctl          = dasd_ioctl,
-       .compat_ioctl   = dasd_compat_ioctl,
+       .locked_ioctl   = dasd_ioctl,
        .getgeo         = dasd_getgeo,
 };
 
index aee6565aaf983fda86bfaaf483d2aaeb9ddfac9a..e99d566b69cccdbdce2b5b680a1ec46ac97d2c3a 100644 (file)
@@ -99,7 +99,7 @@ int dasd_scan_partitions(struct dasd_block *block)
        struct block_device *bdev;
 
        bdev = bdget_disk(block->gdp, 0);
-       if (!bdev || blkdev_get(bdev, FMODE_READ, 1) < 0)
+       if (!bdev || blkdev_get(bdev, FMODE_READ) < 0)
                return -ENODEV;
        /*
         * See fs/partition/check.c:register_disk,rescan_partitions
@@ -152,7 +152,7 @@ void dasd_destroy_partitions(struct dasd_block *block)
 
        invalidate_partition(block->gdp, 0);
        /* Matching blkdev_put to the blkdev_get in dasd_scan_partitions. */
-       blkdev_put(bdev);
+       blkdev_put(bdev, FMODE_READ);
        set_capacity(block->gdp, 0);
 }
 
index 489d5fe488fb7d60616caebf36e78360ec4cfdd8..05a14536c369685985e39b225afc69b0e89e9930 100644 (file)
@@ -610,8 +610,7 @@ int dasd_scan_partitions(struct dasd_block *);
 void dasd_destroy_partitions(struct dasd_block *);
 
 /* externals in dasd_ioctl.c */
-int  dasd_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
-long dasd_compat_ioctl(struct file *, unsigned int, unsigned long);
+int  dasd_ioctl(struct block_device *, fmode_t, unsigned int, unsigned long);
 
 /* externals in dasd_proc.c */
 int dasd_proc_init(void);
index 91a64630cb0f4095f9fa9933189df9a520bd77ab..b82d816d9ef7adda1d7d9ddd3c6f463666dc041b 100644 (file)
@@ -366,10 +366,9 @@ static int dasd_ioctl_readall_cmb(struct dasd_block *block, unsigned int cmd,
 }
 
 int
-dasd_ioctl(struct inode *inode, struct file *file,
+dasd_ioctl(struct block_device *bdev, fmode_t mode,
           unsigned int cmd, unsigned long arg)
 {
-       struct block_device *bdev = inode->i_bdev;
        struct dasd_block *block = bdev->bd_disk->private_data;
        void __user *argp = (void __user *)arg;
 
@@ -421,15 +420,3 @@ dasd_ioctl(struct inode *inode, struct file *file,
                return -EINVAL;
        }
 }
-
-long
-dasd_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
-       int rval;
-
-       lock_kernel();
-       rval = dasd_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
-       unlock_kernel();
-
-       return (rval == -EINVAL) ? -ENOIOCTLCMD : rval;
-}
index a7ff167d5b81089c781a3f3c9aa9e736cc8da48e..63f26a135fe5ae9764a26eda10cd5cae64aa4c49 100644 (file)
@@ -31,8 +31,8 @@
 #define PRINT_WARN(x...)  printk(KERN_WARNING DCSSBLK_NAME " warning: " x)
 #define PRINT_ERR(x...)          printk(KERN_ERR DCSSBLK_NAME " error: " x)
 
-static int dcssblk_open(struct inode *inode, struct file *filp);
-static int dcssblk_release(struct inode *inode, struct file *filp);
+static int dcssblk_open(struct block_device *bdev, fmode_t mode);
+static int dcssblk_release(struct gendisk *disk, fmode_t mode);
 static int dcssblk_make_request(struct request_queue *q, struct bio *bio);
 static int dcssblk_direct_access(struct block_device *bdev, sector_t secnum,
                                 void **kaddr, unsigned long *pfn);
@@ -776,32 +776,31 @@ out_buf:
 }
 
 static int
-dcssblk_open(struct inode *inode, struct file *filp)
+dcssblk_open(struct block_device *bdev, fmode_t mode)
 {
        struct dcssblk_dev_info *dev_info;
        int rc;
 
-       dev_info = inode->i_bdev->bd_disk->private_data;
+       dev_info = bdev->bd_disk->private_data;
        if (NULL == dev_info) {
                rc = -ENODEV;
                goto out;
        }
        atomic_inc(&dev_info->use_count);
-       inode->i_bdev->bd_block_size = 4096;
+       bdev->bd_block_size = 4096;
        rc = 0;
 out:
        return rc;
 }
 
 static int
-dcssblk_release(struct inode *inode, struct file *filp)
+dcssblk_release(struct gendisk *disk, fmode_t mode)
 {
-       struct dcssblk_dev_info *dev_info;
+       struct dcssblk_dev_info *dev_info = disk->private_data;
        struct segment_info *entry;
        int rc;
 
-       dev_info = inode->i_bdev->bd_disk->private_data;
-       if (NULL == dev_info) {
+       if (!dev_info) {
                rc = -ENODEV;
                goto out;
        }
index a25b8bf54f418103ef4dca4da08dd13e1e9d6513..023803dbb0c7bd691189b10976e28874cc69403c 100644 (file)
@@ -43,9 +43,9 @@
 /*
  * file operation structure for tape block frontend
  */
-static int tapeblock_open(struct inode *, struct file *);
-static int tapeblock_release(struct inode *, struct file *);
-static int tapeblock_ioctl(struct inode *, struct file *, unsigned int,
+static int tapeblock_open(struct block_device *, fmode_t);
+static int tapeblock_release(struct gendisk *, fmode_t);
+static int tapeblock_ioctl(struct block_device *, fmode_t, unsigned int,
                                unsigned long);
 static int tapeblock_medium_changed(struct gendisk *);
 static int tapeblock_revalidate_disk(struct gendisk *);
@@ -54,7 +54,7 @@ static struct block_device_operations tapeblock_fops = {
        .owner           = THIS_MODULE,
        .open            = tapeblock_open,
        .release         = tapeblock_release,
-       .ioctl           = tapeblock_ioctl,
+       .locked_ioctl           = tapeblock_ioctl,
        .media_changed   = tapeblock_medium_changed,
        .revalidate_disk = tapeblock_revalidate_disk,
 };
@@ -364,13 +364,12 @@ tapeblock_medium_changed(struct gendisk *disk)
  * Block frontend tape device open function.
  */
 static int
-tapeblock_open(struct inode *inode, struct file *filp)
+tapeblock_open(struct block_device *bdev, fmode_t mode)
 {
-       struct gendisk *        disk;
+       struct gendisk *        disk = bdev->bd_disk;
        struct tape_device *    device;
        int                     rc;
 
-       disk   = inode->i_bdev->bd_disk;
        device = tape_get_device_reference(disk->private_data);
 
        if (device->required_tapemarks) {
@@ -410,9 +409,8 @@ release:
  *       we just get the pointer here and release the reference.
  */
 static int
-tapeblock_release(struct inode *inode, struct file *filp)
+tapeblock_release(struct gendisk *disk, fmode_t mode)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
        struct tape_device *device = disk->private_data;
 
        tape_state_set(device, TS_IN_USE);
@@ -427,22 +425,21 @@ tapeblock_release(struct inode *inode, struct file *filp)
  */
 static int
 tapeblock_ioctl(
-       struct inode *          inode,
-       struct file *           file,
+       struct block_device *   bdev,
+       fmode_t                 mode,
        unsigned int            command,
        unsigned long           arg
 ) {
        int rc;
        int minor;
-       struct gendisk *disk;
+       struct gendisk *disk = bdev->bd_disk;
        struct tape_device *device;
 
        rc     = 0;
-       disk   = inode->i_bdev->bd_disk;
        BUG_ON(!disk);
        device = disk->private_data;
        BUG_ON(!device);
-       minor  = iminor(inode);
+       minor  = MINOR(bdev->bd_dev);
 
        DBF_LH(6, "tapeblock_ioctl(0x%0x)\n", command);
        DBF_LH(6, "device = %d:%d\n", tapeblock_major, minor);
index 326db1e827c4dbe41f70419a9af53b1a997a7e7a..e3fe6838293ad4f238cd9bb81df92a59ec61d72b 100644 (file)
@@ -659,9 +659,9 @@ static ssize_t poll_timeout_store(struct bus_type *bus, const char *buf,
        hr_time = ktime_set(0, poll_timeout);
 
        if (!hrtimer_is_queued(&ap_poll_timer) ||
-           !hrtimer_forward(&ap_poll_timer, ap_poll_timer.expires, hr_time)) {
-               ap_poll_timer.expires = hr_time;
-               hrtimer_start(&ap_poll_timer, hr_time, HRTIMER_MODE_ABS);
+           !hrtimer_forward(&ap_poll_timer, hrtimer_get_expires(&ap_poll_timer), hr_time)) {
+               hrtimer_set_expires(&ap_poll_timer, hr_time);
+               hrtimer_start_expires(&ap_poll_timer, HRTIMER_MODE_ABS);
        }
        return count;
 }
index b92c19bb6876971bf042c9f0e8e372e6bd5e91ef..5311317c2e4cafd10d1382f93b41ed3f6a9baf08 100644 (file)
@@ -1924,12 +1924,9 @@ static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int re
            (cmd->sc_data_direction == DMA_FROM_DEVICE ||
             cmd->sc_data_direction == DMA_BIDIRECTIONAL)) {
                if (scsi_sg_count(cmd) == 1) {
-                       unsigned long flags;
                        void *buf = tw_dev->generic_buffer_virt[request_id];
 
-                       local_irq_save(flags);
                        scsi_sg_copy_from_buffer(cmd, buf, TW_SECTOR_SIZE);
-                       local_irq_restore(flags);
                }
        }
 } /* End twa_scsiop_execute_scsi_complete() */
index a0537f09aa216a3d41f7e92a518e8bae3cf8d05a..c03f1d2c9e2ec1f08e1f37d1ab389bc68d517fc6 100644 (file)
@@ -1466,12 +1466,7 @@ static int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id)
 static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
                                 void *data, unsigned int len)
 {
-       struct scsi_cmnd *cmd = tw_dev->srb[request_id];
-       unsigned long flags;
-
-       local_irq_save(flags);
-       scsi_sg_copy_from_buffer(cmd, data, len);
-       local_irq_restore(flags);
+       scsi_sg_copy_from_buffer(tw_dev->srb[request_id], data, len);
 }
 
 /* This function is called by the isr to complete an inquiry command */
index b5a868d85eb49760ac1f512195b29cb88c43578b..1e5478abd90ee8ae6c2371ff7f043d6f4f9122bf 100644 (file)
@@ -337,7 +337,7 @@ CMD_INC_RESID(struct scsi_cmnd *cmd, int inc)
 #else
 #define IRQ_MIN 9
 #if defined(__PPC)
-#define IRQ_MAX (NR_IRQS-1)
+#define IRQ_MAX (nr_irqs-1)
 #else
 #define IRQ_MAX 12
 #endif
index cca16fc5b4ad746a0ec02fedb575eea6dbc7df90..0666c22ab55b60934e815e35fc37edea6ef4eac5 100644 (file)
@@ -79,6 +79,17 @@ VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#77 $"
                mvi     SEQINTCODE, code;                               \
        }
 
+/*
+ * Registers marked "dont_generate_debug_code" are not (yet) referenced
+ * from the driver code, and this keyword inhibit generation
+ * of debug code for them.
+ *
+ * REG_PRETTY_PRINT config will complain if dont_generate_debug_code
+ * is added to the register which is referenced in the driver.
+ * Unreferenced register with no dont_generate_debug_code will result
+ * in dead code. No warning is issued.
+ */
+
 /*
  * Mode Pointer
  * Controls which of the 5, 512byte, address spaces should be used
@@ -91,6 +102,7 @@ register MODE_PTR {
        field   DST_MODE        0x70
        field   SRC_MODE        0x07
        mode_pointer
+       dont_generate_debug_code
 }
 
 const SRC_MODE_SHIFT   0
@@ -190,6 +202,7 @@ register SEQINTCODE {
                SAW_HWERR,
                BAD_SCB_STATUS
        }
+       dont_generate_debug_code
 }
 
 /*
@@ -207,6 +220,7 @@ register CLRINT {
        field   CLRSEQINT       0x04
        field   CLRCMDINT       0x02
        field   CLRSPLTINT      0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -222,6 +236,7 @@ register ERROR {
        field   SQPARERR        0x08
        field   ILLOPCODE       0x04
        field   DSCTMOUT        0x02
+       dont_generate_debug_code
 }
 
 /*
@@ -255,6 +270,7 @@ register HCNTRL {
        field   INTEN           0x02
        field   CHIPRST         0x01
        field   CHIPRSTACK      0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -265,6 +281,7 @@ register HNSCB_QOFF {
        access_mode     RW
        size            2
        count           2
+       dont_generate_debug_code
 }
 
 /*
@@ -274,6 +291,7 @@ register HESCB_QOFF {
        address                 0x008
        access_mode     RW
        count           2
+       dont_generate_debug_code
 }
 
 /*
@@ -311,6 +329,7 @@ register CLRSEQINTSTAT {
        field   CLRSEQ_SCSIINT  0x04
        field   CLRSEQ_PCIINT   0x02
        field   CLRSEQ_SPLTINT  0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -320,6 +339,7 @@ register SWTIMER {
        address                 0x00E
        access_mode     RW
        size            2
+       dont_generate_debug_code
 }
 
 /*
@@ -330,6 +350,7 @@ register SNSCB_QOFF {
        access_mode     RW
        size            2
        modes           M_CCHAN
+       dont_generate_debug_code
 }
 
 /*
@@ -340,6 +361,7 @@ register SESCB_QOFF {
        count           2
        access_mode     RW
        modes           M_CCHAN
+       dont_generate_debug_code
 }
 
 /*
@@ -350,6 +372,7 @@ register SDSCB_QOFF {
        access_mode     RW
        modes           M_CCHAN
        size            2
+       dont_generate_debug_code
 }
 
 /*
@@ -378,6 +401,7 @@ register QOFF_CTLSTA {
                SCB_QSIZE_8192,
                SCB_QSIZE_16384
        }
+       dont_generate_debug_code
 }
 
 /*
@@ -431,6 +455,7 @@ register DSCOMMAND0 {
        field   EXTREQLCK       0x10    /* External Request Lock */
        field   DISABLE_TWATE   0x02    /* Rev B or greater */
        field   CIOPARCKEN      0x01    /* Internal bus parity error enable */
+       dont_generate_debug_code
 }
 
 /*
@@ -459,6 +484,7 @@ register SG_CACHE_PRE {
        field   SG_ADDR_MASK    0xf8
        field   ODD_SEG         0x04
        field   LAST_SEG        0x02
+       dont_generate_debug_code
 }
 
 register SG_CACHE_SHADOW {
@@ -491,6 +517,7 @@ register HADDR {
        access_mode     RW
        size            8
        modes           M_DFF0, M_DFF1
+       dont_generate_debug_code
 }
 
 /*
@@ -522,6 +549,7 @@ register HCNT {
        access_mode     RW
        size            3
        modes           M_DFF0, M_DFF1
+       dont_generate_debug_code
 }
 
 /*
@@ -551,6 +579,7 @@ register SGHADDR {
        access_mode     RW
        size            8
        modes           M_DFF0, M_DFF1
+       dont_generate_debug_code
 }
 
 /*
@@ -561,6 +590,7 @@ register SCBHADDR {
        access_mode     RW
        size            8
        modes           M_CCHAN
+       dont_generate_debug_code
 }
 
 /*
@@ -570,6 +600,7 @@ register SGHCNT {
        address                 0x084
        access_mode     RW
        modes           M_DFF0, M_DFF1
+       dont_generate_debug_code
 }
 
 /*
@@ -579,6 +610,7 @@ register SCBHCNT {
        address                 0x084
        access_mode     RW
        modes           M_CCHAN
+       dont_generate_debug_code
 }
 
 /*
@@ -609,6 +641,7 @@ register DFF_THRSH {
                RD_DFTHRSH_90,
                RD_DFTHRSH_MAX
        }
+       dont_generate_debug_code
 }
 
 /*
@@ -817,6 +850,7 @@ register PCIXCTL {
        field   SRSPDPEEN       0x04
        field   TSCSERREN       0x02
        field   CMPABCDIS       0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -863,6 +897,7 @@ register DCHSPLTSTAT0 {
        field   RXOVRUN         0x04
        field   RXSCEMSG        0x02
        field   RXSPLTRSP       0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -908,6 +943,7 @@ register DCHSPLTSTAT1 {
        modes           M_DFF0, M_DFF1
        count           2
        field   RXDATABUCKET    0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -1069,6 +1105,7 @@ register SGSPLTSTAT0 {
        field   RXOVRUN         0x04
        field   RXSCEMSG        0x02
        field   RXSPLTRSP       0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -1080,6 +1117,7 @@ register SGSPLTSTAT1 {
        modes           M_DFF0, M_DFF1
        count           2
        field   RXDATABUCKET    0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -1091,6 +1129,7 @@ register SFUNCT {
        modes           M_CFG
        field   TEST_GROUP      0xF0
        field   TEST_NUM        0x0F
+       dont_generate_debug_code
 }
 
 /*
@@ -1109,6 +1148,7 @@ register DF0PCISTAT {
        field   RDPERR          0x04
        field   TWATERR         0x02
        field   DPR             0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -1204,6 +1244,7 @@ register TARGPCISTAT {
        field   SSE             0x40
        field   STA             0x08
        field   TWATERR         0x02
+       dont_generate_debug_code
 }
 
 /*
@@ -1216,6 +1257,7 @@ register LQIN {
        size            20
        count           2
        modes           M_DFF0, M_DFF1, M_SCSI
+       dont_generate_debug_code
 }
 
 /*
@@ -1247,6 +1289,7 @@ register LUNPTR {
        access_mode     RW
        modes           M_CFG
        count           2
+       dont_generate_debug_code
 }
 
 /*
@@ -1278,6 +1321,7 @@ register CMDLENPTR {
        access_mode     RW
        modes           M_CFG
        count           1
+       dont_generate_debug_code
 }
 
 /*
@@ -1290,6 +1334,7 @@ register ATTRPTR {
        access_mode     RW
        modes           M_CFG
        count           1
+       dont_generate_debug_code
 }
 
 /*
@@ -1302,6 +1347,7 @@ register FLAGPTR {
        access_mode     RW
        modes           M_CFG
        count           1
+       dont_generate_debug_code
 }
 
 /*
@@ -1313,6 +1359,7 @@ register CMDPTR {
        access_mode     RW
        modes           M_CFG
        count           1
+       dont_generate_debug_code
 }
 
 /*
@@ -1324,6 +1371,7 @@ register QNEXTPTR {
        access_mode     RW
        modes           M_CFG
        count           1
+       dont_generate_debug_code
 }
 
 /*
@@ -1347,6 +1395,7 @@ register ABRTBYTEPTR {
        access_mode     RW
        modes           M_CFG
        count           1
+       dont_generate_debug_code
 }
 
 /*
@@ -1358,6 +1407,7 @@ register ABRTBITPTR {
        access_mode     RW
        modes           M_CFG
        count           1
+       dont_generate_debug_code
 }
 
 /*
@@ -1398,6 +1448,7 @@ register LUNLEN {
        count           2
        mask            ILUNLEN 0x0F
        mask            TLUNLEN 0xF0
+       dont_generate_debug_code
 }
 const LUNLEN_SINGLE_LEVEL_LUN 0xF
 
@@ -1410,6 +1461,7 @@ register CDBLIMIT {
        access_mode     RW
        modes           M_CFG
        count           1
+       dont_generate_debug_code
 }
 
 /*
@@ -1422,6 +1474,7 @@ register MAXCMD {
        access_mode     RW
        modes           M_CFG
        count           9
+       dont_generate_debug_code
 }
 
 /*
@@ -1432,6 +1485,7 @@ register MAXCMDCNT {
        address                 0x033
        access_mode     RW
        modes           M_CFG
+       dont_generate_debug_code
 }
 
 /*
@@ -1490,6 +1544,7 @@ register LQCTL1 {
        field   PCI2PCI         0x04
        field   SINGLECMD       0x02
        field   ABORTPENDING    0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -1508,6 +1563,7 @@ register LQCTL2 {
        field   LQOCONTINUE     0x04
        field   LQOTOIDLE       0x02
        field   LQOPAUSE        0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -1578,6 +1634,7 @@ register SXFRCTL0 {
        field   DFPEXP          0x40
        field   BIOSCANCELEN    0x10
        field   SPIOEN          0x08
+       dont_generate_debug_code
 }
 
 /*
@@ -1594,6 +1651,7 @@ register SXFRCTL1 {
        field   ENSTIMER        0x04
        field   ACTNEGEN        0x02
        field   STPWEN          0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -1696,6 +1754,7 @@ register SCSISIGO {
                P_STATUS        CDO|IOO,
                P_MESGIN        CDO|IOO|MSGO
        }
+       dont_generate_debug_code
 }
 
 /*
@@ -1738,6 +1797,7 @@ register MULTARGID {
        modes           M_CFG
        size            2
        count           2
+       dont_generate_debug_code
 }
 
 /*
@@ -1774,6 +1834,7 @@ register SCSIDAT {
        access_mode     RW
        modes           M_DFF0, M_DFF1, M_SCSI
        size            2
+       dont_generate_debug_code
 }
 
 /*
@@ -1796,6 +1857,7 @@ register TARGIDIN {
        count           2
        field   CLKOUT          0x80
        field   TARGID          0x0F
+       dont_generate_debug_code
 }
 
 /*
@@ -1825,6 +1887,7 @@ register SBLKCTL {
        field   ENAB40          0x08    /* LVD transceiver active */
        field   ENAB20          0x04    /* SE/HVD transceiver active */
        field   SELWIDE         0x02
+       dont_generate_debug_code
 }
 
 /*
@@ -1842,6 +1905,7 @@ register OPTIONMODE {
        field   ENDGFORMCHK             0x04
        field   AUTO_MSGOUT_DE          0x02
        mask    OPTIONMODE_DEFAULTS     AUTO_MSGOUT_DE
+       dont_generate_debug_code
 }
 
 /*
@@ -1876,6 +1940,7 @@ register CLRSINT0 {
        field   CLROVERRUN      0x04
        field   CLRSPIORDY      0x02
        field   CLRARBDO        0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -1929,6 +1994,7 @@ register CLRSINT1 {
        field   CLRSCSIPERR     0x04
        field   CLRSTRB2FAST    0x02
        field   CLRREQINIT      0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -1962,6 +2028,7 @@ register CLRSINT2 {
        field   CLRWIDE_RES     0x04    /* Modes 0 and 1 only */
        field   CLRSDONE        0x02    /* Modes 0 and 1 only */
        field   CLRDMADONE      0x01    /* Modes 0 and 1 only */
+       dont_generate_debug_code
 }
 
 /*
@@ -2002,6 +2069,7 @@ register LQISTATE {
        access_mode     RO
        modes           M_CFG
        count           6
+       dont_generate_debug_code
 }
 
 /*
@@ -2022,6 +2090,7 @@ register LQOSTATE {
        access_mode     RO
        modes           M_CFG
        count           2
+       dont_generate_debug_code
 }
 
 /*
@@ -2054,6 +2123,7 @@ register CLRLQIINT0 {
        field   CLRLQIBADLQT    0x04
        field   CLRLQIATNLQ     0x02
        field   CLRLQIATNCMD    0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -2070,6 +2140,7 @@ register LQIMODE0 {
        field   ENLQIBADLQT     0x04
        field   ENLQIATNLQ      0x02
        field   ENLQIATNCMD     0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -2106,6 +2177,7 @@ register CLRLQIINT1 {
        field   CLRLQIBADLQI    0x04
        field   CLRLQIOVERI_LQ  0x02
        field   CLRLQIOVERI_NLQ 0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -2124,6 +2196,7 @@ register LQIMODE1 {
        field   ENLQIBADLQI     0x04
        field   ENLQIOVERI_LQ   0x02    /* LQIOVERI1 */
        field   ENLQIOVERI_NLQ  0x01    /* LQIOVERI2 */
+       dont_generate_debug_code
 }
 
 /*
@@ -2165,6 +2238,7 @@ register CLRSINT3 {
        count           3
        field   CLRNTRAMPERR    0x02
        field   CLROSRAMPERR    0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -2177,6 +2251,7 @@ register SIMODE3 {
        count           4
        field   ENNTRAMPERR     0x02
        field   ENOSRAMPERR     0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -2207,6 +2282,7 @@ register CLRLQOINT0 {
        field   CLRLQOATNLQ             0x04
        field   CLRLQOATNPKT            0x02
        field   CLRLQOTCRC              0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -2222,6 +2298,7 @@ register LQOMODE0 {
        field   ENLQOATNLQ              0x04
        field   ENLQOATNPKT             0x02
        field   ENLQOTCRC               0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -2251,6 +2328,7 @@ register CLRLQOINT1 {
        field   CLRLQOBADQAS            0x04
        field   CLRLQOBUSFREE           0x02
        field   CLRLQOPHACHGINPKT       0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -2266,6 +2344,7 @@ register LQOMODE1 {
        field   ENLQOBADQAS             0x04
        field   ENLQOBUSFREE            0x02
        field   ENLQOPHACHGINPKT        0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -2289,6 +2368,7 @@ register OS_SPACE_CNT {
        access_mode     RO
        modes           M_CFG
        count           2
+       dont_generate_debug_code
 }
 
 /*
@@ -2318,6 +2398,7 @@ register GSFIFO {
        access_mode     RO
        size            2
        modes           M_DFF0, M_DFF1, M_SCSI
+       dont_generate_debug_code
 }
 
 /*
@@ -2341,6 +2422,7 @@ register NEXTSCB {
        access_mode     RW
        size            2
        modes           M_SCSI
+       dont_generate_debug_code
 }
 
 /*
@@ -2357,6 +2439,7 @@ register LQOSCSCTL {
        field           LQOBUSETDLY     0x40
        field           LQONOHOLDLACK   0x02
        field           LQONOCHKOVER    0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -2389,6 +2472,7 @@ register CLRSEQINTSRC {
        field   CLRCFG4TSTAT    0x04
        field   CLRCFG4ICMD     0x02
        field   CLRCFG4TCMD     0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -2415,6 +2499,7 @@ register CURRSCB {
        access_mode     RW
        size            2
        modes           M_SCSI
+       dont_generate_debug_code
 }
 
 /*
@@ -2472,6 +2557,7 @@ register LASTSCB {
        access_mode     RW
        size            2
        modes           M_SCSI
+       dont_generate_debug_code
 }
 
 /*
@@ -2494,6 +2580,7 @@ register SHADDR {
        access_mode     RO
        size            8
        modes           M_DFF0, M_DFF1
+       dont_generate_debug_code
 }
 
 /*
@@ -2513,6 +2600,7 @@ register NEGOADDR {
        address                 0x060
        access_mode     RW
        modes           M_SCSI
+       dont_generate_debug_code
 }
 
 /*
@@ -2523,6 +2611,7 @@ register NEGPERIOD {
        access_mode     RW
        modes           M_SCSI
        count           1
+       dont_generate_debug_code
 }
 
 /*
@@ -2543,6 +2632,7 @@ register NEGOFFSET {
        access_mode     RW
        modes           M_SCSI
        count           1
+       dont_generate_debug_code
 }
 
 /*
@@ -2557,6 +2647,7 @@ register NEGPPROPTS {
        field   PPROPT_QAS      0x04
        field   PPROPT_DT       0x02
        field   PPROPT_IUT      0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -2573,6 +2664,7 @@ register NEGCONOPTS {
        field   ENAUTOATNI      0x04
        field   ENAUTOATNO      0x02
        field   WIDEXFER        0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -2583,6 +2675,7 @@ register ANNEXCOL {
        access_mode     RW
        modes           M_SCSI
        count           7
+       dont_generate_debug_code
 }
 
 /*
@@ -2602,6 +2695,7 @@ register SCSCHKN {
        field   DFFACTCLR       0x04
        field   SHVALIDSTDIS    0x02
        field   LSTSGCLRDIS     0x01
+       dont_generate_debug_code
 }
 
 const AHD_ANNEXCOL_PER_DEV0    4
@@ -2635,6 +2729,7 @@ register ANNEXDAT {
        access_mode     RW
        modes           M_SCSI
        count           3
+       dont_generate_debug_code
 }
 
 /*
@@ -2645,6 +2740,7 @@ register IOWNID {
        address                 0x067
        access_mode     RW
        modes           M_SCSI
+       dont_generate_debug_code
 }
 
 /*
@@ -2671,6 +2767,7 @@ register TOWNID {
        access_mode     RW
        modes           M_SCSI
        count           2
+       dont_generate_debug_code
 }
 
 /*
@@ -2702,6 +2799,7 @@ register SHCNT {
        access_mode     RW
        size            3
        modes           M_DFF0, M_DFF1
+       dont_generate_debug_code
 }
 
 /*
@@ -2789,6 +2887,7 @@ register SCBPTR {
        access_mode     RW
        size            2
        modes           M_DFF0, M_DFF1, M_CCHAN, M_SCSI
+       dont_generate_debug_code
 }
 
 /*
@@ -2816,6 +2915,7 @@ register SCBAUTOPTR {
        field   AUSCBPTR_EN     0x80
        field   SCBPTR_ADDR     0x38
        field   SCBPTR_OFF      0x07
+       dont_generate_debug_code
 }
 
 /*
@@ -2825,6 +2925,7 @@ register CCSGADDR {
        address                 0x0AC
        access_mode     RW
        modes           M_DFF0, M_DFF1
+       dont_generate_debug_code
 }
 
 /*
@@ -2834,6 +2935,7 @@ register CCSCBADDR {
        address                 0x0AC
        access_mode     RW
        modes           M_CCHAN
+       dont_generate_debug_code
 }
 
 /*
@@ -2899,6 +3001,7 @@ register CCSGRAM {
        address                 0x0B0
        access_mode     RW
        modes           M_DFF0, M_DFF1
+       dont_generate_debug_code
 }
 
 /*
@@ -2908,6 +3011,7 @@ register CCSCBRAM {
        address                 0x0B0
        access_mode     RW
        modes           M_CCHAN
+       dont_generate_debug_code
 }
 
 /*
@@ -2958,6 +3062,7 @@ register BRDDAT {
        access_mode     RW
        modes           M_SCSI
        count           2
+       dont_generate_debug_code
 }
 
 /*
@@ -2974,6 +3079,7 @@ register BRDCTL {
        field   BRDEN           0x04
        field   BRDRW           0x02
        field   BRDSTB          0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -2984,6 +3090,7 @@ register SEEADR {
        access_mode     RW
        modes           M_SCSI
        count           4
+       dont_generate_debug_code
 }
 
 /*
@@ -2995,6 +3102,7 @@ register SEEDAT {
        size            2
        modes           M_SCSI
        count           4
+       dont_generate_debug_code
 }
 
 /*
@@ -3011,6 +3119,7 @@ register SEESTAT {
        field   SEEARBACK       0x04
        field   SEEBUSY         0x02
        field   SEESTART        0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -3036,6 +3145,7 @@ register SEECTL {
        mask    SEEOP_EWDS      0x40
        field   SEERST          0x02
        field   SEESTART        0x01
+       dont_generate_debug_code
 }
 
 const SEEOP_ERAL_ADDR  0x80
@@ -3050,6 +3160,7 @@ register SCBCNT {
        address                 0x0BF
        access_mode     RW
        modes           M_SCSI
+       dont_generate_debug_code
 }
 
 /*
@@ -3061,6 +3172,7 @@ register DFWADDR {
        access_mode     RW
        size            2
        modes           M_DFF0, M_DFF1
+       dont_generate_debug_code
 }
 
 /*
@@ -3087,6 +3199,7 @@ register DSPDATACTL {
        field   DESQDIS         0x10
        field   RCVROFFSTDIS    0x04
        field   XMITOFFSTDIS    0x02
+       dont_generate_debug_code
 }
 
 /*
@@ -3132,6 +3245,7 @@ register DFDAT {
        address                 0x0C4
        access_mode     RW
        modes           M_DFF0, M_DFF1
+       dont_generate_debug_code
 }
 
 /*
@@ -3144,6 +3258,7 @@ register DSPSELECT {
        count           1
        field   AUTOINCEN       0x80
        field   DSPSEL          0x1F
+       dont_generate_debug_code
 }
 
 const NUMDSPS 0x14
@@ -3158,6 +3273,7 @@ register WRTBIASCTL {
        count           3
        field   AUTOXBCDIS      0x80
        field   XMITMANVAL      0x3F
+       dont_generate_debug_code
 }
 
 /*
@@ -3316,6 +3432,7 @@ register FLAGS {
        count           23
        field   ZERO            0x02
        field   CARRY           0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -3344,6 +3461,7 @@ register SEQRAM {
        address                 0x0DA
        access_mode     RW
        count           2
+       dont_generate_debug_code
 }
 
 /*
@@ -3355,6 +3473,7 @@ register PRGMCNT {
        access_mode     RW
        size            2
        count           5
+       dont_generate_debug_code
 }
 
 /*
@@ -3364,6 +3483,7 @@ register ACCUM {
        address                 0x0E0
        access_mode     RW
        accumulator
+       dont_generate_debug_code
 }
 
 /*
@@ -3380,6 +3500,7 @@ register SINDEX   {
        access_mode     RW
        size            2
        sindex
+       dont_generate_debug_code
 }
 
 /*
@@ -3390,6 +3511,7 @@ register DINDEX {
        address                 0x0E4
        access_mode     RW
        size            2
+       dont_generate_debug_code
 }
 
 /*
@@ -3415,6 +3537,7 @@ register ALLONES {
        address                 0x0E8
        access_mode RO
        allones
+       dont_generate_debug_code
 }
 
 /*
@@ -3425,6 +3548,7 @@ register ALLZEROS {
        address                 0x0EA
        access_mode RO
        allzeros
+       dont_generate_debug_code
 }
 
 /*
@@ -3435,6 +3559,7 @@ register NONE {
        address                 0x0EA
        access_mode WO
        none
+       dont_generate_debug_code
 }
 
 /*
@@ -3445,6 +3570,7 @@ register NONE {
 register SINDIR        {
        address                 0x0EC
        access_mode RO
+       dont_generate_debug_code
 }
 
 /*
@@ -3455,6 +3581,7 @@ register SINDIR   {
 register DINDIR         {
        address                 0x0ED
        access_mode WO
+       dont_generate_debug_code
 }
 
 /*
@@ -3479,6 +3606,7 @@ register FUNCTION1 {
 register STACK {
        address                 0x0F2
        access_mode RW
+       dont_generate_debug_code
 }
 
 /*
@@ -3491,6 +3619,7 @@ register INTVEC1_ADDR {
        size            2
        modes           M_CFG
        count           1
+       dont_generate_debug_code
 }
 
 /*
@@ -3503,6 +3632,7 @@ register CURADDR {
        size            2
        modes           M_SCSI
        count           2
+       dont_generate_debug_code
 }
 
 /*
@@ -3515,6 +3645,7 @@ register INTVEC2_ADDR {
        size            2
        modes           M_CFG
        count           1
+       dont_generate_debug_code
 }
 
 /*
@@ -3543,12 +3674,14 @@ scratch_ram {
        modes   0, 1, 2, 3
        REG0 {
                size            2
+               dont_generate_debug_code
        }
        REG1 {
                size            2
        }
        REG_ISR {
                size            2
+               dont_generate_debug_code
        }
        SG_STATE {
                size            1
@@ -3572,9 +3705,11 @@ scratch_ram {
        modes   0, 1, 2, 3
        LONGJMP_ADDR {
                size            2
+               dont_generate_debug_code
        }
        ACCUM_SAVE {
                size            1
+               dont_generate_debug_code
        }
 }
 
@@ -3591,18 +3726,22 @@ scratch_ram {
         */
        WAITING_SCB_TAILS {
                size            32
+               dont_generate_debug_code
        }
        WAITING_TID_HEAD {
                size            2
+               dont_generate_debug_code
        }
        WAITING_TID_TAIL {
                size            2
+               dont_generate_debug_code
        }
        /*
         * SCBID of the next SCB in the new SCB queue.
         */
        NEXT_QUEUED_SCB_ADDR {
                size            4
+               dont_generate_debug_code
        }
        /*
         * head of list of SCBs that have
@@ -3611,6 +3750,7 @@ scratch_ram {
         */
        COMPLETE_SCB_HEAD {
                size            2
+               dont_generate_debug_code
        }
        /*
         * The list of completed SCBs in
@@ -3618,6 +3758,7 @@ scratch_ram {
         */
        COMPLETE_SCB_DMAINPROG_HEAD {
                size            2
+               dont_generate_debug_code
        }
        /*
         * head of list of SCBs that have
@@ -3626,6 +3767,7 @@ scratch_ram {
         */
        COMPLETE_DMA_SCB_HEAD {
                size            2
+               dont_generate_debug_code
        }
        /*
         * tail of list of SCBs that have
@@ -3634,6 +3776,7 @@ scratch_ram {
         */
        COMPLETE_DMA_SCB_TAIL {
                size            2
+               dont_generate_debug_code
        }
        /*
         * head of list of SCBs that have
@@ -3643,6 +3786,7 @@ scratch_ram {
         */
        COMPLETE_ON_QFREEZE_HEAD {
                size            2
+               dont_generate_debug_code
        }
        /*
         * Counting semaphore to prevent new select-outs
@@ -3667,6 +3811,7 @@ scratch_ram {
         */
        MSG_OUT {
                size            1
+               dont_generate_debug_code
        }
        /* Parameters for DMA Logic */
        DMAPARAMS {
@@ -3682,6 +3827,7 @@ scratch_ram {
                field   DIRECTION       0x04    /* Set indicates PCI->SCSI */
                field   FIFOFLUSH       0x02
                field   FIFORESET       0x01
+               dont_generate_debug_code
        }
        SEQ_FLAGS {
                size            1
@@ -3703,9 +3849,11 @@ scratch_ram {
         */
        SAVED_SCSIID {
                size            1
+               dont_generate_debug_code
        }
        SAVED_LUN {
                size            1
+               dont_generate_debug_code
        }
        /*
         * The last bus phase as seen by the sequencer. 
@@ -3733,6 +3881,7 @@ scratch_ram {
         */
        QOUTFIFO_ENTRY_VALID_TAG {
                size            1
+               dont_generate_debug_code
        }
        /*
         * Kernel and sequencer offsets into the queue of
@@ -3742,10 +3891,12 @@ scratch_ram {
        KERNEL_TQINPOS {
                size            1
                count           1
+               dont_generate_debug_code
        }
        TQINPOS {
                size            1
                count           8
+               dont_generate_debug_code
        }
        /*
         * Base address of our shared data with the kernel driver in host
@@ -3754,6 +3905,7 @@ scratch_ram {
         */
        SHARED_DATA_ADDR {
                size            4
+               dont_generate_debug_code
        }
        /*
         * Pointer to location in host memory for next
@@ -3761,6 +3913,7 @@ scratch_ram {
         */
        QOUTFIFO_NEXT_ADDR {
                size            4
+               dont_generate_debug_code
        }
        ARG_1 {
                size            1
@@ -3773,11 +3926,13 @@ scratch_ram {
                mask    CONT_MSG_LOOP_READ      0x03
                mask    CONT_MSG_LOOP_TARG      0x02
                alias   RETURN_1
+               dont_generate_debug_code
        }
        ARG_2 {
                size            1
                count           1
                alias   RETURN_2
+               dont_generate_debug_code
        }
 
        /*
@@ -3785,6 +3940,7 @@ scratch_ram {
         */
        LAST_MSG {
                size            1
+               dont_generate_debug_code
        }
 
        /*
@@ -3801,6 +3957,7 @@ scratch_ram {
                field   MANUALP         0x0C
                field   ENAUTOATNP      0x02
                field   ALTSTIM         0x01
+               dont_generate_debug_code
        }
 
        /*
@@ -3809,6 +3966,7 @@ scratch_ram {
        INITIATOR_TAG {
                size            1
                count           1
+               dont_generate_debug_code
        }
 
        SEQ_FLAGS2 {
@@ -3820,6 +3978,7 @@ scratch_ram {
 
        ALLOCFIFO_SCBPTR {
                size            2
+               dont_generate_debug_code
        }
 
        /*
@@ -3829,6 +3988,7 @@ scratch_ram {
         */
        INT_COALESCING_TIMER {
                size            2
+               dont_generate_debug_code
        }
 
        /*
@@ -3838,6 +3998,7 @@ scratch_ram {
         */
        INT_COALESCING_MAXCMDS {
                size            1
+               dont_generate_debug_code
        }
 
        /*
@@ -3846,6 +4007,7 @@ scratch_ram {
         */
        INT_COALESCING_MINCMDS {
                size            1
+               dont_generate_debug_code
        }
 
        /*
@@ -3853,6 +4015,7 @@ scratch_ram {
         */
        CMDS_PENDING {
                size            2
+               dont_generate_debug_code
        }
 
        /*
@@ -3860,6 +4023,7 @@ scratch_ram {
         */
        INT_COALESCING_CMDCOUNT {
                size            1
+               dont_generate_debug_code
        }
 
        /*
@@ -3868,6 +4032,7 @@ scratch_ram {
         */
        LOCAL_HS_MAILBOX {
                size            1
+               dont_generate_debug_code
        }
        /*
         * Target-mode CDB type to CDB length table used
@@ -3876,6 +4041,7 @@ scratch_ram {
        CMDSIZE_TABLE {
                size            8
                count           8
+               dont_generate_debug_code
        }
        /*
         * When an SCB with the MK_MESSAGE flag is
@@ -3908,25 +4074,31 @@ scb {
                size    4
                alias   SCB_CDB_STORE
                alias   SCB_HOST_CDB_PTR
+               dont_generate_debug_code
        }
        SCB_RESIDUAL_SGPTR {
                size    4
                field   SG_ADDR_MASK            0xf8    /* In the last byte */
                field   SG_OVERRUN_RESID        0x02    /* In the first byte */
                field   SG_LIST_NULL            0x01    /* In the first byte */
+               dont_generate_debug_code
        }
        SCB_SCSI_STATUS {
                size    1
                alias   SCB_HOST_CDB_LEN
+               dont_generate_debug_code
        }
        SCB_TARGET_PHASES {
                size    1
+               dont_generate_debug_code
        }
        SCB_TARGET_DATA_DIR {
                size    1
+               dont_generate_debug_code
        }
        SCB_TARGET_ITAG {
                size    1
+               dont_generate_debug_code
        }
        SCB_SENSE_BUSADDR {
                /*
@@ -3936,10 +4108,12 @@ scb {
                 */
                size    4
                alias   SCB_NEXT_COMPLETE
+               dont_generate_debug_code
        }
        SCB_TAG {
                alias   SCB_FIFO_USE_COUNT
                size    2
+               dont_generate_debug_code
        }
        SCB_CONTROL {
                size    1
@@ -3959,6 +4133,7 @@ scb {
        SCB_LUN {
                size    1
                field   LID     0xff
+               dont_generate_debug_code
        }
        SCB_TASK_ATTRIBUTE {
                size    1
@@ -3967,16 +4142,20 @@ scb {
                 * ignore wide residue message handling.
                 */
                field   SCB_XFERLEN_ODD 0x01
+               dont_generate_debug_code
        }
        SCB_CDB_LEN {
                size    1
                field   SCB_CDB_LEN_PTR 0x80    /* CDB in host memory */
+               dont_generate_debug_code
        }
        SCB_TASK_MANAGEMENT {
                size    1
+               dont_generate_debug_code
        }
        SCB_DATAPTR {
                size    8
+               dont_generate_debug_code
        }
        SCB_DATACNT {
                /*
@@ -3986,22 +4165,27 @@ scb {
                size    4
                field   SG_LAST_SEG             0x80    /* In the fourth byte */
                field   SG_HIGH_ADDR_BITS       0x7F    /* In the fourth byte */
+               dont_generate_debug_code
        }
        SCB_SGPTR {
                size    4
                field   SG_STATUS_VALID 0x04    /* In the first byte */
                field   SG_FULL_RESID   0x02    /* In the first byte */
                field   SG_LIST_NULL    0x01    /* In the first byte */
+               dont_generate_debug_code
        }
        SCB_BUSADDR {
                size    4
+               dont_generate_debug_code
        }
        SCB_NEXT {
                alias   SCB_NEXT_SCB_BUSADDR
                size    2
+               dont_generate_debug_code
        }
        SCB_NEXT2 {
                size    2
+               dont_generate_debug_code
        }
        SCB_SPARE {
                size    8
@@ -4009,6 +4193,7 @@ scb {
        }
        SCB_DISCONNECTED_LISTS {
                size    8
+               dont_generate_debug_code
        }
 }
 
index 55508b0fcec4020df71de8236e854f712a952393..bdad54ec088cc8d0dd6970c7f1cd9618859c6f6a 100644 (file)
@@ -2472,8 +2472,6 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
                if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0)
                        ahd_outb(ahd, CLRLQOINT1, 0);
        } else if ((status & SELTO) != 0) {
-               u_int  scbid;
-
                /* Stop the selection */
                ahd_outb(ahd, SCSISEQ0, 0);
 
@@ -2583,9 +2581,6 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
                case BUSFREE_DFF0:
                case BUSFREE_DFF1:
                {
-                       u_int   scbid;
-                       struct  scb *scb;
-
                        mode = busfreetime == BUSFREE_DFF0
                             ? AHD_MODE_DFF0 : AHD_MODE_DFF1;
                        ahd_set_modes(ahd, mode, mode);
@@ -3689,7 +3684,7 @@ ahd_free_tstate(struct ahd_softc *ahd, u_int scsi_id, char channel, int force)
  * by the capabilities of the bus connectivity of and sync settings for
  * the target.
  */
-void
+static void
 ahd_devlimited_syncrate(struct ahd_softc *ahd,
                        struct ahd_initiator_tinfo *tinfo,
                        u_int *period, u_int *ppr_options, role_t role)
@@ -4136,7 +4131,7 @@ ahd_update_neg_table(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
 
                        /*
                         * Harpoon2A assumed that there would be a
-                        * fallback rate between 160MHz and 80Mhz,
+                        * fallback rate between 160MHz and 80MHz,
                         * so 7 is used as the period factor rather
                         * than 8 for 160MHz.
                         */
@@ -8708,7 +8703,7 @@ ahd_reset_current_bus(struct ahd_softc *ahd)
 int
 ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset)
 {
-       struct  ahd_devinfo devinfo;
+       struct  ahd_devinfo caminfo;
        u_int   initiator;
        u_int   target;
        u_int   max_scsiid;
@@ -8729,7 +8724,7 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset)
 
        ahd->pending_device = NULL;
 
-       ahd_compile_devinfo(&devinfo,
+       ahd_compile_devinfo(&caminfo,
                            CAM_TARGET_WILDCARD,
                            CAM_TARGET_WILDCARD,
                            CAM_LUN_WILDCARD,
@@ -8868,7 +8863,7 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset)
        }
 
        /* Notify the XPT that a bus reset occurred */
-       ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD,
+       ahd_send_async(ahd, caminfo.channel, CAM_TARGET_WILDCARD,
                       CAM_LUN_WILDCARD, AC_BUS_RESET);
 
        ahd_restart(ahd);
index c25b6adffbf94f50fd5684063e7add6b04984895..a734d77e880efb2430795442d2e3e4c719259946 100644 (file)
@@ -223,10 +223,10 @@ static const char *pci_bus_modes[] =
        "PCI bus mode unknown",
        "PCI bus mode unknown",
        "PCI bus mode unknown",
-       "PCI-X 101-133Mhz",
-       "PCI-X 67-100Mhz",
-       "PCI-X 50-66Mhz",
-       "PCI 33 or 66Mhz"
+       "PCI-X 101-133MHz",
+       "PCI-X 67-100MHz",
+       "PCI-X 50-66MHz",
+       "PCI 33 or 66MHz"
 };
 
 #define                TESTMODE        0x00000800ul
@@ -337,8 +337,6 @@ ahd_pci_config(struct ahd_softc *ahd, const struct ahd_pci_identity *entry)
         * 64bit bus (PCI64BIT set in devconfig).
         */
        if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) {
-               uint32_t devconfig;
-
                if (bootverbose)
                        printf("%s: Enabling 39Bit Addressing\n",
                               ahd_name(ahd));
@@ -483,8 +481,6 @@ ahd_pci_test_register_access(struct ahd_softc *ahd)
                goto fail;
 
        if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
-               u_int targpcistat;
-
                ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
                targpcistat = ahd_inb(ahd, TARGPCISTAT);
                if ((targpcistat & STA) != 0)
index c21ceab8e9134f699af09203b6dada11acd1d132..cdcead071ef6449c337b99d1696910c319cd9b70 100644 (file)
@@ -33,13 +33,6 @@ ahd_reg_print_t ahd_seqintcode_print;
     ahd_print_register(NULL, 0, "SEQINTCODE", 0x02, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_clrint_print;
-#else
-#define ahd_clrint_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "CLRINT", 0x03, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_error_print;
 #else
@@ -47,20 +40,6 @@ ahd_reg_print_t ahd_error_print;
     ahd_print_register(NULL, 0, "ERROR", 0x04, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_hcntrl_print;
-#else
-#define ahd_hcntrl_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "HCNTRL", 0x05, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_hnscb_qoff_print;
-#else
-#define ahd_hnscb_qoff_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "HNSCB_QOFF", 0x06, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_hescb_qoff_print;
 #else
@@ -96,13 +75,6 @@ ahd_reg_print_t ahd_swtimer_print;
     ahd_print_register(NULL, 0, "SWTIMER", 0x0e, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_snscb_qoff_print;
-#else
-#define ahd_snscb_qoff_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SNSCB_QOFF", 0x10, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_sescb_qoff_print;
 #else
@@ -110,20 +82,6 @@ ahd_reg_print_t ahd_sescb_qoff_print;
     ahd_print_register(NULL, 0, "SESCB_QOFF", 0x12, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_sdscb_qoff_print;
-#else
-#define ahd_sdscb_qoff_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SDSCB_QOFF", 0x14, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_qoff_ctlsta_print;
-#else
-#define ahd_qoff_ctlsta_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "QOFF_CTLSTA", 0x16, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_intctl_print;
 #else
@@ -138,13 +96,6 @@ ahd_reg_print_t ahd_dfcntrl_print;
     ahd_print_register(NULL, 0, "DFCNTRL", 0x19, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_dscommand0_print;
-#else
-#define ahd_dscommand0_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "DSCOMMAND0", 0x19, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_dfstatus_print;
 #else
@@ -159,13 +110,6 @@ ahd_reg_print_t ahd_sg_cache_shadow_print;
     ahd_print_register(NULL, 0, "SG_CACHE_SHADOW", 0x1b, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_sg_cache_pre_print;
-#else
-#define ahd_sg_cache_pre_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SG_CACHE_PRE", 0x1b, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_lqin_print;
 #else
@@ -292,13 +236,6 @@ ahd_reg_print_t ahd_sxfrctl0_print;
     ahd_print_register(NULL, 0, "SXFRCTL0", 0x3c, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_sxfrctl1_print;
-#else
-#define ahd_sxfrctl1_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SXFRCTL1", 0x3d, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_dffstat_print;
 #else
@@ -313,13 +250,6 @@ ahd_reg_print_t ahd_multargid_print;
     ahd_print_register(NULL, 0, "MULTARGID", 0x40, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_scsisigo_print;
-#else
-#define ahd_scsisigo_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SCSISIGO", 0x40, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_scsisigi_print;
 #else
@@ -362,13 +292,6 @@ ahd_reg_print_t ahd_selid_print;
     ahd_print_register(NULL, 0, "SELID", 0x49, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_optionmode_print;
-#else
-#define ahd_optionmode_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "OPTIONMODE", 0x4a, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_sblkctl_print;
 #else
@@ -390,13 +313,6 @@ ahd_reg_print_t ahd_simode0_print;
     ahd_print_register(NULL, 0, "SIMODE0", 0x4b, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_clrsint0_print;
-#else
-#define ahd_clrsint0_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "CLRSINT0", 0x4b, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_sstat1_print;
 #else
@@ -404,13 +320,6 @@ ahd_reg_print_t ahd_sstat1_print;
     ahd_print_register(NULL, 0, "SSTAT1", 0x4c, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_clrsint1_print;
-#else
-#define ahd_clrsint1_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "CLRSINT1", 0x4c, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_sstat2_print;
 #else
@@ -461,17 +370,17 @@ ahd_reg_print_t ahd_lqistat0_print;
 #endif
 
 #if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_lqimode0_print;
+ahd_reg_print_t ahd_clrlqiint0_print;
 #else
-#define ahd_lqimode0_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "LQIMODE0", 0x50, regvalue, cur_col, wrap)
+#define ahd_clrlqiint0_print(regvalue, cur_col, wrap) \
+    ahd_print_register(NULL, 0, "CLRLQIINT0", 0x50, regvalue, cur_col, wrap)
 #endif
 
 #if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_clrlqiint0_print;
+ahd_reg_print_t ahd_lqimode0_print;
 #else
-#define ahd_clrlqiint0_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "CLRLQIINT0", 0x50, regvalue, cur_col, wrap)
+#define ahd_lqimode0_print(regvalue, cur_col, wrap) \
+    ahd_print_register(NULL, 0, "LQIMODE0", 0x50, regvalue, cur_col, wrap)
 #endif
 
 #if AIC_DEBUG_REGISTERS
@@ -629,17 +538,17 @@ ahd_reg_print_t ahd_seqintsrc_print;
 #endif
 
 #if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_seqimode_print;
+ahd_reg_print_t ahd_currscb_print;
 #else
-#define ahd_seqimode_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SEQIMODE", 0x5c, regvalue, cur_col, wrap)
+#define ahd_currscb_print(regvalue, cur_col, wrap) \
+    ahd_print_register(NULL, 0, "CURRSCB", 0x5c, regvalue, cur_col, wrap)
 #endif
 
 #if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_currscb_print;
+ahd_reg_print_t ahd_seqimode_print;
 #else
-#define ahd_currscb_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "CURRSCB", 0x5c, regvalue, cur_col, wrap)
+#define ahd_seqimode_print(regvalue, cur_col, wrap) \
+    ahd_print_register(NULL, 0, "SEQIMODE", 0x5c, regvalue, cur_col, wrap)
 #endif
 
 #if AIC_DEBUG_REGISTERS
@@ -656,13 +565,6 @@ ahd_reg_print_t ahd_lastscb_print;
     ahd_print_register(NULL, 0, "LASTSCB", 0x5e, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_shaddr_print;
-#else
-#define ahd_shaddr_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SHADDR", 0x60, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_negoaddr_print;
 #else
@@ -747,27 +649,6 @@ ahd_reg_print_t ahd_seloid_print;
     ahd_print_register(NULL, 0, "SELOID", 0x6b, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_haddr_print;
-#else
-#define ahd_haddr_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "HADDR", 0x70, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_hcnt_print;
-#else
-#define ahd_hcnt_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "HCNT", 0x78, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_sghaddr_print;
-#else
-#define ahd_sghaddr_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SGHADDR", 0x7c, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_scbhaddr_print;
 #else
@@ -776,10 +657,10 @@ ahd_reg_print_t ahd_scbhaddr_print;
 #endif
 
 #if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_sghcnt_print;
+ahd_reg_print_t ahd_sghaddr_print;
 #else
-#define ahd_sghcnt_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SGHCNT", 0x84, regvalue, cur_col, wrap)
+#define ahd_sghaddr_print(regvalue, cur_col, wrap) \
+    ahd_print_register(NULL, 0, "SGHADDR", 0x7c, regvalue, cur_col, wrap)
 #endif
 
 #if AIC_DEBUG_REGISTERS
@@ -790,10 +671,10 @@ ahd_reg_print_t ahd_scbhcnt_print;
 #endif
 
 #if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_dff_thrsh_print;
+ahd_reg_print_t ahd_sghcnt_print;
 #else
-#define ahd_dff_thrsh_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "DFF_THRSH", 0x88, regvalue, cur_col, wrap)
+#define ahd_sghcnt_print(regvalue, cur_col, wrap) \
+    ahd_print_register(NULL, 0, "SGHCNT", 0x84, regvalue, cur_col, wrap)
 #endif
 
 #if AIC_DEBUG_REGISTERS
@@ -866,13 +747,6 @@ ahd_reg_print_t ahd_targpcistat_print;
     ahd_print_register(NULL, 0, "TARGPCISTAT", 0xa7, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_scbptr_print;
-#else
-#define ahd_scbptr_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SCBPTR", 0xa8, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_scbautoptr_print;
 #else
@@ -880,13 +754,6 @@ ahd_reg_print_t ahd_scbautoptr_print;
     ahd_print_register(NULL, 0, "SCBAUTOPTR", 0xab, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_ccsgaddr_print;
-#else
-#define ahd_ccsgaddr_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "CCSGADDR", 0xac, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_ccscbaddr_print;
 #else
@@ -908,13 +775,6 @@ ahd_reg_print_t ahd_ccsgctl_print;
     ahd_print_register(NULL, 0, "CCSGCTL", 0xad, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_ccsgram_print;
-#else
-#define ahd_ccsgram_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "CCSGRAM", 0xb0, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_ccscbram_print;
 #else
@@ -929,13 +789,6 @@ ahd_reg_print_t ahd_brddat_print;
     ahd_print_register(NULL, 0, "BRDDAT", 0xb8, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_brdctl_print;
-#else
-#define ahd_brdctl_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "BRDCTL", 0xb9, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_seeadr_print;
 #else
@@ -971,13 +824,6 @@ ahd_reg_print_t ahd_dspdatactl_print;
     ahd_print_register(NULL, 0, "DSPDATACTL", 0xc1, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_dfdat_print;
-#else
-#define ahd_dfdat_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "DFDAT", 0xc4, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_dspselect_print;
 #else
@@ -999,13 +845,6 @@ ahd_reg_print_t ahd_seqctl0_print;
     ahd_print_register(NULL, 0, "SEQCTL0", 0xd6, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_flags_print;
-#else
-#define ahd_flags_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "FLAGS", 0xd8, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_seqintctl_print;
 #else
@@ -1013,13 +852,6 @@ ahd_reg_print_t ahd_seqintctl_print;
     ahd_print_register(NULL, 0, "SEQINTCTL", 0xd9, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_seqram_print;
-#else
-#define ahd_seqram_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SEQRAM", 0xda, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_prgmcnt_print;
 #else
@@ -1027,41 +859,6 @@ ahd_reg_print_t ahd_prgmcnt_print;
     ahd_print_register(NULL, 0, "PRGMCNT", 0xde, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_accum_print;
-#else
-#define ahd_accum_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "ACCUM", 0xe0, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_sindex_print;
-#else
-#define ahd_sindex_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SINDEX", 0xe2, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_dindex_print;
-#else
-#define ahd_dindex_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "DINDEX", 0xe4, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_allones_print;
-#else
-#define ahd_allones_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "ALLONES", 0xe8, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_allzeros_print;
-#else
-#define ahd_allzeros_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "ALLZEROS", 0xea, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_none_print;
 #else
@@ -1069,27 +866,6 @@ ahd_reg_print_t ahd_none_print;
     ahd_print_register(NULL, 0, "NONE", 0xea, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_sindir_print;
-#else
-#define ahd_sindir_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SINDIR", 0xec, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_dindir_print;
-#else
-#define ahd_dindir_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "DINDIR", 0xed, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_stack_print;
-#else
-#define ahd_stack_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "STACK", 0xf2, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_intvec1_addr_print;
 #else
@@ -1126,17 +902,17 @@ ahd_reg_print_t ahd_accum_save_print;
 #endif
 
 #if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_sram_base_print;
+ahd_reg_print_t ahd_waiting_scb_tails_print;
 #else
-#define ahd_sram_base_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SRAM_BASE", 0x100, regvalue, cur_col, wrap)
+#define ahd_waiting_scb_tails_print(regvalue, cur_col, wrap) \
+    ahd_print_register(NULL, 0, "WAITING_SCB_TAILS", 0x100, regvalue, cur_col, wrap)
 #endif
 
 #if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_waiting_scb_tails_print;
+ahd_reg_print_t ahd_sram_base_print;
 #else
-#define ahd_waiting_scb_tails_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "WAITING_SCB_TAILS", 0x100, regvalue, cur_col, wrap)
+#define ahd_sram_base_print(regvalue, cur_col, wrap) \
+    ahd_print_register(NULL, 0, "SRAM_BASE", 0x100, regvalue, cur_col, wrap)
 #endif
 
 #if AIC_DEBUG_REGISTERS
@@ -1223,13 +999,6 @@ ahd_reg_print_t ahd_msg_out_print;
     ahd_print_register(NULL, 0, "MSG_OUT", 0x137, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_dmaparams_print;
-#else
-#define ahd_dmaparams_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "DMAPARAMS", 0x138, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_seq_flags_print;
 #else
@@ -1237,20 +1006,6 @@ ahd_reg_print_t ahd_seq_flags_print;
     ahd_print_register(NULL, 0, "SEQ_FLAGS", 0x139, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_saved_scsiid_print;
-#else
-#define ahd_saved_scsiid_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SAVED_SCSIID", 0x13a, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_saved_lun_print;
-#else
-#define ahd_saved_lun_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SAVED_LUN", 0x13b, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_lastphase_print;
 #else
@@ -1272,20 +1027,6 @@ ahd_reg_print_t ahd_kernel_tqinpos_print;
     ahd_print_register(NULL, 0, "KERNEL_TQINPOS", 0x13e, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_tqinpos_print;
-#else
-#define ahd_tqinpos_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "TQINPOS", 0x13f, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_shared_data_addr_print;
-#else
-#define ahd_shared_data_addr_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SHARED_DATA_ADDR", 0x140, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_qoutfifo_next_addr_print;
 #else
@@ -1293,20 +1034,6 @@ ahd_reg_print_t ahd_qoutfifo_next_addr_print;
     ahd_print_register(NULL, 0, "QOUTFIFO_NEXT_ADDR", 0x144, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_arg_1_print;
-#else
-#define ahd_arg_1_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "ARG_1", 0x148, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_arg_2_print;
-#else
-#define ahd_arg_2_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "ARG_2", 0x149, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_last_msg_print;
 #else
@@ -1405,13 +1132,6 @@ ahd_reg_print_t ahd_mk_message_scsiid_print;
     ahd_print_register(NULL, 0, "MK_MESSAGE_SCSIID", 0x162, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_scb_residual_datacnt_print;
-#else
-#define ahd_scb_residual_datacnt_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SCB_RESIDUAL_DATACNT", 0x180, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_scb_base_print;
 #else
@@ -1420,17 +1140,10 @@ ahd_reg_print_t ahd_scb_base_print;
 #endif
 
 #if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_scb_residual_sgptr_print;
-#else
-#define ahd_scb_residual_sgptr_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SCB_RESIDUAL_SGPTR", 0x184, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_scb_scsi_status_print;
+ahd_reg_print_t ahd_scb_residual_datacnt_print;
 #else
-#define ahd_scb_scsi_status_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SCB_SCSI_STATUS", 0x188, regvalue, cur_col, wrap)
+#define ahd_scb_residual_datacnt_print(regvalue, cur_col, wrap) \
+    ahd_print_register(NULL, 0, "SCB_RESIDUAL_DATACNT", 0x180, regvalue, cur_col, wrap)
 #endif
 
 #if AIC_DEBUG_REGISTERS
@@ -1475,13 +1188,6 @@ ahd_reg_print_t ahd_scb_task_attribute_print;
     ahd_print_register(NULL, 0, "SCB_TASK_ATTRIBUTE", 0x195, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_scb_cdb_len_print;
-#else
-#define ahd_scb_cdb_len_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SCB_CDB_LEN", 0x196, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_scb_task_management_print;
 #else
@@ -1517,13 +1223,6 @@ ahd_reg_print_t ahd_scb_busaddr_print;
     ahd_print_register(NULL, 0, "SCB_BUSADDR", 0x1a8, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_scb_next_print;
-#else
-#define ahd_scb_next_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "SCB_NEXT", 0x1ac, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_scb_next2_print;
 #else
@@ -1717,10 +1416,10 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 
 #define        SG_CACHE_PRE                    0x1b
 
-#define        TYPEPTR                         0x20
-
 #define        LQIN                            0x20
 
+#define        TYPEPTR                         0x20
+
 #define        TAGPTR                          0x21
 
 #define        LUNPTR                          0x22
@@ -1780,6 +1479,14 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define                SINGLECMD               0x02
 #define                ABORTPENDING            0x01
 
+#define        SCSBIST0                        0x39
+#define                GSBISTERR               0x40
+#define                GSBISTDONE              0x20
+#define                GSBISTRUN               0x10
+#define                OSBISTERR               0x04
+#define                OSBISTDONE              0x02
+#define                OSBISTRUN               0x01
+
 #define        LQCTL2                          0x39
 #define                LQIRETRY                0x80
 #define                LQICONTINUE             0x40
@@ -1790,13 +1497,10 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define                LQOTOIDLE               0x02
 #define                LQOPAUSE                0x01
 
-#define        SCSBIST0                        0x39
-#define                GSBISTERR               0x40
-#define                GSBISTDONE              0x20
-#define                GSBISTRUN               0x10
-#define                OSBISTERR               0x04
-#define                OSBISTDONE              0x02
-#define                OSBISTRUN               0x01
+#define        SCSBIST1                        0x3a
+#define                NTBISTERR               0x04
+#define                NTBISTDONE              0x02
+#define                NTBISTRUN               0x01
 
 #define        SCSISEQ0                        0x3a
 #define                TEMODEO                 0x80
@@ -1805,15 +1509,8 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define                FORCEBUSFREE            0x10
 #define                SCSIRSTO                0x01
 
-#define        SCSBIST1                        0x3a
-#define                NTBISTERR               0x04
-#define                NTBISTDONE              0x02
-#define                NTBISTRUN               0x01
-
 #define        SCSISEQ1                        0x3b
 
-#define        BUSINITID                       0x3c
-
 #define        SXFRCTL0                        0x3c
 #define                DFON                    0x80
 #define                DFPEXP                  0x40
@@ -1822,6 +1519,8 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 
 #define        DLCOUNT                         0x3c
 
+#define        BUSINITID                       0x3c
+
 #define        SXFRCTL1                        0x3d
 #define                BITBUCKET               0x80
 #define                ENSACHK                 0x40
@@ -1846,8 +1545,6 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define                CURRFIFO_1              0x01
 #define                CURRFIFO_0              0x00
 
-#define        MULTARGID                       0x40
-
 #define        SCSISIGO                        0x40
 #define                CDO                     0x80
 #define                IOO                     0x40
@@ -1858,6 +1555,8 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define                REQO                    0x02
 #define                ACKO                    0x01
 
+#define        MULTARGID                       0x40
+
 #define        SCSISIGI                        0x41
 #define                ATNI                    0x10
 #define                SELI                    0x08
@@ -1904,6 +1603,15 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define                ENAB20                  0x04
 #define                SELWIDE                 0x02
 
+#define        CLRSINT0                        0x4b
+#define                CLRSELDO                0x40
+#define                CLRSELDI                0x20
+#define                CLRSELINGO              0x10
+#define                CLRIOERR                0x08
+#define                CLROVERRUN              0x04
+#define                CLRSPIORDY              0x02
+#define                CLRARBDO                0x01
+
 #define        SSTAT0                          0x4b
 #define                TARGET                  0x80
 #define                SELDO                   0x40
@@ -1923,14 +1631,14 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define                ENSPIORDY               0x02
 #define                ENARBDO                 0x01
 
-#define        CLRSINT0                        0x4b
-#define                CLRSELDO                0x40
-#define                CLRSELDI                0x20
-#define                CLRSELINGO              0x10
-#define                CLRIOERR                0x08
-#define                CLROVERRUN              0x04
-#define                CLRSPIORDY              0x02
-#define                CLRARBDO                0x01
+#define        CLRSINT1                        0x4c
+#define                CLRSELTIMEO             0x80
+#define                CLRATNO                 0x40
+#define                CLRSCSIRSTI             0x20
+#define                CLRBUSFREE              0x08
+#define                CLRSCSIPERR             0x04
+#define                CLRSTRB2FAST            0x02
+#define                CLRREQINIT              0x01
 
 #define        SSTAT1                          0x4c
 #define                SELTO                   0x80
@@ -1942,15 +1650,6 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define                STRB2FAST               0x02
 #define                REQINIT                 0x01
 
-#define        CLRSINT1                        0x4c
-#define                CLRSELTIMEO             0x80
-#define                CLRATNO                 0x40
-#define                CLRSCSIRSTI             0x20
-#define                CLRBUSFREE              0x08
-#define                CLRSCSIPERR             0x04
-#define                CLRSTRB2FAST            0x02
-#define                CLRREQINIT              0x01
-
 #define        SSTAT2                          0x4d
 #define                BUSFREETIME             0xc0
 #define                NONPACKREQ              0x20
@@ -1998,14 +1697,6 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define                LQIATNLQ                0x02
 #define                LQIATNCMD               0x01
 
-#define        LQIMODE0                        0x50
-#define                ENLQIATNQASK            0x20
-#define                ENLQICRCT1              0x10
-#define                ENLQICRCT2              0x08
-#define                ENLQIBADLQT             0x04
-#define                ENLQIATNLQ              0x02
-#define                ENLQIATNCMD             0x01
-
 #define        CLRLQIINT0                      0x50
 #define                CLRLQIATNQAS            0x20
 #define                CLRLQICRCT1             0x10
@@ -2014,6 +1705,14 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define                CLRLQIATNLQ             0x02
 #define                CLRLQIATNCMD            0x01
 
+#define        LQIMODE0                        0x50
+#define                ENLQIATNQASK            0x20
+#define                ENLQICRCT1              0x10
+#define                ENLQICRCT2              0x08
+#define                ENLQIBADLQT             0x04
+#define                ENLQIATNLQ              0x02
+#define                ENLQIATNCMD             0x01
+
 #define        LQIMODE1                        0x51
 #define                ENLQIPHASE_LQ           0x80
 #define                ENLQIPHASE_NLQ          0x40
@@ -2160,6 +1859,8 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define                CFG4ICMD                0x02
 #define                CFG4TCMD                0x01
 
+#define        CURRSCB                         0x5c
+
 #define        SEQIMODE                        0x5c
 #define                ENCTXTDONE              0x40
 #define                ENSAVEPTRS              0x20
@@ -2169,8 +1870,6 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define                ENCFG4ICMD              0x02
 #define                ENCFG4TCMD              0x01
 
-#define        CURRSCB                         0x5c
-
 #define        MDFFSTAT                        0x5d
 #define                SHCNTNEGATIVE           0x40
 #define                SHCNTMINUS1             0x20
@@ -2185,29 +1884,29 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 
 #define        DFFTAG                          0x5e
 
+#define        LASTSCB                         0x5e
+
 #define        SCSITEST                        0x5e
 #define                CNTRTEST                0x08
 #define                SEL_TXPLL_DEBUG         0x04
 
-#define        LASTSCB                         0x5e
-
 #define        IOPDNCTL                        0x5f
 #define                DISABLE_OE              0x80
 #define                PDN_IDIST               0x04
 #define                PDN_DIFFSENSE           0x01
 
-#define        DGRPCRCI                        0x60
-
 #define        SHADDR                          0x60
 
 #define        NEGOADDR                        0x60
 
-#define        NEGPERIOD                       0x61
+#define        DGRPCRCI                        0x60
 
-#define        NEGOFFSET                       0x62
+#define        NEGPERIOD                       0x61
 
 #define        PACKCRCI                        0x62
 
+#define        NEGOFFSET                       0x62
+
 #define        NEGPPROPTS                      0x63
 #define                PPROPT_PACE             0x08
 #define                PPROPT_QAS              0x04
@@ -2253,8 +1952,6 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 
 #define        SELOID                          0x6b
 
-#define        FAIRNESS                        0x6c
-
 #define        PLL400CTL0                      0x6c
 #define                PLL_VCOSEL              0x80
 #define                PLL_PWDN                0x40
@@ -2264,6 +1961,8 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define                PLL_DLPF                0x02
 #define                PLL_ENFBM               0x01
 
+#define        FAIRNESS                        0x6c
+
 #define        PLL400CTL1                      0x6d
 #define                PLL_CNTEN               0x80
 #define                PLL_CNTCLR              0x40
@@ -2275,25 +1974,25 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 
 #define        HADDR                           0x70
 
-#define        HODMAADR                        0x70
-
 #define        PLLDELAY                        0x70
 #define                SPLIT_DROP_REQ          0x80
 
-#define        HCNT                            0x78
+#define        HODMAADR                        0x70
 
 #define        HODMACNT                        0x78
 
-#define        HODMAEN                         0x7a
+#define        HCNT                            0x78
 
-#define        SGHADDR                         0x7c
+#define        HODMAEN                         0x7a
 
 #define        SCBHADDR                        0x7c
 
-#define        SGHCNT                          0x84
+#define        SGHADDR                         0x7c
 
 #define        SCBHCNT                         0x84
 
+#define        SGHCNT                          0x84
+
 #define        DFF_THRSH                       0x88
 #define                WR_DFTHRSH              0x70
 #define                RD_DFTHRSH              0x07
@@ -2326,10 +2025,6 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 
 #define        CMCRXMSG0                       0x90
 
-#define        OVLYRXMSG0                      0x90
-
-#define        DCHRXMSG0                       0x90
-
 #define        ROENABLE                        0x90
 #define                MSIROEN                 0x20
 #define                OVLYROEN                0x10
@@ -2338,11 +2033,11 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define                DCH1ROEN                0x02
 #define                DCH0ROEN                0x01
 
-#define        OVLYRXMSG1                      0x91
+#define        OVLYRXMSG0                      0x90
 
-#define        CMCRXMSG1                       0x91
+#define        DCHRXMSG0                       0x90
 
-#define        DCHRXMSG1                       0x91
+#define        OVLYRXMSG1                      0x91
 
 #define        NSENABLE                        0x91
 #define                MSINSEN                 0x20
@@ -2352,6 +2047,10 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define                DCH1NSEN                0x02
 #define                DCH0NSEN                0x01
 
+#define        CMCRXMSG1                       0x91
+
+#define        DCHRXMSG1                       0x91
+
 #define        DCHRXMSG2                       0x92
 
 #define        CMCRXMSG2                       0x92
@@ -2375,24 +2074,24 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define                TSCSERREN               0x02
 #define                CMPABCDIS               0x01
 
-#define        CMCSEQBCNT                      0x94
-
 #define        OVLYSEQBCNT                     0x94
 
 #define        DCHSEQBCNT                      0x94
 
+#define        CMCSEQBCNT                      0x94
+
+#define        CMCSPLTSTAT0                    0x96
+
 #define        DCHSPLTSTAT0                    0x96
 
 #define        OVLYSPLTSTAT0                   0x96
 
-#define        CMCSPLTSTAT0                    0x96
+#define        CMCSPLTSTAT1                    0x97
 
 #define        OVLYSPLTSTAT1                   0x97
 
 #define        DCHSPLTSTAT1                    0x97
 
-#define        CMCSPLTSTAT1                    0x97
-
 #define        SGRXMSG0                        0x98
 #define                CDNUM                   0xf8
 #define                CFNUM                   0x07
@@ -2420,15 +2119,18 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define                TAG_NUM                 0x1f
 #define                RLXORD                  0x10
 
+#define        SGSEQBCNT                       0x9c
+
 #define        SLVSPLTOUTATTR0                 0x9c
 #define                LOWER_BCNT              0xff
 
-#define        SGSEQBCNT                       0x9c
-
 #define        SLVSPLTOUTATTR1                 0x9d
 #define                CMPLT_DNUM              0xf8
 #define                CMPLT_FNUM              0x07
 
+#define        SLVSPLTOUTATTR2                 0x9e
+#define                CMPLT_BNUM              0xff
+
 #define        SGSPLTSTAT0                     0x9e
 #define                STAETERM                0x80
 #define                SCBCERR                 0x40
@@ -2439,9 +2141,6 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define                RXSCEMSG                0x02
 #define                RXSPLTRSP               0x01
 
-#define        SLVSPLTOUTATTR2                 0x9e
-#define                CMPLT_BNUM              0xff
-
 #define        SGSPLTSTAT1                     0x9f
 #define                RXDATABUCKET            0x01
 
@@ -2497,10 +2196,10 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 
 #define        CCSGADDR                        0xac
 
-#define        CCSCBADDR                       0xac
-
 #define        CCSCBADR_BK                     0xac
 
+#define        CCSCBADDR                       0xac
+
 #define        CMC_RAMBIST                     0xad
 #define                SG_ELEMENT_SIZE         0x80
 #define                SCBRAMBIST_FAIL         0x40
@@ -2554,9 +2253,9 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define        SEEDAT                          0xbc
 
 #define        SEECTL                          0xbe
-#define                SEEOP_EWDS              0x40
 #define                SEEOP_WALL              0x40
 #define                SEEOP_EWEN              0x40
+#define                SEEOP_EWDS              0x40
 #define                SEEOPCODE               0x70
 #define                SEERST                  0x02
 #define                SEESTART                0x01
@@ -2573,25 +2272,25 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 
 #define        SCBCNT                          0xbf
 
+#define        DFWADDR                         0xc0
+
 #define        DSPFLTRCTL                      0xc0
 #define                FLTRDISABLE             0x20
 #define                EDGESENSE               0x10
 #define                DSPFCNTSEL              0x0f
 
-#define        DFWADDR                         0xc0
-
 #define        DSPDATACTL                      0xc1
 #define                BYPASSENAB              0x80
 #define                DESQDIS                 0x10
 #define                RCVROFFSTDIS            0x04
 #define                XMITOFFSTDIS            0x02
 
+#define        DFRADDR                         0xc2
+
 #define        DSPREQCTL                       0xc2
 #define                MANREQCTL               0xc0
 #define                MANREQDLY               0x3f
 
-#define        DFRADDR                         0xc2
-
 #define        DSPACKCTL                       0xc3
 #define                MANACKCTL               0xc0
 #define                MANACKDLY               0x3f
@@ -2612,14 +2311,14 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 
 #define        WRTBIASCALC                     0xc7
 
-#define        DFPTRS                          0xc8
-
 #define        RCVRBIASCALC                    0xc8
 
-#define        DFBKPTR                         0xc9
+#define        DFPTRS                          0xc8
 
 #define        SKEWCALC                        0xc9
 
+#define        DFBKPTR                         0xc9
+
 #define        DFDBCTL                         0xcb
 #define                DFF_CIO_WR_RDY          0x20
 #define                DFF_CIO_RD_RDY          0x10
@@ -2704,12 +2403,12 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 
 #define        ACCUM_SAVE                      0xfa
 
+#define        WAITING_SCB_TAILS               0x100
+
 #define        AHD_PCI_CONFIG_BASE             0x100
 
 #define        SRAM_BASE                       0x100
 
-#define        WAITING_SCB_TAILS               0x100
-
 #define        WAITING_TID_HEAD                0x120
 
 #define        WAITING_TID_TAIL                0x122
@@ -2738,8 +2437,8 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define                PRELOADEN               0x80
 #define                WIDEODD                 0x40
 #define                SCSIEN                  0x20
-#define                SDMAENACK               0x10
 #define                SDMAEN                  0x10
+#define                SDMAENACK               0x10
 #define                HDMAEN                  0x08
 #define                HDMAENACK               0x08
 #define                DIRECTION               0x04
@@ -2837,12 +2536,12 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 
 #define        MK_MESSAGE_SCSIID               0x162
 
+#define        SCB_BASE                        0x180
+
 #define        SCB_RESIDUAL_DATACNT            0x180
 #define        SCB_CDB_STORE                   0x180
 #define        SCB_HOST_CDB_PTR                0x180
 
-#define        SCB_BASE                        0x180
-
 #define        SCB_RESIDUAL_SGPTR              0x184
 #define                SG_ADDR_MASK            0xf8
 #define                SG_OVERRUN_RESID        0x02
@@ -2910,17 +2609,6 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define        SCB_DISCONNECTED_LISTS          0x1b8
 
 
-#define        CMD_GROUP_CODE_SHIFT    0x05
-#define        STIMESEL_MIN    0x18
-#define        STIMESEL_SHIFT  0x03
-#define        INVALID_ADDR    0x80
-#define        AHD_PRECOMP_MASK        0x07
-#define        TARGET_DATA_IN  0x01
-#define        CCSCBADDR_MAX   0x80
-#define        NUMDSPS         0x14
-#define        SEEOP_EWEN_ADDR 0xc0
-#define        AHD_ANNEXCOL_PER_DEV0   0x04
-#define        DST_MODE_SHIFT  0x04
 #define        AHD_TIMER_MAX_US        0x18ffe7
 #define        AHD_TIMER_MAX_TICKS     0xffff
 #define        AHD_SENSE_BUFSIZE       0x100
@@ -2955,32 +2643,43 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
 #define        LUNLEN_SINGLE_LEVEL_LUN 0x0f
 #define        NVRAM_SCB_OFFSET        0x2c
 #define        STATUS_PKT_SENSE        0xff
+#define        CMD_GROUP_CODE_SHIFT    0x05
 #define        MAX_OFFSET_PACED_BUG    0x7f
 #define        STIMESEL_BUG_ADJ        0x08
+#define        STIMESEL_MIN    0x18
+#define        STIMESEL_SHIFT  0x03
 #define        CCSGRAM_MAXSEGS 0x10
+#define        INVALID_ADDR    0x80
 #define        SEEOP_ERAL_ADDR 0x80
 #define        AHD_SLEWRATE_DEF_REVB   0x08
 #define        AHD_PRECOMP_CUTBACK_17  0x04
+#define        AHD_PRECOMP_MASK        0x07
 #define        SRC_MODE_SHIFT  0x00
 #define        PKT_OVERRUN_BUFSIZE     0x200
 #define        SCB_TRANSFER_SIZE_1BYTE_LUN     0x30
+#define        TARGET_DATA_IN  0x01
 #define        HOST_MSG        0xff
 #define        MAX_OFFSET      0xfe
 #define        BUS_16_BIT      0x01
+#define        CCSCBADDR_MAX   0x80
+#define        NUMDSPS         0x14
+#define        SEEOP_EWEN_ADDR 0xc0
+#define        AHD_ANNEXCOL_PER_DEV0   0x04
+#define        DST_MODE_SHIFT  0x04
 
 
 /* Downloaded Constant Definitions */
-#define        SG_SIZEOF       0x04
-#define        SG_PREFETCH_ALIGN_MASK  0x02
-#define        SG_PREFETCH_CNT_LIMIT   0x01
 #define        CACHELINE_MASK  0x07
 #define        SCB_TRANSFER_SIZE       0x06
 #define        PKT_OVERRUN_BUFOFFSET   0x05
+#define        SG_SIZEOF       0x04
 #define        SG_PREFETCH_ADDR_MASK   0x03
+#define        SG_PREFETCH_ALIGN_MASK  0x02
+#define        SG_PREFETCH_CNT_LIMIT   0x01
 #define        SG_PREFETCH_CNT 0x00
 #define        DOWNLOAD_CONST_COUNT    0x08
 
 
 /* Exported Labels */
-#define        LABEL_timer_isr 0x28b
 #define        LABEL_seq_isr   0x28f
+#define        LABEL_timer_isr 0x28b
index c4c8a96bf5a36b53003f8ce15549760f94dfd134..f5ea715d6ac33af433688a62669506ebb67303cf 100644 (file)
@@ -8,18 +8,6 @@
 
 #include "aic79xx_osm.h"
 
-static const ahd_reg_parse_entry_t MODE_PTR_parse_table[] = {
-       { "SRC_MODE",           0x07, 0x07 },
-       { "DST_MODE",           0x70, 0x70 }
-};
-
-int
-ahd_mode_ptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(MODE_PTR_parse_table, 2, "MODE_PTR",
-           0x00, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t INTSTAT_parse_table[] = {
        { "SPLTINT",            0x01, 0x01 },
        { "CMDCMPLT",           0x02, 0x02 },
@@ -39,110 +27,6 @@ ahd_intstat_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x01, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t SEQINTCODE_parse_table[] = {
-       { "NO_SEQINT",          0x00, 0xff },
-       { "BAD_PHASE",          0x01, 0xff },
-       { "SEND_REJECT",        0x02, 0xff },
-       { "PROTO_VIOLATION",    0x03, 0xff },
-       { "NO_MATCH",           0x04, 0xff },
-       { "IGN_WIDE_RES",       0x05, 0xff },
-       { "PDATA_REINIT",       0x06, 0xff },
-       { "HOST_MSG_LOOP",      0x07, 0xff },
-       { "BAD_STATUS",         0x08, 0xff },
-       { "DATA_OVERRUN",       0x09, 0xff },
-       { "MKMSG_FAILED",       0x0a, 0xff },
-       { "MISSED_BUSFREE",     0x0b, 0xff },
-       { "DUMP_CARD_STATE",    0x0c, 0xff },
-       { "ILLEGAL_PHASE",      0x0d, 0xff },
-       { "INVALID_SEQINT",     0x0e, 0xff },
-       { "CFG4ISTAT_INTR",     0x0f, 0xff },
-       { "STATUS_OVERRUN",     0x10, 0xff },
-       { "CFG4OVERRUN",        0x11, 0xff },
-       { "ENTERING_NONPACK",   0x12, 0xff },
-       { "TASKMGMT_FUNC_COMPLETE",0x13, 0xff },
-       { "TASKMGMT_CMD_CMPLT_OKAY",0x14, 0xff },
-       { "TRACEPOINT0",        0x15, 0xff },
-       { "TRACEPOINT1",        0x16, 0xff },
-       { "TRACEPOINT2",        0x17, 0xff },
-       { "TRACEPOINT3",        0x18, 0xff },
-       { "SAW_HWERR",          0x19, 0xff },
-       { "BAD_SCB_STATUS",     0x1a, 0xff }
-};
-
-int
-ahd_seqintcode_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SEQINTCODE_parse_table, 27, "SEQINTCODE",
-           0x02, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t CLRINT_parse_table[] = {
-       { "CLRSPLTINT",         0x01, 0x01 },
-       { "CLRCMDINT",          0x02, 0x02 },
-       { "CLRSEQINT",          0x04, 0x04 },
-       { "CLRSCSIINT",         0x08, 0x08 },
-       { "CLRPCIINT",          0x10, 0x10 },
-       { "CLRSWTMINT",         0x20, 0x20 },
-       { "CLRBRKADRINT",       0x40, 0x40 },
-       { "CLRHWERRINT",        0x80, 0x80 }
-};
-
-int
-ahd_clrint_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(CLRINT_parse_table, 8, "CLRINT",
-           0x03, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t ERROR_parse_table[] = {
-       { "DSCTMOUT",           0x02, 0x02 },
-       { "ILLOPCODE",          0x04, 0x04 },
-       { "SQPARERR",           0x08, 0x08 },
-       { "DPARERR",            0x10, 0x10 },
-       { "MPARERR",            0x20, 0x20 },
-       { "CIOACCESFAIL",       0x40, 0x40 },
-       { "CIOPARERR",          0x80, 0x80 }
-};
-
-int
-ahd_error_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(ERROR_parse_table, 7, "ERROR",
-           0x04, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t HCNTRL_parse_table[] = {
-       { "CHIPRST",            0x01, 0x01 },
-       { "CHIPRSTACK",         0x01, 0x01 },
-       { "INTEN",              0x02, 0x02 },
-       { "PAUSE",              0x04, 0x04 },
-       { "SWTIMER_START_B",    0x08, 0x08 },
-       { "SWINT",              0x10, 0x10 },
-       { "POWRDN",             0x40, 0x40 },
-       { "SEQ_RESET",          0x80, 0x80 }
-};
-
-int
-ahd_hcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(HCNTRL_parse_table, 8, "HCNTRL",
-           0x05, regvalue, cur_col, wrap));
-}
-
-int
-ahd_hnscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "HNSCB_QOFF",
-           0x06, regvalue, cur_col, wrap));
-}
-
-int
-ahd_hescb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "HESCB_QOFF",
-           0x08, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t HS_MAILBOX_parse_table[] = {
        { "ENINT_COALESCE",     0x40, 0x40 },
        { "HOST_TQINPOS",       0x80, 0x80 }
@@ -170,77 +54,6 @@ ahd_seqintstat_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x0c, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t CLRSEQINTSTAT_parse_table[] = {
-       { "CLRSEQ_SPLTINT",     0x01, 0x01 },
-       { "CLRSEQ_PCIINT",      0x02, 0x02 },
-       { "CLRSEQ_SCSIINT",     0x04, 0x04 },
-       { "CLRSEQ_SEQINT",      0x08, 0x08 },
-       { "CLRSEQ_SWTMRTO",     0x10, 0x10 }
-};
-
-int
-ahd_clrseqintstat_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(CLRSEQINTSTAT_parse_table, 5, "CLRSEQINTSTAT",
-           0x0c, regvalue, cur_col, wrap));
-}
-
-int
-ahd_swtimer_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SWTIMER",
-           0x0e, regvalue, cur_col, wrap));
-}
-
-int
-ahd_snscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SNSCB_QOFF",
-           0x10, regvalue, cur_col, wrap));
-}
-
-int
-ahd_sescb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SESCB_QOFF",
-           0x12, regvalue, cur_col, wrap));
-}
-
-int
-ahd_sdscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SDSCB_QOFF",
-           0x14, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t QOFF_CTLSTA_parse_table[] = {
-       { "SCB_QSIZE_4",        0x00, 0x0f },
-       { "SCB_QSIZE_8",        0x01, 0x0f },
-       { "SCB_QSIZE_16",       0x02, 0x0f },
-       { "SCB_QSIZE_32",       0x03, 0x0f },
-       { "SCB_QSIZE_64",       0x04, 0x0f },
-       { "SCB_QSIZE_128",      0x05, 0x0f },
-       { "SCB_QSIZE_256",      0x06, 0x0f },
-       { "SCB_QSIZE_512",      0x07, 0x0f },
-       { "SCB_QSIZE_1024",     0x08, 0x0f },
-       { "SCB_QSIZE_2048",     0x09, 0x0f },
-       { "SCB_QSIZE_4096",     0x0a, 0x0f },
-       { "SCB_QSIZE_8192",     0x0b, 0x0f },
-       { "SCB_QSIZE_16384",    0x0c, 0x0f },
-       { "SCB_QSIZE",          0x0f, 0x0f },
-       { "HS_MAILBOX_ACT",     0x10, 0x10 },
-       { "SDSCB_ROLLOVR",      0x20, 0x20 },
-       { "NEW_SCB_AVAIL",      0x40, 0x40 },
-       { "EMPTY_SCB_AVAIL",    0x80, 0x80 }
-};
-
-int
-ahd_qoff_ctlsta_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(QOFF_CTLSTA_parse_table, 18, "QOFF_CTLSTA",
-           0x16, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t INTCTL_parse_table[] = {
        { "SPLTINTEN",          0x01, 0x01 },
        { "SEQINTEN",           0x02, 0x02 },
@@ -280,22 +93,6 @@ ahd_dfcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x19, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t DSCOMMAND0_parse_table[] = {
-       { "CIOPARCKEN",         0x01, 0x01 },
-       { "DISABLE_TWATE",      0x02, 0x02 },
-       { "EXTREQLCK",          0x10, 0x10 },
-       { "MPARCKEN",           0x20, 0x20 },
-       { "DPARCKEN",           0x40, 0x40 },
-       { "CACHETHEN",          0x80, 0x80 }
-};
-
-int
-ahd_dscommand0_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(DSCOMMAND0_parse_table, 6, "DSCOMMAND0",
-           0x19, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t DFSTATUS_parse_table[] = {
        { "FIFOEMP",            0x01, 0x01 },
        { "FIFOFULL",           0x02, 0x02 },
@@ -327,146 +124,6 @@ ahd_sg_cache_shadow_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x1b, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t SG_CACHE_PRE_parse_table[] = {
-       { "LAST_SEG",           0x02, 0x02 },
-       { "ODD_SEG",            0x04, 0x04 },
-       { "SG_ADDR_MASK",       0xf8, 0xf8 }
-};
-
-int
-ahd_sg_cache_pre_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SG_CACHE_PRE_parse_table, 3, "SG_CACHE_PRE",
-           0x1b, regvalue, cur_col, wrap));
-}
-
-int
-ahd_lqin_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "LQIN",
-           0x20, regvalue, cur_col, wrap));
-}
-
-int
-ahd_lunptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "LUNPTR",
-           0x22, regvalue, cur_col, wrap));
-}
-
-int
-ahd_cmdlenptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "CMDLENPTR",
-           0x25, regvalue, cur_col, wrap));
-}
-
-int
-ahd_attrptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "ATTRPTR",
-           0x26, regvalue, cur_col, wrap));
-}
-
-int
-ahd_flagptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "FLAGPTR",
-           0x27, regvalue, cur_col, wrap));
-}
-
-int
-ahd_cmdptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "CMDPTR",
-           0x28, regvalue, cur_col, wrap));
-}
-
-int
-ahd_qnextptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "QNEXTPTR",
-           0x29, regvalue, cur_col, wrap));
-}
-
-int
-ahd_abrtbyteptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "ABRTBYTEPTR",
-           0x2b, regvalue, cur_col, wrap));
-}
-
-int
-ahd_abrtbitptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "ABRTBITPTR",
-           0x2c, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t LUNLEN_parse_table[] = {
-       { "ILUNLEN",            0x0f, 0x0f },
-       { "TLUNLEN",            0xf0, 0xf0 }
-};
-
-int
-ahd_lunlen_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(LUNLEN_parse_table, 2, "LUNLEN",
-           0x30, regvalue, cur_col, wrap));
-}
-
-int
-ahd_cdblimit_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "CDBLIMIT",
-           0x31, regvalue, cur_col, wrap));
-}
-
-int
-ahd_maxcmd_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "MAXCMD",
-           0x32, regvalue, cur_col, wrap));
-}
-
-int
-ahd_maxcmdcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "MAXCMDCNT",
-           0x33, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t LQCTL1_parse_table[] = {
-       { "ABORTPENDING",       0x01, 0x01 },
-       { "SINGLECMD",          0x02, 0x02 },
-       { "PCI2PCI",            0x04, 0x04 }
-};
-
-int
-ahd_lqctl1_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(LQCTL1_parse_table, 3, "LQCTL1",
-           0x38, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t LQCTL2_parse_table[] = {
-       { "LQOPAUSE",           0x01, 0x01 },
-       { "LQOTOIDLE",          0x02, 0x02 },
-       { "LQOCONTINUE",        0x04, 0x04 },
-       { "LQORETRY",           0x08, 0x08 },
-       { "LQIPAUSE",           0x10, 0x10 },
-       { "LQITOIDLE",          0x20, 0x20 },
-       { "LQICONTINUE",        0x40, 0x40 },
-       { "LQIRETRY",           0x80, 0x80 }
-};
-
-int
-ahd_lqctl2_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(LQCTL2_parse_table, 8, "LQCTL2",
-           0x39, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t SCSISEQ0_parse_table[] = {
        { "SCSIRSTO",           0x01, 0x01 },
        { "FORCEBUSFREE",       0x10, 0x10 },
@@ -498,37 +155,6 @@ ahd_scsiseq1_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x3b, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t SXFRCTL0_parse_table[] = {
-       { "SPIOEN",             0x08, 0x08 },
-       { "BIOSCANCELEN",       0x10, 0x10 },
-       { "DFPEXP",             0x40, 0x40 },
-       { "DFON",               0x80, 0x80 }
-};
-
-int
-ahd_sxfrctl0_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SXFRCTL0_parse_table, 4, "SXFRCTL0",
-           0x3c, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t SXFRCTL1_parse_table[] = {
-       { "STPWEN",             0x01, 0x01 },
-       { "ACTNEGEN",           0x02, 0x02 },
-       { "ENSTIMER",           0x04, 0x04 },
-       { "STIMESEL",           0x18, 0x18 },
-       { "ENSPCHK",            0x20, 0x20 },
-       { "ENSACHK",            0x40, 0x40 },
-       { "BITBUCKET",          0x80, 0x80 }
-};
-
-int
-ahd_sxfrctl1_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SXFRCTL1_parse_table, 7, "SXFRCTL1",
-           0x3d, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t DFFSTAT_parse_table[] = {
        { "CURRFIFO_0",         0x00, 0x03 },
        { "CURRFIFO_1",         0x01, 0x03 },
@@ -545,40 +171,6 @@ ahd_dffstat_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x3f, regvalue, cur_col, wrap));
 }
 
-int
-ahd_multargid_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "MULTARGID",
-           0x40, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t SCSISIGO_parse_table[] = {
-       { "P_DATAOUT",          0x00, 0xe0 },
-       { "P_DATAOUT_DT",       0x20, 0xe0 },
-       { "P_DATAIN",           0x40, 0xe0 },
-       { "P_DATAIN_DT",        0x60, 0xe0 },
-       { "P_COMMAND",          0x80, 0xe0 },
-       { "P_MESGOUT",          0xa0, 0xe0 },
-       { "P_STATUS",           0xc0, 0xe0 },
-       { "P_MESGIN",           0xe0, 0xe0 },
-       { "ACKO",               0x01, 0x01 },
-       { "REQO",               0x02, 0x02 },
-       { "BSYO",               0x04, 0x04 },
-       { "SELO",               0x08, 0x08 },
-       { "ATNO",               0x10, 0x10 },
-       { "MSGO",               0x20, 0x20 },
-       { "IOO",                0x40, 0x40 },
-       { "CDO",                0x80, 0x80 },
-       { "PHASE_MASK",         0xe0, 0xe0 }
-};
-
-int
-ahd_scsisigo_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SCSISIGO_parse_table, 17, "SCSISIGO",
-           0x40, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t SCSISIGI_parse_table[] = {
        { "P_DATAOUT",          0x00, 0xe0 },
        { "P_DATAOUT_DT",       0x20, 0xe0 },
@@ -623,13 +215,6 @@ ahd_scsiphase_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x42, regvalue, cur_col, wrap));
 }
 
-int
-ahd_scsidat_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SCSIDAT",
-           0x44, regvalue, cur_col, wrap));
-}
-
 int
 ahd_scsibus_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
@@ -637,18 +222,6 @@ ahd_scsibus_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x46, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t TARGIDIN_parse_table[] = {
-       { "TARGID",             0x0f, 0x0f },
-       { "CLKOUT",             0x80, 0x80 }
-};
-
-int
-ahd_targidin_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(TARGIDIN_parse_table, 2, "TARGIDIN",
-           0x48, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t SELID_parse_table[] = {
        { "ONEBIT",             0x08, 0x08 },
        { "SELID_MASK",         0xf0, 0xf0 }
@@ -661,38 +234,6 @@ ahd_selid_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x49, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t OPTIONMODE_parse_table[] = {
-       { "AUTO_MSGOUT_DE",     0x02, 0x02 },
-       { "ENDGFORMCHK",        0x04, 0x04 },
-       { "BUSFREEREV",         0x10, 0x10 },
-       { "BIASCANCTL",         0x20, 0x20 },
-       { "AUTOACKEN",          0x40, 0x40 },
-       { "BIOSCANCTL",         0x80, 0x80 },
-       { "OPTIONMODE_DEFAULTS",0x02, 0x02 }
-};
-
-int
-ahd_optionmode_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(OPTIONMODE_parse_table, 7, "OPTIONMODE",
-           0x4a, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t SBLKCTL_parse_table[] = {
-       { "SELWIDE",            0x02, 0x02 },
-       { "ENAB20",             0x04, 0x04 },
-       { "ENAB40",             0x08, 0x08 },
-       { "DIAGLEDON",          0x40, 0x40 },
-       { "DIAGLEDEN",          0x80, 0x80 }
-};
-
-int
-ahd_sblkctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SBLKCTL_parse_table, 5, "SBLKCTL",
-           0x4a, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t SSTAT0_parse_table[] = {
        { "ARBDO",              0x01, 0x01 },
        { "SPIORDY",            0x02, 0x02 },
@@ -728,23 +269,6 @@ ahd_simode0_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x4b, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t CLRSINT0_parse_table[] = {
-       { "CLRARBDO",           0x01, 0x01 },
-       { "CLRSPIORDY",         0x02, 0x02 },
-       { "CLROVERRUN",         0x04, 0x04 },
-       { "CLRIOERR",           0x08, 0x08 },
-       { "CLRSELINGO",         0x10, 0x10 },
-       { "CLRSELDI",           0x20, 0x20 },
-       { "CLRSELDO",           0x40, 0x40 }
-};
-
-int
-ahd_clrsint0_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(CLRSINT0_parse_table, 7, "CLRSINT0",
-           0x4b, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t SSTAT1_parse_table[] = {
        { "REQINIT",            0x01, 0x01 },
        { "STRB2FAST",          0x02, 0x02 },
@@ -763,23 +287,6 @@ ahd_sstat1_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x4c, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t CLRSINT1_parse_table[] = {
-       { "CLRREQINIT",         0x01, 0x01 },
-       { "CLRSTRB2FAST",       0x02, 0x02 },
-       { "CLRSCSIPERR",        0x04, 0x04 },
-       { "CLRBUSFREE",         0x08, 0x08 },
-       { "CLRSCSIRSTI",        0x20, 0x20 },
-       { "CLRATNO",            0x40, 0x40 },
-       { "CLRSELTIMEO",        0x80, 0x80 }
-};
-
-int
-ahd_clrsint1_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(CLRSINT1_parse_table, 7, "CLRSINT1",
-           0x4c, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t SSTAT2_parse_table[] = {
        { "BUSFREE_LQO",        0x40, 0xc0 },
        { "BUSFREE_DFF0",       0x80, 0xc0 },
@@ -800,20 +307,6 @@ ahd_sstat2_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x4d, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t CLRSINT2_parse_table[] = {
-       { "CLRDMADONE",         0x01, 0x01 },
-       { "CLRSDONE",           0x02, 0x02 },
-       { "CLRWIDE_RES",        0x04, 0x04 },
-       { "CLRNONPACKREQ",      0x20, 0x20 }
-};
-
-int
-ahd_clrsint2_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(CLRSINT2_parse_table, 4, "CLRSINT2",
-           0x4d, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t PERRDIAG_parse_table[] = {
        { "DTERR",              0x01, 0x01 },
        { "DGFORMERR",          0x02, 0x02 },
@@ -832,13 +325,6 @@ ahd_perrdiag_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x4e, regvalue, cur_col, wrap));
 }
 
-int
-ahd_lqistate_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "LQISTATE",
-           0x4e, regvalue, cur_col, wrap));
-}
-
 int
 ahd_soffcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
@@ -846,13 +332,6 @@ ahd_soffcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x4f, regvalue, cur_col, wrap));
 }
 
-int
-ahd_lqostate_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "LQOSTATE",
-           0x4f, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t LQISTAT0_parse_table[] = {
        { "LQIATNCMD",          0x01, 0x01 },
        { "LQIATNLQ",           0x02, 0x02 },
@@ -869,56 +348,6 @@ ahd_lqistat0_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x50, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t LQIMODE0_parse_table[] = {
-       { "ENLQIATNCMD",        0x01, 0x01 },
-       { "ENLQIATNLQ",         0x02, 0x02 },
-       { "ENLQIBADLQT",        0x04, 0x04 },
-       { "ENLQICRCT2",         0x08, 0x08 },
-       { "ENLQICRCT1",         0x10, 0x10 },
-       { "ENLQIATNQASK",       0x20, 0x20 }
-};
-
-int
-ahd_lqimode0_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(LQIMODE0_parse_table, 6, "LQIMODE0",
-           0x50, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t CLRLQIINT0_parse_table[] = {
-       { "CLRLQIATNCMD",       0x01, 0x01 },
-       { "CLRLQIATNLQ",        0x02, 0x02 },
-       { "CLRLQIBADLQT",       0x04, 0x04 },
-       { "CLRLQICRCT2",        0x08, 0x08 },
-       { "CLRLQICRCT1",        0x10, 0x10 },
-       { "CLRLQIATNQAS",       0x20, 0x20 }
-};
-
-int
-ahd_clrlqiint0_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(CLRLQIINT0_parse_table, 6, "CLRLQIINT0",
-           0x50, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t LQIMODE1_parse_table[] = {
-       { "ENLQIOVERI_NLQ",     0x01, 0x01 },
-       { "ENLQIOVERI_LQ",      0x02, 0x02 },
-       { "ENLQIBADLQI",        0x04, 0x04 },
-       { "ENLQICRCI_NLQ",      0x08, 0x08 },
-       { "ENLQICRCI_LQ",       0x10, 0x10 },
-       { "ENLIQABORT",         0x20, 0x20 },
-       { "ENLQIPHASE_NLQ",     0x40, 0x40 },
-       { "ENLQIPHASE_LQ",      0x80, 0x80 }
-};
-
-int
-ahd_lqimode1_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(LQIMODE1_parse_table, 8, "LQIMODE1",
-           0x51, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t LQISTAT1_parse_table[] = {
        { "LQIOVERI_NLQ",       0x01, 0x01 },
        { "LQIOVERI_LQ",        0x02, 0x02 },
@@ -937,24 +366,6 @@ ahd_lqistat1_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x51, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t CLRLQIINT1_parse_table[] = {
-       { "CLRLQIOVERI_NLQ",    0x01, 0x01 },
-       { "CLRLQIOVERI_LQ",     0x02, 0x02 },
-       { "CLRLQIBADLQI",       0x04, 0x04 },
-       { "CLRLQICRCI_NLQ",     0x08, 0x08 },
-       { "CLRLQICRCI_LQ",      0x10, 0x10 },
-       { "CLRLIQABORT",        0x20, 0x20 },
-       { "CLRLQIPHASE_NLQ",    0x40, 0x40 },
-       { "CLRLQIPHASE_LQ",     0x80, 0x80 }
-};
-
-int
-ahd_clrlqiint1_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(CLRLQIINT1_parse_table, 8, "CLRLQIINT1",
-           0x51, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t LQISTAT2_parse_table[] = {
        { "LQIGSAVAIL",         0x01, 0x01 },
        { "LQISTOPCMD",         0x02, 0x02 },
@@ -985,30 +396,6 @@ ahd_sstat3_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x53, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t SIMODE3_parse_table[] = {
-       { "ENOSRAMPERR",        0x01, 0x01 },
-       { "ENNTRAMPERR",        0x02, 0x02 }
-};
-
-int
-ahd_simode3_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SIMODE3_parse_table, 2, "SIMODE3",
-           0x53, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t CLRSINT3_parse_table[] = {
-       { "CLROSRAMPERR",       0x01, 0x01 },
-       { "CLRNTRAMPERR",       0x02, 0x02 }
-};
-
-int
-ahd_clrsint3_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(CLRSINT3_parse_table, 2, "CLRSINT3",
-           0x53, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t LQOSTAT0_parse_table[] = {
        { "LQOTCRC",            0x01, 0x01 },
        { "LQOATNPKT",          0x02, 0x02 },
@@ -1024,51 +411,6 @@ ahd_lqostat0_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x54, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t CLRLQOINT0_parse_table[] = {
-       { "CLRLQOTCRC",         0x01, 0x01 },
-       { "CLRLQOATNPKT",       0x02, 0x02 },
-       { "CLRLQOATNLQ",        0x04, 0x04 },
-       { "CLRLQOSTOPT2",       0x08, 0x08 },
-       { "CLRLQOTARGSCBPERR",  0x10, 0x10 }
-};
-
-int
-ahd_clrlqoint0_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(CLRLQOINT0_parse_table, 5, "CLRLQOINT0",
-           0x54, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t LQOMODE0_parse_table[] = {
-       { "ENLQOTCRC",          0x01, 0x01 },
-       { "ENLQOATNPKT",        0x02, 0x02 },
-       { "ENLQOATNLQ",         0x04, 0x04 },
-       { "ENLQOSTOPT2",        0x08, 0x08 },
-       { "ENLQOTARGSCBPERR",   0x10, 0x10 }
-};
-
-int
-ahd_lqomode0_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(LQOMODE0_parse_table, 5, "LQOMODE0",
-           0x54, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t LQOMODE1_parse_table[] = {
-       { "ENLQOPHACHGINPKT",   0x01, 0x01 },
-       { "ENLQOBUSFREE",       0x02, 0x02 },
-       { "ENLQOBADQAS",        0x04, 0x04 },
-       { "ENLQOSTOPI2",        0x08, 0x08 },
-       { "ENLQOINITSCBPERR",   0x10, 0x10 }
-};
-
-int
-ahd_lqomode1_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(LQOMODE1_parse_table, 5, "LQOMODE1",
-           0x55, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t LQOSTAT1_parse_table[] = {
        { "LQOPHACHGINPKT",     0x01, 0x01 },
        { "LQOBUSFREE",         0x02, 0x02 },
@@ -1084,21 +426,6 @@ ahd_lqostat1_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x55, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t CLRLQOINT1_parse_table[] = {
-       { "CLRLQOPHACHGINPKT",  0x01, 0x01 },
-       { "CLRLQOBUSFREE",      0x02, 0x02 },
-       { "CLRLQOBADQAS",       0x04, 0x04 },
-       { "CLRLQOSTOPI2",       0x08, 0x08 },
-       { "CLRLQOINITSCBPERR",  0x10, 0x10 }
-};
-
-int
-ahd_clrlqoint1_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(CLRLQOINT1_parse_table, 5, "CLRLQOINT1",
-           0x55, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t LQOSTAT2_parse_table[] = {
        { "LQOSTOP0",           0x01, 0x01 },
        { "LQOPHACHGOUTPKT",    0x02, 0x02 },
@@ -1113,13 +440,6 @@ ahd_lqostat2_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x56, regvalue, cur_col, wrap));
 }
 
-int
-ahd_os_space_cnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "OS_SPACE_CNT",
-           0x56, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t SIMODE1_parse_table[] = {
        { "ENREQINIT",          0x01, 0x01 },
        { "ENSTRB2FAST",        0x02, 0x02 },
@@ -1138,13 +458,6 @@ ahd_simode1_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x57, regvalue, cur_col, wrap));
 }
 
-int
-ahd_gsfifo_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "GSFIFO",
-           0x58, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t DFFSXFRCTL_parse_table[] = {
        { "RSTCHN",             0x01, 0x01 },
        { "CLRCHN",             0x02, 0x02 },
@@ -1159,44 +472,6 @@ ahd_dffsxfrctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x5a, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t LQOSCSCTL_parse_table[] = {
-       { "LQONOCHKOVER",       0x01, 0x01 },
-       { "LQONOHOLDLACK",      0x02, 0x02 },
-       { "LQOBUSETDLY",        0x40, 0x40 },
-       { "LQOH2A_VERSION",     0x80, 0x80 }
-};
-
-int
-ahd_lqoscsctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(LQOSCSCTL_parse_table, 4, "LQOSCSCTL",
-           0x5a, regvalue, cur_col, wrap));
-}
-
-int
-ahd_nextscb_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "NEXTSCB",
-           0x5a, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t CLRSEQINTSRC_parse_table[] = {
-       { "CLRCFG4TCMD",        0x01, 0x01 },
-       { "CLRCFG4ICMD",        0x02, 0x02 },
-       { "CLRCFG4TSTAT",       0x04, 0x04 },
-       { "CLRCFG4ISTAT",       0x08, 0x08 },
-       { "CLRCFG4DATA",        0x10, 0x10 },
-       { "CLRSAVEPTRS",        0x20, 0x20 },
-       { "CLRCTXTDONE",        0x40, 0x40 }
-};
-
-int
-ahd_clrseqintsrc_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(CLRSEQINTSRC_parse_table, 7, "CLRSEQINTSRC",
-           0x5b, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t SEQINTSRC_parse_table[] = {
        { "CFG4TCMD",           0x01, 0x01 },
        { "CFG4ICMD",           0x02, 0x02 },
@@ -1231,13 +506,6 @@ ahd_seqimode_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x5c, regvalue, cur_col, wrap));
 }
 
-int
-ahd_currscb_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "CURRSCB",
-           0x5c, regvalue, cur_col, wrap));
-}
-
 static const ahd_reg_parse_entry_t MDFFSTAT_parse_table[] = {
        { "FIFOFREE",           0x01, 0x01 },
        { "DATAINFIFO",         0x02, 0x02 },
@@ -1256,1213 +524,222 @@ ahd_mdffstat_print(u_int regvalue, u_int *cur_col, u_int wrap)
 }
 
 int
-ahd_lastscb_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "LASTSCB",
-           0x5e, regvalue, cur_col, wrap));
-}
-
-int
-ahd_shaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SHADDR",
-           0x60, regvalue, cur_col, wrap));
-}
-
-int
-ahd_negoaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "NEGOADDR",
-           0x60, regvalue, cur_col, wrap));
-}
-
-int
-ahd_negperiod_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "NEGPERIOD",
-           0x61, regvalue, cur_col, wrap));
-}
-
-int
-ahd_negoffset_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_seloid_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahd_print_register(NULL, 0, "NEGOFFSET",
-           0x62, regvalue, cur_col, wrap));
+       return (ahd_print_register(NULL, 0, "SELOID",
+           0x6b, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t NEGPPROPTS_parse_table[] = {
-       { "PPROPT_IUT",         0x01, 0x01 },
-       { "PPROPT_DT",          0x02, 0x02 },
-       { "PPROPT_QAS",         0x04, 0x04 },
-       { "PPROPT_PACE",        0x08, 0x08 }
+static const ahd_reg_parse_entry_t SG_STATE_parse_table[] = {
+       { "SEGS_AVAIL",         0x01, 0x01 },
+       { "LOADING_NEEDED",     0x02, 0x02 },
+       { "FETCH_INPROG",       0x04, 0x04 }
 };
 
 int
-ahd_negppropts_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_sg_state_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahd_print_register(NEGPPROPTS_parse_table, 4, "NEGPPROPTS",
-           0x63, regvalue, cur_col, wrap));
+       return (ahd_print_register(SG_STATE_parse_table, 3, "SG_STATE",
+           0xa6, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t NEGCONOPTS_parse_table[] = {
-       { "WIDEXFER",           0x01, 0x01 },
-       { "ENAUTOATNO",         0x02, 0x02 },
-       { "ENAUTOATNI",         0x04, 0x04 },
-       { "ENSLOWCRC",          0x08, 0x08 },
-       { "RTI_OVRDTRN",        0x10, 0x10 },
-       { "RTI_WRTDIS",         0x20, 0x20 },
-       { "ENSNAPSHOT",         0x40, 0x40 }
+static const ahd_reg_parse_entry_t CCSCBCTL_parse_table[] = {
+       { "CCSCBRESET",         0x01, 0x01 },
+       { "CCSCBDIR",           0x04, 0x04 },
+       { "CCSCBEN",            0x08, 0x08 },
+       { "CCARREN",            0x10, 0x10 },
+       { "ARRDONE",            0x40, 0x40 },
+       { "CCSCBDONE",          0x80, 0x80 }
 };
 
 int
-ahd_negconopts_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NEGCONOPTS_parse_table, 7, "NEGCONOPTS",
-           0x64, regvalue, cur_col, wrap));
-}
-
-int
-ahd_annexcol_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "ANNEXCOL",
-           0x65, regvalue, cur_col, wrap));
-}
-
-int
-ahd_annexdat_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_ccscbctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahd_print_register(NULL, 0, "ANNEXDAT",
-           0x66, regvalue, cur_col, wrap));
+       return (ahd_print_register(CCSCBCTL_parse_table, 6, "CCSCBCTL",
+           0xad, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t SCSCHKN_parse_table[] = {
-       { "LSTSGCLRDIS",        0x01, 0x01 },
-       { "SHVALIDSTDIS",       0x02, 0x02 },
-       { "DFFACTCLR",          0x04, 0x04 },
-       { "SDONEMSKDIS",        0x08, 0x08 },
-       { "WIDERESEN",          0x10, 0x10 },
-       { "CURRFIFODEF",        0x20, 0x20 },
-       { "STSELSKIDDIS",       0x40, 0x40 },
-       { "BIDICHKDIS",         0x80, 0x80 }
+static const ahd_reg_parse_entry_t CCSGCTL_parse_table[] = {
+       { "CCSGRESET",          0x01, 0x01 },
+       { "SG_FETCH_REQ",       0x02, 0x02 },
+       { "CCSGENACK",          0x08, 0x08 },
+       { "SG_CACHE_AVAIL",     0x10, 0x10 },
+       { "CCSGDONE",           0x80, 0x80 },
+       { "CCSGEN",             0x0c, 0x0c }
 };
 
 int
-ahd_scschkn_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_ccsgctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahd_print_register(SCSCHKN_parse_table, 8, "SCSCHKN",
-           0x66, regvalue, cur_col, wrap));
+       return (ahd_print_register(CCSGCTL_parse_table, 6, "CCSGCTL",
+           0xad, regvalue, cur_col, wrap));
 }
 
-int
-ahd_iownid_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "IOWNID",
-           0x67, regvalue, cur_col, wrap));
-}
+static const ahd_reg_parse_entry_t SEQCTL0_parse_table[] = {
+       { "LOADRAM",            0x01, 0x01 },
+       { "SEQRESET",           0x02, 0x02 },
+       { "STEP",               0x04, 0x04 },
+       { "BRKADRINTEN",        0x08, 0x08 },
+       { "FASTMODE",           0x10, 0x10 },
+       { "FAILDIS",            0x20, 0x20 },
+       { "PAUSEDIS",           0x40, 0x40 },
+       { "PERRORDIS",          0x80, 0x80 }
+};
 
 int
-ahd_shcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_seqctl0_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahd_print_register(NULL, 0, "SHCNT",
-           0x68, regvalue, cur_col, wrap));
+       return (ahd_print_register(SEQCTL0_parse_table, 8, "SEQCTL0",
+           0xd6, regvalue, cur_col, wrap));
 }
 
-int
-ahd_townid_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "TOWNID",
-           0x69, regvalue, cur_col, wrap));
-}
+static const ahd_reg_parse_entry_t SEQINTCTL_parse_table[] = {
+       { "IRET",               0x01, 0x01 },
+       { "INTMASK1",           0x02, 0x02 },
+       { "INTMASK2",           0x04, 0x04 },
+       { "SCS_SEQ_INT1M0",     0x08, 0x08 },
+       { "SCS_SEQ_INT1M1",     0x10, 0x10 },
+       { "INT1_CONTEXT",       0x20, 0x20 },
+       { "INTVEC1DSL",         0x80, 0x80 }
+};
 
 int
-ahd_seloid_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_seqintctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahd_print_register(NULL, 0, "SELOID",
-           0x6b, regvalue, cur_col, wrap));
+       return (ahd_print_register(SEQINTCTL_parse_table, 7, "SEQINTCTL",
+           0xd9, regvalue, cur_col, wrap));
 }
 
 int
-ahd_haddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_sram_base_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahd_print_register(NULL, 0, "HADDR",
-           0x70, regvalue, cur_col, wrap));
+       return (ahd_print_register(NULL, 0, "SRAM_BASE",
+           0x100, regvalue, cur_col, wrap));
 }
 
 int
-ahd_hcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_qfreeze_count_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahd_print_register(NULL, 0, "HCNT",
-           0x78, regvalue, cur_col, wrap));
+       return (ahd_print_register(NULL, 0, "QFREEZE_COUNT",
+           0x132, regvalue, cur_col, wrap));
 }
 
 int
-ahd_sghaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_kernel_qfreeze_count_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahd_print_register(NULL, 0, "SGHADDR",
-           0x7c, regvalue, cur_col, wrap));
+       return (ahd_print_register(NULL, 0, "KERNEL_QFREEZE_COUNT",
+           0x134, regvalue, cur_col, wrap));
 }
 
 int
-ahd_scbhaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_saved_mode_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahd_print_register(NULL, 0, "SCBHADDR",
-           0x7c, regvalue, cur_col, wrap));
+       return (ahd_print_register(NULL, 0, "SAVED_MODE",
+           0x136, regvalue, cur_col, wrap));
 }
 
-int
-ahd_sghcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SGHCNT",
-           0x84, regvalue, cur_col, wrap));
-}
+static const ahd_reg_parse_entry_t SEQ_FLAGS_parse_table[] = {
+       { "NO_DISCONNECT",      0x01, 0x01 },
+       { "SPHASE_PENDING",     0x02, 0x02 },
+       { "DPHASE_PENDING",     0x04, 0x04 },
+       { "CMDPHASE_PENDING",   0x08, 0x08 },
+       { "TARG_CMD_PENDING",   0x10, 0x10 },
+       { "DPHASE",             0x20, 0x20 },
+       { "NO_CDB_SENT",        0x40, 0x40 },
+       { "TARGET_CMD_IS_TAGGED",0x40, 0x40 },
+       { "NOT_IDENTIFIED",     0x80, 0x80 }
+};
 
 int
-ahd_scbhcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_seq_flags_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahd_print_register(NULL, 0, "SCBHCNT",
-           0x84, regvalue, cur_col, wrap));
+       return (ahd_print_register(SEQ_FLAGS_parse_table, 9, "SEQ_FLAGS",
+           0x139, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t DFF_THRSH_parse_table[] = {
-       { "WR_DFTHRSH_MIN",     0x00, 0x70 },
-       { "RD_DFTHRSH_MIN",     0x00, 0x07 },
-       { "RD_DFTHRSH_25",      0x01, 0x07 },
-       { "RD_DFTHRSH_50",      0x02, 0x07 },
-       { "RD_DFTHRSH_63",      0x03, 0x07 },
-       { "RD_DFTHRSH_75",      0x04, 0x07 },
-       { "RD_DFTHRSH_85",      0x05, 0x07 },
-       { "RD_DFTHRSH_90",      0x06, 0x07 },
-       { "RD_DFTHRSH_MAX",     0x07, 0x07 },
-       { "WR_DFTHRSH_25",      0x10, 0x70 },
-       { "WR_DFTHRSH_50",      0x20, 0x70 },
-       { "WR_DFTHRSH_63",      0x30, 0x70 },
-       { "WR_DFTHRSH_75",      0x40, 0x70 },
-       { "WR_DFTHRSH_85",      0x50, 0x70 },
-       { "WR_DFTHRSH_90",      0x60, 0x70 },
-       { "WR_DFTHRSH_MAX",     0x70, 0x70 },
-       { "RD_DFTHRSH",         0x07, 0x07 },
-       { "WR_DFTHRSH",         0x70, 0x70 }
+static const ahd_reg_parse_entry_t LASTPHASE_parse_table[] = {
+       { "P_DATAOUT",          0x00, 0xe0 },
+       { "P_DATAOUT_DT",       0x20, 0xe0 },
+       { "P_DATAIN",           0x40, 0xe0 },
+       { "P_DATAIN_DT",        0x60, 0xe0 },
+       { "P_COMMAND",          0x80, 0xe0 },
+       { "P_MESGOUT",          0xa0, 0xe0 },
+       { "P_STATUS",           0xc0, 0xe0 },
+       { "P_MESGIN",           0xe0, 0xe0 },
+       { "P_BUSFREE",          0x01, 0x01 },
+       { "MSGI",               0x20, 0x20 },
+       { "IOI",                0x40, 0x40 },
+       { "CDI",                0x80, 0x80 },
+       { "PHASE_MASK",         0xe0, 0xe0 }
 };
 
 int
-ahd_dff_thrsh_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_lastphase_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahd_print_register(DFF_THRSH_parse_table, 18, "DFF_THRSH",
-           0x88, regvalue, cur_col, wrap));
+       return (ahd_print_register(LASTPHASE_parse_table, 13, "LASTPHASE",
+           0x13c, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t PCIXCTL_parse_table[] = {
-       { "CMPABCDIS",          0x01, 0x01 },
-       { "TSCSERREN",          0x02, 0x02 },
-       { "SRSPDPEEN",          0x04, 0x04 },
-       { "SPLTSTADIS",         0x08, 0x08 },
-       { "SPLTSMADIS",         0x10, 0x10 },
-       { "UNEXPSCIEN",         0x20, 0x20 },
-       { "SERRPULSE",          0x80, 0x80 }
+static const ahd_reg_parse_entry_t SEQ_FLAGS2_parse_table[] = {
+       { "PENDING_MK_MESSAGE", 0x01, 0x01 },
+       { "TARGET_MSG_PENDING", 0x02, 0x02 },
+       { "SELECTOUT_QFROZEN",  0x04, 0x04 }
 };
 
 int
-ahd_pcixctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_seq_flags2_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahd_print_register(PCIXCTL_parse_table, 7, "PCIXCTL",
-           0x93, regvalue, cur_col, wrap));
+       return (ahd_print_register(SEQ_FLAGS2_parse_table, 3, "SEQ_FLAGS2",
+           0x14d, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t DCHSPLTSTAT0_parse_table[] = {
-       { "RXSPLTRSP",          0x01, 0x01 },
-       { "RXSCEMSG",           0x02, 0x02 },
-       { "RXOVRUN",            0x04, 0x04 },
-       { "CNTNOTCMPLT",        0x08, 0x08 },
-       { "SCDATBUCKET",        0x10, 0x10 },
-       { "SCADERR",            0x20, 0x20 },
-       { "SCBCERR",            0x40, 0x40 },
-       { "STAETERM",           0x80, 0x80 }
-};
-
 int
-ahd_dchspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_mk_message_scb_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahd_print_register(DCHSPLTSTAT0_parse_table, 8, "DCHSPLTSTAT0",
-           0x96, regvalue, cur_col, wrap));
+       return (ahd_print_register(NULL, 0, "MK_MESSAGE_SCB",
+           0x160, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t DCHSPLTSTAT1_parse_table[] = {
-       { "RXDATABUCKET",       0x01, 0x01 }
-};
-
 int
-ahd_dchspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_mk_message_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahd_print_register(DCHSPLTSTAT1_parse_table, 1, "DCHSPLTSTAT1",
-           0x97, regvalue, cur_col, wrap));
+       return (ahd_print_register(NULL, 0, "MK_MESSAGE_SCSIID",
+           0x162, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t SGSPLTSTAT0_parse_table[] = {
-       { "RXSPLTRSP",          0x01, 0x01 },
-       { "RXSCEMSG",           0x02, 0x02 },
-       { "RXOVRUN",            0x04, 0x04 },
-       { "CNTNOTCMPLT",        0x08, 0x08 },
-       { "SCDATBUCKET",        0x10, 0x10 },
-       { "SCADERR",            0x20, 0x20 },
-       { "SCBCERR",            0x40, 0x40 },
-       { "STAETERM",           0x80, 0x80 }
-};
-
 int
-ahd_sgspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_scb_base_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahd_print_register(SGSPLTSTAT0_parse_table, 8, "SGSPLTSTAT0",
-           0x9e, regvalue, cur_col, wrap));
+       return (ahd_print_register(NULL, 0, "SCB_BASE",
+           0x180, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t SGSPLTSTAT1_parse_table[] = {
-       { "RXDATABUCKET",       0x01, 0x01 }
+static const ahd_reg_parse_entry_t SCB_CONTROL_parse_table[] = {
+       { "SCB_TAG_TYPE",       0x03, 0x03 },
+       { "DISCONNECTED",       0x04, 0x04 },
+       { "STATUS_RCVD",        0x08, 0x08 },
+       { "MK_MESSAGE",         0x10, 0x10 },
+       { "TAG_ENB",            0x20, 0x20 },
+       { "DISCENB",            0x40, 0x40 },
+       { "TARGET_SCB",         0x80, 0x80 }
 };
 
 int
-ahd_sgspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_scb_control_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahd_print_register(SGSPLTSTAT1_parse_table, 1, "SGSPLTSTAT1",
-           0x9f, regvalue, cur_col, wrap));
+       return (ahd_print_register(SCB_CONTROL_parse_table, 7, "SCB_CONTROL",
+           0x192, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t DF0PCISTAT_parse_table[] = {
-       { "DPR",                0x01, 0x01 },
-       { "TWATERR",            0x02, 0x02 },
-       { "RDPERR",             0x04, 0x04 },
-       { "SCAAPERR",           0x08, 0x08 },
-       { "RTA",                0x10, 0x10 },
-       { "RMA",                0x20, 0x20 },
-       { "SSE",                0x40, 0x40 },
-       { "DPE",                0x80, 0x80 }
+static const ahd_reg_parse_entry_t SCB_SCSIID_parse_table[] = {
+       { "OID",                0x0f, 0x0f },
+       { "TID",                0xf0, 0xf0 }
 };
 
 int
-ahd_df0pcistat_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(DF0PCISTAT_parse_table, 8, "DF0PCISTAT",
-           0xa0, regvalue, cur_col, wrap));
-}
-
-int
-ahd_reg0_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "REG0",
-           0xa0, regvalue, cur_col, wrap));
-}
-
-int
-ahd_reg_isr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "REG_ISR",
-           0xa4, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t SG_STATE_parse_table[] = {
-       { "SEGS_AVAIL",         0x01, 0x01 },
-       { "LOADING_NEEDED",     0x02, 0x02 },
-       { "FETCH_INPROG",       0x04, 0x04 }
-};
-
-int
-ahd_sg_state_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SG_STATE_parse_table, 3, "SG_STATE",
-           0xa6, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t TARGPCISTAT_parse_table[] = {
-       { "TWATERR",            0x02, 0x02 },
-       { "STA",                0x08, 0x08 },
-       { "SSE",                0x40, 0x40 },
-       { "DPE",                0x80, 0x80 }
-};
-
-int
-ahd_targpcistat_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(TARGPCISTAT_parse_table, 4, "TARGPCISTAT",
-           0xa7, regvalue, cur_col, wrap));
-}
-
-int
-ahd_scbptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SCBPTR",
-           0xa8, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t SCBAUTOPTR_parse_table[] = {
-       { "SCBPTR_OFF",         0x07, 0x07 },
-       { "SCBPTR_ADDR",        0x38, 0x38 },
-       { "AUSCBPTR_EN",        0x80, 0x80 }
-};
-
-int
-ahd_scbautoptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SCBAUTOPTR_parse_table, 3, "SCBAUTOPTR",
-           0xab, regvalue, cur_col, wrap));
-}
-
-int
-ahd_ccsgaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "CCSGADDR",
-           0xac, regvalue, cur_col, wrap));
-}
-
-int
-ahd_ccscbaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "CCSCBADDR",
-           0xac, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t CCSCBCTL_parse_table[] = {
-       { "CCSCBRESET",         0x01, 0x01 },
-       { "CCSCBDIR",           0x04, 0x04 },
-       { "CCSCBEN",            0x08, 0x08 },
-       { "CCARREN",            0x10, 0x10 },
-       { "ARRDONE",            0x40, 0x40 },
-       { "CCSCBDONE",          0x80, 0x80 }
-};
-
-int
-ahd_ccscbctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(CCSCBCTL_parse_table, 6, "CCSCBCTL",
-           0xad, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t CCSGCTL_parse_table[] = {
-       { "CCSGRESET",          0x01, 0x01 },
-       { "SG_FETCH_REQ",       0x02, 0x02 },
-       { "CCSGENACK",          0x08, 0x08 },
-       { "SG_CACHE_AVAIL",     0x10, 0x10 },
-       { "CCSGDONE",           0x80, 0x80 },
-       { "CCSGEN",             0x0c, 0x0c }
-};
-
-int
-ahd_ccsgctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(CCSGCTL_parse_table, 6, "CCSGCTL",
-           0xad, regvalue, cur_col, wrap));
-}
-
-int
-ahd_ccsgram_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "CCSGRAM",
-           0xb0, regvalue, cur_col, wrap));
-}
-
-int
-ahd_ccscbram_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "CCSCBRAM",
-           0xb0, regvalue, cur_col, wrap));
-}
-
-int
-ahd_brddat_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "BRDDAT",
-           0xb8, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t BRDCTL_parse_table[] = {
-       { "BRDSTB",             0x01, 0x01 },
-       { "BRDRW",              0x02, 0x02 },
-       { "BRDEN",              0x04, 0x04 },
-       { "BRDADDR",            0x38, 0x38 },
-       { "FLXARBREQ",          0x40, 0x40 },
-       { "FLXARBACK",          0x80, 0x80 }
-};
-
-int
-ahd_brdctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(BRDCTL_parse_table, 6, "BRDCTL",
-           0xb9, regvalue, cur_col, wrap));
-}
-
-int
-ahd_seeadr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SEEADR",
-           0xba, regvalue, cur_col, wrap));
-}
-
-int
-ahd_seedat_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SEEDAT",
-           0xbc, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t SEECTL_parse_table[] = {
-       { "SEEOP_ERAL",         0x40, 0x70 },
-       { "SEEOP_WRITE",        0x50, 0x70 },
-       { "SEEOP_READ",         0x60, 0x70 },
-       { "SEEOP_ERASE",        0x70, 0x70 },
-       { "SEESTART",           0x01, 0x01 },
-       { "SEERST",             0x02, 0x02 },
-       { "SEEOPCODE",          0x70, 0x70 },
-       { "SEEOP_EWEN",         0x40, 0x40 },
-       { "SEEOP_WALL",         0x40, 0x40 },
-       { "SEEOP_EWDS",         0x40, 0x40 }
-};
-
-int
-ahd_seectl_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SEECTL_parse_table, 10, "SEECTL",
-           0xbe, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t SEESTAT_parse_table[] = {
-       { "SEESTART",           0x01, 0x01 },
-       { "SEEBUSY",            0x02, 0x02 },
-       { "SEEARBACK",          0x04, 0x04 },
-       { "LDALTID_L",          0x08, 0x08 },
-       { "SEEOPCODE",          0x70, 0x70 },
-       { "INIT_DONE",          0x80, 0x80 }
-};
-
-int
-ahd_seestat_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SEESTAT_parse_table, 6, "SEESTAT",
-           0xbe, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t DSPDATACTL_parse_table[] = {
-       { "XMITOFFSTDIS",       0x02, 0x02 },
-       { "RCVROFFSTDIS",       0x04, 0x04 },
-       { "DESQDIS",            0x10, 0x10 },
-       { "BYPASSENAB",         0x80, 0x80 }
-};
-
-int
-ahd_dspdatactl_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(DSPDATACTL_parse_table, 4, "DSPDATACTL",
-           0xc1, regvalue, cur_col, wrap));
-}
-
-int
-ahd_dfdat_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "DFDAT",
-           0xc4, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t DSPSELECT_parse_table[] = {
-       { "DSPSEL",             0x1f, 0x1f },
-       { "AUTOINCEN",          0x80, 0x80 }
-};
-
-int
-ahd_dspselect_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(DSPSELECT_parse_table, 2, "DSPSELECT",
-           0xc4, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t WRTBIASCTL_parse_table[] = {
-       { "XMITMANVAL",         0x3f, 0x3f },
-       { "AUTOXBCDIS",         0x80, 0x80 }
-};
-
-int
-ahd_wrtbiasctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(WRTBIASCTL_parse_table, 2, "WRTBIASCTL",
-           0xc5, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t SEQCTL0_parse_table[] = {
-       { "LOADRAM",            0x01, 0x01 },
-       { "SEQRESET",           0x02, 0x02 },
-       { "STEP",               0x04, 0x04 },
-       { "BRKADRINTEN",        0x08, 0x08 },
-       { "FASTMODE",           0x10, 0x10 },
-       { "FAILDIS",            0x20, 0x20 },
-       { "PAUSEDIS",           0x40, 0x40 },
-       { "PERRORDIS",          0x80, 0x80 }
-};
-
-int
-ahd_seqctl0_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SEQCTL0_parse_table, 8, "SEQCTL0",
-           0xd6, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t FLAGS_parse_table[] = {
-       { "CARRY",              0x01, 0x01 },
-       { "ZERO",               0x02, 0x02 }
-};
-
-int
-ahd_flags_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(FLAGS_parse_table, 2, "FLAGS",
-           0xd8, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t SEQINTCTL_parse_table[] = {
-       { "IRET",               0x01, 0x01 },
-       { "INTMASK1",           0x02, 0x02 },
-       { "INTMASK2",           0x04, 0x04 },
-       { "SCS_SEQ_INT1M0",     0x08, 0x08 },
-       { "SCS_SEQ_INT1M1",     0x10, 0x10 },
-       { "INT1_CONTEXT",       0x20, 0x20 },
-       { "INTVEC1DSL",         0x80, 0x80 }
-};
-
-int
-ahd_seqintctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SEQINTCTL_parse_table, 7, "SEQINTCTL",
-           0xd9, regvalue, cur_col, wrap));
-}
-
-int
-ahd_seqram_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SEQRAM",
-           0xda, regvalue, cur_col, wrap));
-}
-
-int
-ahd_prgmcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "PRGMCNT",
-           0xde, regvalue, cur_col, wrap));
-}
-
-int
-ahd_accum_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "ACCUM",
-           0xe0, regvalue, cur_col, wrap));
-}
-
-int
-ahd_sindex_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SINDEX",
-           0xe2, regvalue, cur_col, wrap));
-}
-
-int
-ahd_dindex_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "DINDEX",
-           0xe4, regvalue, cur_col, wrap));
-}
-
-int
-ahd_allones_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "ALLONES",
-           0xe8, regvalue, cur_col, wrap));
-}
-
-int
-ahd_allzeros_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "ALLZEROS",
-           0xea, regvalue, cur_col, wrap));
-}
-
-int
-ahd_none_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "NONE",
-           0xea, regvalue, cur_col, wrap));
-}
-
-int
-ahd_sindir_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SINDIR",
-           0xec, regvalue, cur_col, wrap));
-}
-
-int
-ahd_dindir_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "DINDIR",
-           0xed, regvalue, cur_col, wrap));
-}
-
-int
-ahd_stack_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "STACK",
-           0xf2, regvalue, cur_col, wrap));
-}
-
-int
-ahd_intvec1_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "INTVEC1_ADDR",
-           0xf4, regvalue, cur_col, wrap));
-}
-
-int
-ahd_curaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "CURADDR",
-           0xf4, regvalue, cur_col, wrap));
-}
-
-int
-ahd_intvec2_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "INTVEC2_ADDR",
-           0xf6, regvalue, cur_col, wrap));
-}
-
-int
-ahd_longjmp_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "LONGJMP_ADDR",
-           0xf8, regvalue, cur_col, wrap));
-}
-
-int
-ahd_accum_save_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "ACCUM_SAVE",
-           0xfa, regvalue, cur_col, wrap));
-}
-
-int
-ahd_sram_base_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SRAM_BASE",
-           0x100, regvalue, cur_col, wrap));
-}
-
-int
-ahd_waiting_scb_tails_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "WAITING_SCB_TAILS",
-           0x100, regvalue, cur_col, wrap));
-}
-
-int
-ahd_waiting_tid_head_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "WAITING_TID_HEAD",
-           0x120, regvalue, cur_col, wrap));
-}
-
-int
-ahd_waiting_tid_tail_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "WAITING_TID_TAIL",
-           0x122, regvalue, cur_col, wrap));
-}
-
-int
-ahd_next_queued_scb_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "NEXT_QUEUED_SCB_ADDR",
-           0x124, regvalue, cur_col, wrap));
-}
-
-int
-ahd_complete_scb_head_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "COMPLETE_SCB_HEAD",
-           0x128, regvalue, cur_col, wrap));
-}
-
-int
-ahd_complete_scb_dmainprog_head_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "COMPLETE_SCB_DMAINPROG_HEAD",
-           0x12a, regvalue, cur_col, wrap));
-}
-
-int
-ahd_complete_dma_scb_head_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "COMPLETE_DMA_SCB_HEAD",
-           0x12c, regvalue, cur_col, wrap));
-}
-
-int
-ahd_complete_dma_scb_tail_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "COMPLETE_DMA_SCB_TAIL",
-           0x12e, regvalue, cur_col, wrap));
-}
-
-int
-ahd_complete_on_qfreeze_head_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "COMPLETE_ON_QFREEZE_HEAD",
-           0x130, regvalue, cur_col, wrap));
-}
-
-int
-ahd_qfreeze_count_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "QFREEZE_COUNT",
-           0x132, regvalue, cur_col, wrap));
-}
-
-int
-ahd_kernel_qfreeze_count_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "KERNEL_QFREEZE_COUNT",
-           0x134, regvalue, cur_col, wrap));
-}
-
-int
-ahd_saved_mode_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SAVED_MODE",
-           0x136, regvalue, cur_col, wrap));
-}
-
-int
-ahd_msg_out_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "MSG_OUT",
-           0x137, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t DMAPARAMS_parse_table[] = {
-       { "FIFORESET",          0x01, 0x01 },
-       { "FIFOFLUSH",          0x02, 0x02 },
-       { "DIRECTION",          0x04, 0x04 },
-       { "HDMAEN",             0x08, 0x08 },
-       { "HDMAENACK",          0x08, 0x08 },
-       { "SDMAEN",             0x10, 0x10 },
-       { "SDMAENACK",          0x10, 0x10 },
-       { "SCSIEN",             0x20, 0x20 },
-       { "WIDEODD",            0x40, 0x40 },
-       { "PRELOADEN",          0x80, 0x80 }
-};
-
-int
-ahd_dmaparams_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(DMAPARAMS_parse_table, 10, "DMAPARAMS",
-           0x138, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t SEQ_FLAGS_parse_table[] = {
-       { "NO_DISCONNECT",      0x01, 0x01 },
-       { "SPHASE_PENDING",     0x02, 0x02 },
-       { "DPHASE_PENDING",     0x04, 0x04 },
-       { "CMDPHASE_PENDING",   0x08, 0x08 },
-       { "TARG_CMD_PENDING",   0x10, 0x10 },
-       { "DPHASE",             0x20, 0x20 },
-       { "NO_CDB_SENT",        0x40, 0x40 },
-       { "TARGET_CMD_IS_TAGGED",0x40, 0x40 },
-       { "NOT_IDENTIFIED",     0x80, 0x80 }
-};
-
-int
-ahd_seq_flags_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SEQ_FLAGS_parse_table, 9, "SEQ_FLAGS",
-           0x139, regvalue, cur_col, wrap));
-}
-
-int
-ahd_saved_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SAVED_SCSIID",
-           0x13a, regvalue, cur_col, wrap));
-}
-
-int
-ahd_saved_lun_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SAVED_LUN",
-           0x13b, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t LASTPHASE_parse_table[] = {
-       { "P_DATAOUT",          0x00, 0xe0 },
-       { "P_DATAOUT_DT",       0x20, 0xe0 },
-       { "P_DATAIN",           0x40, 0xe0 },
-       { "P_DATAIN_DT",        0x60, 0xe0 },
-       { "P_COMMAND",          0x80, 0xe0 },
-       { "P_MESGOUT",          0xa0, 0xe0 },
-       { "P_STATUS",           0xc0, 0xe0 },
-       { "P_MESGIN",           0xe0, 0xe0 },
-       { "P_BUSFREE",          0x01, 0x01 },
-       { "MSGI",               0x20, 0x20 },
-       { "IOI",                0x40, 0x40 },
-       { "CDI",                0x80, 0x80 },
-       { "PHASE_MASK",         0xe0, 0xe0 }
-};
-
-int
-ahd_lastphase_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(LASTPHASE_parse_table, 13, "LASTPHASE",
-           0x13c, regvalue, cur_col, wrap));
-}
-
-int
-ahd_qoutfifo_entry_valid_tag_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "QOUTFIFO_ENTRY_VALID_TAG",
-           0x13d, regvalue, cur_col, wrap));
-}
-
-int
-ahd_kernel_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "KERNEL_TQINPOS",
-           0x13e, regvalue, cur_col, wrap));
-}
-
-int
-ahd_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "TQINPOS",
-           0x13f, regvalue, cur_col, wrap));
-}
-
-int
-ahd_shared_data_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SHARED_DATA_ADDR",
-           0x140, regvalue, cur_col, wrap));
-}
-
-int
-ahd_qoutfifo_next_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "QOUTFIFO_NEXT_ADDR",
-           0x144, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t ARG_1_parse_table[] = {
-       { "CONT_MSG_LOOP_TARG", 0x02, 0x02 },
-       { "CONT_MSG_LOOP_READ", 0x03, 0x03 },
-       { "CONT_MSG_LOOP_WRITE",0x04, 0x04 },
-       { "EXIT_MSG_LOOP",      0x08, 0x08 },
-       { "MSGOUT_PHASEMIS",    0x10, 0x10 },
-       { "SEND_REJ",           0x20, 0x20 },
-       { "SEND_SENSE",         0x40, 0x40 },
-       { "SEND_MSG",           0x80, 0x80 }
-};
-
-int
-ahd_arg_1_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(ARG_1_parse_table, 8, "ARG_1",
-           0x148, regvalue, cur_col, wrap));
-}
-
-int
-ahd_arg_2_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "ARG_2",
-           0x149, regvalue, cur_col, wrap));
-}
-
-int
-ahd_last_msg_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "LAST_MSG",
-           0x14a, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t SCSISEQ_TEMPLATE_parse_table[] = {
-       { "ALTSTIM",            0x01, 0x01 },
-       { "ENAUTOATNP",         0x02, 0x02 },
-       { "MANUALP",            0x0c, 0x0c },
-       { "ENRSELI",            0x10, 0x10 },
-       { "ENSELI",             0x20, 0x20 },
-       { "MANUALCTL",          0x40, 0x40 }
-};
-
-int
-ahd_scsiseq_template_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SCSISEQ_TEMPLATE_parse_table, 6, "SCSISEQ_TEMPLATE",
-           0x14b, regvalue, cur_col, wrap));
-}
-
-int
-ahd_initiator_tag_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "INITIATOR_TAG",
-           0x14c, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t SEQ_FLAGS2_parse_table[] = {
-       { "PENDING_MK_MESSAGE", 0x01, 0x01 },
-       { "TARGET_MSG_PENDING", 0x02, 0x02 },
-       { "SELECTOUT_QFROZEN",  0x04, 0x04 }
-};
-
-int
-ahd_seq_flags2_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SEQ_FLAGS2_parse_table, 3, "SEQ_FLAGS2",
-           0x14d, regvalue, cur_col, wrap));
-}
-
-int
-ahd_allocfifo_scbptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "ALLOCFIFO_SCBPTR",
-           0x14e, regvalue, cur_col, wrap));
-}
-
-int
-ahd_int_coalescing_timer_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "INT_COALESCING_TIMER",
-           0x150, regvalue, cur_col, wrap));
-}
-
-int
-ahd_int_coalescing_maxcmds_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "INT_COALESCING_MAXCMDS",
-           0x152, regvalue, cur_col, wrap));
-}
-
-int
-ahd_int_coalescing_mincmds_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "INT_COALESCING_MINCMDS",
-           0x153, regvalue, cur_col, wrap));
-}
-
-int
-ahd_cmds_pending_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "CMDS_PENDING",
-           0x154, regvalue, cur_col, wrap));
-}
-
-int
-ahd_int_coalescing_cmdcount_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "INT_COALESCING_CMDCOUNT",
-           0x156, regvalue, cur_col, wrap));
-}
-
-int
-ahd_local_hs_mailbox_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "LOCAL_HS_MAILBOX",
-           0x157, regvalue, cur_col, wrap));
-}
-
-int
-ahd_cmdsize_table_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "CMDSIZE_TABLE",
-           0x158, regvalue, cur_col, wrap));
-}
-
-int
-ahd_mk_message_scb_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "MK_MESSAGE_SCB",
-           0x160, regvalue, cur_col, wrap));
-}
-
-int
-ahd_mk_message_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "MK_MESSAGE_SCSIID",
-           0x162, regvalue, cur_col, wrap));
-}
-
-int
-ahd_scb_residual_datacnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SCB_RESIDUAL_DATACNT",
-           0x180, regvalue, cur_col, wrap));
-}
-
-int
-ahd_scb_base_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SCB_BASE",
-           0x180, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t SCB_RESIDUAL_SGPTR_parse_table[] = {
-       { "SG_LIST_NULL",       0x01, 0x01 },
-       { "SG_OVERRUN_RESID",   0x02, 0x02 },
-       { "SG_ADDR_MASK",       0xf8, 0xf8 }
-};
-
-int
-ahd_scb_residual_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SCB_RESIDUAL_SGPTR_parse_table, 3, "SCB_RESIDUAL_SGPTR",
-           0x184, regvalue, cur_col, wrap));
-}
-
-int
-ahd_scb_scsi_status_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SCB_SCSI_STATUS",
-           0x188, regvalue, cur_col, wrap));
-}
-
-int
-ahd_scb_sense_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SCB_SENSE_BUSADDR",
-           0x18c, regvalue, cur_col, wrap));
-}
-
-int
-ahd_scb_tag_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SCB_TAG",
-           0x190, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t SCB_CONTROL_parse_table[] = {
-       { "SCB_TAG_TYPE",       0x03, 0x03 },
-       { "DISCONNECTED",       0x04, 0x04 },
-       { "STATUS_RCVD",        0x08, 0x08 },
-       { "MK_MESSAGE",         0x10, 0x10 },
-       { "TAG_ENB",            0x20, 0x20 },
-       { "DISCENB",            0x40, 0x40 },
-       { "TARGET_SCB",         0x80, 0x80 }
-};
-
-int
-ahd_scb_control_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SCB_CONTROL_parse_table, 7, "SCB_CONTROL",
-           0x192, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t SCB_SCSIID_parse_table[] = {
-       { "OID",                0x0f, 0x0f },
-       { "TID",                0xf0, 0xf0 }
-};
-
-int
-ahd_scb_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_scb_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
        return (ahd_print_register(SCB_SCSIID_parse_table, 2, "SCB_SCSIID",
            0x193, regvalue, cur_col, wrap));
 }
 
-static const ahd_reg_parse_entry_t SCB_LUN_parse_table[] = {
-       { "LID",                0xff, 0xff }
-};
-
-int
-ahd_scb_lun_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SCB_LUN_parse_table, 1, "SCB_LUN",
-           0x194, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t SCB_TASK_ATTRIBUTE_parse_table[] = {
-       { "SCB_XFERLEN_ODD",    0x01, 0x01 }
-};
-
-int
-ahd_scb_task_attribute_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SCB_TASK_ATTRIBUTE_parse_table, 1, "SCB_TASK_ATTRIBUTE",
-           0x195, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t SCB_CDB_LEN_parse_table[] = {
-       { "SCB_CDB_LEN_PTR",    0x80, 0x80 }
-};
-
-int
-ahd_scb_cdb_len_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SCB_CDB_LEN_parse_table, 1, "SCB_CDB_LEN",
-           0x196, regvalue, cur_col, wrap));
-}
-
-int
-ahd_scb_task_management_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT",
-           0x197, regvalue, cur_col, wrap));
-}
-
-int
-ahd_scb_dataptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SCB_DATAPTR",
-           0x198, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t SCB_DATACNT_parse_table[] = {
-       { "SG_HIGH_ADDR_BITS",  0x7f, 0x7f },
-       { "SG_LAST_SEG",        0x80, 0x80 }
-};
-
-int
-ahd_scb_datacnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SCB_DATACNT_parse_table, 2, "SCB_DATACNT",
-           0x1a0, regvalue, cur_col, wrap));
-}
-
-static const ahd_reg_parse_entry_t SCB_SGPTR_parse_table[] = {
-       { "SG_LIST_NULL",       0x01, 0x01 },
-       { "SG_FULL_RESID",      0x02, 0x02 },
-       { "SG_STATUS_VALID",    0x04, 0x04 }
-};
-
-int
-ahd_scb_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(SCB_SGPTR_parse_table, 3, "SCB_SGPTR",
-           0x1a4, regvalue, cur_col, wrap));
-}
-
-int
-ahd_scb_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SCB_BUSADDR",
-           0x1a8, regvalue, cur_col, wrap));
-}
-
-int
-ahd_scb_next_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SCB_NEXT",
-           0x1ac, regvalue, cur_col, wrap));
-}
-
-int
-ahd_scb_next2_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SCB_NEXT2",
-           0x1ae, regvalue, cur_col, wrap));
-}
-
-int
-ahd_scb_disconnected_lists_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahd_print_register(NULL, 0, "SCB_DISCONNECTED_LISTS",
-           0x1b8, regvalue, cur_col, wrap));
-}
-
index 0d2f763c3427c820300303fb8bec461a4a66548b..9a96e55da39ad6406090b5f693c0396d1512d64f 100644 (file)
@@ -50,6 +50,17 @@ VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#40 $"
  * Adaptec's Technical Documents Department 1-800-934-2766
  */
 
+/*
+ * Registers marked "dont_generate_debug_code" are not (yet) referenced
+ * from the driver code, and this keyword inhibit generation
+ * of debug code for them.
+ *
+ * REG_PRETTY_PRINT config will complain if dont_generate_debug_code
+ * is added to the register which is referenced in the driver.
+ * Unreferenced register with no dont_generate_debug_code will result
+ * in dead code. No warning is issued.
+ */
+
 /*
  * SCSI Sequence Control (p. 3-11).
  * Each bit, when set starts a specific SCSI sequence on the bus
@@ -97,6 +108,7 @@ register SXFRCTL1 {
        field   ENSTIMER        0x04
        field   ACTNEGEN        0x02
        field   STPWEN          0x01    /* Powered Termination */
+       dont_generate_debug_code
 }
 
 /*
@@ -155,6 +167,7 @@ register SCSISIGO {
        mask    P_MESGOUT       CDI|MSGI
        mask    P_STATUS        CDI|IOI
        mask    P_MESGIN        CDI|IOI|MSGI
+       dont_generate_debug_code
 }
 
 /* 
@@ -194,6 +207,7 @@ register SCSIID     {
         */
        alias   SCSIOFFSET
        mask    SOFS_ULTRA2     0x7f            /* Sync offset U2 chips */
+       dont_generate_debug_code
 }
 
 /*
@@ -205,6 +219,7 @@ register SCSIID     {
 register SCSIDATL {
        address                 0x006
        access_mode RW
+       dont_generate_debug_code
 }
 
 register SCSIDATH {
@@ -223,6 +238,7 @@ register STCNT {
        address                 0x008
        size    3
        access_mode RW
+       dont_generate_debug_code
 }
 
 /* ALT_MODE registers (Ultra2 and Ultra160 chips) */
@@ -248,6 +264,7 @@ register OPTIONMODE {
        field   AUTO_MSGOUT_DE          0x02
        field   DIS_MSGIN_DUALEDGE      0x01
        mask    OPTIONMODE_DEFAULTS     AUTO_MSGOUT_DE|DIS_MSGIN_DUALEDGE
+       dont_generate_debug_code
 }
 
 /* ALT_MODE register on Ultra160 chips */
@@ -256,6 +273,7 @@ register TARGCRCCNT {
        size    2
        access_mode RW
        count           2
+       dont_generate_debug_code
 }
 
 /*
@@ -271,6 +289,7 @@ register CLRSINT0 {
        field   CLRSWRAP        0x08
        field   CLRIOERR        0x08    /* Ultra2 Only */
        field   CLRSPIORDY      0x02
+       dont_generate_debug_code
 }
 
 /*
@@ -306,6 +325,7 @@ register CLRSINT1 {
        field   CLRSCSIPERR     0x04
        field   CLRPHASECHG     0x02
        field   CLRREQINIT      0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -360,6 +380,7 @@ register SCSIID_ULTRA2 {
        access_mode RW
        mask    TID             0xf0            /* Target ID mask */
        mask    OID             0x0f            /* Our ID mask */
+       dont_generate_debug_code
 }
 
 /*
@@ -425,6 +446,7 @@ register SHADDR {
        address                 0x014
        size    4
        access_mode RO
+       dont_generate_debug_code
 }
 
 /*
@@ -441,6 +463,7 @@ register SELTIMER {
        field   STAGE2          0x02
        field   STAGE1          0x01
        alias   TARGIDIN
+       dont_generate_debug_code
 }
 
 /*
@@ -453,6 +476,7 @@ register SELID {
        access_mode RW
        mask    SELID_MASK      0xf0
        field   ONEBIT          0x08
+       dont_generate_debug_code
 }
 
 register SCAMCTL {
@@ -473,6 +497,7 @@ register TARGID {
        size                    2
        access_mode RW
        count           14
+       dont_generate_debug_code
 }
 
 /*
@@ -495,6 +520,7 @@ register SPIOCAP {
        field   EEPROM          0x04    /* Writable external BIOS ROM */
        field   ROM             0x02    /* Logic for accessing external ROM */
        field   SSPIOCPS        0x01    /* Termination and cable detection */
+       dont_generate_debug_code
 }
 
 register BRDCTL        {
@@ -514,6 +540,7 @@ register BRDCTL     {
        field   BRDDAT2         0x04
        field   BRDRW_ULTRA2    0x02
        field   BRDSTB_ULTRA2   0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -551,6 +578,7 @@ register SEECTL {
        field   SEECK           0x04
        field   SEEDO           0x02
        field   SEEDI           0x01
+       dont_generate_debug_code
 }
 /*
  * SCSI Block Control (p. 3-32)
@@ -601,6 +629,7 @@ register SEQRAM {
        address                 0x061
        access_mode RW
        count           2
+       dont_generate_debug_code
 }
 
 /*
@@ -610,6 +639,7 @@ register SEQRAM {
 register SEQADDR0 {
        address                 0x062
        access_mode RW
+       dont_generate_debug_code
 }
 
 register SEQADDR1 {
@@ -617,6 +647,7 @@ register SEQADDR1 {
        access_mode RW
        count           8
        mask    SEQADDR1_MASK   0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -627,35 +658,41 @@ register ACCUM {
        address                 0x064
        access_mode RW
        accumulator
+       dont_generate_debug_code
 }
 
 register SINDEX        {
        address                 0x065
        access_mode RW
        sindex
+       dont_generate_debug_code
 }
 
 register DINDEX {
        address                 0x066
        access_mode RW
+       dont_generate_debug_code
 }
 
 register ALLONES {
        address                 0x069
        access_mode RO
        allones
+       dont_generate_debug_code
 }
 
 register ALLZEROS {
        address                 0x06a
        access_mode RO
        allzeros
+       dont_generate_debug_code
 }
 
 register NONE {
        address                 0x06a
        access_mode WO
        none
+       dont_generate_debug_code
 }
 
 register FLAGS {
@@ -664,16 +701,19 @@ register FLAGS {
        count           18
        field   ZERO            0x02
        field   CARRY           0x01
+       dont_generate_debug_code
 }
 
 register SINDIR        {
        address                 0x06c
        access_mode RO
+       dont_generate_debug_code
 }
 
 register DINDIR         {
        address                 0x06d
        access_mode WO
+       dont_generate_debug_code
 }
 
 register FUNCTION1 {
@@ -685,6 +725,7 @@ register STACK {
        address                 0x06f
        access_mode RO
        count           5
+       dont_generate_debug_code
 }
 
 const  STACK_SIZE      4
@@ -716,6 +757,7 @@ register DSCOMMAND0 {
        field   RAMPS           0x04    /* External SCB RAM Present */
        field   USCBSIZE32      0x02    /* Use 32byte SCB Page Size */
        field   CIOPARCKEN      0x01    /* Internal bus parity error enable */
+       dont_generate_debug_code
 }
 
 register DSCOMMAND1 {
@@ -724,6 +766,7 @@ register DSCOMMAND1 {
        mask    DSLATT          0xfc    /* PCI latency timer (non-ultra2) */
        field   HADDLDSEL1      0x02    /* Host Address Load Select Bits */
        field   HADDLDSEL0      0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -735,6 +778,7 @@ register BUSTIME {
        count           2
        mask    BOFF            0xf0
        mask    BON             0x0f
+       dont_generate_debug_code
 }
 
 /*
@@ -749,6 +793,7 @@ register BUSSPD {
        mask    STBON           0x07
        mask    DFTHRSH_100     0xc0
        mask    DFTHRSH_75      0x80
+       dont_generate_debug_code
 }
 
 /* aic7850/55/60/70/80/95 only */
@@ -756,6 +801,7 @@ register DSPCISTATUS {
        address                 0x086
        count           4
        mask    DFTHRSH_100     0xc0
+       dont_generate_debug_code
 }
 
 /* aic7890/91/96/97 only */
@@ -764,6 +810,7 @@ register HS_MAILBOX {
        mask    HOST_MAILBOX    0xF0
        mask    SEQ_MAILBOX     0x0F
        mask    HOST_TQINPOS    0x80    /* Boundary at either 0 or 128 */
+       dont_generate_debug_code
 }
 
 const  HOST_MAILBOX_SHIFT      4
@@ -784,6 +831,7 @@ register HCNTRL {
        field   INTEN           0x02
        field   CHIPRST         0x01
        field   CHIPRSTACK      0x01
+       dont_generate_debug_code
 }
 
 /*
@@ -795,12 +843,14 @@ register HADDR {
        address                 0x088
        size    4
        access_mode RW
+       dont_generate_debug_code
 }
 
 register HCNT {
        address                 0x08c
        size    3
        access_mode RW
+       dont_generate_debug_code
 }
 
 /*
@@ -810,6 +860,7 @@ register HCNT {
 register SCBPTR {
        address                 0x090
        access_mode RW
+       dont_generate_debug_code
 }
 
 /*
@@ -878,6 +929,7 @@ register INTSTAT {
 
        mask    SEQINT_MASK     0xf0|SEQINT     /* SEQINT Status Codes */
        mask    INT_PEND  (BRKADRINT|SEQINT|SCSIINT|CMDCMPLT)
+       dont_generate_debug_code
 }
 
 /*
@@ -911,6 +963,7 @@ register CLRINT {
        field   CLRSCSIINT      0x04
        field   CLRCMDINT       0x02
        field   CLRSEQINT       0x01
+       dont_generate_debug_code
 }
 
 register DFCNTRL {
@@ -944,6 +997,7 @@ register DFSTATUS {
 register DFWADDR {
        address                 0x95
        access_mode RW
+       dont_generate_debug_code
 }
 
 register DFRADDR {
@@ -954,6 +1008,7 @@ register DFRADDR {
 register DFDAT {
        address                 0x099
        access_mode RW
+       dont_generate_debug_code
 }
 
 /*
@@ -967,6 +1022,7 @@ register SCBCNT {
        count           1
        field   SCBAUTO         0x80
        mask    SCBCNT_MASK     0x1f
+       dont_generate_debug_code
 }
 
 /*
@@ -977,6 +1033,7 @@ register QINFIFO {
        address                 0x09b
        access_mode RW
        count           12
+       dont_generate_debug_code
 }
 
 /*
@@ -996,6 +1053,7 @@ register QOUTFIFO {
        address                 0x09d
        access_mode WO
        count           7
+       dont_generate_debug_code
 }
 
 register CRCCONTROL1 {
@@ -1008,6 +1066,7 @@ register CRCCONTROL1 {
        field   CRCREQCHKEN             0x10
        field   TARGCRCENDEN            0x08
        field   TARGCRCCNTEN            0x04
+       dont_generate_debug_code
 }
 
 
@@ -1040,6 +1099,7 @@ register SFUNCT {
        access_mode RW
        count       4
        field   ALT_MODE        0x80
+       dont_generate_debug_code
 }
 
 /*
@@ -1053,24 +1113,31 @@ scb {
                size    4
                alias   SCB_RESIDUAL_DATACNT
                alias   SCB_CDB_STORE
+               dont_generate_debug_code
        }
        SCB_RESIDUAL_SGPTR {
                size    4
+               dont_generate_debug_code
        }
        SCB_SCSI_STATUS {
                size    1
+               dont_generate_debug_code
        }
        SCB_TARGET_PHASES {
                size    1
+               dont_generate_debug_code
        }
        SCB_TARGET_DATA_DIR {
                size    1
+               dont_generate_debug_code
        }
        SCB_TARGET_ITAG {
                size    1
+               dont_generate_debug_code
        }
        SCB_DATAPTR {
                size    4
+               dont_generate_debug_code
        }
        SCB_DATACNT {
                /*
@@ -1080,12 +1147,14 @@ scb {
                size    4
                field   SG_LAST_SEG             0x80    /* In the fourth byte */
                mask    SG_HIGH_ADDR_BITS       0x7F    /* In the fourth byte */
+               dont_generate_debug_code
        }
        SCB_SGPTR {
                size    4
                field   SG_RESID_VALID  0x04    /* In the first byte */
                field   SG_FULL_RESID   0x02    /* In the first byte */
                field   SG_LIST_NULL    0x01    /* In the first byte */
+               dont_generate_debug_code
        }
        SCB_CONTROL {
                size    1
@@ -1115,22 +1184,27 @@ scb {
        }
        SCB_CDB_LEN {
                size    1
+               dont_generate_debug_code
        }
        SCB_SCSIRATE {
                size    1
+               dont_generate_debug_code
        }
        SCB_SCSIOFFSET {
                size    1
                count   1
+               dont_generate_debug_code
        }
        SCB_NEXT {
                size    1
+               dont_generate_debug_code
        }
        SCB_64_SPARE {
                size    16
        }
        SCB_64_BTT {
                size    16
+               dont_generate_debug_code
        }
 }
 
@@ -1149,6 +1223,7 @@ register SEECTL_2840 {
        field   CS_2840         0x04
        field   CK_2840         0x02
        field   DO_2840         0x01
+       dont_generate_debug_code
 }
 
 register STATUS_2840 {
@@ -1159,6 +1234,7 @@ register STATUS_2840 {
        mask    BIOS_SEL        0x60
        mask    ADSEL           0x1e
        field   DI_2840         0x01
+       dont_generate_debug_code
 }
 
 /* --------------------- AIC-7870-only definitions -------------------- */
@@ -1166,18 +1242,22 @@ register STATUS_2840 {
 register CCHADDR {
        address                 0x0E0
        size 8
+       dont_generate_debug_code
 }
 
 register CCHCNT {
        address                 0x0E8
+       dont_generate_debug_code
 }
 
 register CCSGRAM {
        address                 0x0E9
+       dont_generate_debug_code
 }
 
 register CCSGADDR {
        address                 0x0EA
+       dont_generate_debug_code
 }
 
 register CCSGCTL {
@@ -1186,11 +1266,13 @@ register CCSGCTL {
        field   CCSGEN          0x08
        field   SG_FETCH_NEEDED 0x02    /* Bit used for software state */
        field   CCSGRESET       0x01
+       dont_generate_debug_code
 }
 
 register CCSCBCNT {
        address                 0xEF
        count           1
+       dont_generate_debug_code
 }
 
 register CCSCBCTL {
@@ -1201,14 +1283,17 @@ register CCSCBCTL {
        field   CCSCBEN         0x08
        field   CCSCBDIR        0x04
        field   CCSCBRESET      0x01
+       dont_generate_debug_code
 }
 
 register CCSCBADDR {
        address                 0x0ED
+       dont_generate_debug_code
 }
 
 register CCSCBRAM {
        address                 0xEC
+       dont_generate_debug_code
 }
 
 /*
@@ -1218,23 +1303,28 @@ register SCBBADDR {
        address                 0x0F0
        access_mode RW
        count           3
+       dont_generate_debug_code
 }
 
 register CCSCBPTR {
        address                 0x0F1
+       dont_generate_debug_code
 }
 
 register HNSCB_QOFF {
        address                 0x0F4
        count           4
+       dont_generate_debug_code
 }
 
 register SNSCB_QOFF {
        address                 0x0F6
+       dont_generate_debug_code
 }
 
 register SDSCB_QOFF {
        address                 0x0F8
+       dont_generate_debug_code
 }
 
 register QOFF_CTLSTA {
@@ -1244,6 +1334,7 @@ register QOFF_CTLSTA {
        field   SDSCB_ROLLOVER  0x10
        mask    SCB_QSIZE       0x07
        mask    SCB_QSIZE_256   0x06
+       dont_generate_debug_code
 }
 
 register DFF_THRSH {
@@ -1267,6 +1358,7 @@ register DFF_THRSH {
        mask    WR_DFTHRSH_90   0x60
        mask    WR_DFTHRSH_MAX  0x70
        count   4
+       dont_generate_debug_code
 }
 
 register SG_CACHE_PRE {
@@ -1275,6 +1367,7 @@ register SG_CACHE_PRE {
        mask    SG_ADDR_MASK    0xf8
        field   LAST_SEG        0x02
        field   LAST_SEG_DONE   0x01
+       dont_generate_debug_code
 }
 
 register SG_CACHE_SHADOW {
@@ -1283,6 +1376,7 @@ register SG_CACHE_SHADOW {
        mask    SG_ADDR_MASK    0xf8
        field   LAST_SEG        0x02
        field   LAST_SEG_DONE   0x01
+       dont_generate_debug_code
 }
 /* ---------------------- Scratch RAM Offsets ------------------------- */
 /* These offsets are either to values that are initialized by the board's
@@ -1309,6 +1403,7 @@ scratch_ram {
        BUSY_TARGETS {
                alias           TARG_SCSIRATE
                size            16
+               dont_generate_debug_code
        }
        /*
         * Bit vector of targets that have ULTRA enabled as set by
@@ -1321,6 +1416,7 @@ scratch_ram {
                alias           CMDSIZE_TABLE
                size            2
                count           2
+               dont_generate_debug_code
        }
        /*
         * Bit vector of targets that have disconnection disabled as set by
@@ -1331,6 +1427,7 @@ scratch_ram {
        DISC_DSB {
                size            2
                count           6
+               dont_generate_debug_code
        }
        CMDSIZE_TABLE_TAIL {
                size            4
@@ -1341,12 +1438,14 @@ scratch_ram {
         */
        MWI_RESIDUAL {
                size            1
+               dont_generate_debug_code
        }
        /*
         * SCBID of the next SCB to be started by the controller.
         */
        NEXT_QUEUED_SCB {
                size            1
+               dont_generate_debug_code
        }
        /*
         * Single byte buffer used to designate the type or message
@@ -1354,6 +1453,7 @@ scratch_ram {
         */
        MSG_OUT {
                size            1
+               dont_generate_debug_code
        }
        /* Parameters for DMA Logic */
        DMAPARAMS {
@@ -1369,6 +1469,7 @@ scratch_ram {
                field   DIRECTION       0x04    /* Set indicates PCI->SCSI */
                field   FIFOFLUSH       0x02
                field   FIFORESET       0x01
+               dont_generate_debug_code
        }
        SEQ_FLAGS {
                size            1
@@ -1390,9 +1491,11 @@ scratch_ram {
         */
        SAVED_SCSIID {
                size            1
+               dont_generate_debug_code
        }
        SAVED_LUN {
                size            1
+               dont_generate_debug_code
        }
        /*
         * The last bus phase as seen by the sequencer. 
@@ -1417,6 +1520,7 @@ scratch_ram {
         */
        WAITING_SCBH {
                size            1
+               dont_generate_debug_code
        }
        /*
         * head of list of SCBs that are
@@ -1425,6 +1529,7 @@ scratch_ram {
         */
        DISCONNECTED_SCBH {
                size            1
+               dont_generate_debug_code
        }
        /*
         * head of list of SCBs that are
@@ -1432,6 +1537,7 @@ scratch_ram {
         */
        FREE_SCBH {
                size            1
+               dont_generate_debug_code
        }
        /*
         * head of list of SCBs that have
@@ -1446,6 +1552,7 @@ scratch_ram {
         */
        HSCB_ADDR {
                size            4
+               dont_generate_debug_code
        }
        /*
         * Base address of our shared data with the kernel driver in host
@@ -1454,15 +1561,19 @@ scratch_ram {
         */
        SHARED_DATA_ADDR {
                size            4
+               dont_generate_debug_code
        }
        KERNEL_QINPOS {
                size            1
+               dont_generate_debug_code
        }
        QINPOS {
                size            1
+               dont_generate_debug_code
        }
        QOUTPOS {
                size            1
+               dont_generate_debug_code
        }
        /*
         * Kernel and sequencer offsets into the queue of
@@ -1471,9 +1582,11 @@ scratch_ram {
         */
        KERNEL_TQINPOS {
                size            1
+               dont_generate_debug_code
        }
        TQINPOS {
                size            1
+               dont_generate_debug_code
        }
        ARG_1 {
                size            1
@@ -1486,10 +1599,12 @@ scratch_ram {
                mask    CONT_MSG_LOOP           0x04
                mask    CONT_TARG_SESSION       0x02
                alias   RETURN_1
+               dont_generate_debug_code
        }
        ARG_2 {
                size            1
                alias   RETURN_2
+               dont_generate_debug_code
        }
 
        /*
@@ -1498,6 +1613,7 @@ scratch_ram {
        LAST_MSG {
                size            1
                alias   TARG_IMMEDIATE_SCB
+               dont_generate_debug_code
        }
 
        /*
@@ -1513,6 +1629,7 @@ scratch_ram {
                field   ENAUTOATNO      0x08
                field   ENAUTOATNI      0x04
                field   ENAUTOATNP      0x02
+               dont_generate_debug_code
        }
 }
 
@@ -1533,12 +1650,14 @@ scratch_ram {
                field   HA_274_EXTENDED_TRANS   0x01
                alias   INITIATOR_TAG
                count           1
+               dont_generate_debug_code
        }
 
        SEQ_FLAGS2 {
                size    1
                field   SCB_DMA                 0x01
                field   TARGET_MSG_PENDING      0x02
+               dont_generate_debug_code
        }
 }
 
@@ -1562,6 +1681,7 @@ scratch_ram {
                field   ENSPCHK         0x20
                mask    HSCSIID         0x07    /* our SCSI ID */
                mask    HWSCSIID        0x0f    /* our SCSI ID if Wide Bus */
+               dont_generate_debug_code
        }
        INTDEF {
                address         0x05c
@@ -1569,11 +1689,13 @@ scratch_ram {
                count           1
                field   EDGE_TRIG       0x80
                mask    VECTOR          0x0f
+               dont_generate_debug_code
        }
        HOSTCONF {
                address         0x05d
                size            1
                count           1
+               dont_generate_debug_code
        }
        HA_274_BIOSCTRL {
                address         0x05f
@@ -1582,6 +1704,7 @@ scratch_ram {
                mask    BIOSMODE                0x30
                mask    BIOSDISABLED            0x30    
                field   CHANNEL_B_PRIMARY       0x08
+               dont_generate_debug_code
        }
 }
 
@@ -1595,6 +1718,7 @@ scratch_ram {
        TARG_OFFSET {
                size            16
                count           1
+               dont_generate_debug_code
        }
 }
 
index 0ae2b4605d09aa9068765486903aa19929ed7e9d..e6f2bb7365e64da1736a7a45759ddb3a2ec34638 100644 (file)
@@ -814,6 +814,7 @@ ahc_intr(struct ahc_softc *ahc)
 static void
 ahc_restart(struct ahc_softc *ahc)
 {
+       uint8_t sblkctl;
 
        ahc_pause(ahc);
 
@@ -868,6 +869,12 @@ ahc_restart(struct ahc_softc *ahc)
        ahc_outb(ahc, SEQADDR0, 0);
        ahc_outb(ahc, SEQADDR1, 0);
 
+       /*
+        * Take the LED out of diagnostic mode on PM resume, too
+        */
+       sblkctl = ahc_inb(ahc, SBLKCTL);
+       ahc_outb(ahc, SBLKCTL, (sblkctl & ~(DIAGLEDEN|DIAGLEDON)));
+
        ahc_unpause(ahc);
 }
 
index 2ce1febca207c27d5695626a5316c6d1ceb8c17c..e821082a4f47a23db505a829b47c1cfe47eafe26 100644 (file)
@@ -26,20 +26,6 @@ ahc_reg_print_t ahc_sxfrctl0_print;
     ahc_print_register(NULL, 0, "SXFRCTL0", 0x01, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_sxfrctl1_print;
-#else
-#define ahc_sxfrctl1_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SXFRCTL1", 0x02, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scsisigo_print;
-#else
-#define ahc_scsisigo_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCSISIGO", 0x03, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahc_reg_print_t ahc_scsisigi_print;
 #else
@@ -54,55 +40,6 @@ ahc_reg_print_t ahc_scsirate_print;
     ahc_print_register(NULL, 0, "SCSIRATE", 0x04, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scsiid_print;
-#else
-#define ahc_scsiid_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCSIID", 0x05, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scsidatl_print;
-#else
-#define ahc_scsidatl_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCSIDATL", 0x06, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scsidath_print;
-#else
-#define ahc_scsidath_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCSIDATH", 0x07, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_stcnt_print;
-#else
-#define ahc_stcnt_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "STCNT", 0x08, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_optionmode_print;
-#else
-#define ahc_optionmode_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "OPTIONMODE", 0x08, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_targcrccnt_print;
-#else
-#define ahc_targcrccnt_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "TARGCRCCNT", 0x0a, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_clrsint0_print;
-#else
-#define ahc_clrsint0_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "CLRSINT0", 0x0b, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahc_reg_print_t ahc_sstat0_print;
 #else
@@ -110,13 +47,6 @@ ahc_reg_print_t ahc_sstat0_print;
     ahc_print_register(NULL, 0, "SSTAT0", 0x0b, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_clrsint1_print;
-#else
-#define ahc_clrsint1_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "CLRSINT1", 0x0c, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahc_reg_print_t ahc_sstat1_print;
 #else
@@ -138,13 +68,6 @@ ahc_reg_print_t ahc_sstat3_print;
     ahc_print_register(NULL, 0, "SSTAT3", 0x0e, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scsiid_ultra2_print;
-#else
-#define ahc_scsiid_ultra2_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCSIID_ULTRA2", 0x0f, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahc_reg_print_t ahc_simode0_print;
 #else
@@ -166,76 +89,6 @@ ahc_reg_print_t ahc_scsibusl_print;
     ahc_print_register(NULL, 0, "SCSIBUSL", 0x12, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scsibush_print;
-#else
-#define ahc_scsibush_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCSIBUSH", 0x13, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_sxfrctl2_print;
-#else
-#define ahc_sxfrctl2_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SXFRCTL2", 0x13, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_shaddr_print;
-#else
-#define ahc_shaddr_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SHADDR", 0x14, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_seltimer_print;
-#else
-#define ahc_seltimer_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SELTIMER", 0x18, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_selid_print;
-#else
-#define ahc_selid_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SELID", 0x19, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scamctl_print;
-#else
-#define ahc_scamctl_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCAMCTL", 0x1a, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_targid_print;
-#else
-#define ahc_targid_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "TARGID", 0x1b, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_spiocap_print;
-#else
-#define ahc_spiocap_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SPIOCAP", 0x1b, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_brdctl_print;
-#else
-#define ahc_brdctl_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "BRDCTL", 0x1d, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_seectl_print;
-#else
-#define ahc_seectl_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SEECTL", 0x1e, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahc_reg_print_t ahc_sblkctl_print;
 #else
@@ -243,62 +96,6 @@ ahc_reg_print_t ahc_sblkctl_print;
     ahc_print_register(NULL, 0, "SBLKCTL", 0x1f, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_busy_targets_print;
-#else
-#define ahc_busy_targets_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "BUSY_TARGETS", 0x20, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_ultra_enb_print;
-#else
-#define ahc_ultra_enb_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "ULTRA_ENB", 0x30, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_disc_dsb_print;
-#else
-#define ahc_disc_dsb_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "DISC_DSB", 0x32, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_cmdsize_table_tail_print;
-#else
-#define ahc_cmdsize_table_tail_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "CMDSIZE_TABLE_TAIL", 0x34, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_mwi_residual_print;
-#else
-#define ahc_mwi_residual_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "MWI_RESIDUAL", 0x38, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_next_queued_scb_print;
-#else
-#define ahc_next_queued_scb_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "NEXT_QUEUED_SCB", 0x39, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_msg_out_print;
-#else
-#define ahc_msg_out_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "MSG_OUT", 0x3a, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_dmaparams_print;
-#else
-#define ahc_dmaparams_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "DMAPARAMS", 0x3b, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahc_reg_print_t ahc_seq_flags_print;
 #else
@@ -306,20 +103,6 @@ ahc_reg_print_t ahc_seq_flags_print;
     ahc_print_register(NULL, 0, "SEQ_FLAGS", 0x3c, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_saved_scsiid_print;
-#else
-#define ahc_saved_scsiid_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SAVED_SCSIID", 0x3d, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_saved_lun_print;
-#else
-#define ahc_saved_lun_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SAVED_LUN", 0x3e, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahc_reg_print_t ahc_lastphase_print;
 #else
@@ -327,153 +110,6 @@ ahc_reg_print_t ahc_lastphase_print;
     ahc_print_register(NULL, 0, "LASTPHASE", 0x3f, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_waiting_scbh_print;
-#else
-#define ahc_waiting_scbh_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "WAITING_SCBH", 0x40, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_disconnected_scbh_print;
-#else
-#define ahc_disconnected_scbh_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "DISCONNECTED_SCBH", 0x41, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_free_scbh_print;
-#else
-#define ahc_free_scbh_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "FREE_SCBH", 0x42, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_complete_scbh_print;
-#else
-#define ahc_complete_scbh_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "COMPLETE_SCBH", 0x43, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_hscb_addr_print;
-#else
-#define ahc_hscb_addr_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "HSCB_ADDR", 0x44, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_shared_data_addr_print;
-#else
-#define ahc_shared_data_addr_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SHARED_DATA_ADDR", 0x48, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_kernel_qinpos_print;
-#else
-#define ahc_kernel_qinpos_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "KERNEL_QINPOS", 0x4c, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_qinpos_print;
-#else
-#define ahc_qinpos_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "QINPOS", 0x4d, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_qoutpos_print;
-#else
-#define ahc_qoutpos_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "QOUTPOS", 0x4e, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_kernel_tqinpos_print;
-#else
-#define ahc_kernel_tqinpos_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "KERNEL_TQINPOS", 0x4f, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_tqinpos_print;
-#else
-#define ahc_tqinpos_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "TQINPOS", 0x50, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_arg_1_print;
-#else
-#define ahc_arg_1_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "ARG_1", 0x51, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_arg_2_print;
-#else
-#define ahc_arg_2_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "ARG_2", 0x52, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_last_msg_print;
-#else
-#define ahc_last_msg_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "LAST_MSG", 0x53, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scsiseq_template_print;
-#else
-#define ahc_scsiseq_template_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCSISEQ_TEMPLATE", 0x54, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_ha_274_biosglobal_print;
-#else
-#define ahc_ha_274_biosglobal_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "HA_274_BIOSGLOBAL", 0x56, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_seq_flags2_print;
-#else
-#define ahc_seq_flags2_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SEQ_FLAGS2", 0x57, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scsiconf_print;
-#else
-#define ahc_scsiconf_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCSICONF", 0x5a, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_intdef_print;
-#else
-#define ahc_intdef_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "INTDEF", 0x5c, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_hostconf_print;
-#else
-#define ahc_hostconf_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "HOSTCONF", 0x5d, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_ha_274_biosctrl_print;
-#else
-#define ahc_ha_274_biosctrl_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "HA_274_BIOSCTRL", 0x5f, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahc_reg_print_t ahc_seqctl_print;
 #else
@@ -481,111 +117,6 @@ ahc_reg_print_t ahc_seqctl_print;
     ahc_print_register(NULL, 0, "SEQCTL", 0x60, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_seqram_print;
-#else
-#define ahc_seqram_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SEQRAM", 0x61, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_seqaddr0_print;
-#else
-#define ahc_seqaddr0_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SEQADDR0", 0x62, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_seqaddr1_print;
-#else
-#define ahc_seqaddr1_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SEQADDR1", 0x63, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_accum_print;
-#else
-#define ahc_accum_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "ACCUM", 0x64, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_sindex_print;
-#else
-#define ahc_sindex_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SINDEX", 0x65, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_dindex_print;
-#else
-#define ahc_dindex_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "DINDEX", 0x66, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_allones_print;
-#else
-#define ahc_allones_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "ALLONES", 0x69, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_allzeros_print;
-#else
-#define ahc_allzeros_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "ALLZEROS", 0x6a, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_none_print;
-#else
-#define ahc_none_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "NONE", 0x6a, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_flags_print;
-#else
-#define ahc_flags_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "FLAGS", 0x6b, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_sindir_print;
-#else
-#define ahc_sindir_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SINDIR", 0x6c, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_dindir_print;
-#else
-#define ahc_dindir_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "DINDIR", 0x6d, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_function1_print;
-#else
-#define ahc_function1_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "FUNCTION1", 0x6e, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_stack_print;
-#else
-#define ahc_stack_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "STACK", 0x6f, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_targ_offset_print;
-#else
-#define ahc_targ_offset_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "TARG_OFFSET", 0x70, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahc_reg_print_t ahc_sram_base_print;
 #else
@@ -593,97 +124,6 @@ ahc_reg_print_t ahc_sram_base_print;
     ahc_print_register(NULL, 0, "SRAM_BASE", 0x70, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_bctl_print;
-#else
-#define ahc_bctl_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "BCTL", 0x84, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_dscommand0_print;
-#else
-#define ahc_dscommand0_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "DSCOMMAND0", 0x84, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_bustime_print;
-#else
-#define ahc_bustime_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "BUSTIME", 0x85, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_dscommand1_print;
-#else
-#define ahc_dscommand1_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "DSCOMMAND1", 0x85, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_busspd_print;
-#else
-#define ahc_busspd_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "BUSSPD", 0x86, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_hs_mailbox_print;
-#else
-#define ahc_hs_mailbox_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "HS_MAILBOX", 0x86, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_dspcistatus_print;
-#else
-#define ahc_dspcistatus_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "DSPCISTATUS", 0x86, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_hcntrl_print;
-#else
-#define ahc_hcntrl_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "HCNTRL", 0x87, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_haddr_print;
-#else
-#define ahc_haddr_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "HADDR", 0x88, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_hcnt_print;
-#else
-#define ahc_hcnt_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "HCNT", 0x8c, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scbptr_print;
-#else
-#define ahc_scbptr_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCBPTR", 0x90, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_intstat_print;
-#else
-#define ahc_intstat_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "INTSTAT", 0x91, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_clrint_print;
-#else
-#define ahc_clrint_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "CLRINT", 0x92, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahc_reg_print_t ahc_error_print;
 #else
@@ -705,69 +145,6 @@ ahc_reg_print_t ahc_dfstatus_print;
     ahc_print_register(NULL, 0, "DFSTATUS", 0x94, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_dfwaddr_print;
-#else
-#define ahc_dfwaddr_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "DFWADDR", 0x95, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_dfraddr_print;
-#else
-#define ahc_dfraddr_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "DFRADDR", 0x97, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_dfdat_print;
-#else
-#define ahc_dfdat_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "DFDAT", 0x99, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scbcnt_print;
-#else
-#define ahc_scbcnt_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCBCNT", 0x9a, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_qinfifo_print;
-#else
-#define ahc_qinfifo_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "QINFIFO", 0x9b, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_qincnt_print;
-#else
-#define ahc_qincnt_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "QINCNT", 0x9c, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_qoutfifo_print;
-#else
-#define ahc_qoutfifo_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "QOUTFIFO", 0x9d, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_crccontrol1_print;
-#else
-#define ahc_crccontrol1_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "CRCCONTROL1", 0x9d, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_qoutcnt_print;
-#else
-#define ahc_qoutcnt_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "QOUTCNT", 0x9e, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahc_reg_print_t ahc_scsiphase_print;
 #else
@@ -775,13 +152,6 @@ ahc_reg_print_t ahc_scsiphase_print;
     ahc_print_register(NULL, 0, "SCSIPHASE", 0x9e, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_sfunct_print;
-#else
-#define ahc_sfunct_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SFUNCT", 0x9f, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahc_reg_print_t ahc_scb_base_print;
 #else
@@ -789,69 +159,6 @@ ahc_reg_print_t ahc_scb_base_print;
     ahc_print_register(NULL, 0, "SCB_BASE", 0xa0, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scb_cdb_ptr_print;
-#else
-#define ahc_scb_cdb_ptr_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCB_CDB_PTR", 0xa0, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scb_residual_sgptr_print;
-#else
-#define ahc_scb_residual_sgptr_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCB_RESIDUAL_SGPTR", 0xa4, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scb_scsi_status_print;
-#else
-#define ahc_scb_scsi_status_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCB_SCSI_STATUS", 0xa8, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scb_target_phases_print;
-#else
-#define ahc_scb_target_phases_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCB_TARGET_PHASES", 0xa9, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scb_target_data_dir_print;
-#else
-#define ahc_scb_target_data_dir_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCB_TARGET_DATA_DIR", 0xaa, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scb_target_itag_print;
-#else
-#define ahc_scb_target_itag_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCB_TARGET_ITAG", 0xab, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scb_dataptr_print;
-#else
-#define ahc_scb_dataptr_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCB_DATAPTR", 0xac, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scb_datacnt_print;
-#else
-#define ahc_scb_datacnt_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCB_DATACNT", 0xb0, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scb_sgptr_print;
-#else
-#define ahc_scb_sgptr_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCB_SGPTR", 0xb4, regvalue, cur_col, wrap)
-#endif
-
 #if AIC_DEBUG_REGISTERS
 ahc_reg_print_t ahc_scb_control_print;
 #else
@@ -880,188 +187,6 @@ ahc_reg_print_t ahc_scb_tag_print;
     ahc_print_register(NULL, 0, "SCB_TAG", 0xbb, regvalue, cur_col, wrap)
 #endif
 
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scb_cdb_len_print;
-#else
-#define ahc_scb_cdb_len_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCB_CDB_LEN", 0xbc, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scb_scsirate_print;
-#else
-#define ahc_scb_scsirate_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCB_SCSIRATE", 0xbd, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scb_scsioffset_print;
-#else
-#define ahc_scb_scsioffset_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCB_SCSIOFFSET", 0xbe, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scb_next_print;
-#else
-#define ahc_scb_next_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCB_NEXT", 0xbf, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scb_64_spare_print;
-#else
-#define ahc_scb_64_spare_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCB_64_SPARE", 0xc0, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_seectl_2840_print;
-#else
-#define ahc_seectl_2840_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SEECTL_2840", 0xc0, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_status_2840_print;
-#else
-#define ahc_status_2840_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "STATUS_2840", 0xc1, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scb_64_btt_print;
-#else
-#define ahc_scb_64_btt_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCB_64_BTT", 0xd0, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_cchaddr_print;
-#else
-#define ahc_cchaddr_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "CCHADDR", 0xe0, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_cchcnt_print;
-#else
-#define ahc_cchcnt_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "CCHCNT", 0xe8, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_ccsgram_print;
-#else
-#define ahc_ccsgram_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "CCSGRAM", 0xe9, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_ccsgaddr_print;
-#else
-#define ahc_ccsgaddr_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "CCSGADDR", 0xea, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_ccsgctl_print;
-#else
-#define ahc_ccsgctl_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "CCSGCTL", 0xeb, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_ccscbram_print;
-#else
-#define ahc_ccscbram_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "CCSCBRAM", 0xec, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_ccscbaddr_print;
-#else
-#define ahc_ccscbaddr_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "CCSCBADDR", 0xed, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_ccscbctl_print;
-#else
-#define ahc_ccscbctl_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "CCSCBCTL", 0xee, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_ccscbcnt_print;
-#else
-#define ahc_ccscbcnt_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "CCSCBCNT", 0xef, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_scbbaddr_print;
-#else
-#define ahc_scbbaddr_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SCBBADDR", 0xf0, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_ccscbptr_print;
-#else
-#define ahc_ccscbptr_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "CCSCBPTR", 0xf1, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_hnscb_qoff_print;
-#else
-#define ahc_hnscb_qoff_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "HNSCB_QOFF", 0xf4, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_snscb_qoff_print;
-#else
-#define ahc_snscb_qoff_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SNSCB_QOFF", 0xf6, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_sdscb_qoff_print;
-#else
-#define ahc_sdscb_qoff_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SDSCB_QOFF", 0xf8, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_qoff_ctlsta_print;
-#else
-#define ahc_qoff_ctlsta_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "QOFF_CTLSTA", 0xfa, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_dff_thrsh_print;
-#else
-#define ahc_dff_thrsh_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "DFF_THRSH", 0xfb, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_sg_cache_shadow_print;
-#else
-#define ahc_sg_cache_shadow_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SG_CACHE_SHADOW", 0xfc, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_sg_cache_pre_print;
-#else
-#define ahc_sg_cache_pre_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "SG_CACHE_PRE", 0xfc, regvalue, cur_col, wrap)
-#endif
-
 
 #define        SCSISEQ                         0x00
 #define                TEMODE                  0x80
index 309a562b009ef284294ff27fbbe6ea7950dc2cab..9f9b88047d0c610aee6c06d6cbcde7e19965171e 100644 (file)
@@ -43,48 +43,6 @@ ahc_sxfrctl0_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x01, regvalue, cur_col, wrap));
 }
 
-static const ahc_reg_parse_entry_t SXFRCTL1_parse_table[] = {
-       { "STPWEN",             0x01, 0x01 },
-       { "ACTNEGEN",           0x02, 0x02 },
-       { "ENSTIMER",           0x04, 0x04 },
-       { "ENSPCHK",            0x20, 0x20 },
-       { "SWRAPEN",            0x40, 0x40 },
-       { "BITBUCKET",          0x80, 0x80 },
-       { "STIMESEL",           0x18, 0x18 }
-};
-
-int
-ahc_sxfrctl1_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SXFRCTL1_parse_table, 7, "SXFRCTL1",
-           0x02, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t SCSISIGO_parse_table[] = {
-       { "ACKO",               0x01, 0x01 },
-       { "REQO",               0x02, 0x02 },
-       { "BSYO",               0x04, 0x04 },
-       { "SELO",               0x08, 0x08 },
-       { "ATNO",               0x10, 0x10 },
-       { "MSGO",               0x20, 0x20 },
-       { "IOO",                0x40, 0x40 },
-       { "CDO",                0x80, 0x80 },
-       { "P_DATAOUT",          0x00, 0x00 },
-       { "P_DATAIN",           0x40, 0x40 },
-       { "P_COMMAND",          0x80, 0x80 },
-       { "P_MESGOUT",          0xa0, 0xa0 },
-       { "P_STATUS",           0xc0, 0xc0 },
-       { "PHASE_MASK",         0xe0, 0xe0 },
-       { "P_MESGIN",           0xe0, 0xe0 }
-};
-
-int
-ahc_scsisigo_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SCSISIGO_parse_table, 15, "SCSISIGO",
-           0x03, regvalue, cur_col, wrap));
-}
-
 static const ahc_reg_parse_entry_t SCSISIGI_parse_table[] = {
        { "ACKI",               0x01, 0x01 },
        { "REQI",               0x02, 0x02 },
@@ -128,77 +86,6 @@ ahc_scsirate_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x04, regvalue, cur_col, wrap));
 }
 
-static const ahc_reg_parse_entry_t SCSIID_parse_table[] = {
-       { "TWIN_CHNLB",         0x80, 0x80 },
-       { "OID",                0x0f, 0x0f },
-       { "TWIN_TID",           0x70, 0x70 },
-       { "SOFS_ULTRA2",        0x7f, 0x7f },
-       { "TID",                0xf0, 0xf0 }
-};
-
-int
-ahc_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SCSIID_parse_table, 5, "SCSIID",
-           0x05, regvalue, cur_col, wrap));
-}
-
-int
-ahc_scsidatl_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SCSIDATL",
-           0x06, regvalue, cur_col, wrap));
-}
-
-int
-ahc_stcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "STCNT",
-           0x08, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t OPTIONMODE_parse_table[] = {
-       { "DIS_MSGIN_DUALEDGE", 0x01, 0x01 },
-       { "AUTO_MSGOUT_DE",     0x02, 0x02 },
-       { "SCSIDATL_IMGEN",     0x04, 0x04 },
-       { "EXPPHASEDIS",        0x08, 0x08 },
-       { "BUSFREEREV",         0x10, 0x10 },
-       { "ATNMGMNTEN",         0x20, 0x20 },
-       { "AUTOACKEN",          0x40, 0x40 },
-       { "AUTORATEEN",         0x80, 0x80 },
-       { "OPTIONMODE_DEFAULTS",0x03, 0x03 }
-};
-
-int
-ahc_optionmode_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(OPTIONMODE_parse_table, 9, "OPTIONMODE",
-           0x08, regvalue, cur_col, wrap));
-}
-
-int
-ahc_targcrccnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "TARGCRCCNT",
-           0x0a, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t CLRSINT0_parse_table[] = {
-       { "CLRSPIORDY",         0x02, 0x02 },
-       { "CLRSWRAP",           0x08, 0x08 },
-       { "CLRIOERR",           0x08, 0x08 },
-       { "CLRSELINGO",         0x10, 0x10 },
-       { "CLRSELDI",           0x20, 0x20 },
-       { "CLRSELDO",           0x40, 0x40 }
-};
-
-int
-ahc_clrsint0_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(CLRSINT0_parse_table, 6, "CLRSINT0",
-           0x0b, regvalue, cur_col, wrap));
-}
-
 static const ahc_reg_parse_entry_t SSTAT0_parse_table[] = {
        { "DMADONE",            0x01, 0x01 },
        { "SPIORDY",            0x02, 0x02 },
@@ -218,23 +105,6 @@ ahc_sstat0_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x0b, regvalue, cur_col, wrap));
 }
 
-static const ahc_reg_parse_entry_t CLRSINT1_parse_table[] = {
-       { "CLRREQINIT",         0x01, 0x01 },
-       { "CLRPHASECHG",        0x02, 0x02 },
-       { "CLRSCSIPERR",        0x04, 0x04 },
-       { "CLRBUSFREE",         0x08, 0x08 },
-       { "CLRSCSIRSTI",        0x20, 0x20 },
-       { "CLRATNO",            0x40, 0x40 },
-       { "CLRSELTIMEO",        0x80, 0x80 }
-};
-
-int
-ahc_clrsint1_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(CLRSINT1_parse_table, 7, "CLRSINT1",
-           0x0c, regvalue, cur_col, wrap));
-}
-
 static const ahc_reg_parse_entry_t SSTAT1_parse_table[] = {
        { "REQINIT",            0x01, 0x01 },
        { "PHASECHG",           0x02, 0x02 },
@@ -284,18 +154,6 @@ ahc_sstat3_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x0e, regvalue, cur_col, wrap));
 }
 
-static const ahc_reg_parse_entry_t SCSIID_ULTRA2_parse_table[] = {
-       { "OID",                0x0f, 0x0f },
-       { "TID",                0xf0, 0xf0 }
-};
-
-int
-ahc_scsiid_ultra2_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SCSIID_ULTRA2_parse_table, 2, "SCSIID_ULTRA2",
-           0x0f, regvalue, cur_col, wrap));
-}
-
 static const ahc_reg_parse_entry_t SIMODE0_parse_table[] = {
        { "ENDMADONE",          0x01, 0x01 },
        { "ENSPIORDY",          0x02, 0x02 },
@@ -339,107 +197,6 @@ ahc_scsibusl_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x12, regvalue, cur_col, wrap));
 }
 
-int
-ahc_shaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SHADDR",
-           0x14, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t SELTIMER_parse_table[] = {
-       { "STAGE1",             0x01, 0x01 },
-       { "STAGE2",             0x02, 0x02 },
-       { "STAGE3",             0x04, 0x04 },
-       { "STAGE4",             0x08, 0x08 },
-       { "STAGE5",             0x10, 0x10 },
-       { "STAGE6",             0x20, 0x20 }
-};
-
-int
-ahc_seltimer_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SELTIMER_parse_table, 6, "SELTIMER",
-           0x18, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t SELID_parse_table[] = {
-       { "ONEBIT",             0x08, 0x08 },
-       { "SELID_MASK",         0xf0, 0xf0 }
-};
-
-int
-ahc_selid_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SELID_parse_table, 2, "SELID",
-           0x19, regvalue, cur_col, wrap));
-}
-
-int
-ahc_targid_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "TARGID",
-           0x1b, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t SPIOCAP_parse_table[] = {
-       { "SSPIOCPS",           0x01, 0x01 },
-       { "ROM",                0x02, 0x02 },
-       { "EEPROM",             0x04, 0x04 },
-       { "SEEPROM",            0x08, 0x08 },
-       { "EXT_BRDCTL",         0x10, 0x10 },
-       { "SOFTCMDEN",          0x20, 0x20 },
-       { "SOFT0",              0x40, 0x40 },
-       { "SOFT1",              0x80, 0x80 }
-};
-
-int
-ahc_spiocap_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SPIOCAP_parse_table, 8, "SPIOCAP",
-           0x1b, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t BRDCTL_parse_table[] = {
-       { "BRDCTL0",            0x01, 0x01 },
-       { "BRDSTB_ULTRA2",      0x01, 0x01 },
-       { "BRDCTL1",            0x02, 0x02 },
-       { "BRDRW_ULTRA2",       0x02, 0x02 },
-       { "BRDRW",              0x04, 0x04 },
-       { "BRDDAT2",            0x04, 0x04 },
-       { "BRDCS",              0x08, 0x08 },
-       { "BRDDAT3",            0x08, 0x08 },
-       { "BRDSTB",             0x10, 0x10 },
-       { "BRDDAT4",            0x10, 0x10 },
-       { "BRDDAT5",            0x20, 0x20 },
-       { "BRDDAT6",            0x40, 0x40 },
-       { "BRDDAT7",            0x80, 0x80 }
-};
-
-int
-ahc_brdctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(BRDCTL_parse_table, 13, "BRDCTL",
-           0x1d, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t SEECTL_parse_table[] = {
-       { "SEEDI",              0x01, 0x01 },
-       { "SEEDO",              0x02, 0x02 },
-       { "SEECK",              0x04, 0x04 },
-       { "SEECS",              0x08, 0x08 },
-       { "SEERDY",             0x10, 0x10 },
-       { "SEEMS",              0x20, 0x20 },
-       { "EXTARBREQ",          0x40, 0x40 },
-       { "EXTARBACK",          0x80, 0x80 }
-};
-
-int
-ahc_seectl_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SEECTL_parse_table, 8, "SEECTL",
-           0x1e, regvalue, cur_col, wrap));
-}
-
 static const ahc_reg_parse_entry_t SBLKCTL_parse_table[] = {
        { "XCVR",               0x01, 0x01 },
        { "SELWIDE",            0x02, 0x02 },
@@ -458,68 +215,6 @@ ahc_sblkctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x1f, regvalue, cur_col, wrap));
 }
 
-int
-ahc_busy_targets_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "BUSY_TARGETS",
-           0x20, regvalue, cur_col, wrap));
-}
-
-int
-ahc_ultra_enb_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "ULTRA_ENB",
-           0x30, regvalue, cur_col, wrap));
-}
-
-int
-ahc_disc_dsb_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "DISC_DSB",
-           0x32, regvalue, cur_col, wrap));
-}
-
-int
-ahc_mwi_residual_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "MWI_RESIDUAL",
-           0x38, regvalue, cur_col, wrap));
-}
-
-int
-ahc_next_queued_scb_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "NEXT_QUEUED_SCB",
-           0x39, regvalue, cur_col, wrap));
-}
-
-int
-ahc_msg_out_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "MSG_OUT",
-           0x3a, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t DMAPARAMS_parse_table[] = {
-       { "FIFORESET",          0x01, 0x01 },
-       { "FIFOFLUSH",          0x02, 0x02 },
-       { "DIRECTION",          0x04, 0x04 },
-       { "HDMAEN",             0x08, 0x08 },
-       { "HDMAENACK",          0x08, 0x08 },
-       { "SDMAEN",             0x10, 0x10 },
-       { "SDMAENACK",          0x10, 0x10 },
-       { "SCSIEN",             0x20, 0x20 },
-       { "WIDEODD",            0x40, 0x40 },
-       { "PRELOADEN",          0x80, 0x80 }
-};
-
-int
-ahc_dmaparams_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(DMAPARAMS_parse_table, 10, "DMAPARAMS",
-           0x3b, regvalue, cur_col, wrap));
-}
-
 static const ahc_reg_parse_entry_t SEQ_FLAGS_parse_table[] = {
        { "NO_DISCONNECT",      0x01, 0x01 },
        { "SPHASE_PENDING",     0x02, 0x02 },
@@ -539,20 +234,6 @@ ahc_seq_flags_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x3c, regvalue, cur_col, wrap));
 }
 
-int
-ahc_saved_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SAVED_SCSIID",
-           0x3d, regvalue, cur_col, wrap));
-}
-
-int
-ahc_saved_lun_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SAVED_LUN",
-           0x3e, regvalue, cur_col, wrap));
-}
-
 static const ahc_reg_parse_entry_t LASTPHASE_parse_table[] = {
        { "MSGI",               0x20, 0x20 },
        { "IOI",                0x40, 0x40 },
@@ -574,728 +255,127 @@ ahc_lastphase_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0x3f, regvalue, cur_col, wrap));
 }
 
-int
-ahc_waiting_scbh_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "WAITING_SCBH",
-           0x40, regvalue, cur_col, wrap));
-}
+static const ahc_reg_parse_entry_t SEQCTL_parse_table[] = {
+       { "LOADRAM",            0x01, 0x01 },
+       { "SEQRESET",           0x02, 0x02 },
+       { "STEP",               0x04, 0x04 },
+       { "BRKADRINTEN",        0x08, 0x08 },
+       { "FASTMODE",           0x10, 0x10 },
+       { "FAILDIS",            0x20, 0x20 },
+       { "PAUSEDIS",           0x40, 0x40 },
+       { "PERRORDIS",          0x80, 0x80 }
+};
 
 int
-ahc_disconnected_scbh_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahc_seqctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahc_print_register(NULL, 0, "DISCONNECTED_SCBH",
-           0x41, regvalue, cur_col, wrap));
+       return (ahc_print_register(SEQCTL_parse_table, 8, "SEQCTL",
+           0x60, regvalue, cur_col, wrap));
 }
 
 int
-ahc_free_scbh_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahc_sram_base_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahc_print_register(NULL, 0, "FREE_SCBH",
-           0x42, regvalue, cur_col, wrap));
+       return (ahc_print_register(NULL, 0, "SRAM_BASE",
+           0x70, regvalue, cur_col, wrap));
 }
 
-int
-ahc_hscb_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "HSCB_ADDR",
-           0x44, regvalue, cur_col, wrap));
-}
+static const ahc_reg_parse_entry_t ERROR_parse_table[] = {
+       { "ILLHADDR",           0x01, 0x01 },
+       { "ILLSADDR",           0x02, 0x02 },
+       { "ILLOPCODE",          0x04, 0x04 },
+       { "SQPARERR",           0x08, 0x08 },
+       { "DPARERR",            0x10, 0x10 },
+       { "MPARERR",            0x20, 0x20 },
+       { "PCIERRSTAT",         0x40, 0x40 },
+       { "CIOPARERR",          0x80, 0x80 }
+};
 
 int
-ahc_shared_data_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahc_error_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahc_print_register(NULL, 0, "SHARED_DATA_ADDR",
-           0x48, regvalue, cur_col, wrap));
+       return (ahc_print_register(ERROR_parse_table, 8, "ERROR",
+           0x92, regvalue, cur_col, wrap));
 }
 
-int
-ahc_kernel_qinpos_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "KERNEL_QINPOS",
-           0x4c, regvalue, cur_col, wrap));
-}
+static const ahc_reg_parse_entry_t DFCNTRL_parse_table[] = {
+       { "FIFORESET",          0x01, 0x01 },
+       { "FIFOFLUSH",          0x02, 0x02 },
+       { "DIRECTION",          0x04, 0x04 },
+       { "HDMAEN",             0x08, 0x08 },
+       { "HDMAENACK",          0x08, 0x08 },
+       { "SDMAEN",             0x10, 0x10 },
+       { "SDMAENACK",          0x10, 0x10 },
+       { "SCSIEN",             0x20, 0x20 },
+       { "WIDEODD",            0x40, 0x40 },
+       { "PRELOADEN",          0x80, 0x80 }
+};
 
 int
-ahc_qinpos_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahc_dfcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahc_print_register(NULL, 0, "QINPOS",
-           0x4d, regvalue, cur_col, wrap));
+       return (ahc_print_register(DFCNTRL_parse_table, 10, "DFCNTRL",
+           0x93, regvalue, cur_col, wrap));
 }
 
+static const ahc_reg_parse_entry_t DFSTATUS_parse_table[] = {
+       { "FIFOEMP",            0x01, 0x01 },
+       { "FIFOFULL",           0x02, 0x02 },
+       { "DFTHRESH",           0x04, 0x04 },
+       { "HDONE",              0x08, 0x08 },
+       { "MREQPEND",           0x10, 0x10 },
+       { "FIFOQWDEMP",         0x20, 0x20 },
+       { "DFCACHETH",          0x40, 0x40 },
+       { "PRELOAD_AVAIL",      0x80, 0x80 }
+};
+
 int
-ahc_qoutpos_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahc_dfstatus_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahc_print_register(NULL, 0, "QOUTPOS",
-           0x4e, regvalue, cur_col, wrap));
+       return (ahc_print_register(DFSTATUS_parse_table, 8, "DFSTATUS",
+           0x94, regvalue, cur_col, wrap));
 }
 
+static const ahc_reg_parse_entry_t SCSIPHASE_parse_table[] = {
+       { "DATA_OUT_PHASE",     0x01, 0x01 },
+       { "DATA_IN_PHASE",      0x02, 0x02 },
+       { "MSG_OUT_PHASE",      0x04, 0x04 },
+       { "MSG_IN_PHASE",       0x08, 0x08 },
+       { "COMMAND_PHASE",      0x10, 0x10 },
+       { "STATUS_PHASE",       0x20, 0x20 },
+       { "DATA_PHASE_MASK",    0x03, 0x03 }
+};
+
 int
-ahc_kernel_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahc_scsiphase_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahc_print_register(NULL, 0, "KERNEL_TQINPOS",
-           0x4f, regvalue, cur_col, wrap));
+       return (ahc_print_register(SCSIPHASE_parse_table, 7, "SCSIPHASE",
+           0x9e, regvalue, cur_col, wrap));
 }
 
 int
-ahc_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahc_scb_base_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahc_print_register(NULL, 0, "TQINPOS",
-           0x50, regvalue, cur_col, wrap));
+       return (ahc_print_register(NULL, 0, "SCB_BASE",
+           0xa0, regvalue, cur_col, wrap));
 }
 
-static const ahc_reg_parse_entry_t ARG_1_parse_table[] = {
-       { "CONT_TARG_SESSION",  0x02, 0x02 },
-       { "CONT_MSG_LOOP",      0x04, 0x04 },
-       { "EXIT_MSG_LOOP",      0x08, 0x08 },
-       { "MSGOUT_PHASEMIS",    0x10, 0x10 },
-       { "SEND_REJ",           0x20, 0x20 },
-       { "SEND_SENSE",         0x40, 0x40 },
-       { "SEND_MSG",           0x80, 0x80 }
+static const ahc_reg_parse_entry_t SCB_CONTROL_parse_table[] = {
+       { "DISCONNECTED",       0x04, 0x04 },
+       { "ULTRAENB",           0x08, 0x08 },
+       { "MK_MESSAGE",         0x10, 0x10 },
+       { "TAG_ENB",            0x20, 0x20 },
+       { "DISCENB",            0x40, 0x40 },
+       { "TARGET_SCB",         0x80, 0x80 },
+       { "STATUS_RCVD",        0x80, 0x80 },
+       { "SCB_TAG_TYPE",       0x03, 0x03 }
 };
 
 int
-ahc_arg_1_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(ARG_1_parse_table, 7, "ARG_1",
-           0x51, regvalue, cur_col, wrap));
-}
-
-int
-ahc_arg_2_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahc_scb_control_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-       return (ahc_print_register(NULL, 0, "ARG_2",
-           0x52, regvalue, cur_col, wrap));
-}
-
-int
-ahc_last_msg_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "LAST_MSG",
-           0x53, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t SCSISEQ_TEMPLATE_parse_table[] = {
-       { "ENAUTOATNP",         0x02, 0x02 },
-       { "ENAUTOATNI",         0x04, 0x04 },
-       { "ENAUTOATNO",         0x08, 0x08 },
-       { "ENRSELI",            0x10, 0x10 },
-       { "ENSELI",             0x20, 0x20 },
-       { "ENSELO",             0x40, 0x40 }
-};
-
-int
-ahc_scsiseq_template_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SCSISEQ_TEMPLATE_parse_table, 6, "SCSISEQ_TEMPLATE",
-           0x54, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t HA_274_BIOSGLOBAL_parse_table[] = {
-       { "HA_274_EXTENDED_TRANS",0x01, 0x01 }
-};
-
-int
-ahc_ha_274_biosglobal_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(HA_274_BIOSGLOBAL_parse_table, 1, "HA_274_BIOSGLOBAL",
-           0x56, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t SEQ_FLAGS2_parse_table[] = {
-       { "SCB_DMA",            0x01, 0x01 },
-       { "TARGET_MSG_PENDING", 0x02, 0x02 }
-};
-
-int
-ahc_seq_flags2_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SEQ_FLAGS2_parse_table, 2, "SEQ_FLAGS2",
-           0x57, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t SCSICONF_parse_table[] = {
-       { "ENSPCHK",            0x20, 0x20 },
-       { "RESET_SCSI",         0x40, 0x40 },
-       { "TERM_ENB",           0x80, 0x80 },
-       { "HSCSIID",            0x07, 0x07 },
-       { "HWSCSIID",           0x0f, 0x0f }
-};
-
-int
-ahc_scsiconf_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SCSICONF_parse_table, 5, "SCSICONF",
-           0x5a, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t INTDEF_parse_table[] = {
-       { "EDGE_TRIG",          0x80, 0x80 },
-       { "VECTOR",             0x0f, 0x0f }
-};
-
-int
-ahc_intdef_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(INTDEF_parse_table, 2, "INTDEF",
-           0x5c, regvalue, cur_col, wrap));
-}
-
-int
-ahc_hostconf_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "HOSTCONF",
-           0x5d, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t HA_274_BIOSCTRL_parse_table[] = {
-       { "CHANNEL_B_PRIMARY",  0x08, 0x08 },
-       { "BIOSMODE",           0x30, 0x30 },
-       { "BIOSDISABLED",       0x30, 0x30 }
-};
-
-int
-ahc_ha_274_biosctrl_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(HA_274_BIOSCTRL_parse_table, 3, "HA_274_BIOSCTRL",
-           0x5f, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t SEQCTL_parse_table[] = {
-       { "LOADRAM",            0x01, 0x01 },
-       { "SEQRESET",           0x02, 0x02 },
-       { "STEP",               0x04, 0x04 },
-       { "BRKADRINTEN",        0x08, 0x08 },
-       { "FASTMODE",           0x10, 0x10 },
-       { "FAILDIS",            0x20, 0x20 },
-       { "PAUSEDIS",           0x40, 0x40 },
-       { "PERRORDIS",          0x80, 0x80 }
-};
-
-int
-ahc_seqctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SEQCTL_parse_table, 8, "SEQCTL",
-           0x60, regvalue, cur_col, wrap));
-}
-
-int
-ahc_seqram_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SEQRAM",
-           0x61, regvalue, cur_col, wrap));
-}
-
-int
-ahc_seqaddr0_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SEQADDR0",
-           0x62, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t SEQADDR1_parse_table[] = {
-       { "SEQADDR1_MASK",      0x01, 0x01 }
-};
-
-int
-ahc_seqaddr1_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SEQADDR1_parse_table, 1, "SEQADDR1",
-           0x63, regvalue, cur_col, wrap));
-}
-
-int
-ahc_accum_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "ACCUM",
-           0x64, regvalue, cur_col, wrap));
-}
-
-int
-ahc_sindex_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SINDEX",
-           0x65, regvalue, cur_col, wrap));
-}
-
-int
-ahc_dindex_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "DINDEX",
-           0x66, regvalue, cur_col, wrap));
-}
-
-int
-ahc_allones_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "ALLONES",
-           0x69, regvalue, cur_col, wrap));
-}
-
-int
-ahc_allzeros_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "ALLZEROS",
-           0x6a, regvalue, cur_col, wrap));
-}
-
-int
-ahc_none_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "NONE",
-           0x6a, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t FLAGS_parse_table[] = {
-       { "CARRY",              0x01, 0x01 },
-       { "ZERO",               0x02, 0x02 }
-};
-
-int
-ahc_flags_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(FLAGS_parse_table, 2, "FLAGS",
-           0x6b, regvalue, cur_col, wrap));
-}
-
-int
-ahc_sindir_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SINDIR",
-           0x6c, regvalue, cur_col, wrap));
-}
-
-int
-ahc_dindir_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "DINDIR",
-           0x6d, regvalue, cur_col, wrap));
-}
-
-int
-ahc_stack_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "STACK",
-           0x6f, regvalue, cur_col, wrap));
-}
-
-int
-ahc_targ_offset_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "TARG_OFFSET",
-           0x70, regvalue, cur_col, wrap));
-}
-
-int
-ahc_sram_base_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SRAM_BASE",
-           0x70, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t DSCOMMAND0_parse_table[] = {
-       { "CIOPARCKEN",         0x01, 0x01 },
-       { "USCBSIZE32",         0x02, 0x02 },
-       { "RAMPS",              0x04, 0x04 },
-       { "INTSCBRAMSEL",       0x08, 0x08 },
-       { "EXTREQLCK",          0x10, 0x10 },
-       { "MPARCKEN",           0x20, 0x20 },
-       { "DPARCKEN",           0x40, 0x40 },
-       { "CACHETHEN",          0x80, 0x80 }
-};
-
-int
-ahc_dscommand0_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(DSCOMMAND0_parse_table, 8, "DSCOMMAND0",
-           0x84, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t BUSTIME_parse_table[] = {
-       { "BON",                0x0f, 0x0f },
-       { "BOFF",               0xf0, 0xf0 }
-};
-
-int
-ahc_bustime_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(BUSTIME_parse_table, 2, "BUSTIME",
-           0x85, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t DSCOMMAND1_parse_table[] = {
-       { "HADDLDSEL0",         0x01, 0x01 },
-       { "HADDLDSEL1",         0x02, 0x02 },
-       { "DSLATT",             0xfc, 0xfc }
-};
-
-int
-ahc_dscommand1_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(DSCOMMAND1_parse_table, 3, "DSCOMMAND1",
-           0x85, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t BUSSPD_parse_table[] = {
-       { "STBON",              0x07, 0x07 },
-       { "STBOFF",             0x38, 0x38 },
-       { "DFTHRSH_75",         0x80, 0x80 },
-       { "DFTHRSH",            0xc0, 0xc0 },
-       { "DFTHRSH_100",        0xc0, 0xc0 }
-};
-
-int
-ahc_busspd_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(BUSSPD_parse_table, 5, "BUSSPD",
-           0x86, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t HS_MAILBOX_parse_table[] = {
-       { "SEQ_MAILBOX",        0x0f, 0x0f },
-       { "HOST_TQINPOS",       0x80, 0x80 },
-       { "HOST_MAILBOX",       0xf0, 0xf0 }
-};
-
-int
-ahc_hs_mailbox_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(HS_MAILBOX_parse_table, 3, "HS_MAILBOX",
-           0x86, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t DSPCISTATUS_parse_table[] = {
-       { "DFTHRSH_100",        0xc0, 0xc0 }
-};
-
-int
-ahc_dspcistatus_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(DSPCISTATUS_parse_table, 1, "DSPCISTATUS",
-           0x86, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t HCNTRL_parse_table[] = {
-       { "CHIPRST",            0x01, 0x01 },
-       { "CHIPRSTACK",         0x01, 0x01 },
-       { "INTEN",              0x02, 0x02 },
-       { "PAUSE",              0x04, 0x04 },
-       { "IRQMS",              0x08, 0x08 },
-       { "SWINT",              0x10, 0x10 },
-       { "POWRDN",             0x40, 0x40 }
-};
-
-int
-ahc_hcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(HCNTRL_parse_table, 7, "HCNTRL",
-           0x87, regvalue, cur_col, wrap));
-}
-
-int
-ahc_haddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "HADDR",
-           0x88, regvalue, cur_col, wrap));
-}
-
-int
-ahc_hcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "HCNT",
-           0x8c, regvalue, cur_col, wrap));
-}
-
-int
-ahc_scbptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SCBPTR",
-           0x90, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t INTSTAT_parse_table[] = {
-       { "SEQINT",             0x01, 0x01 },
-       { "CMDCMPLT",           0x02, 0x02 },
-       { "SCSIINT",            0x04, 0x04 },
-       { "BRKADRINT",          0x08, 0x08 },
-       { "BAD_PHASE",          0x01, 0x01 },
-       { "INT_PEND",           0x0f, 0x0f },
-       { "SEND_REJECT",        0x11, 0x11 },
-       { "PROTO_VIOLATION",    0x21, 0x21 },
-       { "NO_MATCH",           0x31, 0x31 },
-       { "IGN_WIDE_RES",       0x41, 0x41 },
-       { "PDATA_REINIT",       0x51, 0x51 },
-       { "HOST_MSG_LOOP",      0x61, 0x61 },
-       { "BAD_STATUS",         0x71, 0x71 },
-       { "PERR_DETECTED",      0x81, 0x81 },
-       { "DATA_OVERRUN",       0x91, 0x91 },
-       { "MKMSG_FAILED",       0xa1, 0xa1 },
-       { "MISSED_BUSFREE",     0xb1, 0xb1 },
-       { "SCB_MISMATCH",       0xc1, 0xc1 },
-       { "NO_FREE_SCB",        0xd1, 0xd1 },
-       { "OUT_OF_RANGE",       0xe1, 0xe1 },
-       { "SEQINT_MASK",        0xf1, 0xf1 }
-};
-
-int
-ahc_intstat_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(INTSTAT_parse_table, 21, "INTSTAT",
-           0x91, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t CLRINT_parse_table[] = {
-       { "CLRSEQINT",          0x01, 0x01 },
-       { "CLRCMDINT",          0x02, 0x02 },
-       { "CLRSCSIINT",         0x04, 0x04 },
-       { "CLRBRKADRINT",       0x08, 0x08 },
-       { "CLRPARERR",          0x10, 0x10 }
-};
-
-int
-ahc_clrint_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(CLRINT_parse_table, 5, "CLRINT",
-           0x92, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t ERROR_parse_table[] = {
-       { "ILLHADDR",           0x01, 0x01 },
-       { "ILLSADDR",           0x02, 0x02 },
-       { "ILLOPCODE",          0x04, 0x04 },
-       { "SQPARERR",           0x08, 0x08 },
-       { "DPARERR",            0x10, 0x10 },
-       { "MPARERR",            0x20, 0x20 },
-       { "PCIERRSTAT",         0x40, 0x40 },
-       { "CIOPARERR",          0x80, 0x80 }
-};
-
-int
-ahc_error_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(ERROR_parse_table, 8, "ERROR",
-           0x92, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t DFCNTRL_parse_table[] = {
-       { "FIFORESET",          0x01, 0x01 },
-       { "FIFOFLUSH",          0x02, 0x02 },
-       { "DIRECTION",          0x04, 0x04 },
-       { "HDMAEN",             0x08, 0x08 },
-       { "HDMAENACK",          0x08, 0x08 },
-       { "SDMAEN",             0x10, 0x10 },
-       { "SDMAENACK",          0x10, 0x10 },
-       { "SCSIEN",             0x20, 0x20 },
-       { "WIDEODD",            0x40, 0x40 },
-       { "PRELOADEN",          0x80, 0x80 }
-};
-
-int
-ahc_dfcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(DFCNTRL_parse_table, 10, "DFCNTRL",
-           0x93, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t DFSTATUS_parse_table[] = {
-       { "FIFOEMP",            0x01, 0x01 },
-       { "FIFOFULL",           0x02, 0x02 },
-       { "DFTHRESH",           0x04, 0x04 },
-       { "HDONE",              0x08, 0x08 },
-       { "MREQPEND",           0x10, 0x10 },
-       { "FIFOQWDEMP",         0x20, 0x20 },
-       { "DFCACHETH",          0x40, 0x40 },
-       { "PRELOAD_AVAIL",      0x80, 0x80 }
-};
-
-int
-ahc_dfstatus_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(DFSTATUS_parse_table, 8, "DFSTATUS",
-           0x94, regvalue, cur_col, wrap));
-}
-
-int
-ahc_dfwaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "DFWADDR",
-           0x95, regvalue, cur_col, wrap));
-}
-
-int
-ahc_dfdat_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "DFDAT",
-           0x99, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t SCBCNT_parse_table[] = {
-       { "SCBAUTO",            0x80, 0x80 },
-       { "SCBCNT_MASK",        0x1f, 0x1f }
-};
-
-int
-ahc_scbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SCBCNT_parse_table, 2, "SCBCNT",
-           0x9a, regvalue, cur_col, wrap));
-}
-
-int
-ahc_qinfifo_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "QINFIFO",
-           0x9b, regvalue, cur_col, wrap));
-}
-
-int
-ahc_qoutfifo_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "QOUTFIFO",
-           0x9d, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t CRCCONTROL1_parse_table[] = {
-       { "TARGCRCCNTEN",       0x04, 0x04 },
-       { "TARGCRCENDEN",       0x08, 0x08 },
-       { "CRCREQCHKEN",        0x10, 0x10 },
-       { "CRCENDCHKEN",        0x20, 0x20 },
-       { "CRCVALCHKEN",        0x40, 0x40 },
-       { "CRCONSEEN",          0x80, 0x80 }
-};
-
-int
-ahc_crccontrol1_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(CRCCONTROL1_parse_table, 6, "CRCCONTROL1",
-           0x9d, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t SCSIPHASE_parse_table[] = {
-       { "DATA_OUT_PHASE",     0x01, 0x01 },
-       { "DATA_IN_PHASE",      0x02, 0x02 },
-       { "MSG_OUT_PHASE",      0x04, 0x04 },
-       { "MSG_IN_PHASE",       0x08, 0x08 },
-       { "COMMAND_PHASE",      0x10, 0x10 },
-       { "STATUS_PHASE",       0x20, 0x20 },
-       { "DATA_PHASE_MASK",    0x03, 0x03 }
-};
-
-int
-ahc_scsiphase_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SCSIPHASE_parse_table, 7, "SCSIPHASE",
-           0x9e, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t SFUNCT_parse_table[] = {
-       { "ALT_MODE",           0x80, 0x80 }
-};
-
-int
-ahc_sfunct_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SFUNCT_parse_table, 1, "SFUNCT",
-           0x9f, regvalue, cur_col, wrap));
-}
-
-int
-ahc_scb_base_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SCB_BASE",
-           0xa0, regvalue, cur_col, wrap));
-}
-
-int
-ahc_scb_cdb_ptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SCB_CDB_PTR",
-           0xa0, regvalue, cur_col, wrap));
-}
-
-int
-ahc_scb_residual_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SCB_RESIDUAL_SGPTR",
-           0xa4, regvalue, cur_col, wrap));
-}
-
-int
-ahc_scb_scsi_status_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SCB_SCSI_STATUS",
-           0xa8, regvalue, cur_col, wrap));
-}
-
-int
-ahc_scb_target_phases_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SCB_TARGET_PHASES",
-           0xa9, regvalue, cur_col, wrap));
-}
-
-int
-ahc_scb_target_data_dir_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SCB_TARGET_DATA_DIR",
-           0xaa, regvalue, cur_col, wrap));
-}
-
-int
-ahc_scb_target_itag_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SCB_TARGET_ITAG",
-           0xab, regvalue, cur_col, wrap));
-}
-
-int
-ahc_scb_dataptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SCB_DATAPTR",
-           0xac, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t SCB_DATACNT_parse_table[] = {
-       { "SG_LAST_SEG",        0x80, 0x80 },
-       { "SG_HIGH_ADDR_BITS",  0x7f, 0x7f }
-};
-
-int
-ahc_scb_datacnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SCB_DATACNT_parse_table, 2, "SCB_DATACNT",
-           0xb0, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t SCB_SGPTR_parse_table[] = {
-       { "SG_LIST_NULL",       0x01, 0x01 },
-       { "SG_FULL_RESID",      0x02, 0x02 },
-       { "SG_RESID_VALID",     0x04, 0x04 }
-};
-
-int
-ahc_scb_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SCB_SGPTR_parse_table, 3, "SCB_SGPTR",
-           0xb4, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t SCB_CONTROL_parse_table[] = {
-       { "DISCONNECTED",       0x04, 0x04 },
-       { "ULTRAENB",           0x08, 0x08 },
-       { "MK_MESSAGE",         0x10, 0x10 },
-       { "TAG_ENB",            0x20, 0x20 },
-       { "DISCENB",            0x40, 0x40 },
-       { "TARGET_SCB",         0x80, 0x80 },
-       { "STATUS_RCVD",        0x80, 0x80 },
-       { "SCB_TAG_TYPE",       0x03, 0x03 }
-};
-
-int
-ahc_scb_control_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SCB_CONTROL_parse_table, 8, "SCB_CONTROL",
-           0xb8, regvalue, cur_col, wrap));
+       return (ahc_print_register(SCB_CONTROL_parse_table, 8, "SCB_CONTROL",
+           0xb8, regvalue, cur_col, wrap));
 }
 
 static const ahc_reg_parse_entry_t SCB_SCSIID_parse_table[] = {
@@ -1331,248 +411,3 @@ ahc_scb_tag_print(u_int regvalue, u_int *cur_col, u_int wrap)
            0xbb, regvalue, cur_col, wrap));
 }
 
-int
-ahc_scb_cdb_len_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SCB_CDB_LEN",
-           0xbc, regvalue, cur_col, wrap));
-}
-
-int
-ahc_scb_scsirate_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SCB_SCSIRATE",
-           0xbd, regvalue, cur_col, wrap));
-}
-
-int
-ahc_scb_scsioffset_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SCB_SCSIOFFSET",
-           0xbe, regvalue, cur_col, wrap));
-}
-
-int
-ahc_scb_next_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SCB_NEXT",
-           0xbf, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t SEECTL_2840_parse_table[] = {
-       { "DO_2840",            0x01, 0x01 },
-       { "CK_2840",            0x02, 0x02 },
-       { "CS_2840",            0x04, 0x04 }
-};
-
-int
-ahc_seectl_2840_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SEECTL_2840_parse_table, 3, "SEECTL_2840",
-           0xc0, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t STATUS_2840_parse_table[] = {
-       { "DI_2840",            0x01, 0x01 },
-       { "EEPROM_TF",          0x80, 0x80 },
-       { "ADSEL",              0x1e, 0x1e },
-       { "BIOS_SEL",           0x60, 0x60 }
-};
-
-int
-ahc_status_2840_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(STATUS_2840_parse_table, 4, "STATUS_2840",
-           0xc1, regvalue, cur_col, wrap));
-}
-
-int
-ahc_scb_64_btt_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SCB_64_BTT",
-           0xd0, regvalue, cur_col, wrap));
-}
-
-int
-ahc_cchaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "CCHADDR",
-           0xe0, regvalue, cur_col, wrap));
-}
-
-int
-ahc_cchcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "CCHCNT",
-           0xe8, regvalue, cur_col, wrap));
-}
-
-int
-ahc_ccsgram_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "CCSGRAM",
-           0xe9, regvalue, cur_col, wrap));
-}
-
-int
-ahc_ccsgaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "CCSGADDR",
-           0xea, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t CCSGCTL_parse_table[] = {
-       { "CCSGRESET",          0x01, 0x01 },
-       { "SG_FETCH_NEEDED",    0x02, 0x02 },
-       { "CCSGEN",             0x08, 0x08 },
-       { "CCSGDONE",           0x80, 0x80 }
-};
-
-int
-ahc_ccsgctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(CCSGCTL_parse_table, 4, "CCSGCTL",
-           0xeb, regvalue, cur_col, wrap));
-}
-
-int
-ahc_ccscbram_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "CCSCBRAM",
-           0xec, regvalue, cur_col, wrap));
-}
-
-int
-ahc_ccscbaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "CCSCBADDR",
-           0xed, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t CCSCBCTL_parse_table[] = {
-       { "CCSCBRESET",         0x01, 0x01 },
-       { "CCSCBDIR",           0x04, 0x04 },
-       { "CCSCBEN",            0x08, 0x08 },
-       { "CCARREN",            0x10, 0x10 },
-       { "ARRDONE",            0x40, 0x40 },
-       { "CCSCBDONE",          0x80, 0x80 }
-};
-
-int
-ahc_ccscbctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(CCSCBCTL_parse_table, 6, "CCSCBCTL",
-           0xee, regvalue, cur_col, wrap));
-}
-
-int
-ahc_ccscbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "CCSCBCNT",
-           0xef, regvalue, cur_col, wrap));
-}
-
-int
-ahc_scbbaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SCBBADDR",
-           0xf0, regvalue, cur_col, wrap));
-}
-
-int
-ahc_ccscbptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "CCSCBPTR",
-           0xf1, regvalue, cur_col, wrap));
-}
-
-int
-ahc_hnscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "HNSCB_QOFF",
-           0xf4, regvalue, cur_col, wrap));
-}
-
-int
-ahc_snscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SNSCB_QOFF",
-           0xf6, regvalue, cur_col, wrap));
-}
-
-int
-ahc_sdscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(NULL, 0, "SDSCB_QOFF",
-           0xf8, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t QOFF_CTLSTA_parse_table[] = {
-       { "SDSCB_ROLLOVER",     0x10, 0x10 },
-       { "SNSCB_ROLLOVER",     0x20, 0x20 },
-       { "SCB_AVAIL",          0x40, 0x40 },
-       { "SCB_QSIZE_256",      0x06, 0x06 },
-       { "SCB_QSIZE",          0x07, 0x07 }
-};
-
-int
-ahc_qoff_ctlsta_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(QOFF_CTLSTA_parse_table, 5, "QOFF_CTLSTA",
-           0xfa, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t DFF_THRSH_parse_table[] = {
-       { "RD_DFTHRSH_MIN",     0x00, 0x00 },
-       { "WR_DFTHRSH_MIN",     0x00, 0x00 },
-       { "RD_DFTHRSH_25",      0x01, 0x01 },
-       { "RD_DFTHRSH_50",      0x02, 0x02 },
-       { "RD_DFTHRSH_63",      0x03, 0x03 },
-       { "RD_DFTHRSH_75",      0x04, 0x04 },
-       { "RD_DFTHRSH_85",      0x05, 0x05 },
-       { "RD_DFTHRSH_90",      0x06, 0x06 },
-       { "RD_DFTHRSH",         0x07, 0x07 },
-       { "RD_DFTHRSH_MAX",     0x07, 0x07 },
-       { "WR_DFTHRSH_25",      0x10, 0x10 },
-       { "WR_DFTHRSH_50",      0x20, 0x20 },
-       { "WR_DFTHRSH_63",      0x30, 0x30 },
-       { "WR_DFTHRSH_75",      0x40, 0x40 },
-       { "WR_DFTHRSH_85",      0x50, 0x50 },
-       { "WR_DFTHRSH_90",      0x60, 0x60 },
-       { "WR_DFTHRSH",         0x70, 0x70 },
-       { "WR_DFTHRSH_MAX",     0x70, 0x70 }
-};
-
-int
-ahc_dff_thrsh_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(DFF_THRSH_parse_table, 18, "DFF_THRSH",
-           0xfb, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t SG_CACHE_SHADOW_parse_table[] = {
-       { "LAST_SEG_DONE",      0x01, 0x01 },
-       { "LAST_SEG",           0x02, 0x02 },
-       { "SG_ADDR_MASK",       0xf8, 0xf8 }
-};
-
-int
-ahc_sg_cache_shadow_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SG_CACHE_SHADOW_parse_table, 3, "SG_CACHE_SHADOW",
-           0xfc, regvalue, cur_col, wrap));
-}
-
-static const ahc_reg_parse_entry_t SG_CACHE_PRE_parse_table[] = {
-       { "LAST_SEG_DONE",      0x01, 0x01 },
-       { "LAST_SEG",           0x02, 0x02 },
-       { "SG_ADDR_MASK",       0xf8, 0xf8 }
-};
-
-int
-ahc_sg_cache_pre_print(u_int regvalue, u_int *cur_col, u_int wrap)
-{
-       return (ahc_print_register(SG_CACHE_PRE_parse_table, 3, "SG_CACHE_PRE",
-           0xfc, regvalue, cur_col, wrap));
-}
-
index 81be6a261cc8503a0853699b9e6719139cb9b5f6..e4064433842e62d8c876d478658b5d2597493007 100644 (file)
@@ -147,6 +147,8 @@ void yyerror(const char *string);
 
 %token T_ACCESS_MODE
 
+%token T_DONT_GENERATE_DEBUG_CODE
+
 %token T_MODES
 
 %token T_DEFINE
@@ -357,6 +359,7 @@ reg_attribute:
 |      size
 |      count
 |      access_mode
+|      dont_generate_debug_code
 |      modes
 |      field_defn
 |      enum_defn
@@ -410,6 +413,13 @@ access_mode:
        }
 ;
 
+dont_generate_debug_code:
+       T_DONT_GENERATE_DEBUG_CODE
+       {
+               cur_symbol->dont_generate_debug_code = 1;
+       }
+;
+
 modes:
        T_MODES mode_list
        {
index 2c7f02daf88d21387967be473c660dcc9a2c1a0e..93c8667cd704dd0af10d85a32e2806422ccecfce 100644 (file)
@@ -164,6 +164,7 @@ download            { return T_DOWNLOAD; }
 address                        { return T_ADDRESS; }
 count                  { return T_COUNT; }
 access_mode            { return T_ACCESS_MODE; }
+dont_generate_debug_code { return T_DONT_GENERATE_DEBUG_CODE; }
 modes                  { return T_MODES; }
 RW|RO|WO               {
                                 if (strcmp(yytext, "RW") == 0)
index fcd357872b43d0e360456e732dbdb868f7eb013c..078ed600f47ab14bec403cc44633ef27520ba03d 100644 (file)
@@ -539,6 +539,9 @@ symtable_dump(FILE *ofile, FILE *dfile)
        aic_print_include(dfile, stock_include_file);
        SLIST_FOREACH(curnode, &registers, links) {
 
+               if (curnode->symbol->dont_generate_debug_code)
+                       continue;
+
                switch(curnode->symbol->type) {
                case REGISTER:
                case SCBLOC:
index 05190c1a2fb779b880efbb2cc672b65da2058e4c..2ba73ae7c7774f362bf80391ae999ec8b3fff02b 100644 (file)
@@ -137,7 +137,8 @@ typedef struct symbol {
                struct label_info *linfo;
                struct cond_info  *condinfo;
                struct macro_info *macroinfo;
-       }info;
+       } info;
+       int     dont_generate_debug_code;
 } symbol_t;
 
 typedef struct symbol_ref {
index a43c3ed4df28c3dcb68d1843a6028459d085c0f0..3d50cabca7eeba34bbdda3ae84eb8ce9228df5f3 100644 (file)
@@ -401,6 +401,9 @@ static int check_ownership(struct scsi_device *sdev, struct rdac_dh_data *h)
                }
        }
 
+       if (h->lun_state == RDAC_LUN_UNOWNED)
+               h->state = RDAC_STATE_PASSIVE;
+
        return err;
 }
 
index 740bad435995268112883ff77c61af58e93ce8b6..2370fd82ebfe365fa477634d8c55d259dd39ab43 100644 (file)
@@ -343,6 +343,11 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r
 }
 
 #ifdef CONFIG_IDE_PROC_FS
+static ide_proc_entry_t idescsi_proc[] = {
+       { "capacity", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL },
+       { NULL, 0, NULL, NULL }
+};
+
 #define ide_scsi_devset_get(name, field) \
 static int get_##name(ide_drive_t *drive) \
 { \
@@ -378,6 +383,16 @@ static const struct ide_proc_devset idescsi_settings[] = {
        IDE_PROC_DEVSET(transform, 0,    3),
        { 0 },
 };
+
+static ide_proc_entry_t *ide_scsi_proc_entries(ide_drive_t *drive)
+{
+       return idescsi_proc;
+}
+
+static const struct ide_proc_devset *ide_scsi_proc_devsets(ide_drive_t *drive)
+{
+       return idescsi_settings;
+}
 #endif
 
 /*
@@ -419,13 +434,6 @@ static void ide_scsi_remove(ide_drive_t *drive)
 
 static int ide_scsi_probe(ide_drive_t *);
 
-#ifdef CONFIG_IDE_PROC_FS
-static ide_proc_entry_t idescsi_proc[] = {
-       { "capacity", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL },
-       { NULL, 0, NULL, NULL }
-};
-#endif
-
 static ide_driver_t idescsi_driver = {
        .gen_driver = {
                .owner          = THIS_MODULE,
@@ -439,45 +447,39 @@ static ide_driver_t idescsi_driver = {
        .end_request            = idescsi_end_request,
        .error                  = idescsi_atapi_error,
 #ifdef CONFIG_IDE_PROC_FS
-       .proc                   = idescsi_proc,
-       .settings               = idescsi_settings,
+       .proc_entries           = ide_scsi_proc_entries,
+       .proc_devsets           = ide_scsi_proc_devsets,
 #endif
 };
 
-static int idescsi_ide_open(struct inode *inode, struct file *filp)
+static int idescsi_ide_open(struct block_device *bdev, fmode_t mode)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct ide_scsi_obj *scsi;
+       struct ide_scsi_obj *scsi = ide_scsi_get(bdev->bd_disk);
 
-       if (!(scsi = ide_scsi_get(disk)))
+       if (!scsi)
                return -ENXIO;
 
        return 0;
 }
 
-static int idescsi_ide_release(struct inode *inode, struct file *filp)
+static int idescsi_ide_release(struct gendisk *disk, fmode_t mode)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct ide_scsi_obj *scsi = ide_scsi_g(disk);
-
-       ide_scsi_put(scsi);
-
+       ide_scsi_put(ide_scsi_g(disk));
        return 0;
 }
 
-static int idescsi_ide_ioctl(struct inode *inode, struct file *file,
+static int idescsi_ide_ioctl(struct block_device *bdev, fmode_t mode,
                        unsigned int cmd, unsigned long arg)
 {
-       struct block_device *bdev = inode->i_bdev;
        struct ide_scsi_obj *scsi = ide_scsi_g(bdev->bd_disk);
-       return generic_ide_ioctl(scsi->drive, file, bdev, cmd, arg);
+       return generic_ide_ioctl(scsi->drive, bdev, cmd, arg);
 }
 
 static struct block_device_operations idescsi_ops = {
        .owner          = THIS_MODULE,
        .open           = idescsi_ide_open,
        .release        = idescsi_ide_release,
-       .ioctl          = idescsi_ide_ioctl,
+       .locked_ioctl   = idescsi_ide_ioctl,
 };
 
 static int idescsi_slave_configure(struct scsi_device * sdp)
index d30eb7ba018e6dde266ac53253b95c8687dde8e8..ded854a6dd35bd0d916f630090fc87990cd59182 100644 (file)
@@ -2456,20 +2456,14 @@ static ssize_t ipr_read_trace(struct kobject *kobj,
        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 size = IPR_TRACE_SIZE;
-       char *src = (char *)ioa_cfg->trace;
-
-       if (off > size)
-               return 0;
-       if (off + count > size) {
-               size -= off;
-               count = size;
-       }
+       ssize_t ret;
 
        spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
-       memcpy(buf, &src[off], count);
+       ret = memory_read_from_buffer(buf, count, &off, ioa_cfg->trace,
+                               IPR_TRACE_SIZE);
        spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
-       return count;
+
+       return ret;
 }
 
 static struct bin_attribute ipr_trace_attr = {
@@ -7859,7 +7853,6 @@ static struct pci_driver ipr_driver = {
        .remove = ipr_remove,
        .shutdown = ipr_shutdown,
        .err_handler = &ipr_err_handler,
-       .dynids.use_driver_data = 1
 };
 
 /**
index 83c819216771a5c9c10d886789e3fa9350d75cc0..f25f41a499e5ed7be7ebd3dc109d4d4b14c9494a 100644 (file)
@@ -2108,7 +2108,7 @@ struct scsi_qla_host;
 
 struct qla_msix_entry {
        int have_irq;
-       uint16_t msix_vector;
+       uint32_t msix_vector;
        uint16_t msix_entry;
 };
 
index 2aed4721c0d043821a5044483c4081c77adec0f9..21dd182ad512214c7646299a1af4ad4f2e9d9e88 100644 (file)
@@ -1566,9 +1566,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
                        goto probe_out;
        }
 
-       if (pci_find_aer_capability(pdev))
-               if (pci_enable_pcie_error_reporting(pdev))
-                       goto probe_out;
+       /* This may fail but that's ok */
+       pci_enable_pcie_error_reporting(pdev);
 
        host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t));
        if (host == NULL) {
index 28b19ef26309f5c471104250c0683bea0caef3ab..dc1cfb2fd76b9156b63a5b5e78cafcf0c3bb6423 100644 (file)
@@ -237,7 +237,7 @@ int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
        case SCSI_IOCTL_SEND_COMMAND:
                if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
                        return -EACCES;
-               return sg_scsi_ioctl(NULL, sdev->request_queue, NULL, arg);
+               return sg_scsi_ioctl(sdev->request_queue, NULL, 0, arg);
        case SCSI_IOCTL_DOORLOCK:
                return scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
        case SCSI_IOCTL_DOORUNLOCK:
@@ -277,14 +277,14 @@ EXPORT_SYMBOL(scsi_ioctl);
  * @filp: either NULL or a &struct file which must have the O_NONBLOCK flag.
  */
 int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd,
-                           void __user *arg, struct file *filp)
+                           void __user *arg, int ndelay)
 {
        int val, result;
 
        /* The first set of iocts may be executed even if we're doing
         * error processing, as long as the device was opened
         * non-blocking */
-       if (filp && (filp->f_flags & O_NONBLOCK)) {
+       if (ndelay) {
                if (scsi_host_in_recovery(sdev->host))
                        return -ENODEV;
        } else if (!scsi_block_when_processing_errors(sdev))
index e5a9526d20376ab341b54618248dbdd93db3ded3..f5d3b96890dc6d9dd180eb86bb0f2b737a60e7f1 100644 (file)
@@ -529,6 +529,14 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev)
        spin_unlock_irqrestore(shost->host_lock, flags);
 }
 
+static inline int scsi_device_is_busy(struct scsi_device *sdev)
+{
+       if (sdev->device_busy >= sdev->queue_depth || sdev->device_blocked)
+               return 1;
+
+       return 0;
+}
+
 static inline int scsi_target_is_busy(struct scsi_target *starget)
 {
        return ((starget->can_queue > 0 &&
@@ -536,6 +544,15 @@ static inline int scsi_target_is_busy(struct scsi_target *starget)
                 starget->target_blocked);
 }
 
+static inline int scsi_host_is_busy(struct Scsi_Host *shost)
+{
+       if ((shost->can_queue > 0 && shost->host_busy >= shost->can_queue) ||
+           shost->host_blocked || shost->host_self_blocked)
+               return 1;
+
+       return 0;
+}
+
 /*
  * Function:   scsi_run_queue()
  *
@@ -558,11 +575,7 @@ static void scsi_run_queue(struct request_queue *q)
                scsi_single_lun_run(sdev);
 
        spin_lock_irqsave(shost->host_lock, flags);
-       while (!list_empty(&shost->starved_list) &&
-              !shost->host_blocked && !shost->host_self_blocked &&
-               !((shost->can_queue > 0) &&
-                 (shost->host_busy >= shost->can_queue))) {
-
+       while (!list_empty(&shost->starved_list) && !scsi_host_is_busy(shost)) {
                int flagset;
 
                /*
@@ -1348,8 +1361,6 @@ int scsi_prep_fn(struct request_queue *q, struct request *req)
 static inline int scsi_dev_queue_ready(struct request_queue *q,
                                  struct scsi_device *sdev)
 {
-       if (sdev->device_busy >= sdev->queue_depth)
-               return 0;
        if (sdev->device_busy == 0 && sdev->device_blocked) {
                /*
                 * unblock after device_blocked iterates to zero
@@ -1363,7 +1374,7 @@ static inline int scsi_dev_queue_ready(struct request_queue *q,
                        return 0;
                }
        }
-       if (sdev->device_blocked)
+       if (scsi_device_is_busy(sdev))
                return 0;
 
        return 1;
@@ -1440,8 +1451,7 @@ static inline int scsi_host_queue_ready(struct request_queue *q,
                        return 0;
                }
        }
-       if ((shost->can_queue > 0 && shost->host_busy >= shost->can_queue) ||
-           shost->host_blocked || shost->host_self_blocked) {
+       if (scsi_host_is_busy(shost)) {
                if (list_empty(&sdev->starved_entry))
                        list_add_tail(&sdev->starved_entry, &shost->starved_list);
                return 0;
@@ -1454,6 +1464,37 @@ static inline int scsi_host_queue_ready(struct request_queue *q,
        return 1;
 }
 
+/*
+ * Busy state exporting function for request stacking drivers.
+ *
+ * For efficiency, no lock is taken to check the busy state of
+ * shost/starget/sdev, since the returned value is not guaranteed and
+ * may be changed after request stacking drivers call the function,
+ * regardless of taking lock or not.
+ *
+ * When scsi can't dispatch I/Os anymore and needs to kill I/Os
+ * (e.g. !sdev), scsi needs to return 'not busy'.
+ * Otherwise, request stacking drivers may hold requests forever.
+ */
+static int scsi_lld_busy(struct request_queue *q)
+{
+       struct scsi_device *sdev = q->queuedata;
+       struct Scsi_Host *shost;
+       struct scsi_target *starget;
+
+       if (!sdev)
+               return 0;
+
+       shost = sdev->host;
+       starget = scsi_target(sdev);
+
+       if (scsi_host_in_recovery(shost) || scsi_host_is_busy(shost) ||
+           scsi_target_is_busy(starget) || scsi_device_is_busy(sdev))
+               return 1;
+
+       return 0;
+}
+
 /*
  * Kill a request for a dead device
  */
@@ -1757,6 +1798,7 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
        blk_queue_prep_rq(q, scsi_prep_fn);
        blk_queue_softirq_done(q, scsi_softirq_done);
        blk_queue_rq_timed_out(q, scsi_times_out);
+       blk_queue_lld_busy(q, scsi_lld_busy);
        return q;
 }
 
@@ -2105,22 +2147,21 @@ scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries,
        do {
                result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0, sshdr,
                                          timeout, retries);
-       } while ((driver_byte(result) & DRIVER_SENSE) &&
-                sshdr && sshdr->sense_key == UNIT_ATTENTION &&
-                --retries);
+               if (sdev->removable && scsi_sense_valid(sshdr) &&
+                   sshdr->sense_key == UNIT_ATTENTION)
+                       sdev->changed = 1;
+       } while (scsi_sense_valid(sshdr) &&
+                sshdr->sense_key == UNIT_ATTENTION && --retries);
 
        if (!sshdr)
                /* could not allocate sense buffer, so can't process it */
                return result;
 
-       if ((driver_byte(result) & DRIVER_SENSE) && sdev->removable) {
-
-               if ((scsi_sense_valid(sshdr)) &&
-                   ((sshdr->sense_key == UNIT_ATTENTION) ||
-                    (sshdr->sense_key == NOT_READY))) {
-                       sdev->changed = 1;
-                       result = 0;
-               }
+       if (sdev->removable && scsi_sense_valid(sshdr) &&
+           (sshdr->sense_key == UNIT_ATTENTION ||
+            sshdr->sense_key == NOT_READY)) {
+               sdev->changed = 1;
+               result = 0;
        }
        if (!sshdr_external)
                kfree(sshdr);
index b37e133de80557e3be96e70f0960d5ef910c1fb5..723fdecd91bdd4ba027ae4edd20470c6d84bc520 100644 (file)
@@ -205,16 +205,13 @@ static struct notifier_block scsi_netlink_notifier = {
 };
 
 
-/**
+/*
  * GENERIC SCSI transport receive and event handlers
- **/
+ */
 
 /**
- * scsi_generic_msg_handler - receive message handler for GENERIC transport
- *                      messages
- *
+ * scsi_generic_msg_handler - receive message handler for GENERIC transport messages
  * @skb:               socket receive buffer
- *
  **/
 static int
 scsi_generic_msg_handler(struct sk_buff *skb)
index 7c4d2e68df1c3e974998d12dbc83c66302ef0d59..c9e1242eaf2511067e122e89b331d438823a0a69 100644 (file)
@@ -609,17 +609,15 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
  *     In the latter case @inode and @filp carry an abridged amount
  *     of information as noted above.
  **/
-static int sd_open(struct inode *inode, struct file *filp)
+static int sd_open(struct block_device *bdev, fmode_t mode)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct scsi_disk *sdkp;
+       struct scsi_disk *sdkp = scsi_disk_get(bdev->bd_disk);
        struct scsi_device *sdev;
        int retval;
 
-       if (!(sdkp = scsi_disk_get(disk)))
+       if (!sdkp)
                return -ENXIO;
 
-
        SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_open\n"));
 
        sdev = sdkp->device;
@@ -633,14 +631,13 @@ static int sd_open(struct inode *inode, struct file *filp)
                goto error_out;
 
        if (sdev->removable || sdkp->write_prot)
-               check_disk_change(inode->i_bdev);
+               check_disk_change(bdev);
 
        /*
         * If the drive is empty, just let the open fail.
         */
        retval = -ENOMEDIUM;
-       if (sdev->removable && !sdkp->media_present &&
-           !(filp->f_flags & O_NDELAY))
+       if (sdev->removable && !sdkp->media_present && !(mode & FMODE_NDELAY))
                goto error_out;
 
        /*
@@ -648,7 +645,7 @@ static int sd_open(struct inode *inode, struct file *filp)
         * if the user expects to be able to write to the thing.
         */
        retval = -EROFS;
-       if (sdkp->write_prot && (filp->f_mode & FMODE_WRITE))
+       if (sdkp->write_prot && (mode & FMODE_WRITE))
                goto error_out;
 
        /*
@@ -684,9 +681,8 @@ error_out:
  *     Note: may block (uninterruptible) if error recovery is underway
  *     on this disk.
  **/
-static int sd_release(struct inode *inode, struct file *filp)
+static int sd_release(struct gendisk *disk, fmode_t mode)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
        struct scsi_disk *sdkp = scsi_disk(disk);
        struct scsi_device *sdev = sdkp->device;
 
@@ -743,10 +739,9 @@ static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
  *     Note: most ioctls are forward onto the block subsystem or further
  *     down in the scsi subsystem.
  **/
-static int sd_ioctl(struct inode * inode, struct file * filp, 
+static int sd_ioctl(struct block_device *bdev, fmode_t mode,
                    unsigned int cmd, unsigned long arg)
 {
-       struct block_device *bdev = inode->i_bdev;
        struct gendisk *disk = bdev->bd_disk;
        struct scsi_device *sdp = scsi_disk(disk)->device;
        void __user *p = (void __user *)arg;
@@ -761,7 +756,8 @@ static int sd_ioctl(struct inode * inode, struct file * filp,
         * may try and take the device offline, in which case all further
         * access to the device is prohibited.
         */
-       error = scsi_nonblockable_ioctl(sdp, cmd, p, filp);
+       error = scsi_nonblockable_ioctl(sdp, cmd, p,
+                                       (mode & FMODE_NDELAY_NOW) != 0);
        if (!scsi_block_when_processing_errors(sdp) || !error)
                return error;
 
@@ -775,7 +771,7 @@ static int sd_ioctl(struct inode * inode, struct file * filp,
                case SCSI_IOCTL_GET_BUS_NUMBER:
                        return scsi_ioctl(sdp, cmd, p);
                default:
-                       error = scsi_cmd_ioctl(filp, disk->queue, disk, cmd, p);
+                       error = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, p);
                        if (error != -ENOTTY)
                                return error;
        }
@@ -928,11 +924,10 @@ static void sd_rescan(struct device *dev)
  * This gets directly called from VFS. When the ioctl 
  * is not recognized we go back to the other translation paths. 
  */
-static long sd_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode,
+                          unsigned int cmd, unsigned long arg)
 {
-       struct block_device *bdev = file->f_path.dentry->d_inode->i_bdev;
-       struct gendisk *disk = bdev->bd_disk;
-       struct scsi_device *sdev = scsi_disk(disk)->device;
+       struct scsi_device *sdev = scsi_disk(bdev->bd_disk)->device;
 
        /*
         * If we are in the middle of error recovery, don't let anyone
@@ -962,7 +957,7 @@ static struct block_device_operations sd_fops = {
        .owner                  = THIS_MODULE,
        .open                   = sd_open,
        .release                = sd_release,
-       .ioctl                  = sd_ioctl,
+       .locked_ioctl           = sd_ioctl,
        .getgeo                 = sd_getgeo,
 #ifdef CONFIG_COMPAT
        .compat_ioctl           = sd_compat_ioctl,
@@ -1054,7 +1049,6 @@ static int sd_done(struct scsi_cmnd *SCpnt)
                good_bytes = sd_completed_bytes(SCpnt);
                break;
        case RECOVERED_ERROR:
-       case NO_SENSE:
                /* Inform the user, but make sure that it's not treated
                 * as a hard error.
                 */
@@ -1063,6 +1057,15 @@ static int sd_done(struct scsi_cmnd *SCpnt)
                memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
                good_bytes = scsi_bufflen(SCpnt);
                break;
+       case NO_SENSE:
+               /* This indicates a false check condition, so ignore it.  An
+                * unknown amount of data was transferred so treat it as an
+                * error.
+                */
+               scsi_print_sense("sd", SCpnt);
+               SCpnt->result = 0;
+               memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
+               break;
        case ABORTED_COMMAND:
                if (sshdr.asc == 0x10) { /* DIF: Disk detected corruption */
                        scsi_print_result(SCpnt);
@@ -1076,15 +1079,6 @@ static int sd_done(struct scsi_cmnd *SCpnt)
                        scsi_print_sense("sd", SCpnt);
                        good_bytes = sd_completed_bytes(SCpnt);
                }
-               if (!scsi_device_protection(SCpnt->device) &&
-                   SCpnt->device->use_10_for_rw &&
-                   (SCpnt->cmnd[0] == READ_10 ||
-                    SCpnt->cmnd[0] == WRITE_10))
-                       SCpnt->device->use_10_for_rw = 0;
-               if (SCpnt->device->use_10_for_ms &&
-                   (SCpnt->cmnd[0] == MODE_SENSE_10 ||
-                    SCpnt->cmnd[0] == MODE_SELECT_10))
-                       SCpnt->device->use_10_for_ms = 0;
                break;
        default:
                break;
@@ -1437,7 +1431,7 @@ got_data:
 
        {
                char cap_str_2[10], cap_str_10[10];
-               u64 sz = sdkp->capacity << ffz(~sector_size);
+               u64 sz = (u64)sdkp->capacity << ilog2(sector_size);
 
                string_get_size(sz, STRING_UNITS_2, cap_str_2,
                                sizeof(cap_str_2));
index 93bd59a1ed79b80bde26a459b45b0a0d40ae7f83..9adf35bd8b5667f6c535070729194d1c04bfe291 100644 (file)
@@ -1059,7 +1059,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
                        if (sg_allow_access(filp, &opcode))
                                return -EPERM;
                }
-               return sg_scsi_ioctl(filp, sdp->device->request_queue, NULL, p);
+               return sg_scsi_ioctl(sdp->device->request_queue, NULL, filp->f_mode, p);
        case SG_SET_DEBUG:
                result = get_user(val, ip);
                if (result)
index 0f17009c99d2f75581ea96b30e3927f89beaa408..62b6633e3a97b8d27511f1fbc9c9cb5d118abcea 100644 (file)
@@ -471,38 +471,31 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq)
        return scsi_prep_return(q, rq, ret);
 }
 
-static int sr_block_open(struct inode *inode, struct file *file)
+static int sr_block_open(struct block_device *bdev, fmode_t mode)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct scsi_cd *cd;
-       int ret = 0;
-
-       if(!(cd = scsi_cd_get(disk)))
-               return -ENXIO;
-
-       if((ret = cdrom_open(&cd->cdi, inode, file)) != 0)
-               scsi_cd_put(cd);
+       struct scsi_cd *cd = scsi_cd_get(bdev->bd_disk);
+       int ret = -ENXIO;
 
+       if (cd) {
+               ret = cdrom_open(&cd->cdi, bdev, mode);
+               if (ret)
+                       scsi_cd_put(cd);
+       }
        return ret;
 }
 
-static int sr_block_release(struct inode *inode, struct file *file)
+static int sr_block_release(struct gendisk *disk, fmode_t mode)
 {
-       int ret;
-       struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
-       ret = cdrom_release(&cd->cdi, file);
-       if(ret)
-               return ret;
-       
+       struct scsi_cd *cd = scsi_cd(disk);
+       cdrom_release(&cd->cdi, mode);
        scsi_cd_put(cd);
-
        return 0;
 }
 
-static int sr_block_ioctl(struct inode *inode, struct file *file, unsigned cmd,
+static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
                          unsigned long arg)
 {
-       struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
+       struct scsi_cd *cd = scsi_cd(bdev->bd_disk);
        struct scsi_device *sdev = cd->device;
        void __user *argp = (void __user *)arg;
        int ret;
@@ -517,7 +510,7 @@ static int sr_block_ioctl(struct inode *inode, struct file *file, unsigned cmd,
                return scsi_ioctl(sdev, cmd, argp);
        }
 
-       ret = cdrom_ioctl(file, &cd->cdi, inode, cmd, arg);
+       ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, arg);
        if (ret != -ENOSYS)
                return ret;
 
@@ -527,7 +520,8 @@ static int sr_block_ioctl(struct inode *inode, struct file *file, unsigned cmd,
         * case fall through to scsi_ioctl, which will return ENDOEV again
         * if it doesn't recognise the ioctl
         */
-       ret = scsi_nonblockable_ioctl(sdev, cmd, argp, NULL);
+       ret = scsi_nonblockable_ioctl(sdev, cmd, argp,
+                                       (mode & FMODE_NDELAY_NOW) != 0);
        if (ret != -ENODEV)
                return ret;
        return scsi_ioctl(sdev, cmd, argp);
@@ -544,7 +538,7 @@ static struct block_device_operations sr_bdops =
        .owner          = THIS_MODULE,
        .open           = sr_block_open,
        .release        = sr_block_release,
-       .ioctl          = sr_block_ioctl,
+       .locked_ioctl   = sr_block_ioctl,
        .media_changed  = sr_block_media_changed,
        /* 
         * No compat_ioctl for now because sr_block_ioctl never
index 5c28d08f18f46a1bc3f28c5451f84606af747f7c..c959bdc55f4f765d7a02c096a6b1be64ca30c0c8 100644 (file)
@@ -3263,7 +3263,8 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
         * may try and take the device offline, in which case all further
         * access to the device is prohibited.
         */
-       retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p, file);
+       retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p,
+                                       file->f_flags & O_NDELAY);
        if (!scsi_block_when_processing_errors(STp->device) || retval != -ENODEV)
                goto out;
        retval = 0;
@@ -3567,8 +3568,8 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
                            !capable(CAP_SYS_RAWIO))
                                i = -EPERM;
                        else
-                               i = scsi_cmd_ioctl(file, STp->disk->queue,
-                                                  STp->disk, cmd_in, p);
+                               i = scsi_cmd_ioctl(STp->disk->queue, STp->disk,
+                                                  file->f_mode, cmd_in, p);
                        if (i != -ENOTTY)
                                return i;
                        break;
index 7514b3a0390e5b19b75689a4493047a7ef3d67be..34a99620e5bd35ca2d7ed411ed42004d59788240 100644 (file)
@@ -213,7 +213,7 @@ static int __devinit esp_sun3x_probe(struct platform_device *dev)
        esp->ops = &sun3x_esp_ops;
 
        res = platform_get_resource(dev, IORESOURCE_MEM, 0);
-       if (!res && !res->start)
+       if (!res || !res->start)
                goto fail_unlink;
 
        esp->regs = ioremap_nocache(res->start, 0x20);
@@ -221,7 +221,7 @@ static int __devinit esp_sun3x_probe(struct platform_device *dev)
                goto fail_unmap_regs;
 
        res = platform_get_resource(dev, IORESOURCE_MEM, 1);
-       if (!res && !res->start)
+       if (!res || !res->start)
                goto fail_unmap_regs;
 
        esp->dma_regs = ioremap_nocache(res->start, 0x10);
index 381b12ac20e0d249522b0811caf665c0448fba3d..d935b2d04f93345c9cc577373dd9a89e4357188c 100644 (file)
@@ -66,7 +66,6 @@
 #endif
 
 static struct m68k_serial m68k_soft[NR_PORTS];
-struct m68k_serial *IRQ_ports[NR_IRQS];
 
 static unsigned int uart_irqs[NR_PORTS] = UART_IRQ_DEFNS;
 
@@ -375,15 +374,11 @@ clear_and_return:
  */
 irqreturn_t rs_interrupt(int irq, void *dev_id)
 {
-       struct m68k_serial * info;
+       struct m68k_serial *info = dev_id;
        m68328_uart *uart;
        unsigned short rx;
        unsigned short tx;
 
-       info = IRQ_ports[irq];
-       if(!info)
-           return IRQ_NONE;
-
        uart = &uart_addr[info->line];
        rx = uart->urx.w;
 
@@ -1383,8 +1378,6 @@ rs68328_init(void)
                   info->port, info->irq);
            printk(" is a builtin MC68328 UART\n");
            
-           IRQ_ports[info->irq] = info;        /* waste of space */
-
 #ifdef CONFIG_M68VZ328
                if (i > 0 )
                        PJSEL &= 0xCF;  /* PSW enable second port output */
@@ -1393,7 +1386,7 @@ rs68328_init(void)
            if (request_irq(uart_irqs[i],
                            rs_interrupt,
                            IRQF_DISABLED,
-                           "M68328_UART", NULL))
+                           "M68328_UART", info))
                 panic("Unable to attach 68328 serial interrupt\n");
        }
        local_irq_restore(flags);
index 1528de23a6504987f78038db7be1e933e4762364..303272af386ef4ac307517d6df654759cbc23d43 100644 (file)
@@ -156,11 +156,15 @@ struct uart_8250_port {
 };
 
 struct irq_info {
-       spinlock_t              lock;
+       struct                  hlist_node node;
+       int                     irq;
+       spinlock_t              lock;   /* Protects list not the hash */
        struct list_head        *head;
 };
 
-static struct irq_info irq_lists[NR_IRQS];
+#define NR_IRQ_HASH            32      /* Can be adjusted later */
+static struct hlist_head irq_lists[NR_IRQ_HASH];
+static DEFINE_MUTEX(hash_mutex);       /* Used to walk the hash */
 
 /*
  * Here we define the default xmit fifo size used for each type of UART.
@@ -1545,15 +1549,43 @@ static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up)
                BUG_ON(i->head != &up->list);
                i->head = NULL;
        }
-
        spin_unlock_irq(&i->lock);
+       /* List empty so throw away the hash node */
+       if (i->head == NULL) {
+               hlist_del(&i->node);
+               kfree(i);
+       }
 }
 
 static int serial_link_irq_chain(struct uart_8250_port *up)
 {
-       struct irq_info *i = irq_lists + up->port.irq;
+       struct hlist_head *h;
+       struct hlist_node *n;
+       struct irq_info *i;
        int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;
 
+       mutex_lock(&hash_mutex);
+
+       h = &irq_lists[up->port.irq % NR_IRQ_HASH];
+
+       hlist_for_each(n, h) {
+               i = hlist_entry(n, struct irq_info, node);
+               if (i->irq == up->port.irq)
+                       break;
+       }
+
+       if (n == NULL) {
+               i = kzalloc(sizeof(struct irq_info), GFP_KERNEL);
+               if (i == NULL) {
+                       mutex_unlock(&hash_mutex);
+                       return -ENOMEM;
+               }
+               spin_lock_init(&i->lock);
+               i->irq = up->port.irq;
+               hlist_add_head(&i->node, h);
+       }
+       mutex_unlock(&hash_mutex);
+
        spin_lock_irq(&i->lock);
 
        if (i->head) {
@@ -1577,14 +1609,28 @@ static int serial_link_irq_chain(struct uart_8250_port *up)
 
 static void serial_unlink_irq_chain(struct uart_8250_port *up)
 {
-       struct irq_info *i = irq_lists + up->port.irq;
+       struct irq_info *i;
+       struct hlist_node *n;
+       struct hlist_head *h;
 
+       mutex_lock(&hash_mutex);
+
+       h = &irq_lists[up->port.irq % NR_IRQ_HASH];
+
+       hlist_for_each(n, h) {
+               i = hlist_entry(n, struct irq_info, node);
+               if (i->irq == up->port.irq)
+                       break;
+       }
+
+       BUG_ON(n == NULL);
        BUG_ON(i->head == NULL);
 
        if (list_empty(i->head))
                free_irq(up->port.irq, i);
 
        serial_do_unlink(i, up);
+       mutex_unlock(&hash_mutex);
 }
 
 /* Base timer interval for polling */
@@ -2447,7 +2493,7 @@ static void serial8250_config_port(struct uart_port *port, int flags)
 static int
 serial8250_verify_port(struct uart_port *port, struct serial_struct *ser)
 {
-       if (ser->irq >= NR_IRQS || ser->irq < 0 ||
+       if (ser->irq >= nr_irqs || ser->irq < 0 ||
            ser->baud_base < 9600 || ser->type < PORT_UNKNOWN ||
            ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS ||
            ser->type == PORT_STARTECH)
@@ -2967,7 +3013,7 @@ EXPORT_SYMBOL(serial8250_unregister_port);
 
 static int __init serial8250_init(void)
 {
-       int ret, i;
+       int ret;
 
        if (nr_uarts > UART_NR)
                nr_uarts = UART_NR;
@@ -2976,9 +3022,6 @@ static int __init serial8250_init(void)
                "%d ports, IRQ sharing %sabled\n", nr_uarts,
                share_irqs ? "en" : "dis");
 
-       for (i = 0; i < NR_IRQS; i++)
-               spin_lock_init(&irq_lists[i].lock);
-
 #ifdef CONFIG_SPARC
        ret = sunserial_register_minors(&serial8250_reg, UART_NR);
 #else
@@ -3006,15 +3049,15 @@ static int __init serial8250_init(void)
                goto out;
 
        platform_device_del(serial8250_isa_devs);
- put_dev:
+put_dev:
        platform_device_put(serial8250_isa_devs);
- unreg_uart_drv:
+unreg_uart_drv:
 #ifdef CONFIG_SPARC
        sunserial_unregister_minors(&serial8250_reg, UART_NR);
 #else
        uart_unregister_driver(&serial8250_reg);
 #endif
- out:
+out:
        return ret;
 }
 
index c014ffb110e98c8b4801d47c4884ddead3a4b492..5450a0e5ecdb37940e13cd47d62c56e3be6e3042 100644 (file)
@@ -1100,6 +1100,8 @@ enum pci_board_num_t {
        pbn_b0_4_1843200_200,
        pbn_b0_8_1843200_200,
 
+       pbn_b0_1_4000000,
+
        pbn_b0_bt_1_115200,
        pbn_b0_bt_2_115200,
        pbn_b0_bt_8_115200,
@@ -1167,6 +1169,10 @@ enum pci_board_num_t {
        pbn_exsys_4055,
        pbn_plx_romulus,
        pbn_oxsemi,
+       pbn_oxsemi_1_4000000,
+       pbn_oxsemi_2_4000000,
+       pbn_oxsemi_4_4000000,
+       pbn_oxsemi_8_4000000,
        pbn_intel_i960,
        pbn_sgi_ioc3,
        pbn_computone_4,
@@ -1290,6 +1296,12 @@ static struct pciserial_board pci_boards[] __devinitdata = {
                .base_baud      = 1843200,
                .uart_offset    = 0x200,
        },
+       [pbn_b0_1_4000000] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 1,
+               .base_baud      = 4000000,
+               .uart_offset    = 8,
+       },
 
        [pbn_b0_bt_1_115200] = {
                .flags          = FL_BASE0|FL_BASE_BARS,
@@ -1625,6 +1637,35 @@ static struct pciserial_board pci_boards[] __devinitdata = {
                .base_baud      = 115200,
                .uart_offset    = 8,
        },
+       [pbn_oxsemi_1_4000000] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 1,
+               .base_baud      = 4000000,
+               .uart_offset    = 0x200,
+               .first_offset   = 0x1000,
+       },
+       [pbn_oxsemi_2_4000000] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 2,
+               .base_baud      = 4000000,
+               .uart_offset    = 0x200,
+               .first_offset   = 0x1000,
+       },
+       [pbn_oxsemi_4_4000000] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 4,
+               .base_baud      = 4000000,
+               .uart_offset    = 0x200,
+               .first_offset   = 0x1000,
+       },
+       [pbn_oxsemi_8_4000000] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 8,
+               .base_baud      = 4000000,
+               .uart_offset    = 0x200,
+               .first_offset   = 0x1000,
+       },
+
 
        /*
         * EKF addition for i960 Boards form EKF with serial port.
@@ -1813,6 +1854,39 @@ serial_pci_matches(struct pciserial_board *board,
            board->first_offset == guessed->first_offset;
 }
 
+/*
+ * Oxford Semiconductor Inc.
+ * Check that device is part of the Tornado range of devices, then determine
+ * the number of ports available on the device.
+ */
+static int pci_oxsemi_tornado_init(struct pci_dev *dev, struct pciserial_board *board)
+{
+       u8 __iomem *p;
+       unsigned long deviceID;
+       unsigned int  number_uarts;
+
+       /* OxSemi Tornado devices are all 0xCxxx */
+       if (dev->vendor == PCI_VENDOR_ID_OXSEMI &&
+           (dev->device & 0xF000) != 0xC000)
+               return 0;
+
+       p = pci_iomap(dev, 0, 5);
+       if (p == NULL)
+               return -ENOMEM;
+
+       deviceID = ioread32(p);
+       /* Tornado device */
+       if (deviceID == 0x07000200) {
+               number_uarts = ioread8(p + 4);
+               board->num_ports = number_uarts;
+               printk(KERN_DEBUG
+                       "%d ports detected on Oxford PCI Express device\n",
+                                                               number_uarts);
+       }
+       pci_iounmap(dev, p);
+       return 0;
+}
+
 struct serial_private *
 pciserial_init_ports(struct pci_dev *dev, struct pciserial_board *board)
 {
@@ -1821,6 +1895,13 @@ pciserial_init_ports(struct pci_dev *dev, struct pciserial_board *board)
        struct pci_serial_quirk *quirk;
        int rc, nr_ports, i;
 
+       /*
+        * Find number of ports on board
+        */
+       if (dev->vendor == PCI_VENDOR_ID_OXSEMI ||
+           dev->vendor == PCI_VENDOR_ID_MAINPINE)
+               pci_oxsemi_tornado_init(dev, board);
+
        nr_ports = board->num_ports;
 
        /*
@@ -2300,6 +2381,156 @@ static struct pci_device_id serial_pci_tbl[] = {
                PCI_ANY_ID, PCI_ANY_ID, 0, 0,
                pbn_b0_bt_2_921600 },
 
+       /*
+        * Oxford Semiconductor Inc. Tornado PCI express device range.
+        */
+       {       PCI_VENDOR_ID_OXSEMI, 0xc101,    /* OXPCIe952 1 Legacy UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc105,    /* OXPCIe952 1 Legacy UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc11b,    /* OXPCIe952 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc11f,    /* OXPCIe952 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc120,    /* OXPCIe952 1 Legacy UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc124,    /* OXPCIe952 1 Legacy UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc138,    /* OXPCIe952 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc13d,    /* OXPCIe952 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc140,    /* OXPCIe952 1 Legacy UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc141,    /* OXPCIe952 1 Legacy UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc144,    /* OXPCIe952 1 Legacy UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc145,    /* OXPCIe952 1 Legacy UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc158,    /* OXPCIe952 2 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_2_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc15d,    /* OXPCIe952 2 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_2_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc208,    /* OXPCIe954 4 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_4_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc20d,    /* OXPCIe954 4 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_4_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc308,    /* OXPCIe958 8 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_8_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc30d,    /* OXPCIe958 8 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_8_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc40b,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc40f,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc41b,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc41f,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc42b,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc42f,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc43b,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc43f,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc44b,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc44f,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc45b,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc45f,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc46b,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc46f,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc47b,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc47f,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc48b,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc48f,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc49b,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc49f,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc4ab,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc4af,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc4bb,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc4bf,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc4cb,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0xc4cf,    /* OXPCIe200 1 Native UART */
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       /*
+        * Mainpine Inc. IQ Express "Rev3" utilizing OxSemi Tornado
+        */
+       {       PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 1 Port V.34 Super-G3 Fax */
+               PCI_VENDOR_ID_MAINPINE, 0x4001, 0, 0,
+               pbn_oxsemi_1_4000000 },
+       {       PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 2 Port V.34 Super-G3 Fax */
+               PCI_VENDOR_ID_MAINPINE, 0x4002, 0, 0,
+               pbn_oxsemi_2_4000000 },
+       {       PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 4 Port V.34 Super-G3 Fax */
+               PCI_VENDOR_ID_MAINPINE, 0x4004, 0, 0,
+               pbn_oxsemi_4_4000000 },
+       {       PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 8 Port V.34 Super-G3 Fax */
+               PCI_VENDOR_ID_MAINPINE, 0x4008, 0, 0,
+               pbn_oxsemi_8_4000000 },
        /*
         * SBS Technologies, Inc. P-Octal and PMC-OCTPRO cards,
         * from skokodyn@yahoo.com
index db783b77a881b9a74cbf298f3442433a6b5eeb4c..c94d3c4b75211448aabc65651c296819a6dc52bf 100644 (file)
@@ -457,7 +457,7 @@ config SERIAL_SAMSUNG
 
 config SERIAL_SAMSUNG_DEBUG
        bool "Samsung SoC serial debug"
-       depends on SERIAL_SAMSUNG
+       depends on SERIAL_SAMSUNG && DEBUG_LL
        help
          Add support for debugging the serial driver. Since this is
          generally being used as a console, we use our own output
index 90b56c2c31e20f7cc5d2ea0fccb73a2a1f4b8d98..71562689116ff4e45f326dbfc6e8cbb10732ad31 100644 (file)
@@ -512,7 +512,7 @@ static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser)
        int ret = 0;
        if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA)
                ret = -EINVAL;
-       if (ser->irq < 0 || ser->irq >= NR_IRQS)
+       if (ser->irq < 0 || ser->irq >= nr_irqs)
                ret = -EINVAL;
        if (ser->baud_base < 9600)
                ret = -EINVAL;
index 9d08f27208a187db0823fee6dcabf22ba3ac0668..b7180046f8dba082f02767e07775fae72aafc53d 100644 (file)
@@ -572,7 +572,7 @@ static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser)
        int ret = 0;
        if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA)
                ret = -EINVAL;
-       if (ser->irq < 0 || ser->irq >= NR_IRQS)
+       if (ser->irq < 0 || ser->irq >= nr_irqs)
                ret = -EINVAL;
        if (ser->baud_base < 9600)
                ret = -EINVAL;
index a6c4d744495e3b694894c35453bbac4a0baff512..bde4b4b0b80f08efe1f2c5db4da2fb7e0e61b9b5 100644 (file)
@@ -623,7 +623,7 @@ static int cpm_uart_verify_port(struct uart_port *port,
 
        if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM)
                ret = -EINVAL;
-       if (ser->irq < 0 || ser->irq >= NR_IRQS)
+       if (ser->irq < 0 || ser->irq >= nr_irqs)
                ret = -EINVAL;
        if (ser->baud_base < 9600)
                ret = -EINVAL;
index 23d0305110195353e8d74146fe477d1efb365608..611c97a15654d546a4941fe6e1b1008cef3c237f 100644 (file)
@@ -922,7 +922,7 @@ static void m32r_sio_config_port(struct uart_port *port, int flags)
 static int
 m32r_sio_verify_port(struct uart_port *port, struct serial_struct *ser)
 {
-       if (ser->irq >= NR_IRQS || ser->irq < 0 ||
+       if (ser->irq >= nr_irqs || ser->irq < 0 ||
            ser->baud_base < 9600 || ser->type < PORT_UNKNOWN ||
            ser->type >= ARRAY_SIZE(uart_config))
                return -EINVAL;
@@ -1162,7 +1162,7 @@ static int __init m32r_sio_init(void)
 
        printk(KERN_INFO "Serial: M32R SIO driver\n");
 
-       for (i = 0; i < NR_IRQS; i++)
+       for (i = 0; i < nr_irqs; i++)
                spin_lock_init(&irq_lists[i].lock);
 
        ret = uart_register_driver(&m32r_sio_reg);
index 6bdf3362e3b1e5f743ae8bad1f0bc8c9f682bf08..874786a11fe9977b98d4de8c540669111170e7ee 100644 (file)
@@ -741,7 +741,7 @@ static int uart_set_info(struct uart_state *state,
        if (port->ops->verify_port)
                retval = port->ops->verify_port(port, &new_serial);
 
-       if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) ||
+       if ((new_serial.irq >= nr_irqs) || (new_serial.irq < 0) ||
            (new_serial.baud_base < 9600))
                retval = -EINVAL;
 
index cb49a5ac022f880d38008c65ae4b844880c92fc3..61dc8b3daa26ce2c5159febbc05d71f89746ce54 100644 (file)
@@ -460,7 +460,7 @@ static int lh7a40xuart_verify_port (struct uart_port* port,
 
        if (ser->type != PORT_UNKNOWN && ser->type != PORT_LH7A40X)
                ret = -EINVAL;
-       if (ser->irq < 0 || ser->irq >= NR_IRQS)
+       if (ser->irq < 0 || ser->irq >= nr_irqs)
                ret = -EINVAL;
        if (ser->baud_base < 9600) /* *** FIXME: is this true? */
                ret = -EINVAL;
index 3b9d2d83b59008df447dfcff84bb1fc33e5f4425..f0658d2c45b20e2aa462f3d4b3db29e27fc0773f 100644 (file)
@@ -1149,7 +1149,7 @@ static int sci_verify_port(struct uart_port *port, struct serial_struct *ser)
 {
        struct sci_port *s = &sci_ports[port->line];
 
-       if (ser->irq != s->irqs[SCIx_TXI_IRQ] || ser->irq > NR_IRQS)
+       if (ser->irq != s->irqs[SCIx_TXI_IRQ] || ser->irq > nr_irqs)
                return -EINVAL;
        if (ser->baud_base < 2400)
                /* No paper tape reader for Mitch.. */
index 539c933b335f306b2dc92182785ab09cf271cec6..315a9333ca3cd1b7723197c74d0ebec1fe6fcdf3 100644 (file)
@@ -1066,7 +1066,7 @@ static int qe_uart_verify_port(struct uart_port *port,
        if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM)
                return -EINVAL;
 
-       if (ser->irq < 0 || ser->irq >= NR_IRQS)
+       if (ser->irq < 0 || ser->irq >= nr_irqs)
                return -EINVAL;
 
        if (ser->baud_base < 9600)
index 2a79decd7dfcc01120de769f59e1aa586c9e0912..e1654f59eb709f997300d2dee136002856009f2d 100644 (file)
@@ -43,4 +43,6 @@ source "drivers/staging/echo/Kconfig"
 
 source "drivers/staging/at76_usb/Kconfig"
 
+source "drivers/staging/poch/Kconfig"
+
 endif # STAGING
index 325bca4f71c06b8467ec2813555f2e17d9bb26d6..71c4d53760b842815514e6b82a9b0c0b244d509b 100644 (file)
@@ -13,3 +13,4 @@ obj-$(CONFIG_W35UND)          += winbond/
 obj-$(CONFIG_PRISM2_USB)       += wlan-ng/
 obj-$(CONFIG_ECHO)             += echo/
 obj-$(CONFIG_USB_ATMEL)                += at76_usb/
+obj-$(CONFIG_POCH)             += poch/
index 52df0c665183cd24e8ad7e14ce1ec83682aa1ae1..174e2bec922323775f9fefa99927bdc98bd71e1d 100644 (file)
@@ -2319,9 +2319,11 @@ static int at76_iw_handler_get_scan(struct net_device *netdev,
        if (!iwe)
                return -ENOMEM;
 
-       if (priv->scan_state != SCAN_COMPLETED)
+       if (priv->scan_state != SCAN_COMPLETED) {
                /* scan not yet finished */
+               kfree(iwe);
                return -EAGAIN;
+       }
 
        spin_lock_irqsave(&priv->bss_list_spinlock, flags);
 
index b32f4bf993970f4d58e1951640a63500b3715162..cecdcf3fd755ab640d602ce6aebde0e1273b2c43 100644 (file)
 #if !defined(_BIT_OPERATIONS_H_)
 #define _BIT_OPERATIONS_H_
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #if defined(__i386__)  ||  defined(__x86_64__)
 /*! \brief Find the bit position of the highest set bit in a word
     \param bits The word to be searched
     \return The bit number of the highest set bit, or -1 if the word is zero. */
 static __inline__ int top_bit(unsigned int bits)
 {
-    int res;
-
-    __asm__ (" xorl %[res],%[res];\n"
-             " decl %[res];\n"
-             " bsrl %[bits],%[res]\n"
-             : [res] "=&r" (res)
-             : [bits] "rm" (bits));
-    return res;
+       int res;
+
+       __asm__(" xorl %[res],%[res];\n"
+               " decl %[res];\n"
+               " bsrl %[bits],%[res]\n"
+               :[res] "=&r" (res)
+               :[bits] "rm"(bits)
+       );
+       return res;
 }
-/*- End of function --------------------------------------------------------*/
 
 /*! \brief Find the bit position of the lowest set bit in a word
     \param bits The word to be searched
     \return The bit number of the lowest set bit, or -1 if the word is zero. */
 static __inline__ int bottom_bit(unsigned int bits)
 {
-    int res;
-
-    __asm__ (" xorl %[res],%[res];\n"
-             " decl %[res];\n"
-             " bsfl %[bits],%[res]\n"
-             : [res] "=&r" (res)
-             : [bits] "rm" (bits));
-    return res;
+       int res;
+
+       __asm__(" xorl %[res],%[res];\n"
+               " decl %[res];\n"
+               " bsfl %[bits],%[res]\n"
+               :[res] "=&r" (res)
+               :[bits] "rm"(bits)
+       );
+       return res;
 }
-/*- End of function --------------------------------------------------------*/
 #else
 static __inline__ int top_bit(unsigned int bits)
 {
-    int i;
-
-    if (bits == 0)
-        return -1;
-    i = 0;
-    if (bits & 0xFFFF0000)
-    {
-        bits &= 0xFFFF0000;
-        i += 16;
-    }
-    if (bits & 0xFF00FF00)
-    {
-        bits &= 0xFF00FF00;
-        i += 8;
-    }
-    if (bits & 0xF0F0F0F0)
-    {
-        bits &= 0xF0F0F0F0;
-        i += 4;
-    }
-    if (bits & 0xCCCCCCCC)
-    {
-        bits &= 0xCCCCCCCC;
-        i += 2;
-    }
-    if (bits & 0xAAAAAAAA)
-    {
-        bits &= 0xAAAAAAAA;
-        i += 1;
-    }
-    return i;
+       int i;
+
+       if (bits == 0)
+               return -1;
+       i = 0;
+       if (bits & 0xFFFF0000) {
+               bits &= 0xFFFF0000;
+               i += 16;
+       }
+       if (bits & 0xFF00FF00) {
+               bits &= 0xFF00FF00;
+               i += 8;
+       }
+       if (bits & 0xF0F0F0F0) {
+               bits &= 0xF0F0F0F0;
+               i += 4;
+       }
+       if (bits & 0xCCCCCCCC) {
+               bits &= 0xCCCCCCCC;
+               i += 2;
+       }
+       if (bits & 0xAAAAAAAA) {
+               bits &= 0xAAAAAAAA;
+               i += 1;
+       }
+       return i;
 }
-/*- End of function --------------------------------------------------------*/
 
 static __inline__ int bottom_bit(unsigned int bits)
 {
-    int i;
-
-    if (bits == 0)
-        return -1;
-    i = 32;
-    if (bits & 0x0000FFFF)
-    {
-        bits &= 0x0000FFFF;
-        i -= 16;
-    }
-    if (bits & 0x00FF00FF)
-    {
-        bits &= 0x00FF00FF;
-        i -= 8;
-    }
-    if (bits & 0x0F0F0F0F)
-    {
-        bits &= 0x0F0F0F0F;
-        i -= 4;
-    }
-    if (bits & 0x33333333)
-    {
-        bits &= 0x33333333;
-        i -= 2;
-    }
-    if (bits & 0x55555555)
-    {
-        bits &= 0x55555555;
-        i -= 1;
-    }
-    return i;
+       int i;
+
+       if (bits == 0)
+               return -1;
+       i = 32;
+       if (bits & 0x0000FFFF) {
+               bits &= 0x0000FFFF;
+               i -= 16;
+       }
+       if (bits & 0x00FF00FF) {
+               bits &= 0x00FF00FF;
+               i -= 8;
+       }
+       if (bits & 0x0F0F0F0F) {
+               bits &= 0x0F0F0F0F;
+               i -= 4;
+       }
+       if (bits & 0x33333333) {
+               bits &= 0x33333333;
+               i -= 2;
+       }
+       if (bits & 0x55555555) {
+               bits &= 0x55555555;
+               i -= 1;
+       }
+       return i;
 }
-/*- End of function --------------------------------------------------------*/
 #endif
 
 /*! \brief Bit reverse a byte.
@@ -146,16 +130,16 @@ static __inline__ int bottom_bit(unsigned int bits)
 static __inline__ uint8_t bit_reverse8(uint8_t x)
 {
 #if defined(__i386__)  ||  defined(__x86_64__)
-    /* If multiply is fast */
-    return ((x*0x0802U & 0x22110U) | (x*0x8020U & 0x88440U))*0x10101U >> 16;
+       /* If multiply is fast */
+       return ((x * 0x0802U & 0x22110U) | (x * 0x8020U & 0x88440U)) *
+           0x10101U >> 16;
 #else
-    /* If multiply is slow, but we have a barrel shifter */
-    x = (x >> 4) | (x << 4);
-    x = ((x & 0xCC) >> 2) | ((x & 0x33) << 2);
-    return ((x & 0xAA) >> 1) | ((x & 0x55) << 1);
+       /* If multiply is slow, but we have a barrel shifter */
+       x = (x >> 4) | (x << 4);
+       x = ((x & 0xCC) >> 2) | ((x & 0x33) << 2);
+       return ((x & 0xAA) >> 1) | ((x & 0x55) << 1);
 #endif
 }
-/*- End of function --------------------------------------------------------*/
 
 /*! \brief Bit reverse a 16 bit word.
     \param data The word to be reversed.
@@ -193,9 +177,8 @@ uint16_t make_mask16(uint16_t x);
     \return The word with the single set bit. */
 static __inline__ uint32_t least_significant_one32(uint32_t x)
 {
-    return (x & (-(int32_t) x));
+       return (x & (-(int32_t) x));
 }
-/*- End of function --------------------------------------------------------*/
 
 /*! \brief Find the most significant one in a word, and return a word
            with just that bit set.
@@ -204,50 +187,42 @@ static __inline__ uint32_t least_significant_one32(uint32_t x)
 static __inline__ uint32_t most_significant_one32(uint32_t x)
 {
 #if defined(__i386__)  ||  defined(__x86_64__)
-    return 1 << top_bit(x);
+       return 1 << top_bit(x);
 #else
-    x = make_mask32(x);
-    return (x ^ (x >> 1));
+       x = make_mask32(x);
+       return (x ^ (x >> 1));
 #endif
 }
-/*- End of function --------------------------------------------------------*/
 
 /*! \brief Find the parity of a byte.
     \param x The byte to be checked.
     \return 1 for odd, or 0 for even. */
 static __inline__ int parity8(uint8_t x)
 {
-    x = (x ^ (x >> 4)) & 0x0F;
-    return (0x6996 >> x) & 1;
+       x = (x ^ (x >> 4)) & 0x0F;
+       return (0x6996 >> x) & 1;
 }
-/*- End of function --------------------------------------------------------*/
 
 /*! \brief Find the parity of a 16 bit word.
     \param x The word to be checked.
     \return 1 for odd, or 0 for even. */
 static __inline__ int parity16(uint16_t x)
 {
-    x ^= (x >> 8);
-    x = (x ^ (x >> 4)) & 0x0F;
-    return (0x6996 >> x) & 1;
+       x ^= (x >> 8);
+       x = (x ^ (x >> 4)) & 0x0F;
+       return (0x6996 >> x) & 1;
 }
-/*- End of function --------------------------------------------------------*/
 
 /*! \brief Find the parity of a 32 bit word.
     \param x The word to be checked.
     \return 1 for odd, or 0 for even. */
 static __inline__ int parity32(uint32_t x)
 {
-    x ^= (x >> 16);
-    x ^= (x >> 8);
-    x = (x ^ (x >> 4)) & 0x0F;
-    return (0x6996 >> x) & 1;
+       x ^= (x >> 16);
+       x ^= (x >> 8);
+       x = (x ^ (x >> 4)) & 0x0F;
+       return (0x6996 >> x) & 1;
 }
-/*- End of function --------------------------------------------------------*/
-
-#ifdef __cplusplus
-}
-#endif
 
 #endif
 /*- End of file ------------------------------------------------------------*/
index 4a281b14fc5840031cc7c8f936bd7acab88b021d..b8f2c5e9dee5e575e6e3a5053f9f186c92a4cb19 100644 (file)
@@ -74,7 +74,6 @@
 
    Steve also has some nice notes on echo cancellers in echo.h
 
-
    References:
 
    [1] Ochiai, Areseki, and Ogihara, "Echo Canceller with Two Echo
    Mark, Pawel, and Pavel.
 */
 
-#include <linux/kernel.h>       /* We're doing kernel work */
+#include <linux/kernel.h>      /* We're doing kernel work */
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
-#define malloc(a) kmalloc((a), GFP_KERNEL)
-#define free(a) kfree(a)
 
 #include "bit_operations.h"
 #include "echo.h"
 
 #define MIN_TX_POWER_FOR_ADAPTION   64
 #define MIN_RX_POWER_FOR_ADAPTION   64
-#define DTD_HANGOVER               600     /* 600 samples, or 75ms     */
-#define DC_LOG2BETA                  3     /* log2() of DC filter Beta */
+#define DTD_HANGOVER               600 /* 600 samples, or 75ms     */
+#define DC_LOG2BETA                  3 /* log2() of DC filter Beta */
 
 /*-----------------------------------------------------------------------*\
                                FUNCTIONS
 
 /* adapting coeffs using the traditional stochastic descent (N)LMS algorithm */
 
-
-#ifdef __BLACKFIN_ASM__
-static void __inline__ lms_adapt_bg(echo_can_state_t *ec, int clean, int shift)
+#ifdef __bfin__
+static void __inline__ lms_adapt_bg(struct oslec_state *ec, int clean,
+                                   int shift)
 {
-    int i, j;
-    int offset1;
-    int offset2;
-    int factor;
-    int exp;
-    int16_t *phist;
-    int n;
-
-    if (shift > 0)
-       factor = clean << shift;
-    else
-       factor = clean >> -shift;
-
-    /* Update the FIR taps */
-
-    offset2 = ec->curr_pos;
-    offset1 = ec->taps - offset2;
-    phist = &ec->fir_state_bg.history[offset2];
-
-    /* st: and en: help us locate the assembler in echo.s */
-
-    //asm("st:");
-    n = ec->taps;
-    for (i = 0, j = offset2;  i < n;  i++, j++)
-    {
-       exp = *phist++ * factor;
-       ec->fir_taps16[1][i] += (int16_t) ((exp+(1<<14)) >> 15);
-    }
-    //asm("en:");
-
-    /* Note the asm for the inner loop above generated by Blackfin gcc
-       4.1.1 is pretty good (note even parallel instructions used):
-
-       R0 = W [P0++] (X);
-       R0 *= R2;
-       R0 = R0 + R3 (NS) ||
-       R1 = W [P1] (X) ||
-       nop;
-       R0 >>>= 15;
-       R0 = R0 + R1;
-       W [P1++] = R0;
-
-       A block based update algorithm would be much faster but the
-       above can't be improved on much.  Every instruction saved in
-       the loop above is 2 MIPs/ch!  The for loop above is where the
-       Blackfin spends most of it's time - about 17 MIPs/ch measured
-       with speedtest.c with 256 taps (32ms).  Write-back and
-       Write-through cache gave about the same performance.
-    */
+       int i, j;
+       int offset1;
+       int offset2;
+       int factor;
+       int exp;
+       int16_t *phist;
+       int n;
+
+       if (shift > 0)
+               factor = clean << shift;
+       else
+               factor = clean >> -shift;
+
+       /* Update the FIR taps */
+
+       offset2 = ec->curr_pos;
+       offset1 = ec->taps - offset2;
+       phist = &ec->fir_state_bg.history[offset2];
+
+       /* st: and en: help us locate the assembler in echo.s */
+
+       //asm("st:");
+       n = ec->taps;
+       for (i = 0, j = offset2; i < n; i++, j++) {
+               exp = *phist++ * factor;
+               ec->fir_taps16[1][i] += (int16_t) ((exp + (1 << 14)) >> 15);
+       }
+       //asm("en:");
+
+       /* Note the asm for the inner loop above generated by Blackfin gcc
+          4.1.1 is pretty good (note even parallel instructions used):
+
+          R0 = W [P0++] (X);
+          R0 *= R2;
+          R0 = R0 + R3 (NS) ||
+          R1 = W [P1] (X) ||
+          nop;
+          R0 >>>= 15;
+          R0 = R0 + R1;
+          W [P1++] = R0;
+
+          A block based update algorithm would be much faster but the
+          above can't be improved on much.  Every instruction saved in
+          the loop above is 2 MIPs/ch!  The for loop above is where the
+          Blackfin spends most of it's time - about 17 MIPs/ch measured
+          with speedtest.c with 256 taps (32ms).  Write-back and
+          Write-through cache gave about the same performance.
+        */
 }
 
 /*
@@ -200,392 +196,393 @@ static void __inline__ lms_adapt_bg(echo_can_state_t *ec, int clean, int shift)
 */
 
 #else
-static __inline__ void lms_adapt_bg(echo_can_state_t *ec, int clean, int shift)
+static __inline__ void lms_adapt_bg(struct oslec_state *ec, int clean,
+                                   int shift)
 {
-    int i;
-
-    int offset1;
-    int offset2;
-    int factor;
-    int exp;
-
-    if (shift > 0)
-       factor = clean << shift;
-    else
-       factor = clean >> -shift;
-
-    /* Update the FIR taps */
-
-    offset2 = ec->curr_pos;
-    offset1 = ec->taps - offset2;
-
-    for (i = ec->taps - 1;  i >= offset1;  i--)
-    {
-       exp = (ec->fir_state_bg.history[i - offset1]*factor);
-       ec->fir_taps16[1][i] += (int16_t) ((exp+(1<<14)) >> 15);
-    }
-    for (  ;  i >= 0;  i--)
-    {
-       exp = (ec->fir_state_bg.history[i + offset2]*factor);
-       ec->fir_taps16[1][i] += (int16_t) ((exp+(1<<14)) >> 15);
-    }
+       int i;
+
+       int offset1;
+       int offset2;
+       int factor;
+       int exp;
+
+       if (shift > 0)
+               factor = clean << shift;
+       else
+               factor = clean >> -shift;
+
+       /* Update the FIR taps */
+
+       offset2 = ec->curr_pos;
+       offset1 = ec->taps - offset2;
+
+       for (i = ec->taps - 1; i >= offset1; i--) {
+               exp = (ec->fir_state_bg.history[i - offset1] * factor);
+               ec->fir_taps16[1][i] += (int16_t) ((exp + (1 << 14)) >> 15);
+       }
+       for (; i >= 0; i--) {
+               exp = (ec->fir_state_bg.history[i + offset2] * factor);
+               ec->fir_taps16[1][i] += (int16_t) ((exp + (1 << 14)) >> 15);
+       }
 }
 #endif
 
-/*- End of function --------------------------------------------------------*/
-
-echo_can_state_t *echo_can_create(int len, int adaption_mode)
+struct oslec_state *oslec_create(int len, int adaption_mode)
 {
-    echo_can_state_t *ec;
-    int i;
-    int j;
-
-    ec = kmalloc(sizeof(*ec), GFP_KERNEL);
-    if (ec == NULL)
-        return  NULL;
-    memset(ec, 0, sizeof(*ec));
-
-    ec->taps = len;
-    ec->log2taps = top_bit(len);
-    ec->curr_pos = ec->taps - 1;
-
-    for (i = 0;  i < 2;  i++)
-    {
-        if ((ec->fir_taps16[i] = (int16_t *) malloc((ec->taps)*sizeof(int16_t))) == NULL)
-        {
-            for (j = 0;  j < i;  j++)
-                kfree(ec->fir_taps16[j]);
-            kfree(ec);
-            return  NULL;
-        }
-        memset(ec->fir_taps16[i], 0, (ec->taps)*sizeof(int16_t));
-    }
-
-    fir16_create(&ec->fir_state,
-                 ec->fir_taps16[0],
-                 ec->taps);
-    fir16_create(&ec->fir_state_bg,
-                 ec->fir_taps16[1],
-                 ec->taps);
-
-    for(i=0; i<5; i++) {
-      ec->xvtx[i] = ec->yvtx[i] = ec->xvrx[i] = ec->yvrx[i] = 0;
-    }
-
-    ec->cng_level = 1000;
-    echo_can_adaption_mode(ec, adaption_mode);
-
-    ec->snapshot = (int16_t*)malloc(ec->taps*sizeof(int16_t));
-    memset(ec->snapshot, 0, sizeof(int16_t)*ec->taps);
-
-    ec->cond_met = 0;
-    ec->Pstates = 0;
-    ec->Ltxacc = ec->Lrxacc = ec->Lcleanacc = ec->Lclean_bgacc = 0;
-    ec->Ltx = ec->Lrx = ec->Lclean = ec->Lclean_bg = 0;
-    ec->tx_1 = ec->tx_2 = ec->rx_1 = ec->rx_2 = 0;
-    ec->Lbgn = ec->Lbgn_acc = 0;
-    ec->Lbgn_upper = 200;
-    ec->Lbgn_upper_acc = ec->Lbgn_upper << 13;
-
-    return  ec;
+       struct oslec_state *ec;
+       int i;
+
+       ec = kzalloc(sizeof(*ec), GFP_KERNEL);
+       if (!ec)
+               return NULL;
+
+       ec->taps = len;
+       ec->log2taps = top_bit(len);
+       ec->curr_pos = ec->taps - 1;
+
+       for (i = 0; i < 2; i++) {
+               ec->fir_taps16[i] =
+                   kcalloc(ec->taps, sizeof(int16_t), GFP_KERNEL);
+               if (!ec->fir_taps16[i])
+                       goto error_oom;
+       }
+
+       fir16_create(&ec->fir_state, ec->fir_taps16[0], ec->taps);
+       fir16_create(&ec->fir_state_bg, ec->fir_taps16[1], ec->taps);
+
+       for (i = 0; i < 5; i++) {
+               ec->xvtx[i] = ec->yvtx[i] = ec->xvrx[i] = ec->yvrx[i] = 0;
+       }
+
+       ec->cng_level = 1000;
+       oslec_adaption_mode(ec, adaption_mode);
+
+       ec->snapshot = kcalloc(ec->taps, sizeof(int16_t), GFP_KERNEL);
+       if (!ec->snapshot)
+               goto error_oom;
+
+       ec->cond_met = 0;
+       ec->Pstates = 0;
+       ec->Ltxacc = ec->Lrxacc = ec->Lcleanacc = ec->Lclean_bgacc = 0;
+       ec->Ltx = ec->Lrx = ec->Lclean = ec->Lclean_bg = 0;
+       ec->tx_1 = ec->tx_2 = ec->rx_1 = ec->rx_2 = 0;
+       ec->Lbgn = ec->Lbgn_acc = 0;
+       ec->Lbgn_upper = 200;
+       ec->Lbgn_upper_acc = ec->Lbgn_upper << 13;
+
+       return ec;
+
+      error_oom:
+       for (i = 0; i < 2; i++)
+               kfree(ec->fir_taps16[i]);
+
+       kfree(ec);
+       return NULL;
 }
-/*- End of function --------------------------------------------------------*/
 
-void echo_can_free(echo_can_state_t *ec)
+EXPORT_SYMBOL_GPL(oslec_create);
+
+void oslec_free(struct oslec_state *ec)
 {
        int i;
 
        fir16_free(&ec->fir_state);
        fir16_free(&ec->fir_state_bg);
-       for (i = 0;  i < 2;  i++)
+       for (i = 0; i < 2; i++)
                kfree(ec->fir_taps16[i]);
        kfree(ec->snapshot);
        kfree(ec);
 }
-/*- End of function --------------------------------------------------------*/
 
-void echo_can_adaption_mode(echo_can_state_t *ec, int adaption_mode)
+EXPORT_SYMBOL_GPL(oslec_free);
+
+void oslec_adaption_mode(struct oslec_state *ec, int adaption_mode)
 {
-    ec->adaption_mode = adaption_mode;
+       ec->adaption_mode = adaption_mode;
 }
-/*- End of function --------------------------------------------------------*/
 
-void echo_can_flush(echo_can_state_t *ec)
+EXPORT_SYMBOL_GPL(oslec_adaption_mode);
+
+void oslec_flush(struct oslec_state *ec)
 {
-    int i;
+       int i;
 
-    ec->Ltxacc = ec->Lrxacc = ec->Lcleanacc = ec->Lclean_bgacc = 0;
-    ec->Ltx = ec->Lrx = ec->Lclean = ec->Lclean_bg = 0;
-    ec->tx_1 = ec->tx_2 = ec->rx_1 = ec->rx_2 = 0;
+       ec->Ltxacc = ec->Lrxacc = ec->Lcleanacc = ec->Lclean_bgacc = 0;
+       ec->Ltx = ec->Lrx = ec->Lclean = ec->Lclean_bg = 0;
+       ec->tx_1 = ec->tx_2 = ec->rx_1 = ec->rx_2 = 0;
 
-    ec->Lbgn = ec->Lbgn_acc = 0;
-    ec->Lbgn_upper = 200;
-    ec->Lbgn_upper_acc = ec->Lbgn_upper << 13;
+       ec->Lbgn = ec->Lbgn_acc = 0;
+       ec->Lbgn_upper = 200;
+       ec->Lbgn_upper_acc = ec->Lbgn_upper << 13;
 
-    ec->nonupdate_dwell = 0;
+       ec->nonupdate_dwell = 0;
 
-    fir16_flush(&ec->fir_state);
-    fir16_flush(&ec->fir_state_bg);
-    ec->fir_state.curr_pos = ec->taps - 1;
-    ec->fir_state_bg.curr_pos = ec->taps - 1;
-    for (i = 0;  i < 2;  i++)
-        memset(ec->fir_taps16[i], 0, ec->taps*sizeof(int16_t));
+       fir16_flush(&ec->fir_state);
+       fir16_flush(&ec->fir_state_bg);
+       ec->fir_state.curr_pos = ec->taps - 1;
+       ec->fir_state_bg.curr_pos = ec->taps - 1;
+       for (i = 0; i < 2; i++)
+               memset(ec->fir_taps16[i], 0, ec->taps * sizeof(int16_t));
 
-    ec->curr_pos = ec->taps - 1;
-    ec->Pstates = 0;
+       ec->curr_pos = ec->taps - 1;
+       ec->Pstates = 0;
 }
-/*- End of function --------------------------------------------------------*/
 
-void echo_can_snapshot(echo_can_state_t *ec) {
-    memcpy(ec->snapshot, ec->fir_taps16[0], ec->taps*sizeof(int16_t));
+EXPORT_SYMBOL_GPL(oslec_flush);
+
+void oslec_snapshot(struct oslec_state *ec)
+{
+       memcpy(ec->snapshot, ec->fir_taps16[0], ec->taps * sizeof(int16_t));
 }
-/*- End of function --------------------------------------------------------*/
+
+EXPORT_SYMBOL_GPL(oslec_snapshot);
 
 /* Dual Path Echo Canceller ------------------------------------------------*/
 
-int16_t echo_can_update(echo_can_state_t *ec, int16_t tx, int16_t rx)
+int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx)
 {
-    int32_t echo_value;
-    int clean_bg;
-    int tmp, tmp1;
-
-    /* Input scaling was found be required to prevent problems when tx
-       starts clipping.  Another possible way to handle this would be the
-       filter coefficent scaling. */
-
-    ec->tx = tx; ec->rx = rx;
-    tx >>=1;
-    rx >>=1;
-
-    /*
-       Filter DC, 3dB point is 160Hz (I think), note 32 bit precision required
-       otherwise values do not track down to 0. Zero at DC, Pole at (1-Beta)
-       only real axis.  Some chip sets (like Si labs) don't need
-       this, but something like a $10 X100P card does.  Any DC really slows
-       down convergence.
-
-       Note: removes some low frequency from the signal, this reduces
-       the speech quality when listening to samples through headphones
-       but may not be obvious through a telephone handset.
-
-       Note that the 3dB frequency in radians is approx Beta, e.g. for
-       Beta = 2^(-3) = 0.125, 3dB freq is 0.125 rads = 159Hz.
-    */
-
-    if (ec->adaption_mode & ECHO_CAN_USE_RX_HPF) {
-      tmp = rx << 15;
+       int32_t echo_value;
+       int clean_bg;
+       int tmp, tmp1;
+
+       /* Input scaling was found be required to prevent problems when tx
+          starts clipping.  Another possible way to handle this would be the
+          filter coefficent scaling. */
+
+       ec->tx = tx;
+       ec->rx = rx;
+       tx >>= 1;
+       rx >>= 1;
+
+       /*
+          Filter DC, 3dB point is 160Hz (I think), note 32 bit precision required
+          otherwise values do not track down to 0. Zero at DC, Pole at (1-Beta)
+          only real axis.  Some chip sets (like Si labs) don't need
+          this, but something like a $10 X100P card does.  Any DC really slows
+          down convergence.
+
+          Note: removes some low frequency from the signal, this reduces
+          the speech quality when listening to samples through headphones
+          but may not be obvious through a telephone handset.
+
+          Note that the 3dB frequency in radians is approx Beta, e.g. for
+          Beta = 2^(-3) = 0.125, 3dB freq is 0.125 rads = 159Hz.
+        */
+
+       if (ec->adaption_mode & ECHO_CAN_USE_RX_HPF) {
+               tmp = rx << 15;
 #if 1
-        /* Make sure the gain of the HPF is 1.0. This can still saturate a little under
-           impulse conditions, and it might roll to 32768 and need clipping on sustained peak
-           level signals. However, the scale of such clipping is small, and the error due to
-           any saturation should not markedly affect the downstream processing. */
-        tmp -= (tmp >> 4);
+               /* Make sure the gain of the HPF is 1.0. This can still saturate a little under
+                  impulse conditions, and it might roll to 32768 and need clipping on sustained peak
+                  level signals. However, the scale of such clipping is small, and the error due to
+                  any saturation should not markedly affect the downstream processing. */
+               tmp -= (tmp >> 4);
 #endif
-      ec->rx_1 += -(ec->rx_1>>DC_LOG2BETA) + tmp - ec->rx_2;
+               ec->rx_1 += -(ec->rx_1 >> DC_LOG2BETA) + tmp - ec->rx_2;
+
+               /* hard limit filter to prevent clipping.  Note that at this stage
+                  rx should be limited to +/- 16383 due to right shift above */
+               tmp1 = ec->rx_1 >> 15;
+               if (tmp1 > 16383)
+                       tmp1 = 16383;
+               if (tmp1 < -16383)
+                       tmp1 = -16383;
+               rx = tmp1;
+               ec->rx_2 = tmp;
+       }
 
-      /* hard limit filter to prevent clipping.  Note that at this stage
-        rx should be limited to +/- 16383 due to right shift above */
-      tmp1 = ec->rx_1 >> 15;
-      if (tmp1 > 16383) tmp1 = 16383;
-      if (tmp1 < -16383) tmp1 = -16383;
-      rx = tmp1;
-      ec->rx_2 = tmp;
-    }
+       /* Block average of power in the filter states.  Used for
+          adaption power calculation. */
 
-    /* Block average of power in the filter states.  Used for
-       adaption power calculation. */
+       {
+               int new, old;
+
+               /* efficient "out with the old and in with the new" algorithm so
+                  we don't have to recalculate over the whole block of
+                  samples. */
+               new = (int)tx *(int)tx;
+               old = (int)ec->fir_state.history[ec->fir_state.curr_pos] *
+                   (int)ec->fir_state.history[ec->fir_state.curr_pos];
+               ec->Pstates +=
+                   ((new - old) + (1 << ec->log2taps)) >> ec->log2taps;
+               if (ec->Pstates < 0)
+                       ec->Pstates = 0;
+       }
 
-    {
-       int new, old;
+       /* Calculate short term average levels using simple single pole IIRs */
 
-       /* efficient "out with the old and in with the new" algorithm so
-          we don't have to recalculate over the whole block of
-          samples. */
-       new = (int)tx * (int)tx;
-       old = (int)ec->fir_state.history[ec->fir_state.curr_pos] *
-              (int)ec->fir_state.history[ec->fir_state.curr_pos];
-       ec->Pstates += ((new - old) + (1<<ec->log2taps)) >> ec->log2taps;
-       if (ec->Pstates < 0) ec->Pstates = 0;
-    }
-
-    /* Calculate short term average levels using simple single pole IIRs */
-
-    ec->Ltxacc += abs(tx) - ec->Ltx;
-    ec->Ltx = (ec->Ltxacc + (1<<4)) >> 5;
-    ec->Lrxacc += abs(rx) - ec->Lrx;
-    ec->Lrx = (ec->Lrxacc + (1<<4)) >> 5;
-
-    /* Foreground filter ---------------------------------------------------*/
-
-    ec->fir_state.coeffs = ec->fir_taps16[0];
-    echo_value = fir16(&ec->fir_state, tx);
-    ec->clean = rx - echo_value;
-    ec->Lcleanacc += abs(ec->clean) - ec->Lclean;
-    ec->Lclean = (ec->Lcleanacc + (1<<4)) >> 5;
-
-    /* Background filter ---------------------------------------------------*/
-
-    echo_value = fir16(&ec->fir_state_bg, tx);
-    clean_bg = rx - echo_value;
-    ec->Lclean_bgacc += abs(clean_bg) - ec->Lclean_bg;
-    ec->Lclean_bg = (ec->Lclean_bgacc + (1<<4)) >> 5;
-
-    /* Background Filter adaption -----------------------------------------*/
-
-    /* Almost always adap bg filter, just simple DT and energy
-       detection to minimise adaption in cases of strong double talk.
-       However this is not critical for the dual path algorithm.
-    */
-    ec->factor = 0;
-    ec->shift = 0;
-    if ((ec->nonupdate_dwell == 0)) {
-       int   P, logP, shift;
-
-       /* Determine:
-
-          f = Beta * clean_bg_rx/P ------ (1)
-
-          where P is the total power in the filter states.
-
-          The Boffins have shown that if we obey (1) we converge
-          quickly and avoid instability.
-
-          The correct factor f must be in Q30, as this is the fixed
-          point format required by the lms_adapt_bg() function,
-          therefore the scaled version of (1) is:
-
-          (2^30) * f  = (2^30) * Beta * clean_bg_rx/P
-              factor  = (2^30) * Beta * clean_bg_rx/P         ----- (2)
-
-          We have chosen Beta = 0.25 by experiment, so:
-
-              factor  = (2^30) * (2^-2) * clean_bg_rx/P
-
-                                       (30 - 2 - log2(P))
-              factor  = clean_bg_rx 2                         ----- (3)
-
-          To avoid a divide we approximate log2(P) as top_bit(P),
-          which returns the position of the highest non-zero bit in
-          P.  This approximation introduces an error as large as a
-          factor of 2, but the algorithm seems to handle it OK.
-
-          Come to think of it a divide may not be a big deal on a
-          modern DSP, so its probably worth checking out the cycles
-          for a divide versus a top_bit() implementation.
-       */
-
-       P = MIN_TX_POWER_FOR_ADAPTION + ec->Pstates;
-       logP = top_bit(P) + ec->log2taps;
-       shift = 30 - 2 - logP;
-       ec->shift = shift;
-
-       lms_adapt_bg(ec, clean_bg, shift);
-    }
-
-    /* very simple DTD to make sure we dont try and adapt with strong
-       near end speech */
-
-    ec->adapt = 0;
-    if ((ec->Lrx > MIN_RX_POWER_FOR_ADAPTION) && (ec->Lrx > ec->Ltx))
-       ec->nonupdate_dwell = DTD_HANGOVER;
-    if (ec->nonupdate_dwell)
-       ec->nonupdate_dwell--;
+       ec->Ltxacc += abs(tx) - ec->Ltx;
+       ec->Ltx = (ec->Ltxacc + (1 << 4)) >> 5;
+       ec->Lrxacc += abs(rx) - ec->Lrx;
+       ec->Lrx = (ec->Lrxacc + (1 << 4)) >> 5;
 
-    /* Transfer logic ------------------------------------------------------*/
+       /* Foreground filter --------------------------------------------------- */
 
-    /* These conditions are from the dual path paper [1], I messed with
-       them a bit to improve performance. */
+       ec->fir_state.coeffs = ec->fir_taps16[0];
+       echo_value = fir16(&ec->fir_state, tx);
+       ec->clean = rx - echo_value;
+       ec->Lcleanacc += abs(ec->clean) - ec->Lclean;
+       ec->Lclean = (ec->Lcleanacc + (1 << 4)) >> 5;
 
-    if ((ec->adaption_mode & ECHO_CAN_USE_ADAPTION) &&
-       (ec->nonupdate_dwell == 0) &&
-       (8*ec->Lclean_bg < 7*ec->Lclean) /* (ec->Lclean_bg < 0.875*ec->Lclean) */ &&
-       (8*ec->Lclean_bg < ec->Ltx)      /* (ec->Lclean_bg < 0.125*ec->Ltx)    */ )
-    {
-       if (ec->cond_met == 6) {
-           /* BG filter has had better results for 6 consecutive samples */
-           ec->adapt = 1;
-           memcpy(ec->fir_taps16[0], ec->fir_taps16[1], ec->taps*sizeof(int16_t));
-       }
-       else
-           ec->cond_met++;
-    }
-    else
-       ec->cond_met = 0;
+       /* Background filter --------------------------------------------------- */
 
-    /* Non-Linear Processing ---------------------------------------------------*/
+       echo_value = fir16(&ec->fir_state_bg, tx);
+       clean_bg = rx - echo_value;
+       ec->Lclean_bgacc += abs(clean_bg) - ec->Lclean_bg;
+       ec->Lclean_bg = (ec->Lclean_bgacc + (1 << 4)) >> 5;
 
-    ec->clean_nlp = ec->clean;
-    if (ec->adaption_mode & ECHO_CAN_USE_NLP)
-    {
-        /* Non-linear processor - a fancy way to say "zap small signals, to avoid
-           residual echo due to (uLaw/ALaw) non-linearity in the channel.". */
+       /* Background Filter adaption ----------------------------------------- */
 
-      if ((16*ec->Lclean < ec->Ltx))
-      {
-       /* Our e/c has improved echo by at least 24 dB (each factor of 2 is 6dB,
-          so 2*2*2*2=16 is the same as 6+6+6+6=24dB) */
-        if (ec->adaption_mode & ECHO_CAN_USE_CNG)
-       {
-           ec->cng_level = ec->Lbgn;
-
-           /* Very elementary comfort noise generation.  Just random
-              numbers rolled off very vaguely Hoth-like.  DR: This
-              noise doesn't sound quite right to me - I suspect there
-              are some overlfow issues in the filtering as it's too
-              "crackly".  TODO: debug this, maybe just play noise at
-              high level or look at spectrum.
-           */
-
-           ec->cng_rndnum = 1664525U*ec->cng_rndnum + 1013904223U;
-           ec->cng_filter = ((ec->cng_rndnum & 0xFFFF) - 32768 + 5*ec->cng_filter) >> 3;
-           ec->clean_nlp = (ec->cng_filter*ec->cng_level*8) >> 14;
-
-        }
-        else if (ec->adaption_mode & ECHO_CAN_USE_CLIP)
-       {
-           /* This sounds much better than CNG */
-           if (ec->clean_nlp > ec->Lbgn)
-             ec->clean_nlp = ec->Lbgn;
-           if (ec->clean_nlp < -ec->Lbgn)
-             ec->clean_nlp = -ec->Lbgn;
+       /* Almost always adap bg filter, just simple DT and energy
+          detection to minimise adaption in cases of strong double talk.
+          However this is not critical for the dual path algorithm.
+        */
+       ec->factor = 0;
+       ec->shift = 0;
+       if ((ec->nonupdate_dwell == 0)) {
+               int P, logP, shift;
+
+               /* Determine:
+
+                  f = Beta * clean_bg_rx/P ------ (1)
+
+                  where P is the total power in the filter states.
+
+                  The Boffins have shown that if we obey (1) we converge
+                  quickly and avoid instability.
+
+                  The correct factor f must be in Q30, as this is the fixed
+                  point format required by the lms_adapt_bg() function,
+                  therefore the scaled version of (1) is:
+
+                  (2^30) * f  = (2^30) * Beta * clean_bg_rx/P
+                  factor  = (2^30) * Beta * clean_bg_rx/P         ----- (2)
+
+                  We have chosen Beta = 0.25 by experiment, so:
+
+                  factor  = (2^30) * (2^-2) * clean_bg_rx/P
+
+                  (30 - 2 - log2(P))
+                  factor  = clean_bg_rx 2                         ----- (3)
+
+                  To avoid a divide we approximate log2(P) as top_bit(P),
+                  which returns the position of the highest non-zero bit in
+                  P.  This approximation introduces an error as large as a
+                  factor of 2, but the algorithm seems to handle it OK.
+
+                  Come to think of it a divide may not be a big deal on a
+                  modern DSP, so its probably worth checking out the cycles
+                  for a divide versus a top_bit() implementation.
+                */
+
+               P = MIN_TX_POWER_FOR_ADAPTION + ec->Pstates;
+               logP = top_bit(P) + ec->log2taps;
+               shift = 30 - 2 - logP;
+               ec->shift = shift;
+
+               lms_adapt_bg(ec, clean_bg, shift);
        }
-       else
-        {
-         /* just mute the residual, doesn't sound very good, used mainly
-            in G168 tests */
-          ec->clean_nlp = 0;
-        }
-      }
-      else {
-         /* Background noise estimator.  I tried a few algorithms
-            here without much luck.  This very simple one seems to
-            work best, we just average the level using a slow (1 sec
-            time const) filter if the current level is less than a
-            (experimentally derived) constant.  This means we dont
-            include high level signals like near end speech.  When
-            combined with CNG or especially CLIP seems to work OK.
-         */
-         if (ec->Lclean < 40) {
-             ec->Lbgn_acc += abs(ec->clean) - ec->Lbgn;
-             ec->Lbgn = (ec->Lbgn_acc + (1<<11)) >> 12;
-         }
-       }
-    }
-
-    /* Roll around the taps buffer */
-    if (ec->curr_pos <= 0)
-        ec->curr_pos = ec->taps;
-    ec->curr_pos--;
-
-    if (ec->adaption_mode & ECHO_CAN_DISABLE)
-      ec->clean_nlp = rx;
-
-    /* Output scaled back up again to match input scaling */
-
-    return (int16_t) ec->clean_nlp << 1;
+
+       /* very simple DTD to make sure we dont try and adapt with strong
+          near end speech */
+
+       ec->adapt = 0;
+       if ((ec->Lrx > MIN_RX_POWER_FOR_ADAPTION) && (ec->Lrx > ec->Ltx))
+               ec->nonupdate_dwell = DTD_HANGOVER;
+       if (ec->nonupdate_dwell)
+               ec->nonupdate_dwell--;
+
+       /* Transfer logic ------------------------------------------------------ */
+
+       /* These conditions are from the dual path paper [1], I messed with
+          them a bit to improve performance. */
+
+       if ((ec->adaption_mode & ECHO_CAN_USE_ADAPTION) &&
+           (ec->nonupdate_dwell == 0) &&
+           (8 * ec->Lclean_bg <
+            7 * ec->Lclean) /* (ec->Lclean_bg < 0.875*ec->Lclean) */ &&
+           (8 * ec->Lclean_bg <
+            ec->Ltx) /* (ec->Lclean_bg < 0.125*ec->Ltx)    */ ) {
+               if (ec->cond_met == 6) {
+                       /* BG filter has had better results for 6 consecutive samples */
+                       ec->adapt = 1;
+                       memcpy(ec->fir_taps16[0], ec->fir_taps16[1],
+                              ec->taps * sizeof(int16_t));
+               } else
+                       ec->cond_met++;
+       } else
+               ec->cond_met = 0;
+
+       /* Non-Linear Processing --------------------------------------------------- */
+
+       ec->clean_nlp = ec->clean;
+       if (ec->adaption_mode & ECHO_CAN_USE_NLP) {
+               /* Non-linear processor - a fancy way to say "zap small signals, to avoid
+                  residual echo due to (uLaw/ALaw) non-linearity in the channel.". */
+
+               if ((16 * ec->Lclean < ec->Ltx)) {
+                       /* Our e/c has improved echo by at least 24 dB (each factor of 2 is 6dB,
+                          so 2*2*2*2=16 is the same as 6+6+6+6=24dB) */
+                       if (ec->adaption_mode & ECHO_CAN_USE_CNG) {
+                               ec->cng_level = ec->Lbgn;
+
+                               /* Very elementary comfort noise generation.  Just random
+                                  numbers rolled off very vaguely Hoth-like.  DR: This
+                                  noise doesn't sound quite right to me - I suspect there
+                                  are some overlfow issues in the filtering as it's too
+                                  "crackly".  TODO: debug this, maybe just play noise at
+                                  high level or look at spectrum.
+                                */
+
+                               ec->cng_rndnum =
+                                   1664525U * ec->cng_rndnum + 1013904223U;
+                               ec->cng_filter =
+                                   ((ec->cng_rndnum & 0xFFFF) - 32768 +
+                                    5 * ec->cng_filter) >> 3;
+                               ec->clean_nlp =
+                                   (ec->cng_filter * ec->cng_level * 8) >> 14;
+
+                       } else if (ec->adaption_mode & ECHO_CAN_USE_CLIP) {
+                               /* This sounds much better than CNG */
+                               if (ec->clean_nlp > ec->Lbgn)
+                                       ec->clean_nlp = ec->Lbgn;
+                               if (ec->clean_nlp < -ec->Lbgn)
+                                       ec->clean_nlp = -ec->Lbgn;
+                       } else {
+                               /* just mute the residual, doesn't sound very good, used mainly
+                                  in G168 tests */
+                               ec->clean_nlp = 0;
+                       }
+               } else {
+                       /* Background noise estimator.  I tried a few algorithms
+                          here without much luck.  This very simple one seems to
+                          work best, we just average the level using a slow (1 sec
+                          time const) filter if the current level is less than a
+                          (experimentally derived) constant.  This means we dont
+                          include high level signals like near end speech.  When
+                          combined with CNG or especially CLIP seems to work OK.
+                        */
+                       if (ec->Lclean < 40) {
+                               ec->Lbgn_acc += abs(ec->clean) - ec->Lbgn;
+                               ec->Lbgn = (ec->Lbgn_acc + (1 << 11)) >> 12;
+                       }
+               }
+       }
+
+       /* Roll around the taps buffer */
+       if (ec->curr_pos <= 0)
+               ec->curr_pos = ec->taps;
+       ec->curr_pos--;
+
+       if (ec->adaption_mode & ECHO_CAN_DISABLE)
+               ec->clean_nlp = rx;
+
+       /* Output scaled back up again to match input scaling */
+
+       return (int16_t) ec->clean_nlp << 1;
 }
 
-/*- End of function --------------------------------------------------------*/
+EXPORT_SYMBOL_GPL(oslec_update);
 
 /* This function is seperated from the echo canceller is it is usually called
    as part of the tx process.  See rx HP (DC blocking) filter above, it's
@@ -608,25 +605,35 @@ int16_t echo_can_update(echo_can_state_t *ec, int16_t tx, int16_t rx)
    precision, which noise shapes things, giving very clean DC removal.
 */
 
-int16_t echo_can_hpf_tx(echo_can_state_t *ec, int16_t tx) {
-    int tmp, tmp1;
+int16_t oslec_hpf_tx(struct oslec_state * ec, int16_t tx)
+{
+       int tmp, tmp1;
 
-    if (ec->adaption_mode & ECHO_CAN_USE_TX_HPF) {
-        tmp = tx << 15;
+       if (ec->adaption_mode & ECHO_CAN_USE_TX_HPF) {
+               tmp = tx << 15;
 #if 1
-        /* Make sure the gain of the HPF is 1.0. The first can still saturate a little under
-           impulse conditions, and it might roll to 32768 and need clipping on sustained peak
-           level signals. However, the scale of such clipping is small, and the error due to
-           any saturation should not markedly affect the downstream processing. */
-        tmp -= (tmp >> 4);
+               /* Make sure the gain of the HPF is 1.0. The first can still saturate a little under
+                  impulse conditions, and it might roll to 32768 and need clipping on sustained peak
+                  level signals. However, the scale of such clipping is small, and the error due to
+                  any saturation should not markedly affect the downstream processing. */
+               tmp -= (tmp >> 4);
 #endif
-        ec->tx_1 += -(ec->tx_1>>DC_LOG2BETA) + tmp - ec->tx_2;
-        tmp1 = ec->tx_1 >> 15;
-       if (tmp1 > 32767) tmp1 = 32767;
-       if (tmp1 < -32767) tmp1 = -32767;
-       tx = tmp1;
-        ec->tx_2 = tmp;
-    }
-
-    return tx;
+               ec->tx_1 += -(ec->tx_1 >> DC_LOG2BETA) + tmp - ec->tx_2;
+               tmp1 = ec->tx_1 >> 15;
+               if (tmp1 > 32767)
+                       tmp1 = 32767;
+               if (tmp1 < -32767)
+                       tmp1 = -32767;
+               tx = tmp1;
+               ec->tx_2 = tmp;
+       }
+
+       return tx;
 }
+
+EXPORT_SYMBOL_GPL(oslec_hpf_tx);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Rowe");
+MODULE_DESCRIPTION("Open Source Line Echo Canceller");
+MODULE_VERSION("0.3.0");
index 7a91b4390f3bbc9b91c6c46204f55db450c51bf9..9fb9543c4f13a2de76d37f2390f8b161f67dadc9 100644 (file)
@@ -118,23 +118,14 @@ a minor burden.
 */
 
 #include "fir.h"
-
-/* Mask bits for the adaption mode */
-#define ECHO_CAN_USE_ADAPTION  0x01
-#define ECHO_CAN_USE_NLP       0x02
-#define ECHO_CAN_USE_CNG       0x04
-#define ECHO_CAN_USE_CLIP      0x08
-#define ECHO_CAN_USE_TX_HPF    0x10
-#define ECHO_CAN_USE_RX_HPF    0x20
-#define ECHO_CAN_DISABLE       0x40
+#include "oslec.h"
 
 /*!
     G.168 echo canceller descriptor. This defines the working state for a line
     echo canceller.
 */
-typedef struct
-{
-       int16_t tx,rx;
+struct oslec_state {
+       int16_t tx, rx;
        int16_t clean;
        int16_t clean_nlp;
 
@@ -176,45 +167,6 @@ typedef struct
 
        /* snapshot sample of coeffs used for development */
        int16_t *snapshot;
-} echo_can_state_t;
-
-/*! Create a voice echo canceller context.
-    \param len The length of the canceller, in samples.
-    \return The new canceller context, or NULL if the canceller could not be created.
-*/
-echo_can_state_t *echo_can_create(int len, int adaption_mode);
-
-/*! Free a voice echo canceller context.
-    \param ec The echo canceller context.
-*/
-void echo_can_free(echo_can_state_t *ec);
-
-/*! Flush (reinitialise) a voice echo canceller context.
-    \param ec The echo canceller context.
-*/
-void echo_can_flush(echo_can_state_t *ec);
-
-/*! Set the adaption mode of a voice echo canceller context.
-    \param ec The echo canceller context.
-    \param adapt The mode.
-*/
-void echo_can_adaption_mode(echo_can_state_t *ec, int adaption_mode);
-
-void echo_can_snapshot(echo_can_state_t *ec);
-
-/*! Process a sample through a voice echo canceller.
-    \param ec The echo canceller context.
-    \param tx The transmitted audio sample.
-    \param rx The received audio sample.
-    \return The clean (echo cancelled) received sample.
-*/
-int16_t echo_can_update(echo_can_state_t *ec, int16_t tx, int16_t rx);
-
-/*! Process to high pass filter the tx signal.
-    \param ec The echo canceller context.
-    \param tx The transmitted auio sample.
-    \return The HP filtered transmit sample, send this to your D/A.
-*/
-int16_t echo_can_hpf_tx(echo_can_state_t *ec, int16_t tx);
+};
 
-#endif /* __ECHO_H */
+#endif /* __ECHO_H */
index e1bfc4994886a57051bf4ad4645f60e68604b316..5645cb1b2f90cb7dac0595852283534899dcf051 100644 (file)
@@ -72,8 +72,7 @@
     16 bit integer FIR descriptor. This defines the working state for a single
     instance of an FIR filter using 16 bit integer coefficients.
 */
-typedef struct
-{
+typedef struct {
        int taps;
        int curr_pos;
        const int16_t *coeffs;
@@ -85,8 +84,7 @@ typedef struct
     instance of an FIR filter using 32 bit integer coefficients, and filtering
     16 bit integer data.
 */
-typedef struct
-{
+typedef struct {
        int taps;
        int curr_pos;
        const int32_t *coeffs;
@@ -97,273 +95,201 @@ typedef struct
     Floating point FIR descriptor. This defines the working state for a single
     instance of an FIR filter using floating point coefficients and data.
 */
-typedef struct
-{
+typedef struct {
        int taps;
        int curr_pos;
        const float *coeffs;
        float *history;
 } fir_float_state_t;
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-static __inline__ const int16_t *fir16_create(fir16_state_t *fir,
-                                              const int16_t *coeffs,
-                                              int taps)
+static __inline__ const int16_t *fir16_create(fir16_state_t * fir,
+                                             const int16_t * coeffs, int taps)
 {
        fir->taps = taps;
        fir->curr_pos = taps - 1;
        fir->coeffs = coeffs;
-#if defined(USE_MMX)  ||  defined(USE_SSE2) || defined(__BLACKFIN_ASM__)
-       if ((fir->history = malloc(2*taps*sizeof(int16_t))))
-               memset(fir->history, 0, 2*taps*sizeof(int16_t));
+#if defined(USE_MMX)  ||  defined(USE_SSE2) || defined(__bfin__)
+       fir->history = kcalloc(2 * taps, sizeof(int16_t), GFP_KERNEL);
 #else
-       if ((fir->history = (int16_t *) malloc(taps*sizeof(int16_t))))
-               memset(fir->history, 0, taps*sizeof(int16_t));
+       fir->history = kcalloc(taps, sizeof(int16_t), GFP_KERNEL);
 #endif
        return fir->history;
 }
-/*- End of function --------------------------------------------------------*/
 
-static __inline__ void fir16_flush(fir16_state_t *fir)
+static __inline__ void fir16_flush(fir16_state_t * fir)
 {
-#if defined(USE_MMX)  ||  defined(USE_SSE2) || defined(__BLACKFIN_ASM__)
-    memset(fir->history, 0, 2*fir->taps*sizeof(int16_t));
+#if defined(USE_MMX)  ||  defined(USE_SSE2) || defined(__bfin__)
+       memset(fir->history, 0, 2 * fir->taps * sizeof(int16_t));
 #else
-    memset(fir->history, 0, fir->taps*sizeof(int16_t));
+       memset(fir->history, 0, fir->taps * sizeof(int16_t));
 #endif
 }
-/*- End of function --------------------------------------------------------*/
 
-static __inline__ void fir16_free(fir16_state_t *fir)
+static __inline__ void fir16_free(fir16_state_t * fir)
 {
-       free(fir->history);
+       kfree(fir->history);
 }
-/*- End of function --------------------------------------------------------*/
 
-#ifdef __BLACKFIN_ASM__
+#ifdef __bfin__
 static inline int32_t dot_asm(short *x, short *y, int len)
 {
-   int dot;
-
-   len--;
-
-   __asm__
-   (
-   "I0 = %1;\n\t"
-   "I1 = %2;\n\t"
-   "A0 = 0;\n\t"
-   "R0.L = W[I0++] || R1.L = W[I1++];\n\t"
-   "LOOP dot%= LC0 = %3;\n\t"
-   "LOOP_BEGIN dot%=;\n\t"
-      "A0 += R0.L * R1.L (IS) || R0.L = W[I0++] || R1.L = W[I1++];\n\t"
-   "LOOP_END dot%=;\n\t"
-   "A0 += R0.L*R1.L (IS);\n\t"
-   "R0 = A0;\n\t"
-   "%0 = R0;\n\t"
-   : "=&d" (dot)
-   : "a" (x), "a" (y), "a" (len)
-   : "I0", "I1", "A1", "A0", "R0", "R1"
-   );
-
-   return dot;
+       int dot;
+
+       len--;
+
+       __asm__("I0 = %1;\n\t"
+               "I1 = %2;\n\t"
+               "A0 = 0;\n\t"
+               "R0.L = W[I0++] || R1.L = W[I1++];\n\t"
+               "LOOP dot%= LC0 = %3;\n\t"
+               "LOOP_BEGIN dot%=;\n\t"
+               "A0 += R0.L * R1.L (IS) || R0.L = W[I0++] || R1.L = W[I1++];\n\t"
+               "LOOP_END dot%=;\n\t"
+               "A0 += R0.L*R1.L (IS);\n\t"
+               "R0 = A0;\n\t"
+               "%0 = R0;\n\t"
+               :"=&d"(dot)
+               :"a"(x), "a"(y), "a"(len)
+               :"I0", "I1", "A1", "A0", "R0", "R1"
+       );
+
+       return dot;
 }
 #endif
-/*- End of function --------------------------------------------------------*/
 
-static __inline__ int16_t fir16(fir16_state_t *fir, int16_t sample)
+static __inline__ int16_t fir16(fir16_state_t * fir, int16_t sample)
 {
-    int32_t y;
+       int32_t y;
 #if defined(USE_MMX)
-    int i;
-    mmx_t *mmx_coeffs;
-    mmx_t *mmx_hist;
-
-    fir->history[fir->curr_pos] = sample;
-    fir->history[fir->curr_pos + fir->taps] = sample;
-
-    mmx_coeffs = (mmx_t *) fir->coeffs;
-    mmx_hist = (mmx_t *) &fir->history[fir->curr_pos];
-    i = fir->taps;
-    pxor_r2r(mm4, mm4);
-    /* 8 samples per iteration, so the filter must be a multiple of 8 long. */
-    while (i > 0)
-    {
-        movq_m2r(mmx_coeffs[0], mm0);
-        movq_m2r(mmx_coeffs[1], mm2);
-        movq_m2r(mmx_hist[0], mm1);
-        movq_m2r(mmx_hist[1], mm3);
-        mmx_coeffs += 2;
-        mmx_hist += 2;
-        pmaddwd_r2r(mm1, mm0);
-        pmaddwd_r2r(mm3, mm2);
-        paddd_r2r(mm0, mm4);
-        paddd_r2r(mm2, mm4);
-        i -= 8;
-    }
-    movq_r2r(mm4, mm0);
-    psrlq_i2r(32, mm0);
-    paddd_r2r(mm0, mm4);
-    movd_r2m(mm4, y);
-    emms();
+       int i;
+       mmx_t *mmx_coeffs;
+       mmx_t *mmx_hist;
+
+       fir->history[fir->curr_pos] = sample;
+       fir->history[fir->curr_pos + fir->taps] = sample;
+
+       mmx_coeffs = (mmx_t *) fir->coeffs;
+       mmx_hist = (mmx_t *) & fir->history[fir->curr_pos];
+       i = fir->taps;
+       pxor_r2r(mm4, mm4);
+       /* 8 samples per iteration, so the filter must be a multiple of 8 long. */
+       while (i > 0) {
+               movq_m2r(mmx_coeffs[0], mm0);
+               movq_m2r(mmx_coeffs[1], mm2);
+               movq_m2r(mmx_hist[0], mm1);
+               movq_m2r(mmx_hist[1], mm3);
+               mmx_coeffs += 2;
+               mmx_hist += 2;
+               pmaddwd_r2r(mm1, mm0);
+               pmaddwd_r2r(mm3, mm2);
+               paddd_r2r(mm0, mm4);
+               paddd_r2r(mm2, mm4);
+               i -= 8;
+       }
+       movq_r2r(mm4, mm0);
+       psrlq_i2r(32, mm0);
+       paddd_r2r(mm0, mm4);
+       movd_r2m(mm4, y);
+       emms();
 #elif defined(USE_SSE2)
-    int i;
-    xmm_t *xmm_coeffs;
-    xmm_t *xmm_hist;
-
-    fir->history[fir->curr_pos] = sample;
-    fir->history[fir->curr_pos + fir->taps] = sample;
-
-    xmm_coeffs = (xmm_t *) fir->coeffs;
-    xmm_hist = (xmm_t *) &fir->history[fir->curr_pos];
-    i = fir->taps;
-    pxor_r2r(xmm4, xmm4);
-    /* 16 samples per iteration, so the filter must be a multiple of 16 long. */
-    while (i > 0)
-    {
-        movdqu_m2r(xmm_coeffs[0], xmm0);
-        movdqu_m2r(xmm_coeffs[1], xmm2);
-        movdqu_m2r(xmm_hist[0], xmm1);
-        movdqu_m2r(xmm_hist[1], xmm3);
-        xmm_coeffs += 2;
-        xmm_hist += 2;
-        pmaddwd_r2r(xmm1, xmm0);
-        pmaddwd_r2r(xmm3, xmm2);
-        paddd_r2r(xmm0, xmm4);
-        paddd_r2r(xmm2, xmm4);
-        i -= 16;
-    }
-    movdqa_r2r(xmm4, xmm0);
-    psrldq_i2r(8, xmm0);
-    paddd_r2r(xmm0, xmm4);
-    movdqa_r2r(xmm4, xmm0);
-    psrldq_i2r(4, xmm0);
-    paddd_r2r(xmm0, xmm4);
-    movd_r2m(xmm4, y);
-#elif defined(__BLACKFIN_ASM__)
-    fir->history[fir->curr_pos] = sample;
-    fir->history[fir->curr_pos + fir->taps] = sample;
-    y = dot_asm((int16_t*)fir->coeffs, &fir->history[fir->curr_pos], fir->taps);
+       int i;
+       xmm_t *xmm_coeffs;
+       xmm_t *xmm_hist;
+
+       fir->history[fir->curr_pos] = sample;
+       fir->history[fir->curr_pos + fir->taps] = sample;
+
+       xmm_coeffs = (xmm_t *) fir->coeffs;
+       xmm_hist = (xmm_t *) & fir->history[fir->curr_pos];
+       i = fir->taps;
+       pxor_r2r(xmm4, xmm4);
+       /* 16 samples per iteration, so the filter must be a multiple of 16 long. */
+       while (i > 0) {
+               movdqu_m2r(xmm_coeffs[0], xmm0);
+               movdqu_m2r(xmm_coeffs[1], xmm2);
+               movdqu_m2r(xmm_hist[0], xmm1);
+               movdqu_m2r(xmm_hist[1], xmm3);
+               xmm_coeffs += 2;
+               xmm_hist += 2;
+               pmaddwd_r2r(xmm1, xmm0);
+               pmaddwd_r2r(xmm3, xmm2);
+               paddd_r2r(xmm0, xmm4);
+               paddd_r2r(xmm2, xmm4);
+               i -= 16;
+       }
+       movdqa_r2r(xmm4, xmm0);
+       psrldq_i2r(8, xmm0);
+       paddd_r2r(xmm0, xmm4);
+       movdqa_r2r(xmm4, xmm0);
+       psrldq_i2r(4, xmm0);
+       paddd_r2r(xmm0, xmm4);
+       movd_r2m(xmm4, y);
+#elif defined(__bfin__)
+       fir->history[fir->curr_pos] = sample;
+       fir->history[fir->curr_pos + fir->taps] = sample;
+       y = dot_asm((int16_t *) fir->coeffs, &fir->history[fir->curr_pos],
+                   fir->taps);
 #else
-    int i;
-    int offset1;
-    int offset2;
-
-    fir->history[fir->curr_pos] = sample;
-
-    offset2 = fir->curr_pos;
-    offset1 = fir->taps - offset2;
-    y = 0;
-    for (i = fir->taps - 1;  i >= offset1;  i--)
-        y += fir->coeffs[i]*fir->history[i - offset1];
-    for (  ;  i >= 0;  i--)
-        y += fir->coeffs[i]*fir->history[i + offset2];
+       int i;
+       int offset1;
+       int offset2;
+
+       fir->history[fir->curr_pos] = sample;
+
+       offset2 = fir->curr_pos;
+       offset1 = fir->taps - offset2;
+       y = 0;
+       for (i = fir->taps - 1; i >= offset1; i--)
+               y += fir->coeffs[i] * fir->history[i - offset1];
+       for (; i >= 0; i--)
+               y += fir->coeffs[i] * fir->history[i + offset2];
 #endif
-    if (fir->curr_pos <= 0)
-       fir->curr_pos = fir->taps;
-    fir->curr_pos--;
-    return (int16_t) (y >> 15);
-}
-/*- End of function --------------------------------------------------------*/
-
-static __inline__ const int16_t *fir32_create(fir32_state_t *fir,
-                                              const int32_t *coeffs,
-                                              int taps)
-{
-    fir->taps = taps;
-    fir->curr_pos = taps - 1;
-    fir->coeffs = coeffs;
-    fir->history = (int16_t *) malloc(taps*sizeof(int16_t));
-    if (fir->history)
-       memset(fir->history, '\0', taps*sizeof(int16_t));
-    return fir->history;
-}
-/*- End of function --------------------------------------------------------*/
-
-static __inline__ void fir32_flush(fir32_state_t *fir)
-{
-    memset(fir->history, 0, fir->taps*sizeof(int16_t));
+       if (fir->curr_pos <= 0)
+               fir->curr_pos = fir->taps;
+       fir->curr_pos--;
+       return (int16_t) (y >> 15);
 }
-/*- End of function --------------------------------------------------------*/
 
-static __inline__ void fir32_free(fir32_state_t *fir)
+static __inline__ const int16_t *fir32_create(fir32_state_t * fir,
+                                             const int32_t * coeffs, int taps)
 {
-    free(fir->history);
-}
-/*- End of function --------------------------------------------------------*/
-
-static __inline__ int16_t fir32(fir32_state_t *fir, int16_t sample)
-{
-    int i;
-    int32_t y;
-    int offset1;
-    int offset2;
-
-    fir->history[fir->curr_pos] = sample;
-    offset2 = fir->curr_pos;
-    offset1 = fir->taps - offset2;
-    y = 0;
-    for (i = fir->taps - 1;  i >= offset1;  i--)
-        y += fir->coeffs[i]*fir->history[i - offset1];
-    for (  ;  i >= 0;  i--)
-        y += fir->coeffs[i]*fir->history[i + offset2];
-    if (fir->curr_pos <= 0)
-       fir->curr_pos = fir->taps;
-    fir->curr_pos--;
-    return (int16_t) (y >> 15);
+       fir->taps = taps;
+       fir->curr_pos = taps - 1;
+       fir->coeffs = coeffs;
+       fir->history = kcalloc(taps, sizeof(int16_t), GFP_KERNEL);
+       return fir->history;
 }
-/*- End of function --------------------------------------------------------*/
 
-#ifndef __KERNEL__
-static __inline__ const float *fir_float_create(fir_float_state_t *fir,
-                                                const float *coeffs,
-                                               int taps)
+static __inline__ void fir32_flush(fir32_state_t * fir)
 {
-    fir->taps = taps;
-    fir->curr_pos = taps - 1;
-    fir->coeffs = coeffs;
-    fir->history = (float *) malloc(taps*sizeof(float));
-    if (fir->history)
-        memset(fir->history, '\0', taps*sizeof(float));
-    return fir->history;
+       memset(fir->history, 0, fir->taps * sizeof(int16_t));
 }
-/*- End of function --------------------------------------------------------*/
 
-static __inline__ void fir_float_free(fir_float_state_t *fir)
+static __inline__ void fir32_free(fir32_state_t * fir)
 {
-    free(fir->history);
+       kfree(fir->history);
 }
-/*- End of function --------------------------------------------------------*/
 
-static __inline__ int16_t fir_float(fir_float_state_t *fir, int16_t sample)
+static __inline__ int16_t fir32(fir32_state_t * fir, int16_t sample)
 {
-    int i;
-    float y;
-    int offset1;
-    int offset2;
-
-    fir->history[fir->curr_pos] = sample;
-
-    offset2 = fir->curr_pos;
-    offset1 = fir->taps - offset2;
-    y = 0;
-    for (i = fir->taps - 1;  i >= offset1;  i--)
-        y += fir->coeffs[i]*fir->history[i - offset1];
-    for (  ;  i >= 0;  i--)
-        y += fir->coeffs[i]*fir->history[i + offset2];
-    if (fir->curr_pos <= 0)
-       fir->curr_pos = fir->taps;
-    fir->curr_pos--;
-    return  (int16_t) y;
+       int i;
+       int32_t y;
+       int offset1;
+       int offset2;
+
+       fir->history[fir->curr_pos] = sample;
+       offset2 = fir->curr_pos;
+       offset1 = fir->taps - offset2;
+       y = 0;
+       for (i = fir->taps - 1; i >= offset1; i--)
+               y += fir->coeffs[i] * fir->history[i - offset1];
+       for (; i >= 0; i--)
+               y += fir->coeffs[i] * fir->history[i + offset2];
+       if (fir->curr_pos <= 0)
+               fir->curr_pos = fir->taps;
+       fir->curr_pos--;
+       return (int16_t) (y >> 15);
 }
-/*- End of function --------------------------------------------------------*/
-#endif
-
-#ifdef __cplusplus
-}
-#endif
 
 #endif
 /*- End of file ------------------------------------------------------------*/
index b5a3964865b6c04de521a8dc4d189a7d95939b92..35412efe61ce5b5478a41b175f753a4ab1e876a7 100644 (file)
  * values by ULL, lest they be truncated by the compiler)
  */
 
-typedef        union {
-        long long               q;      /* Quadword (64-bit) value */
-        unsigned long long      uq;     /* Unsigned Quadword */
-        int                     d[2];   /* 2 Doubleword (32-bit) values */
-        unsigned int            ud[2];  /* 2 Unsigned Doubleword */
-        short                   w[4];   /* 4 Word (16-bit) values */
-        unsigned short          uw[4];  /* 4 Unsigned Word */
-        char                    b[8];   /* 8 Byte (8-bit) values */
-        unsigned char           ub[8];  /* 8 Unsigned Byte */
-        float                   s[2];   /* Single-precision (32-bit) value */
-} mmx_t;        /* On an 8-byte (64-bit) boundary */
+typedef union {
+       long long q;            /* Quadword (64-bit) value */
+       unsigned long long uq;  /* Unsigned Quadword */
+       int d[2];               /* 2 Doubleword (32-bit) values */
+       unsigned int ud[2];     /* 2 Unsigned Doubleword */
+       short w[4];             /* 4 Word (16-bit) values */
+       unsigned short uw[4];   /* 4 Unsigned Word */
+       char b[8];              /* 8 Byte (8-bit) values */
+       unsigned char ub[8];    /* 8 Unsigned Byte */
+       float s[2];             /* Single-precision (32-bit) value */
+} mmx_t;                       /* On an 8-byte (64-bit) boundary */
 
 /* SSE registers */
 typedef union {
        char b[16];
 } xmm_t;
 
-
 #define         mmx_i2r(op,imm,reg) \
         __asm__ __volatile__ (#op " %0, %%" #reg \
                               : /* nothing */ \
@@ -63,7 +62,6 @@ typedef union {
 #define         mmx_r2r(op,regs,regd) \
         __asm__ __volatile__ (#op " %" #regs ", %" #regd)
 
-
 #define         emms() __asm__ __volatile__ ("emms")
 
 #define         movd_m2r(var,reg)           mmx_m2r (movd, var, reg)
@@ -192,16 +190,13 @@ typedef union {
 #define         pxor_m2r(var,reg)           mmx_m2r (pxor, var, reg)
 #define         pxor_r2r(regs,regd)         mmx_r2r (pxor, regs, regd)
 
-
 /* 3DNOW extensions */
 
 #define         pavgusb_m2r(var,reg)        mmx_m2r (pavgusb, var, reg)
 #define         pavgusb_r2r(regs,regd)      mmx_r2r (pavgusb, regs, regd)
 
-
 /* AMD MMX extensions - also available in intel SSE */
 
-
 #define         mmx_m2ri(op,mem,reg,imm) \
         __asm__ __volatile__ (#op " %1, %0, %%" #reg \
                               : /* nothing */ \
@@ -216,7 +211,6 @@ typedef union {
                               : /* nothing */ \
                               : "m" (mem))
 
-
 #define         maskmovq(regs,maskreg)      mmx_r2ri (maskmovq, regs, maskreg)
 
 #define         movntq_r2m(mmreg,var)       mmx_r2m (movntq, mmreg, var)
@@ -284,5 +278,4 @@ typedef union {
 #define         punpcklqdq_r2r(regs,regd)   mmx_r2r (punpcklqdq, regs, regd)
 #define         punpckhqdq_r2r(regs,regd)   mmx_r2r (punpckhqdq, regs, regd)
 
-
 #endif /* AVCODEC_I386MMX_H */
diff --git a/drivers/staging/echo/oslec.h b/drivers/staging/echo/oslec.h
new file mode 100644 (file)
index 0000000..bad8523
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ *  OSLEC - A line echo canceller.  This code is being developed
+ *          against and partially complies with G168. Using code from SpanDSP
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ *         and David Rowe <david_at_rowetel_dot_com>
+ *
+ * Copyright (C) 2001 Steve Underwood and 2007-2008 David Rowe
+ *
+ * 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 version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __OSLEC_H
+#define __OSLEC_H
+
+/* TODO: document interface */
+
+/* Mask bits for the adaption mode */
+#define ECHO_CAN_USE_ADAPTION  0x01
+#define ECHO_CAN_USE_NLP       0x02
+#define ECHO_CAN_USE_CNG       0x04
+#define ECHO_CAN_USE_CLIP      0x08
+#define ECHO_CAN_USE_TX_HPF    0x10
+#define ECHO_CAN_USE_RX_HPF    0x20
+#define ECHO_CAN_DISABLE       0x40
+
+/*!
+    G.168 echo canceller descriptor. This defines the working state for a line
+    echo canceller.
+*/
+struct oslec_state;
+
+/*! Create a voice echo canceller context.
+    \param len The length of the canceller, in samples.
+    \return The new canceller context, or NULL if the canceller could not be created.
+*/
+struct oslec_state *oslec_create(int len, int adaption_mode);
+
+/*! Free a voice echo canceller context.
+    \param ec The echo canceller context.
+*/
+void oslec_free(struct oslec_state *ec);
+
+/*! Flush (reinitialise) a voice echo canceller context.
+    \param ec The echo canceller context.
+*/
+void oslec_flush(struct oslec_state *ec);
+
+/*! Set the adaption mode of a voice echo canceller context.
+    \param ec The echo canceller context.
+    \param adapt The mode.
+*/
+void oslec_adaption_mode(struct oslec_state *ec, int adaption_mode);
+
+void oslec_snapshot(struct oslec_state *ec);
+
+/*! Process a sample through a voice echo canceller.
+    \param ec The echo canceller context.
+    \param tx The transmitted audio sample.
+    \param rx The received audio sample.
+    \return The clean (echo cancelled) received sample.
+*/
+int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx);
+
+/*! Process to high pass filter the tx signal.
+    \param ec The echo canceller context.
+    \param tx The transmitted auio sample.
+    \return The HP filtered transmit sample, send this to your D/A.
+*/
+int16_t oslec_hpf_tx(struct oslec_state *ec, int16_t tx);
+
+#endif /* __OSLEC_H */
index 6c4fa54419ea3efa7f2884c49f7f240f26837157..9dd6dfd9a03373f5c40a351d425ed96493ba63a6 100644 (file)
@@ -84,7 +84,6 @@
 #include <linux/if_arp.h>
 #include <linux/ioport.h>
 #include <linux/random.h>
-#include <linux/delay.h>
 
 #include "et1310_phy.h"
 #include "et1310_pm.h"
@@ -95,7 +94,6 @@
 #include "et131x_initpci.h"
 
 #include "et1310_address_map.h"
-#include "et1310_jagcore.h"
 #include "et1310_tx.h"
 #include "et1310_rx.h"
 #include "et1310_mac.h"
index 9ee5bce92c279be51b64c84e95bf2e9c05b5dda6..d1dd46e0a9c83a4e1c4ea16b47351c42a7eae6d5 100644 (file)
@@ -97,7 +97,6 @@
 #include "et131x_isr.h"
 
 #include "et1310_address_map.h"
-#include "et1310_jagcore.h"
 #include "et1310_tx.h"
 #include "et1310_rx.h"
 #include "et1310_mac.h"
index 4c6f171f5b7c553e9f449426a72ae993a0e49272..a18c499d0ae05147dc63ed13082bba352809fc3d 100644 (file)
@@ -97,7 +97,6 @@
 #include "et131x_isr.h"
 
 #include "et1310_address_map.h"
-#include "et1310_jagcore.h"
 #include "et1310_tx.h"
 #include "et1310_rx.h"
 #include "et1310_mac.h"
index 81ae4b0fa8902e720dc7b4a4120ae3f9c798838f..e4ead96679c89d0897877f61930af4037a1c3de1 100644 (file)
@@ -16,7 +16,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
index c2aea1020b0de7babe5abc0b2a5bd0abb32eb020..a0e17b0e0ce3bba9ff5a4bf4df0340a85574e5a5 100644 (file)
@@ -26,7 +26,6 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/version.h>
 #include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/device.h>
index 10baae3dade6a07a88e353f82e78af3b8e43bcb7..cd55b76eabc77ced3efe9fccfa8c9f9b0ed58dcc 100644 (file)
@@ -15,7 +15,6 @@
  * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index d4ed6d2b715f5bd7f99b148609f3842c8f175734..3f5ee3424e7263a8141f30f44099557b8ecbb329 100644 (file)
@@ -16,7 +16,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/wait.h>
index 382740c405ffe788704ca1aa5e95a33bcdd47ed3..a7de401f61ab22d1636939ba87ba939ad1f15654 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
index f5f11e927af3b3bf9be168c1b50daa1bcd37b9cd..2f9efca046065e3a66d93f5c6d66e6de29ac4cf7 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/version.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 
index c1aff1b923a0f6e82a194876c7a1f187af3fbbaa..11689723945e0e067fcd268f99821b8fd29c41a1 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/version.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <linux/ioctl.h>
index 5c94c883b312041c566d6696b79277bd3d9c443e..59417a7174d7c2cc6d57a2165989139b0170ef35 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/version.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <linux/ioctl.h>
index 5997fb4794596c237bcf9b203fc7550306516f18..5a91ee409a7ced90522cccaf623c54e37fc3121e 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/version.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/tuner.h>
index 27fe4d0d4ed695e933f208e1f14c797e9976916f..57b8f2b1caa36017b92e0ae5edffe7ca00fcdab6 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/version.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <linux/ioctl.h>
index d8e41968022e92a057214d71dd79b0442b023f6d..40627b282cb41665178e5626c0f7ec4af1f71ba9 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/version.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <linux/ioctl.h>
index a0894e3cb8c725de45b09dcece074c31f1b56d73..555645c0cc1a298f7e5f0d373ae9f6c2413e369d 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/version.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/tvaudio.h>
index 862dd7ffb5c06e663858335f4ad4dffdb08358ff..0b33773bb4f68412d5d44f3b99fed07fb1ab2041 100644 (file)
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
-#include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/unistd.h>
 #include <linux/list.h>
 #include <linux/proc_fs.h>
-
+#include <linux/types.h>
 #include <linux/poll.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
-#include <linux/types.h>
-
-#include <linux/slab.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
 
 /* Include-File for the Meilhaus ME-4000 I/O board */
 #include "me4000.h"
@@ -57,14 +54,14 @@ MODULE_SUPPORTED_DEVICE("Meilhaus ME-4000 Multi I/O boards");
 MODULE_LICENSE("GPL");
 
 /* Board specific data are kept in a global list */
-LIST_HEAD(me4000_board_info_list);
+static LIST_HEAD(me4000_board_info_list);
 
 /* Major Device Numbers. 0 means to get it automatically from the System */
-static int me4000_ao_major_driver_no = 0;
-static int me4000_ai_major_driver_no = 0;
-static int me4000_dio_major_driver_no = 0;
-static int me4000_cnt_major_driver_no = 0;
-static int me4000_ext_int_major_driver_no = 0;
+static int me4000_ao_major_driver_no;
+static int me4000_ai_major_driver_no;
+static int me4000_dio_major_driver_no;
+static int me4000_cnt_major_driver_no;
+static int me4000_ext_int_major_driver_no;
 
 /* Let the user specify a custom major driver number */
 module_param(me4000_ao_major_driver_no, int, 0);
@@ -87,37 +84,23 @@ module_param(me4000_ext_int_major_driver_no, int, 0);
 MODULE_PARM_DESC(me4000_ext_int_major_driver_no,
                 "Major driver number for external interrupt (default 0)");
 
-/*-----------------------------------------------------------------------------
-  Module stuff
-  ---------------------------------------------------------------------------*/
-int init_module(void);
-void cleanup_module(void);
-
 /*-----------------------------------------------------------------------------
   Board detection and initialization
   ---------------------------------------------------------------------------*/
 static int me4000_probe(struct pci_dev *dev, const struct pci_device_id *id);
-static int me4000_xilinx_download(me4000_info_t *);
-static int me4000_reset_board(me4000_info_t *);
+static int me4000_xilinx_download(struct me4000_info *);
+static int me4000_reset_board(struct me4000_info *);
 
 static void clear_board_info_list(void);
-static int get_registers(struct pci_dev *dev, me4000_info_t * info);
-static int init_board_info(struct pci_dev *dev, me4000_info_t * board_info);
-static int alloc_ao_contexts(me4000_info_t * info);
-static void release_ao_contexts(me4000_info_t * board_info);
-static int alloc_ai_context(me4000_info_t * info);
-static int alloc_dio_context(me4000_info_t * info);
-static int alloc_cnt_context(me4000_info_t * info);
-static int alloc_ext_int_context(me4000_info_t * info);
-
+static void release_ao_contexts(struct me4000_info *board_info);
 /*-----------------------------------------------------------------------------
   Stuff used by all device parts
   ---------------------------------------------------------------------------*/
 static int me4000_open(struct inode *, struct file *);
 static int me4000_release(struct inode *, struct file *);
 
-static int me4000_get_user_info(me4000_user_info_t *,
-                               me4000_info_t * board_info);
+static int me4000_get_user_info(struct me4000_user_info *,
+                               struct me4000_info *board_info);
 static int me4000_read_procmem(char *, char **, off_t, int, int *, void *);
 
 /*-----------------------------------------------------------------------------
@@ -140,40 +123,42 @@ static int me4000_ao_ioctl_cont(struct inode *, struct file *, unsigned int,
 static unsigned int me4000_ao_poll_cont(struct file *, poll_table *);
 static int me4000_ao_fsync_cont(struct file *, struct dentry *, int);
 
-static int me4000_ao_start(unsigned long *, me4000_ao_context_t *);
-static int me4000_ao_stop(me4000_ao_context_t *);
-static int me4000_ao_immediate_stop(me4000_ao_context_t *);
-static int me4000_ao_timer_set_divisor(u32 *, me4000_ao_context_t *);
-static int me4000_ao_preload(me4000_ao_context_t *);
-static int me4000_ao_preload_update(me4000_ao_context_t *);
-static int me4000_ao_ex_trig_set_edge(int *, me4000_ao_context_t *);
-static int me4000_ao_ex_trig_enable(me4000_ao_context_t *);
-static int me4000_ao_ex_trig_disable(me4000_ao_context_t *);
-static int me4000_ao_prepare(me4000_ao_context_t * ao_info);
-static int me4000_ao_reset(me4000_ao_context_t * ao_info);
-static int me4000_ao_enable_do(me4000_ao_context_t *);
-static int me4000_ao_disable_do(me4000_ao_context_t *);
-static int me4000_ao_fsm_state(int *, me4000_ao_context_t *);
-
-static int me4000_ao_simultaneous_ex_trig(me4000_ao_context_t * ao_context);
-static int me4000_ao_simultaneous_sw(me4000_ao_context_t * ao_context);
-static int me4000_ao_simultaneous_disable(me4000_ao_context_t * ao_context);
-static int me4000_ao_simultaneous_update(me4000_ao_channel_list_t * channels,
-                                        me4000_ao_context_t * ao_context);
-
-static int me4000_ao_synchronous_ex_trig(me4000_ao_context_t * ao_context);
-static int me4000_ao_synchronous_sw(me4000_ao_context_t * ao_context);
-static int me4000_ao_synchronous_disable(me4000_ao_context_t * ao_context);
+static int me4000_ao_start(unsigned long *, struct me4000_ao_context *);
+static int me4000_ao_stop(struct me4000_ao_context *);
+static int me4000_ao_immediate_stop(struct me4000_ao_context *);
+static int me4000_ao_timer_set_divisor(u32 *, struct me4000_ao_context *);
+static int me4000_ao_preload(struct me4000_ao_context *);
+static int me4000_ao_preload_update(struct me4000_ao_context *);
+static int me4000_ao_ex_trig_set_edge(int *, struct me4000_ao_context *);
+static int me4000_ao_ex_trig_enable(struct me4000_ao_context *);
+static int me4000_ao_ex_trig_disable(struct me4000_ao_context *);
+static int me4000_ao_prepare(struct me4000_ao_context *ao_info);
+static int me4000_ao_reset(struct me4000_ao_context *ao_info);
+static int me4000_ao_enable_do(struct me4000_ao_context *);
+static int me4000_ao_disable_do(struct me4000_ao_context *);
+static int me4000_ao_fsm_state(int *, struct me4000_ao_context *);
+
+static int me4000_ao_simultaneous_ex_trig(struct me4000_ao_context *ao_context);
+static int me4000_ao_simultaneous_sw(struct me4000_ao_context *ao_context);
+static int me4000_ao_simultaneous_disable(struct me4000_ao_context *ao_context);
+static int me4000_ao_simultaneous_update(
+                                       struct me4000_ao_channel_list *channels,
+                                       struct me4000_ao_context *ao_context);
+
+static int me4000_ao_synchronous_ex_trig(struct me4000_ao_context *ao_context);
+static int me4000_ao_synchronous_sw(struct me4000_ao_context *ao_context);
+static int me4000_ao_synchronous_disable(struct me4000_ao_context *ao_context);
 
 static int me4000_ao_ex_trig_timeout(unsigned long *arg,
-                                    me4000_ao_context_t * ao_context);
+                                    struct me4000_ao_context *ao_context);
 static int me4000_ao_get_free_buffer(unsigned long *arg,
-                                    me4000_ao_context_t * ao_context);
+                                    struct me4000_ao_context *ao_context);
 
 /*-----------------------------------------------------------------------------
   Analog input stuff
   ---------------------------------------------------------------------------*/
-static int me4000_ai_single(me4000_ai_single_t *, me4000_ai_context_t *);
+static int me4000_ai_single(struct me4000_ai_single *,
+                               struct me4000_ai_context *);
 static int me4000_ai_ioctl_sing(struct inode *, struct file *, unsigned int,
                                unsigned long);
 
@@ -186,68 +171,69 @@ static int me4000_ai_fasync(int fd, struct file *file_p, int mode);
 static int me4000_ai_ioctl_ext(struct inode *, struct file *, unsigned int,
                               unsigned long);
 
-static int me4000_ai_prepare(me4000_ai_context_t * ai_context);
-static int me4000_ai_reset(me4000_ai_context_t * ai_context);
-static int me4000_ai_config(me4000_ai_config_t *, me4000_ai_context_t *);
-static int me4000_ai_start(me4000_ai_context_t *);
-static int me4000_ai_start_ex(unsigned long *, me4000_ai_context_t *);
-static int me4000_ai_stop(me4000_ai_context_t *);
-static int me4000_ai_immediate_stop(me4000_ai_context_t *);
-static int me4000_ai_ex_trig_enable(me4000_ai_context_t *);
-static int me4000_ai_ex_trig_disable(me4000_ai_context_t *);
-static int me4000_ai_ex_trig_setup(me4000_ai_trigger_t *,
-                                  me4000_ai_context_t *);
-static int me4000_ai_sc_setup(me4000_ai_sc_t * arg,
-                             me4000_ai_context_t * ai_context);
-static int me4000_ai_offset_enable(me4000_ai_context_t * ai_context);
-static int me4000_ai_offset_disable(me4000_ai_context_t * ai_context);
-static int me4000_ai_fullscale_enable(me4000_ai_context_t * ai_context);
-static int me4000_ai_fullscale_disable(me4000_ai_context_t * ai_context);
-static int me4000_ai_fsm_state(int *arg, me4000_ai_context_t * ai_context);
+static int me4000_ai_prepare(struct me4000_ai_context *ai_context);
+static int me4000_ai_reset(struct me4000_ai_context *ai_context);
+static int me4000_ai_config(struct me4000_ai_config *,
+                               struct me4000_ai_context *);
+static int me4000_ai_start(struct me4000_ai_context *);
+static int me4000_ai_start_ex(unsigned long *, struct me4000_ai_context *);
+static int me4000_ai_stop(struct me4000_ai_context *);
+static int me4000_ai_immediate_stop(struct me4000_ai_context *);
+static int me4000_ai_ex_trig_enable(struct me4000_ai_context *);
+static int me4000_ai_ex_trig_disable(struct me4000_ai_context *);
+static int me4000_ai_ex_trig_setup(struct me4000_ai_trigger *,
+                                  struct me4000_ai_context *);
+static int me4000_ai_sc_setup(struct me4000_ai_sc *arg,
+                             struct me4000_ai_context *ai_context);
+static int me4000_ai_offset_enable(struct me4000_ai_context *ai_context);
+static int me4000_ai_offset_disable(struct me4000_ai_context *ai_context);
+static int me4000_ai_fullscale_enable(struct me4000_ai_context *ai_context);
+static int me4000_ai_fullscale_disable(struct me4000_ai_context *ai_context);
+static int me4000_ai_fsm_state(int *arg, struct me4000_ai_context *ai_context);
 static int me4000_ai_get_count_buffer(unsigned long *arg,
-                                     me4000_ai_context_t * ai_context);
+                                     struct me4000_ai_context *ai_context);
 
 /*-----------------------------------------------------------------------------
   EEPROM stuff
   ---------------------------------------------------------------------------*/
-static int me4000_eeprom_read(me4000_eeprom_t * arg,
-                             me4000_ai_context_t * ai_context);
-static int me4000_eeprom_write(me4000_eeprom_t * arg,
-                              me4000_ai_context_t * ai_context);
-static unsigned short eeprom_read_cmd(me4000_ai_context_t * ai_context,
-                                     unsigned long cmd, int length);
-static int eeprom_write_cmd(me4000_ai_context_t * ai_context, unsigned long cmd,
-                           int length);
+static int me4000_eeprom_read(struct me4000_eeprom *arg,
+                             struct me4000_ai_context *ai_context);
+static int me4000_eeprom_write(struct me4000_eeprom *arg,
+                              struct me4000_ai_context *ai_context);
 
 /*-----------------------------------------------------------------------------
   Digital I/O stuff
   ---------------------------------------------------------------------------*/
 static int me4000_dio_ioctl(struct inode *, struct file *, unsigned int,
                            unsigned long);
-static int me4000_dio_config(me4000_dio_config_t *, me4000_dio_context_t *);
-static int me4000_dio_get_byte(me4000_dio_byte_t *, me4000_dio_context_t *);
-static int me4000_dio_set_byte(me4000_dio_byte_t *, me4000_dio_context_t *);
-static int me4000_dio_reset(me4000_dio_context_t *);
+static int me4000_dio_config(struct me4000_dio_config *,
+                               struct me4000_dio_context *);
+static int me4000_dio_get_byte(struct me4000_dio_byte *,
+                               struct me4000_dio_context *);
+static int me4000_dio_set_byte(struct me4000_dio_byte *,
+                               struct me4000_dio_context *);
+static int me4000_dio_reset(struct me4000_dio_context *);
 
 /*-----------------------------------------------------------------------------
   Counter stuff
   ---------------------------------------------------------------------------*/
 static int me4000_cnt_ioctl(struct inode *, struct file *, unsigned int,
                            unsigned long);
-static int me4000_cnt_config(me4000_cnt_config_t *, me4000_cnt_context_t *);
-static int me4000_cnt_read(me4000_cnt_t *, me4000_cnt_context_t *);
-static int me4000_cnt_write(me4000_cnt_t *, me4000_cnt_context_t *);
-static int me4000_cnt_reset(me4000_cnt_context_t *);
+static int me4000_cnt_config(struct me4000_cnt_config *,
+                               struct me4000_cnt_context *);
+static int me4000_cnt_read(struct me4000_cnt *, struct me4000_cnt_context *);
+static int me4000_cnt_write(struct me4000_cnt *, struct me4000_cnt_context *);
+static int me4000_cnt_reset(struct me4000_cnt_context *);
 
 /*-----------------------------------------------------------------------------
   External interrupt routines
   ---------------------------------------------------------------------------*/
 static int me4000_ext_int_ioctl(struct inode *, struct file *, unsigned int,
                                unsigned long);
-static int me4000_ext_int_enable(me4000_ext_int_context_t *);
-static int me4000_ext_int_disable(me4000_ext_int_context_t *);
+static int me4000_ext_int_enable(struct me4000_ext_int_context *);
+static int me4000_ext_int_disable(struct me4000_ext_int_context *);
 static int me4000_ext_int_count(unsigned long *arg,
-                               me4000_ext_int_context_t * ext_int_context);
+                               struct me4000_ext_int_context *ext_int_context);
 static int me4000_ext_int_fasync(int fd, struct file *file_ptr, int mode);
 
 /*-----------------------------------------------------------------------------
@@ -260,27 +246,18 @@ static irqreturn_t me4000_ext_int_isr(int, void *);
 /*-----------------------------------------------------------------------------
   Inline functions
   ---------------------------------------------------------------------------*/
-static int inline me4000_buf_count(me4000_circ_buf_t, int);
-static int inline me4000_buf_space(me4000_circ_buf_t, int);
-static int inline me4000_space_to_end(me4000_circ_buf_t, int);
-static int inline me4000_values_to_end(me4000_circ_buf_t, int);
-
-static void inline me4000_outb(unsigned char value, unsigned long port);
-static void inline me4000_outl(unsigned long value, unsigned long port);
-static unsigned long inline me4000_inl(unsigned long port);
-static unsigned char inline me4000_inb(unsigned long port);
 
-static int me4000_buf_count(me4000_circ_buf_t buf, int size)
+static int inline me4000_buf_count(struct me4000_circ_buf buf, int size)
 {
        return ((buf.head - buf.tail) & (size - 1));
 }
 
-static int me4000_buf_space(me4000_circ_buf_t buf, int size)
+static int inline me4000_buf_space(struct me4000_circ_buf buf, int size)
 {
        return ((buf.tail - (buf.head + 1)) & (size - 1));
 }
 
-static int me4000_values_to_end(me4000_circ_buf_t buf, int size)
+static int inline me4000_values_to_end(struct me4000_circ_buf buf, int size)
 {
        int end;
        int n;
@@ -289,7 +266,7 @@ static int me4000_values_to_end(me4000_circ_buf_t buf, int size)
        return (n < end) ? n : end;
 }
 
-static int me4000_space_to_end(me4000_circ_buf_t buf, int size)
+static int inline me4000_space_to_end(struct me4000_circ_buf buf, int size)
 {
        int end;
        int n;
@@ -299,19 +276,19 @@ static int me4000_space_to_end(me4000_circ_buf_t buf, int size)
        return (n <= end) ? n : (end + 1);
 }
 
-static void me4000_outb(unsigned char value, unsigned long port)
+static void inline me4000_outb(unsigned char value, unsigned long port)
 {
        PORT_PDEBUG("--> 0x%02X port 0x%04lX\n", value, port);
        outb(value, port);
 }
 
-static void me4000_outl(unsigned long value, unsigned long port)
+static void inline me4000_outl(unsigned long value, unsigned long port)
 {
        PORT_PDEBUG("--> 0x%08lX port 0x%04lX\n", value, port);
        outl(value, port);
 }
 
-static unsigned long me4000_inl(unsigned long port)
+static unsigned long inline me4000_inl(unsigned long port)
 {
        unsigned long value;
        value = inl(port);
@@ -319,7 +296,7 @@ static unsigned long me4000_inl(unsigned long port)
        return value;
 }
 
-static unsigned char me4000_inb(unsigned long port)
+static unsigned char inline me4000_inb(unsigned long port)
 {
        unsigned char value;
        value = inb(port);
@@ -327,102 +304,102 @@ static unsigned char me4000_inb(unsigned long port)
        return value;
 }
 
-struct pci_driver me4000_driver = {
+static struct pci_driver me4000_driver = {
        .name = ME4000_NAME,
        .id_table = me4000_pci_table,
        .probe = me4000_probe
 };
 
 static struct file_operations me4000_ao_fops_sing = {
-      owner:THIS_MODULE,
-      write:me4000_ao_write_sing,
-      ioctl:me4000_ao_ioctl_sing,
-      open:me4000_open,
-      release:me4000_release,
+      .owner = THIS_MODULE,
+      .write = me4000_ao_write_sing,
+      .ioctl = me4000_ao_ioctl_sing,
+      .open = me4000_open,
+      .release = me4000_release,
 };
 
 static struct file_operations me4000_ao_fops_wrap = {
-      owner:THIS_MODULE,
-      write:me4000_ao_write_wrap,
-      ioctl:me4000_ao_ioctl_wrap,
-      open:me4000_open,
-      release:me4000_release,
+      .owner = THIS_MODULE,
+      .write = me4000_ao_write_wrap,
+      .ioctl = me4000_ao_ioctl_wrap,
+      .open = me4000_open,
+      .release = me4000_release,
 };
 
 static struct file_operations me4000_ao_fops_cont = {
-      owner:THIS_MODULE,
-      write:me4000_ao_write_cont,
-      poll:me4000_ao_poll_cont,
-      ioctl:me4000_ao_ioctl_cont,
-      open:me4000_open,
-      release:me4000_release,
-      fsync:me4000_ao_fsync_cont,
+      .owner = THIS_MODULE,
+      .write = me4000_ao_write_cont,
+      .poll = me4000_ao_poll_cont,
+      .ioctl = me4000_ao_ioctl_cont,
+      .open = me4000_open,
+      .release = me4000_release,
+      .fsync = me4000_ao_fsync_cont,
 };
 
 static struct file_operations me4000_ai_fops_sing = {
-      owner:THIS_MODULE,
-      ioctl:me4000_ai_ioctl_sing,
-      open:me4000_open,
-      release:me4000_release,
+      .owner = THIS_MODULE,
+      .ioctl = me4000_ai_ioctl_sing,
+      .open = me4000_open,
+      .release = me4000_release,
 };
 
 static struct file_operations me4000_ai_fops_cont_sw = {
-      owner:THIS_MODULE,
-      read:me4000_ai_read,
-      poll:me4000_ai_poll,
-      ioctl:me4000_ai_ioctl_sw,
-      open:me4000_open,
-      release:me4000_release,
-      fasync:me4000_ai_fasync,
+      .owner = THIS_MODULE,
+      .read = me4000_ai_read,
+      .poll = me4000_ai_poll,
+      .ioctl = me4000_ai_ioctl_sw,
+      .open = me4000_open,
+      .release = me4000_release,
+      .fasync = me4000_ai_fasync,
 };
 
 static struct file_operations me4000_ai_fops_cont_et = {
-      owner:THIS_MODULE,
-      read:me4000_ai_read,
-      poll:me4000_ai_poll,
-      ioctl:me4000_ai_ioctl_ext,
-      open:me4000_open,
-      release:me4000_release,
+      .owner = THIS_MODULE,
+      .read = me4000_ai_read,
+      .poll = me4000_ai_poll,
+      .ioctl = me4000_ai_ioctl_ext,
+      .open = me4000_open,
+      .release = me4000_release,
 };
 
 static struct file_operations me4000_ai_fops_cont_et_value = {
-      owner:THIS_MODULE,
-      read:me4000_ai_read,
-      poll:me4000_ai_poll,
-      ioctl:me4000_ai_ioctl_ext,
-      open:me4000_open,
-      release:me4000_release,
+      .owner = THIS_MODULE,
+      .read = me4000_ai_read,
+      .poll = me4000_ai_poll,
+      .ioctl = me4000_ai_ioctl_ext,
+      .open = me4000_open,
+      .release = me4000_release,
 };
 
 static struct file_operations me4000_ai_fops_cont_et_chanlist = {
-      owner:THIS_MODULE,
-      read:me4000_ai_read,
-      poll:me4000_ai_poll,
-      ioctl:me4000_ai_ioctl_ext,
-      open:me4000_open,
-      release:me4000_release,
+      .owner = THIS_MODULE,
+      .read = me4000_ai_read,
+      .poll = me4000_ai_poll,
+      .ioctl = me4000_ai_ioctl_ext,
+      .open = me4000_open,
+      .release = me4000_release,
 };
 
 static struct file_operations me4000_dio_fops = {
-      owner:THIS_MODULE,
-      ioctl:me4000_dio_ioctl,
-      open:me4000_open,
-      release:me4000_release,
+      .owner = THIS_MODULE,
+      .ioctl = me4000_dio_ioctl,
+      .open = me4000_open,
+      .release = me4000_release,
 };
 
 static struct file_operations me4000_cnt_fops = {
-      owner:THIS_MODULE,
-      ioctl:me4000_cnt_ioctl,
-      open:me4000_open,
-      release:me4000_release,
+      .owner = THIS_MODULE,
+      .ioctl = me4000_cnt_ioctl,
+      .open = me4000_open,
+      .release = me4000_release,
 };
 
 static struct file_operations me4000_ext_int_fops = {
-      owner:THIS_MODULE,
-      ioctl:me4000_ext_int_ioctl,
-      open:me4000_open,
-      release:me4000_release,
-      fasync:me4000_ext_int_fasync,
+      .owner = THIS_MODULE,
+      .ioctl = me4000_ext_int_ioctl,
+      .open = me4000_open,
+      .release = me4000_release,
+      .fasync = me4000_ext_int_fasync,
 };
 
 static struct file_operations *me4000_ao_fops_array[] = {
@@ -439,9 +416,9 @@ static struct file_operations *me4000_ai_fops_array[] = {
        &me4000_ai_fops_cont_et_chanlist,       // work through one channel list by external trigger
 };
 
-int __init me4000_init_module(void)
+static int __init me4000_init_module(void)
 {
-       int result = 0;
+       int result;
 
        CALL_PDEBUG("init_module() is executed\n");
 
@@ -533,26 +510,26 @@ int __init me4000_init_module(void)
 
        return 0;
 
-      INIT_ERROR_7:
+INIT_ERROR_7:
        unregister_chrdev(me4000_ext_int_major_driver_no, ME4000_EXT_INT_NAME);
 
-      INIT_ERROR_6:
+INIT_ERROR_6:
        unregister_chrdev(me4000_cnt_major_driver_no, ME4000_CNT_NAME);
 
-      INIT_ERROR_5:
+INIT_ERROR_5:
        unregister_chrdev(me4000_dio_major_driver_no, ME4000_DIO_NAME);
 
-      INIT_ERROR_4:
+INIT_ERROR_4:
        unregister_chrdev(me4000_ai_major_driver_no, ME4000_AI_NAME);
 
-      INIT_ERROR_3:
+INIT_ERROR_3:
        unregister_chrdev(me4000_ao_major_driver_no, ME4000_AO_NAME);
 
-      INIT_ERROR_2:
+INIT_ERROR_2:
        pci_unregister_driver(&me4000_driver);
        clear_board_info_list();
 
-      INIT_ERROR_1:
+INIT_ERROR_1:
        return result;
 }
 
@@ -562,18 +539,18 @@ static void clear_board_info_list(void)
 {
        struct list_head *board_p;
        struct list_head *dac_p;
-       me4000_info_t *board_info;
-       me4000_ao_context_t *ao_context;
+       struct me4000_info *board_info;
+       struct me4000_ao_context *ao_context;
 
        /* Clear context lists */
        for (board_p = me4000_board_info_list.next;
             board_p != &me4000_board_info_list; board_p = board_p->next) {
-               board_info = list_entry(board_p, me4000_info_t, list);
+               board_info = list_entry(board_p, struct me4000_info, list);
                /* Clear analog output context list */
                while (!list_empty(&board_info->ao_context_list)) {
                        dac_p = board_info->ao_context_list.next;
                        ao_context =
-                           list_entry(dac_p, me4000_ao_context_t, list);
+                           list_entry(dac_p, struct me4000_ao_context, list);
                        me4000_ao_reset(ao_context);
                        free_irq(ao_context->irq, ao_context);
                        if (ao_context->circ_buf.buf)
@@ -600,14 +577,14 @@ static void clear_board_info_list(void)
        /* Clear the board info list */
        while (!list_empty(&me4000_board_info_list)) {
                board_p = me4000_board_info_list.next;
-               board_info = list_entry(board_p, me4000_info_t, list);
+               board_info = list_entry(board_p, struct me4000_info, list);
                pci_release_regions(board_info->pci_dev_p);
                list_del(board_p);
                kfree(board_info);
        }
 }
 
-static int get_registers(struct pci_dev *dev, me4000_info_t * board_info)
+static int get_registers(struct pci_dev *dev, struct me4000_info *board_info)
 {
 
        /*--------------------------- plx regbase ---------------------------------*/
@@ -667,20 +644,20 @@ static int get_registers(struct pci_dev *dev, me4000_info_t * board_info)
 }
 
 static int init_board_info(struct pci_dev *pci_dev_p,
-                          me4000_info_t * board_info)
+                          struct me4000_info *board_info)
 {
        int i;
        int result;
        struct list_head *board_p;
        board_info->pci_dev_p = pci_dev_p;
 
-       for (i = 0; i < ME4000_BOARD_VERSIONS; i++) {
+       for (i = 0; i < ARRAY_SIZE(me4000_boards); i++) {
                if (me4000_boards[i].device_id == pci_dev_p->device) {
                        board_info->board_p = &me4000_boards[i];
                        break;
                }
        }
-       if (i == ME4000_BOARD_VERSIONS) {
+       if (i == ARRAY_SIZE(me4000_boards)) {
                printk(KERN_ERR
                       "ME4000:init_board_info():Device ID not valid\n");
                return -ENODEV;
@@ -755,21 +732,21 @@ static int init_board_info(struct pci_dev *pci_dev_p,
        return 0;
 }
 
-static int alloc_ao_contexts(me4000_info_t * info)
+static int alloc_ao_contexts(struct me4000_info *info)
 {
        int i;
        int err;
-       me4000_ao_context_t *ao_context;
+       struct me4000_ao_context *ao_context;
 
        for (i = 0; i < info->board_p->ao.count; i++) {
-               ao_context = kmalloc(sizeof(me4000_ao_context_t), GFP_KERNEL);
+               ao_context = kzalloc(sizeof(struct me4000_ao_context),
+                                                               GFP_KERNEL);
                if (!ao_context) {
                        printk(KERN_ERR
                               "alloc_ao_contexts():Can't get memory for ao context\n");
                        release_ao_contexts(info);
                        return -ENOMEM;
                }
-               memset(ao_context, 0, sizeof(me4000_ao_context_t));
 
                spin_lock_init(&ao_context->use_lock);
                spin_lock_init(&ao_context->int_lock);
@@ -780,15 +757,13 @@ static int alloc_ao_contexts(me4000_info_t * info)
                if (info->board_p->ao.fifo_count) {
                        /* Allocate circular buffer */
                        ao_context->circ_buf.buf =
-                           kmalloc(ME4000_AO_BUFFER_SIZE, GFP_KERNEL);
+                           kzalloc(ME4000_AO_BUFFER_SIZE, GFP_KERNEL);
                        if (!ao_context->circ_buf.buf) {
                                printk(KERN_ERR
                                       "alloc_ao_contexts():Can't get circular buffer\n");
                                release_ao_contexts(info);
                                return -ENOMEM;
                        }
-                       memset(ao_context->circ_buf.buf, 0,
-                              ME4000_AO_BUFFER_SIZE);
 
                        /* Clear the circular buffer */
                        ao_context->circ_buf.head = 0;
@@ -872,9 +847,8 @@ static int alloc_ao_contexts(me4000_info_t * info)
                                        ME4000_NAME, ao_context);
                        if (err) {
                                printk(KERN_ERR
-                                      "alloc_ao_contexts():Can't get interrupt line");
-                               if (ao_context->circ_buf.buf)
-                                       kfree(ao_context->circ_buf.buf);
+                                      "%s:Can't get interrupt line", __func__);
+                               kfree(ao_context->circ_buf.buf);
                                kfree(ao_context);
                                release_ao_contexts(info);
                                return -ENODEV;
@@ -888,35 +862,34 @@ static int alloc_ao_contexts(me4000_info_t * info)
        return 0;
 }
 
-static void release_ao_contexts(me4000_info_t * board_info)
+static void release_ao_contexts(struct me4000_info *board_info)
 {
        struct list_head *dac_p;
-       me4000_ao_context_t *ao_context;
+       struct me4000_ao_context *ao_context;
 
        /* Clear analog output context list */
        while (!list_empty(&board_info->ao_context_list)) {
                dac_p = board_info->ao_context_list.next;
-               ao_context = list_entry(dac_p, me4000_ao_context_t, list);
+               ao_context = list_entry(dac_p, struct me4000_ao_context, list);
                free_irq(ao_context->irq, ao_context);
-               if (ao_context->circ_buf.buf)
-                       kfree(ao_context->circ_buf.buf);
+               kfree(ao_context->circ_buf.buf);
                list_del(dac_p);
                kfree(ao_context);
        }
 }
 
-static int alloc_ai_context(me4000_info_t * info)
+static int alloc_ai_context(struct me4000_info *info)
 {
-       me4000_ai_context_t *ai_context;
+       struct me4000_ai_context *ai_context;
 
        if (info->board_p->ai.count) {
-               ai_context = kmalloc(sizeof(me4000_ai_context_t), GFP_KERNEL);
+               ai_context = kzalloc(sizeof(struct me4000_ai_context),
+                                                               GFP_KERNEL);
                if (!ai_context) {
                        printk(KERN_ERR
                               "ME4000:alloc_ai_context():Can't get memory for ai context\n");
                        return -ENOMEM;
                }
-               memset(ai_context, 0, sizeof(me4000_ai_context_t));
 
                info->ai_context = ai_context;
 
@@ -958,18 +931,18 @@ static int alloc_ai_context(me4000_info_t * info)
        return 0;
 }
 
-static int alloc_dio_context(me4000_info_t * info)
+static int alloc_dio_context(struct me4000_info *info)
 {
-       me4000_dio_context_t *dio_context;
+       struct me4000_dio_context *dio_context;
 
        if (info->board_p->dio.count) {
-               dio_context = kmalloc(sizeof(me4000_dio_context_t), GFP_KERNEL);
+               dio_context = kzalloc(sizeof(struct me4000_dio_context),
+                                                               GFP_KERNEL);
                if (!dio_context) {
                        printk(KERN_ERR
                               "ME4000:alloc_dio_context():Can't get memory for dio context\n");
                        return -ENOMEM;
                }
-               memset(dio_context, 0, sizeof(me4000_dio_context_t));
 
                info->dio_context = dio_context;
 
@@ -995,18 +968,18 @@ static int alloc_dio_context(me4000_info_t * info)
        return 0;
 }
 
-static int alloc_cnt_context(me4000_info_t * info)
+static int alloc_cnt_context(struct me4000_info *info)
 {
-       me4000_cnt_context_t *cnt_context;
+       struct me4000_cnt_context *cnt_context;
 
        if (info->board_p->cnt.count) {
-               cnt_context = kmalloc(sizeof(me4000_cnt_context_t), GFP_KERNEL);
+               cnt_context = kzalloc(sizeof(struct me4000_cnt_context),
+                                                               GFP_KERNEL);
                if (!cnt_context) {
                        printk(KERN_ERR
                               "ME4000:alloc_cnt_context():Can't get memory for cnt context\n");
                        return -ENOMEM;
                }
-               memset(cnt_context, 0, sizeof(me4000_cnt_context_t));
 
                info->cnt_context = cnt_context;
 
@@ -1026,19 +999,18 @@ static int alloc_cnt_context(me4000_info_t * info)
        return 0;
 }
 
-static int alloc_ext_int_context(me4000_info_t * info)
+static int alloc_ext_int_context(struct me4000_info *info)
 {
-       me4000_ext_int_context_t *ext_int_context;
+       struct me4000_ext_int_context *ext_int_context;
 
        if (info->board_p->cnt.count) {
                ext_int_context =
-                   kmalloc(sizeof(me4000_ext_int_context_t), GFP_KERNEL);
+                   kzalloc(sizeof(struct me4000_ext_int_context), GFP_KERNEL);
                if (!ext_int_context) {
                        printk(KERN_ERR
                               "ME4000:alloc_ext_int_context():Can't get memory for cnt context\n");
                        return -ENOMEM;
                }
-               memset(ext_int_context, 0, sizeof(me4000_ext_int_context_t));
 
                info->ext_int_context = ext_int_context;
 
@@ -1060,19 +1032,18 @@ static int alloc_ext_int_context(me4000_info_t * info)
 static int me4000_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
        int result = 0;
-       me4000_info_t *board_info;
+       struct me4000_info *board_info;
 
        CALL_PDEBUG("me4000_probe() is executed\n");
 
        /* Allocate structure for board context */
-       board_info = kmalloc(sizeof(me4000_info_t), GFP_KERNEL);
+       board_info = kzalloc(sizeof(struct me4000_info), GFP_KERNEL);
        if (!board_info) {
                printk(KERN_ERR
                       "ME4000:Can't get memory for board info structure\n");
                result = -ENOMEM;
                goto PROBE_ERROR_1;
        }
-       memset(board_info, 0, sizeof(me4000_info_t));
 
        /* Add to global linked list */
        list_add_tail(&board_info->list, &me4000_board_info_list);
@@ -1080,70 +1051,70 @@ static int me4000_probe(struct pci_dev *dev, const struct pci_device_id *id)
        /* Get the PCI base registers */
        result = get_registers(dev, board_info);
        if (result) {
-               printk(KERN_ERR "me4000_probe():Cannot get registers\n");
+               printk(KERN_ERR "%s:Cannot get registers\n", __func__);
                goto PROBE_ERROR_2;
        }
 
        /* Enable the device */
        result = pci_enable_device(dev);
        if (result < 0) {
-               printk(KERN_ERR "me4000_probe():Cannot enable PCI device\n");
+               printk(KERN_ERR "%s:Cannot enable PCI device\n", __func__);
                goto PROBE_ERROR_2;
        }
 
        /* Request the PCI register regions */
        result = pci_request_regions(dev, ME4000_NAME);
        if (result < 0) {
-               printk(KERN_ERR "me4000_probe():Cannot request I/O regions\n");
+               printk(KERN_ERR "%s:Cannot request I/O regions\n", __func__);
                goto PROBE_ERROR_2;
        }
 
        /* Initialize board info */
        result = init_board_info(dev, board_info);
        if (result) {
-               printk(KERN_ERR "me4000_probe():Cannot init baord info\n");
+               printk(KERN_ERR "%s:Cannot init baord info\n", __func__);
                goto PROBE_ERROR_3;
        }
 
        /* Download the xilinx firmware */
        result = me4000_xilinx_download(board_info);
        if (result) {
-               printk(KERN_ERR "me4000_probe:Can't download firmware\n");
+               printk(KERN_ERR "%s:Can't download firmware\n", __func__);
                goto PROBE_ERROR_3;
        }
 
        /* Make a hardware reset */
        result = me4000_reset_board(board_info);
        if (result) {
-               printk(KERN_ERR "me4000_probe:Can't reset board\n");
+               printk(KERN_ERR "%s :Can't reset board\n", __func__);
                goto PROBE_ERROR_3;
        }
 
        /* Allocate analog output context structures */
        result = alloc_ao_contexts(board_info);
        if (result) {
-               printk(KERN_ERR "me4000_probe():Cannot allocate ao contexts\n");
+               printk(KERN_ERR "%s:Cannot allocate ao contexts\n", __func__);
                goto PROBE_ERROR_3;
        }
 
        /* Allocate analog input context */
        result = alloc_ai_context(board_info);
        if (result) {
-               printk(KERN_ERR "me4000_probe():Cannot allocate ai context\n");
+               printk(KERN_ERR "%s:Cannot allocate ai context\n", __func__);
                goto PROBE_ERROR_4;
        }
 
        /* Allocate digital I/O context */
        result = alloc_dio_context(board_info);
        if (result) {
-               printk(KERN_ERR "me4000_probe():Cannot allocate dio context\n");
+               printk(KERN_ERR "%s:Cannot allocate dio context\n", __func__);
                goto PROBE_ERROR_5;
        }
 
        /* Allocate counter context */
        result = alloc_cnt_context(board_info);
        if (result) {
-               printk(KERN_ERR "me4000_probe():Cannot allocate cnt context\n");
+               printk(KERN_ERR "%s:Cannot allocate cnt context\n", __func__);
                goto PROBE_ERROR_6;
        }
 
@@ -1151,36 +1122,36 @@ static int me4000_probe(struct pci_dev *dev, const struct pci_device_id *id)
        result = alloc_ext_int_context(board_info);
        if (result) {
                printk(KERN_ERR
-                      "me4000_probe():Cannot allocate ext_int context\n");
+                      "%s:Cannot allocate ext_int context\n", __func__);
                goto PROBE_ERROR_7;
        }
 
        return 0;
 
-      PROBE_ERROR_7:
+PROBE_ERROR_7:
        kfree(board_info->cnt_context);
 
-      PROBE_ERROR_6:
+PROBE_ERROR_6:
        kfree(board_info->dio_context);
 
-      PROBE_ERROR_5:
+PROBE_ERROR_5:
        kfree(board_info->ai_context);
 
-      PROBE_ERROR_4:
+PROBE_ERROR_4:
        release_ao_contexts(board_info);
 
-      PROBE_ERROR_3:
+PROBE_ERROR_3:
        pci_release_regions(dev);
 
-      PROBE_ERROR_2:
+PROBE_ERROR_2:
        list_del(&board_info->list);
        kfree(board_info);
 
-      PROBE_ERROR_1:
+PROBE_ERROR_1:
        return result;
 }
 
-static int me4000_xilinx_download(me4000_info_t * info)
+static int me4000_xilinx_download(struct me4000_info *info)
 {
        int size = 0;
        u32 value = 0;
@@ -1211,7 +1182,7 @@ static int me4000_xilinx_download(me4000_info_t * info)
        /* Wait until /INIT pin is set */
        udelay(20);
        if (!inl(info->plx_regbase + PLX_INTCSR) & 0x20) {
-               printk(KERN_ERR "me4000_xilinx_download():Can't init Xilinx\n");
+               printk(KERN_ERR "%s:Can't init Xilinx\n", __func__);
                return -EIO;
        }
 
@@ -1232,7 +1203,7 @@ static int me4000_xilinx_download(me4000_info_t * info)
                /* Check if BUSY flag is low */
                if (inl(info->plx_regbase + PLX_ICR) & 0x20) {
                        printk(KERN_ERR
-                              "me4000_xilinx_download():Xilinx is still busy (idx = %d)\n",
+                              "%s:Xilinx is still busy (idx = %d)\n", __func__,
                               idx);
                        return -EIO;
                }
@@ -1246,9 +1217,9 @@ static int me4000_xilinx_download(me4000_info_t * info)
                PDEBUG("me4000_xilinx_download():Download was successful\n");
        } else {
                printk(KERN_ERR
-                      "ME4000:me4000_xilinx_download():DONE flag is not set\n");
+                      "ME4000:%s:DONE flag is not set\n", __func__);
                printk(KERN_ERR
-                      "ME4000:me4000_xilinx_download():Download not succesful\n");
+                      "ME4000:%s:Download not succesful\n", __func__);
                return -EIO;
        }
 
@@ -1260,7 +1231,7 @@ static int me4000_xilinx_download(me4000_info_t * info)
        return 0;
 }
 
-static int me4000_reset_board(me4000_info_t * info)
+static int me4000_reset_board(struct me4000_info *info)
 {
        unsigned long icr;
 
@@ -1314,12 +1285,12 @@ static int me4000_open(struct inode *inode_p, struct file *file_p)
        int err = 0;
        int i;
        struct list_head *ptr;
-       me4000_info_t *board_info = NULL;
-       me4000_ao_context_t *ao_context = NULL;
-       me4000_ai_context_t *ai_context = NULL;
-       me4000_dio_context_t *dio_context = NULL;
-       me4000_cnt_context_t *cnt_context = NULL;
-       me4000_ext_int_context_t *ext_int_context = NULL;
+       struct me4000_info *board_info = NULL;
+       struct me4000_ao_context *ao_context = NULL;
+       struct me4000_ai_context *ai_context = NULL;
+       struct me4000_dio_context *dio_context = NULL;
+       struct me4000_cnt_context *cnt_context = NULL;
+       struct me4000_ext_int_context *ext_int_context = NULL;
 
        CALL_PDEBUG("me4000_open() is executed\n");
 
@@ -1335,7 +1306,7 @@ static int me4000_open(struct inode *inode_p, struct file *file_p)
                /* Search for the board context */
                for (ptr = me4000_board_info_list.next, i = 0;
                     ptr != &me4000_board_info_list; ptr = ptr->next, i++) {
-                       board_info = list_entry(ptr, me4000_info_t, list);
+                       board_info = list_entry(ptr, struct me4000_info, list);
                        if (i == board)
                                break;
                }
@@ -1351,7 +1322,8 @@ static int me4000_open(struct inode *inode_p, struct file *file_p)
                for (ptr = board_info->ao_context_list.next, i = 0;
                     ptr != &board_info->ao_context_list;
                     ptr = ptr->next, i++) {
-                       ao_context = list_entry(ptr, me4000_ao_context_t, list);
+                       ao_context = list_entry(ptr, struct me4000_ao_context,
+                                                                       list);
                        if (i == dev)
                                break;
                }
@@ -1415,7 +1387,7 @@ static int me4000_open(struct inode *inode_p, struct file *file_p)
                /* Search for the board context */
                for (ptr = me4000_board_info_list.next, i = 0;
                     ptr != &me4000_board_info_list; ptr = ptr->next, i++) {
-                       board_info = list_entry(ptr, me4000_info_t, list);
+                       board_info = list_entry(ptr, struct me4000_info, list);
                        if (i == board)
                                break;
                }
@@ -1469,7 +1441,7 @@ static int me4000_open(struct inode *inode_p, struct file *file_p)
                /* Search for the board context */
                for (ptr = me4000_board_info_list.next;
                     ptr != &me4000_board_info_list; ptr = ptr->next) {
-                       board_info = list_entry(ptr, me4000_info_t, list);
+                       board_info = list_entry(ptr, struct me4000_info, list);
                        if (board_info->board_count == board)
                                break;
                }
@@ -1514,7 +1486,7 @@ static int me4000_open(struct inode *inode_p, struct file *file_p)
                /* Search for the board context */
                for (ptr = me4000_board_info_list.next;
                     ptr != &me4000_board_info_list; ptr = ptr->next) {
-                       board_info = list_entry(ptr, me4000_info_t, list);
+                       board_info = list_entry(ptr, struct me4000_info, list);
                        if (board_info->board_count == board)
                                break;
                }
@@ -1557,7 +1529,7 @@ static int me4000_open(struct inode *inode_p, struct file *file_p)
                /* Search for the board context */
                for (ptr = me4000_board_info_list.next;
                     ptr != &me4000_board_info_list; ptr = ptr->next) {
-                       board_info = list_entry(ptr, me4000_info_t, list);
+                       board_info = list_entry(ptr, struct me4000_info, list);
                        if (board_info->board_count == board)
                                break;
                }
@@ -1613,11 +1585,11 @@ static int me4000_open(struct inode *inode_p, struct file *file_p)
 
 static int me4000_release(struct inode *inode_p, struct file *file_p)
 {
-       me4000_ao_context_t *ao_context;
-       me4000_ai_context_t *ai_context;
-       me4000_dio_context_t *dio_context;
-       me4000_cnt_context_t *cnt_context;
-       me4000_ext_int_context_t *ext_int_context;
+       struct me4000_ao_context *ao_context;
+       struct me4000_ai_context *ai_context;
+       struct me4000_dio_context *dio_context;
+       struct me4000_cnt_context *cnt_context;
+       struct me4000_ext_int_context *ext_int_context;
 
        CALL_PDEBUG("me4000_release() is executed\n");
 
@@ -1677,7 +1649,7 @@ static int me4000_release(struct inode *inode_p, struct file *file_p)
 
 /*------------------------------- Analog output stuff --------------------------------------*/
 
-static int me4000_ao_prepare(me4000_ao_context_t * ao_context)
+static int me4000_ao_prepare(struct me4000_ao_context *ao_context)
 {
        unsigned long flags;
 
@@ -1756,7 +1728,7 @@ static int me4000_ao_prepare(me4000_ao_context_t * ao_context)
        return 0;
 }
 
-static int me4000_ao_reset(me4000_ao_context_t * ao_context)
+static int me4000_ao_reset(struct me4000_ao_context *ao_context)
 {
        u32 tmp;
        wait_queue_head_t queue;
@@ -1777,9 +1749,10 @@ static int me4000_ao_reset(me4000_ao_context_t * ao_context)
                tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP;
                me4000_outl(tmp, ao_context->ctrl_reg);
 
-               while (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) {
-                       sleep_on_timeout(&queue, 1);
-               }
+               wait_event_timeout(queue,
+                       (inl(ao_context->status_reg) &
+                               ME4000_AO_STATUS_BIT_FSM) == 0,
+                       1);
 
                /* Set to transparent mode */
                me4000_ao_simultaneous_disable(ao_context);
@@ -1812,9 +1785,10 @@ static int me4000_ao_reset(me4000_ao_context_t * ao_context)
                me4000_outl(tmp, ao_context->ctrl_reg);
                spin_unlock_irqrestore(&ao_context->int_lock, flags);
 
-               while (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) {
-                       sleep_on_timeout(&queue, 1);
-               }
+               wait_event_timeout(queue,
+                       (inl(ao_context->status_reg) &
+                               ME4000_AO_STATUS_BIT_FSM) == 0,
+                       1);
 
                /* Clear the circular buffer */
                ao_context->circ_buf.head = 0;
@@ -1853,9 +1827,9 @@ static int me4000_ao_reset(me4000_ao_context_t * ao_context)
 }
 
 static ssize_t me4000_ao_write_sing(struct file *filep, const char *buff,
-                                   size_t cnt, loff_t * offp)
+                                   size_t cnt, loff_t *offp)
 {
-       me4000_ao_context_t *ao_context = filep->private_data;
+       struct me4000_ao_context *ao_context = filep->private_data;
        u32 value;
        const u16 *buffer = (const u16 *)buff;
 
@@ -1863,13 +1837,13 @@ static ssize_t me4000_ao_write_sing(struct file *filep, const char *buff,
 
        if (cnt != 2) {
                printk(KERN_ERR
-                      "me4000_ao_write_sing():Write count is not 2\n");
+                      "%s:Write count is not 2\n", __func__);
                return -EINVAL;
        }
 
        if (get_user(value, buffer)) {
                printk(KERN_ERR
-                      "me4000_ao_write_sing():Cannot copy data from user\n");
+                      "%s:Cannot copy data from user\n", __func__);
                return -EFAULT;
        }
 
@@ -1879,9 +1853,9 @@ static ssize_t me4000_ao_write_sing(struct file *filep, const char *buff,
 }
 
 static ssize_t me4000_ao_write_wrap(struct file *filep, const char *buff,
-                                   size_t cnt, loff_t * offp)
+                                   size_t cnt, loff_t *offp)
 {
-       me4000_ao_context_t *ao_context = filep->private_data;
+       struct me4000_ao_context *ao_context = filep->private_data;
        size_t i;
        u32 value;
        u32 tmp;
@@ -1893,13 +1867,13 @@ static ssize_t me4000_ao_write_wrap(struct file *filep, const char *buff,
        /* Check if a conversion is already running */
        if (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) {
                printk(KERN_ERR
-                      "ME4000:me4000_ao_write_wrap():There is already a conversion running\n");
+                      "%s:There is already a conversion running\n", __func__);
                return -EBUSY;
        }
 
        if (count > ME4000_AO_FIFO_COUNT) {
                printk(KERN_ERR
-                      "me4000_ao_write_wrap():Can't load more than %d values\n",
+                      "%s:Can't load more than %d values\n", __func__,
                       ME4000_AO_FIFO_COUNT);
                return -ENOSPC;
        }
@@ -1914,7 +1888,7 @@ static ssize_t me4000_ao_write_wrap(struct file *filep, const char *buff,
        for (i = 0; i < count; i++) {
                if (get_user(value, buffer + i)) {
                        printk(KERN_ERR
-                              "me4000_ao_write_single():Cannot copy data from user\n");
+                              "%s:Cannot copy data from user\n", __func__);
                        return -EFAULT;
                }
                if (((ao_context->fifo_reg & 0xFF) == ME4000_AO_01_FIFO_REG)
@@ -1928,9 +1902,9 @@ static ssize_t me4000_ao_write_wrap(struct file *filep, const char *buff,
 }
 
 static ssize_t me4000_ao_write_cont(struct file *filep, const char *buff,
-                                   size_t cnt, loff_t * offp)
+                                   size_t cnt, loff_t *offp)
 {
-       me4000_ao_context_t *ao_context = filep->private_data;
+       struct me4000_ao_context *ao_context = filep->private_data;
        const u16 *buffer = (const u16 *)buff;
        size_t count = cnt / 2;
        unsigned long flags;
@@ -2154,9 +2128,9 @@ static ssize_t me4000_ao_write_cont(struct file *filep, const char *buff,
        return 2 * ret;
 }
 
-static unsigned int me4000_ao_poll_cont(struct file *file_p, poll_table * wait)
+static unsigned int me4000_ao_poll_cont(struct file *file_p, poll_table *wait)
 {
-       me4000_ao_context_t *ao_context;
+       struct me4000_ao_context *ao_context;
        unsigned long mask = 0;
 
        CALL_PDEBUG("me4000_ao_poll_cont() is executed\n");
@@ -2177,7 +2151,7 @@ static unsigned int me4000_ao_poll_cont(struct file *file_p, poll_table * wait)
 static int me4000_ao_fsync_cont(struct file *file_p, struct dentry *dentry_p,
                                int datasync)
 {
-       me4000_ao_context_t *ao_context;
+       struct me4000_ao_context *ao_context;
        wait_queue_head_t queue;
 
        CALL_PDEBUG("me4000_ao_fsync_cont() is executed\n");
@@ -2187,15 +2161,19 @@ static int me4000_ao_fsync_cont(struct file *file_p, struct dentry *dentry_p,
 
        while (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) {
                interruptible_sleep_on_timeout(&queue, 1);
+                       wait_event_interruptible_timeout(queue,
+                       !(inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM),
+                       1);
                if (ao_context->pipe_flag) {
                        printk(KERN_ERR
-                              "me4000_ao_fsync_cont():Broken pipe detected\n");
+                              "%s:Broken pipe detected\n", __func__);
                        return -EPIPE;
                }
 
                if (signal_pending(current)) {
                        printk(KERN_ERR
-                              "me4000_ao_fsync_cont():Wait on state machine interrupted\n");
+                              "%s:Wait on state machine interrupted\n",
+                              __func__);
                        return -EINTR;
                }
        }
@@ -2206,7 +2184,7 @@ static int me4000_ao_fsync_cont(struct file *file_p, struct dentry *dentry_p,
 static int me4000_ao_ioctl_sing(struct inode *inode_p, struct file *file_p,
                                unsigned int service, unsigned long arg)
 {
-       me4000_ao_context_t *ao_context;
+       struct me4000_ao_context *ao_context;
 
        CALL_PDEBUG("me4000_ao_ioctl_sing() is executed\n");
 
@@ -2229,7 +2207,7 @@ static int me4000_ao_ioctl_sing(struct inode *inode_p, struct file *file_p,
        case ME4000_AO_PRELOAD_UPDATE:
                return me4000_ao_preload_update(ao_context);
        case ME4000_GET_USER_INFO:
-               return me4000_get_user_info((me4000_user_info_t *) arg,
+               return me4000_get_user_info((struct me4000_user_info *)arg,
                                            ao_context->board_info);
        case ME4000_AO_SIMULTANEOUS_EX_TRIG:
                return me4000_ao_simultaneous_ex_trig(ao_context);
@@ -2239,8 +2217,9 @@ static int me4000_ao_ioctl_sing(struct inode *inode_p, struct file *file_p,
                return me4000_ao_simultaneous_disable(ao_context);
        case ME4000_AO_SIMULTANEOUS_UPDATE:
                return
-                   me4000_ao_simultaneous_update((me4000_ao_channel_list_t *)
-                                                 arg, ao_context);
+                   me4000_ao_simultaneous_update(
+                               (struct me4000_ao_channel_list *)arg,
+                               ao_context);
        case ME4000_AO_EX_TRIG_TIMEOUT:
                return me4000_ao_ex_trig_timeout((unsigned long *)arg,
                                                 ao_context);
@@ -2258,7 +2237,7 @@ static int me4000_ao_ioctl_sing(struct inode *inode_p, struct file *file_p,
 static int me4000_ao_ioctl_wrap(struct inode *inode_p, struct file *file_p,
                                unsigned int service, unsigned long arg)
 {
-       me4000_ao_context_t *ao_context;
+       struct me4000_ao_context *ao_context;
 
        CALL_PDEBUG("me4000_ao_ioctl_wrap() is executed\n");
 
@@ -2287,7 +2266,7 @@ static int me4000_ao_ioctl_wrap(struct inode *inode_p, struct file *file_p,
        case ME4000_AO_EX_TRIG_DISABLE:
                return me4000_ao_ex_trig_disable(ao_context);
        case ME4000_GET_USER_INFO:
-               return me4000_get_user_info((me4000_user_info_t *) arg,
+               return me4000_get_user_info((struct me4000_user_info *)arg,
                                            ao_context->board_info);
        case ME4000_AO_FSM_STATE:
                return me4000_ao_fsm_state((int *)arg, ao_context);
@@ -2310,7 +2289,7 @@ static int me4000_ao_ioctl_wrap(struct inode *inode_p, struct file *file_p,
 static int me4000_ao_ioctl_cont(struct inode *inode_p, struct file *file_p,
                                unsigned int service, unsigned long arg)
 {
-       me4000_ao_context_t *ao_context;
+       struct me4000_ao_context *ao_context;
 
        CALL_PDEBUG("me4000_ao_ioctl_cont() is executed\n");
 
@@ -2345,7 +2324,7 @@ static int me4000_ao_ioctl_cont(struct inode *inode_p, struct file *file_p,
        case ME4000_AO_FSM_STATE:
                return me4000_ao_fsm_state((int *)arg, ao_context);
        case ME4000_GET_USER_INFO:
-               return me4000_get_user_info((me4000_user_info_t *) arg,
+               return me4000_get_user_info((struct me4000_user_info *)arg,
                                            ao_context->board_info);
        case ME4000_AO_SYNCHRONOUS_EX_TRIG:
                return me4000_ao_synchronous_ex_trig(ao_context);
@@ -2362,7 +2341,8 @@ static int me4000_ao_ioctl_cont(struct inode *inode_p, struct file *file_p,
        return 0;
 }
 
-static int me4000_ao_start(unsigned long *arg, me4000_ao_context_t * ao_context)
+static int me4000_ao_start(unsigned long *arg,
+                          struct me4000_ao_context *ao_context)
 {
        u32 tmp;
        wait_queue_head_t queue;
@@ -2412,7 +2392,7 @@ static int me4000_ao_start(unsigned long *arg, me4000_ao_context_t * ao_context)
        return 0;
 }
 
-static int me4000_ao_stop(me4000_ao_context_t * ao_context)
+static int me4000_ao_stop(struct me4000_ao_context *ao_context)
 {
        u32 tmp;
        wait_queue_head_t queue;
@@ -2445,7 +2425,7 @@ static int me4000_ao_stop(me4000_ao_context_t * ao_context)
        return 0;
 }
 
-static int me4000_ao_immediate_stop(me4000_ao_context_t * ao_context)
+static int me4000_ao_immediate_stop(struct me4000_ao_context *ao_context)
 {
        u32 tmp;
        wait_queue_head_t queue;
@@ -2477,8 +2457,8 @@ static int me4000_ao_immediate_stop(me4000_ao_context_t * ao_context)
        return 0;
 }
 
-static int me4000_ao_timer_set_divisor(u32 * arg,
-                                      me4000_ao_context_t * ao_context)
+static int me4000_ao_timer_set_divisor(u32 *arg,
+                                      struct me4000_ao_context *ao_context)
 {
        u32 divisor;
        u32 tmp;
@@ -2518,7 +2498,7 @@ static int me4000_ao_timer_set_divisor(u32 * arg,
 }
 
 static int me4000_ao_ex_trig_set_edge(int *arg,
-                                     me4000_ao_context_t * ao_context)
+                                     struct me4000_ao_context *ao_context)
 {
        int mode;
        u32 tmp;
@@ -2569,7 +2549,7 @@ static int me4000_ao_ex_trig_set_edge(int *arg,
        return 0;
 }
 
-static int me4000_ao_ex_trig_enable(me4000_ao_context_t * ao_context)
+static int me4000_ao_ex_trig_enable(struct me4000_ao_context *ao_context)
 {
        u32 tmp;
        unsigned long flags;
@@ -2593,7 +2573,7 @@ static int me4000_ao_ex_trig_enable(me4000_ao_context_t * ao_context)
        return 0;
 }
 
-static int me4000_ao_ex_trig_disable(me4000_ao_context_t * ao_context)
+static int me4000_ao_ex_trig_disable(struct me4000_ao_context *ao_context)
 {
        u32 tmp;
        unsigned long flags;
@@ -2617,7 +2597,7 @@ static int me4000_ao_ex_trig_disable(me4000_ao_context_t * ao_context)
        return 0;
 }
 
-static int me4000_ao_simultaneous_disable(me4000_ao_context_t * ao_context)
+static int me4000_ao_simultaneous_disable(struct me4000_ao_context *ao_context)
 {
        u32 tmp;
 
@@ -2643,7 +2623,7 @@ static int me4000_ao_simultaneous_disable(me4000_ao_context_t * ao_context)
        return 0;
 }
 
-static int me4000_ao_simultaneous_ex_trig(me4000_ao_context_t * ao_context)
+static int me4000_ao_simultaneous_ex_trig(struct me4000_ao_context *ao_context)
 {
        u32 tmp;
 
@@ -2659,7 +2639,7 @@ static int me4000_ao_simultaneous_ex_trig(me4000_ao_context_t * ao_context)
        return 0;
 }
 
-static int me4000_ao_simultaneous_sw(me4000_ao_context_t * ao_context)
+static int me4000_ao_simultaneous_sw(struct me4000_ao_context *ao_context)
 {
        u32 tmp;
 
@@ -2675,13 +2655,13 @@ static int me4000_ao_simultaneous_sw(me4000_ao_context_t * ao_context)
        return 0;
 }
 
-static int me4000_ao_preload(me4000_ao_context_t * ao_context)
+static int me4000_ao_preload(struct me4000_ao_context *ao_context)
 {
        CALL_PDEBUG("me4000_ao_preload() is executed\n");
        return me4000_ao_simultaneous_sw(ao_context);
 }
 
-static int me4000_ao_preload_update(me4000_ao_context_t * ao_context)
+static int me4000_ao_preload_update(struct me4000_ao_context *ao_context)
 {
        u32 tmp;
        u32 ctrl;
@@ -2705,10 +2685,12 @@ static int me4000_ao_preload_update(me4000_ao_context_t * ao_context)
                        if (!
                            (tmp &
                             (0x1 <<
-                             (((me4000_ao_context_t *) entry)->index + 16)))) {
+                             (((struct me4000_ao_context *)entry)->index
+                                                                     + 16)))) {
                                tmp &=
                                    ~(0x1 <<
-                                     (((me4000_ao_context_t *) entry)->index));
+                                     (((struct me4000_ao_context *)entry)->
+                                                                       index));
                        }
                }
        }
@@ -2718,18 +2700,19 @@ static int me4000_ao_preload_update(me4000_ao_context_t * ao_context)
        return 0;
 }
 
-static int me4000_ao_simultaneous_update(me4000_ao_channel_list_t * arg,
-                                        me4000_ao_context_t * ao_context)
+static int me4000_ao_simultaneous_update(struct me4000_ao_channel_list *arg,
+                                        struct me4000_ao_context *ao_context)
 {
        int err;
        int i;
        u32 tmp;
-       me4000_ao_channel_list_t channels;
+       struct me4000_ao_channel_list channels;
 
        CALL_PDEBUG("me4000_ao_simultaneous_update() is executed\n");
 
        /* Copy data from user */
-       err = copy_from_user(&channels, arg, sizeof(me4000_ao_channel_list_t));
+       err = copy_from_user(&channels, arg,
+                       sizeof(struct me4000_ao_channel_list));
        if (err) {
                printk(KERN_ERR
                       "ME4000:me4000_ao_simultaneous_update():Can't copy command\n");
@@ -2737,13 +2720,12 @@ static int me4000_ao_simultaneous_update(me4000_ao_channel_list_t * arg,
        }
 
        channels.list =
-           kmalloc(sizeof(unsigned long) * channels.count, GFP_KERNEL);
+           kzalloc(sizeof(unsigned long) * channels.count, GFP_KERNEL);
        if (!channels.list) {
                printk(KERN_ERR
                       "ME4000:me4000_ao_simultaneous_update():Can't get buffer\n");
                return -ENOMEM;
        }
-       memset(channels.list, 0, sizeof(unsigned long) * channels.count);
 
        /* Copy channel list from user */
        err =
@@ -2777,7 +2759,7 @@ static int me4000_ao_simultaneous_update(me4000_ao_channel_list_t * arg,
        return 0;
 }
 
-static int me4000_ao_synchronous_ex_trig(me4000_ao_context_t * ao_context)
+static int me4000_ao_synchronous_ex_trig(struct me4000_ao_context *ao_context)
 {
        u32 tmp;
        unsigned long flags;
@@ -2813,7 +2795,7 @@ static int me4000_ao_synchronous_ex_trig(me4000_ao_context_t * ao_context)
        return 0;
 }
 
-static int me4000_ao_synchronous_sw(me4000_ao_context_t * ao_context)
+static int me4000_ao_synchronous_sw(struct me4000_ao_context *ao_context)
 {
        u32 tmp;
        unsigned long flags;
@@ -2848,13 +2830,13 @@ static int me4000_ao_synchronous_sw(me4000_ao_context_t * ao_context)
        return 0;
 }
 
-static int me4000_ao_synchronous_disable(me4000_ao_context_t * ao_context)
+static int me4000_ao_synchronous_disable(struct me4000_ao_context *ao_context)
 {
        return me4000_ao_simultaneous_disable(ao_context);
 }
 
 static int me4000_ao_get_free_buffer(unsigned long *arg,
-                                    me4000_ao_context_t * ao_context)
+                                    struct me4000_ao_context *ao_context)
 {
        unsigned long c;
        int err;
@@ -2864,7 +2846,7 @@ static int me4000_ao_get_free_buffer(unsigned long *arg,
        err = copy_to_user(arg, &c, sizeof(unsigned long));
        if (err) {
                printk(KERN_ERR
-                      "ME4000:me4000_ao_get_free_buffer():Can't copy to user space\n");
+                      "%s:Can't copy to user space\n", __func__);
                return -EFAULT;
        }
 
@@ -2872,7 +2854,7 @@ static int me4000_ao_get_free_buffer(unsigned long *arg,
 }
 
 static int me4000_ao_ex_trig_timeout(unsigned long *arg,
-                                    me4000_ao_context_t * ao_context)
+                                    struct me4000_ao_context *ao_context)
 {
        u32 tmp;
        wait_queue_head_t queue;
@@ -2928,7 +2910,7 @@ static int me4000_ao_ex_trig_timeout(unsigned long *arg,
        return 0;
 }
 
-static int me4000_ao_enable_do(me4000_ao_context_t * ao_context)
+static int me4000_ao_enable_do(struct me4000_ao_context *ao_context)
 {
        u32 tmp;
        unsigned long flags;
@@ -2959,7 +2941,7 @@ static int me4000_ao_enable_do(me4000_ao_context_t * ao_context)
        return 0;
 }
 
-static int me4000_ao_disable_do(me4000_ao_context_t * ao_context)
+static int me4000_ao_disable_do(struct me4000_ao_context *ao_context)
 {
        u32 tmp;
        unsigned long flags;
@@ -2989,7 +2971,7 @@ static int me4000_ao_disable_do(me4000_ao_context_t * ao_context)
        return 0;
 }
 
-static int me4000_ao_fsm_state(int *arg, me4000_ao_context_t * ao_context)
+static int me4000_ao_fsm_state(int *arg, struct me4000_ao_context *ao_context)
 {
        unsigned long tmp;
 
@@ -3012,9 +2994,9 @@ static int me4000_ao_fsm_state(int *arg, me4000_ao_context_t * ao_context)
        return 0;
 }
 
-/*------------------------------- Analog input stuff --------------------------------------*/
+/*------------------------- Analog input stuff -------------------------------*/
 
-static int me4000_ai_prepare(me4000_ai_context_t * ai_context)
+static int me4000_ai_prepare(struct me4000_ai_context *ai_context)
 {
        wait_queue_head_t queue;
        int err;
@@ -3057,14 +3039,13 @@ static int me4000_ai_prepare(me4000_ai_context_t * ai_context)
 
                /* Allocate circular buffer */
                ai_context->circ_buf.buf =
-                   kmalloc(ME4000_AI_BUFFER_SIZE, GFP_KERNEL);
+                   kzalloc(ME4000_AI_BUFFER_SIZE, GFP_KERNEL);
                if (!ai_context->circ_buf.buf) {
                        printk(KERN_ERR
                               "ME4000:me4000_ai_prepare():Can't get circular buffer\n");
                        free_irq(ai_context->irq, ai_context);
                        return -ENOMEM;
                }
-               memset(ai_context->circ_buf.buf, 0, ME4000_AI_BUFFER_SIZE);
 
                /* Clear the circular buffer */
                ai_context->circ_buf.head = 0;
@@ -3074,7 +3055,7 @@ static int me4000_ai_prepare(me4000_ai_context_t * ai_context)
        return 0;
 }
 
-static int me4000_ai_reset(me4000_ai_context_t * ai_context)
+static int me4000_ai_reset(struct me4000_ai_context *ai_context)
 {
        wait_queue_head_t queue;
        u32 tmp;
@@ -3139,7 +3120,7 @@ static int me4000_ai_reset(me4000_ai_context_t * ai_context)
 static int me4000_ai_ioctl_sing(struct inode *inode_p, struct file *file_p,
                                unsigned int service, unsigned long arg)
 {
-       me4000_ai_context_t *ai_context;
+       struct me4000_ai_context *ai_context;
 
        CALL_PDEBUG("me4000_ai_ioctl_sing() is executed\n");
 
@@ -3157,16 +3138,17 @@ static int me4000_ai_ioctl_sing(struct inode *inode_p, struct file *file_p,
 
        switch (service) {
        case ME4000_AI_SINGLE:
-               return me4000_ai_single((me4000_ai_single_t *) arg, ai_context);
+               return me4000_ai_single((struct me4000_ai_single *)arg,
+                                                               ai_context);
        case ME4000_AI_EX_TRIG_ENABLE:
                return me4000_ai_ex_trig_enable(ai_context);
        case ME4000_AI_EX_TRIG_DISABLE:
                return me4000_ai_ex_trig_disable(ai_context);
        case ME4000_AI_EX_TRIG_SETUP:
-               return me4000_ai_ex_trig_setup((me4000_ai_trigger_t *) arg,
+               return me4000_ai_ex_trig_setup((struct me4000_ai_trigger *)arg,
                                               ai_context);
        case ME4000_GET_USER_INFO:
-               return me4000_get_user_info((me4000_user_info_t *) arg,
+               return me4000_get_user_info((struct me4000_user_info *)arg,
                                            ai_context->board_info);
        case ME4000_AI_OFFSET_ENABLE:
                return me4000_ai_offset_enable(ai_context);
@@ -3177,9 +3159,11 @@ static int me4000_ai_ioctl_sing(struct inode *inode_p, struct file *file_p,
        case ME4000_AI_FULLSCALE_DISABLE:
                return me4000_ai_fullscale_disable(ai_context);
        case ME4000_AI_EEPROM_READ:
-               return me4000_eeprom_read((me4000_eeprom_t *) arg, ai_context);
+               return me4000_eeprom_read((struct me4000_eeprom *)arg,
+                                                               ai_context);
        case ME4000_AI_EEPROM_WRITE:
-               return me4000_eeprom_write((me4000_eeprom_t *) arg, ai_context);
+               return me4000_eeprom_write((struct me4000_eeprom *)arg,
+                                                               ai_context);
        default:
                printk(KERN_ERR
                       "me4000_ai_ioctl_sing():Invalid service number\n");
@@ -3188,10 +3172,10 @@ static int me4000_ai_ioctl_sing(struct inode *inode_p, struct file *file_p,
        return 0;
 }
 
-static int me4000_ai_single(me4000_ai_single_t * arg,
-                           me4000_ai_context_t * ai_context)
+static int me4000_ai_single(struct me4000_ai_single *arg,
+                           struct me4000_ai_context *ai_context)
 {
-       me4000_ai_single_t cmd;
+       struct me4000_ai_single cmd;
        int err;
        u32 tmp;
        wait_queue_head_t queue;
@@ -3202,7 +3186,7 @@ static int me4000_ai_single(me4000_ai_single_t * arg,
        init_waitqueue_head(&queue);
 
        /* Copy data from user */
-       err = copy_from_user(&cmd, arg, sizeof(me4000_ai_single_t));
+       err = copy_from_user(&cmd, arg, sizeof(struct me4000_ai_single));
        if (err) {
                printk(KERN_ERR
                       "ME4000:me4000_ai_single():Can't copy from user space\n");
@@ -3301,7 +3285,7 @@ static int me4000_ai_single(me4000_ai_single_t * arg,
        cmd.value = me4000_inl(ai_context->data_reg) & 0xFFFF;
 
        /* Copy result back to user */
-       err = copy_to_user(arg, &cmd, sizeof(me4000_ai_single_t));
+       err = copy_to_user(arg, &cmd, sizeof(struct me4000_ai_single));
        if (err) {
                printk(KERN_ERR
                       "ME4000:me4000_ai_single():Can't copy to user space\n");
@@ -3314,7 +3298,7 @@ static int me4000_ai_single(me4000_ai_single_t * arg,
 static int me4000_ai_ioctl_sw(struct inode *inode_p, struct file *file_p,
                              unsigned int service, unsigned long arg)
 {
-       me4000_ai_context_t *ai_context;
+       struct me4000_ai_context *ai_context;
 
        CALL_PDEBUG("me4000_ai_ioctl_sw() is executed\n");
 
@@ -3332,9 +3316,11 @@ static int me4000_ai_ioctl_sw(struct inode *inode_p, struct file *file_p,
 
        switch (service) {
        case ME4000_AI_SC_SETUP:
-               return me4000_ai_sc_setup((me4000_ai_sc_t *) arg, ai_context);
+               return me4000_ai_sc_setup((struct me4000_ai_sc *)arg,
+                                                               ai_context);
        case ME4000_AI_CONFIG:
-               return me4000_ai_config((me4000_ai_config_t *) arg, ai_context);
+               return me4000_ai_config((struct me4000_ai_config *)arg,
+                                                               ai_context);
        case ME4000_AI_START:
                return me4000_ai_start(ai_context);
        case ME4000_AI_STOP:
@@ -3344,19 +3330,20 @@ static int me4000_ai_ioctl_sw(struct inode *inode_p, struct file *file_p,
        case ME4000_AI_FSM_STATE:
                return me4000_ai_fsm_state((int *)arg, ai_context);
        case ME4000_GET_USER_INFO:
-               return me4000_get_user_info((me4000_user_info_t *) arg,
+               return me4000_get_user_info((struct me4000_user_info *)arg,
                                            ai_context->board_info);
        case ME4000_AI_EEPROM_READ:
-               return me4000_eeprom_read((me4000_eeprom_t *) arg, ai_context);
+               return me4000_eeprom_read((struct me4000_eeprom *)arg,
+                                                               ai_context);
        case ME4000_AI_EEPROM_WRITE:
-               return me4000_eeprom_write((me4000_eeprom_t *) arg, ai_context);
+               return me4000_eeprom_write((struct me4000_eeprom *)arg,
+                                                               ai_context);
        case ME4000_AI_GET_COUNT_BUFFER:
                return me4000_ai_get_count_buffer((unsigned long *)arg,
                                                  ai_context);
        default:
                printk(KERN_ERR
-                      "ME4000:me4000_ai_ioctl_sw():Invalid service number %d\n",
-                      service);
+                      "%s:Invalid service number %d\n", __func__, service);
                return -ENOTTY;
        }
        return 0;
@@ -3365,7 +3352,7 @@ static int me4000_ai_ioctl_sw(struct inode *inode_p, struct file *file_p,
 static int me4000_ai_ioctl_ext(struct inode *inode_p, struct file *file_p,
                               unsigned int service, unsigned long arg)
 {
-       me4000_ai_context_t *ai_context;
+       struct me4000_ai_context *ai_context;
 
        CALL_PDEBUG("me4000_ai_ioctl_ext() is executed\n");
 
@@ -3383,9 +3370,11 @@ static int me4000_ai_ioctl_ext(struct inode *inode_p, struct file *file_p,
 
        switch (service) {
        case ME4000_AI_SC_SETUP:
-               return me4000_ai_sc_setup((me4000_ai_sc_t *) arg, ai_context);
+               return me4000_ai_sc_setup((struct me4000_ai_sc *)arg,
+                                                               ai_context);
        case ME4000_AI_CONFIG:
-               return me4000_ai_config((me4000_ai_config_t *) arg, ai_context);
+               return me4000_ai_config((struct me4000_ai_config *)arg,
+                                                               ai_context);
        case ME4000_AI_START:
                return me4000_ai_start_ex((unsigned long *)arg, ai_context);
        case ME4000_AI_STOP:
@@ -3397,20 +3386,19 @@ static int me4000_ai_ioctl_ext(struct inode *inode_p, struct file *file_p,
        case ME4000_AI_EX_TRIG_DISABLE:
                return me4000_ai_ex_trig_disable(ai_context);
        case ME4000_AI_EX_TRIG_SETUP:
-               return me4000_ai_ex_trig_setup((me4000_ai_trigger_t *) arg,
+               return me4000_ai_ex_trig_setup((struct me4000_ai_trigger *)arg,
                                               ai_context);
        case ME4000_AI_FSM_STATE:
                return me4000_ai_fsm_state((int *)arg, ai_context);
        case ME4000_GET_USER_INFO:
-               return me4000_get_user_info((me4000_user_info_t *) arg,
+               return me4000_get_user_info((struct me4000_user_info *)arg,
                                            ai_context->board_info);
        case ME4000_AI_GET_COUNT_BUFFER:
                return me4000_ai_get_count_buffer((unsigned long *)arg,
                                                  ai_context);
        default:
                printk(KERN_ERR
-                      "ME4000:me4000_ai_ioctl_ext():Invalid service number %d\n",
-                      service);
+                      "%s:Invalid service number %d\n", __func__ , service);
                return -ENOTTY;
        }
        return 0;
@@ -3418,7 +3406,7 @@ static int me4000_ai_ioctl_ext(struct inode *inode_p, struct file *file_p,
 
 static int me4000_ai_fasync(int fd, struct file *file_p, int mode)
 {
-       me4000_ai_context_t *ai_context;
+       struct me4000_ai_context *ai_context;
 
        CALL_PDEBUG("me4000_ao_fasync_cont() is executed\n");
 
@@ -3426,10 +3414,10 @@ static int me4000_ai_fasync(int fd, struct file *file_p, int mode)
        return fasync_helper(fd, file_p, mode, &ai_context->fasync_p);
 }
 
-static int me4000_ai_config(me4000_ai_config_t * arg,
-                           me4000_ai_context_t * ai_context)
+static int me4000_ai_config(struct me4000_ai_config *arg,
+                           struct me4000_ai_context *ai_context)
 {
-       me4000_ai_config_t cmd;
+       struct me4000_ai_config cmd;
        u32 *list = NULL;
        u32 mode;
        int i;
@@ -3451,7 +3439,7 @@ static int me4000_ai_config(me4000_ai_config_t * arg,
        }
 
        /* Copy data from user */
-       err = copy_from_user(&cmd, arg, sizeof(me4000_ai_config_t));
+       err = copy_from_user(&cmd, arg, sizeof(struct me4000_ai_config));
        if (err) {
                printk(KERN_ERR
                       "ME4000:me4000_ai_config():Can't copy from user space\n");
@@ -3671,7 +3659,7 @@ static int me4000_ai_config(me4000_ai_config_t * arg,
 
        return 0;
 
-      AI_CONFIG_ERR:
+AI_CONFIG_ERR:
 
        /* Reset the timers */
        ai_context->chan_timer = 66;
@@ -3699,7 +3687,7 @@ static int me4000_ai_config(me4000_ai_config_t * arg,
 
 }
 
-static int ai_common_start(me4000_ai_context_t * ai_context)
+static int ai_common_start(struct me4000_ai_context *ai_context)
 {
        u32 tmp;
        CALL_PDEBUG("ai_common_start() is executed\n");
@@ -3762,7 +3750,7 @@ static int ai_common_start(me4000_ai_context_t * ai_context)
        return 0;
 }
 
-static int me4000_ai_start(me4000_ai_context_t * ai_context)
+static int me4000_ai_start(struct me4000_ai_context *ai_context)
 {
        int err;
        CALL_PDEBUG("me4000_ai_start() is executed\n");
@@ -3779,7 +3767,7 @@ static int me4000_ai_start(me4000_ai_context_t * ai_context)
 }
 
 static int me4000_ai_start_ex(unsigned long *arg,
-                             me4000_ai_context_t * ai_context)
+                             struct me4000_ai_context *ai_context)
 {
        int err;
        wait_queue_head_t queue;
@@ -3834,7 +3822,7 @@ static int me4000_ai_start_ex(unsigned long *arg,
        return 0;
 }
 
-static int me4000_ai_stop(me4000_ai_context_t * ai_context)
+static int me4000_ai_stop(struct me4000_ai_context *ai_context)
 {
        wait_queue_head_t queue;
        u32 tmp;
@@ -3871,7 +3859,7 @@ static int me4000_ai_stop(me4000_ai_context_t * ai_context)
        return 0;
 }
 
-static int me4000_ai_immediate_stop(me4000_ai_context_t * ai_context)
+static int me4000_ai_immediate_stop(struct me4000_ai_context *ai_context)
 {
        wait_queue_head_t queue;
        u32 tmp;
@@ -3908,7 +3896,7 @@ static int me4000_ai_immediate_stop(me4000_ai_context_t * ai_context)
        return 0;
 }
 
-static int me4000_ai_ex_trig_enable(me4000_ai_context_t * ai_context)
+static int me4000_ai_ex_trig_enable(struct me4000_ai_context *ai_context)
 {
        u32 tmp;
        unsigned long flags;
@@ -3924,7 +3912,7 @@ static int me4000_ai_ex_trig_enable(me4000_ai_context_t * ai_context)
        return 0;
 }
 
-static int me4000_ai_ex_trig_disable(me4000_ai_context_t * ai_context)
+static int me4000_ai_ex_trig_disable(struct me4000_ai_context *ai_context)
 {
        u32 tmp;
        unsigned long flags;
@@ -3940,10 +3928,10 @@ static int me4000_ai_ex_trig_disable(me4000_ai_context_t * ai_context)
        return 0;
 }
 
-static int me4000_ai_ex_trig_setup(me4000_ai_trigger_t * arg,
-                                  me4000_ai_context_t * ai_context)
+static int me4000_ai_ex_trig_setup(struct me4000_ai_trigger *arg,
+                                  struct me4000_ai_context *ai_context)
 {
-       me4000_ai_trigger_t cmd;
+       struct me4000_ai_trigger cmd;
        int err;
        u32 tmp;
        unsigned long flags;
@@ -3951,7 +3939,7 @@ static int me4000_ai_ex_trig_setup(me4000_ai_trigger_t * arg,
        CALL_PDEBUG("me4000_ai_ex_trig_setup() is executed\n");
 
        /* Copy data from user */
-       err = copy_from_user(&cmd, arg, sizeof(me4000_ai_trigger_t));
+       err = copy_from_user(&cmd, arg, sizeof(struct me4000_ai_trigger));
        if (err) {
                printk(KERN_ERR
                       "ME4000:me4000_ai_ex_trig_setup():Can't copy from user space\n");
@@ -4000,16 +3988,16 @@ static int me4000_ai_ex_trig_setup(me4000_ai_trigger_t * arg,
        return 0;
 }
 
-static int me4000_ai_sc_setup(me4000_ai_sc_t * arg,
-                             me4000_ai_context_t * ai_context)
+static int me4000_ai_sc_setup(struct me4000_ai_sc *arg,
+                             struct me4000_ai_context *ai_context)
 {
-       me4000_ai_sc_t cmd;
+       struct me4000_ai_sc cmd;
        int err;
 
        CALL_PDEBUG("me4000_ai_sc_setup() is executed\n");
 
        /* Copy data from user */
-       err = copy_from_user(&cmd, arg, sizeof(me4000_ai_sc_t));
+       err = copy_from_user(&cmd, arg, sizeof(struct me4000_ai_sc));
        if (err) {
                printk(KERN_ERR
                       "ME4000:me4000_ai_sc_setup():Can't copy from user space\n");
@@ -4023,9 +4011,9 @@ static int me4000_ai_sc_setup(me4000_ai_sc_t * arg,
 }
 
 static ssize_t me4000_ai_read(struct file *filep, char *buff, size_t cnt,
-                             loff_t * offp)
+                             loff_t *offp)
 {
-       me4000_ai_context_t *ai_context = filep->private_data;
+       struct me4000_ai_context *ai_context = filep->private_data;
        s16 *buffer = (s16 *) buff;
        size_t count = cnt / 2;
        unsigned long flags;
@@ -4150,9 +4138,9 @@ static ssize_t me4000_ai_read(struct file *filep, char *buff, size_t cnt,
        return ret * 2;
 }
 
-static unsigned int me4000_ai_poll(struct file *file_p, poll_table * wait)
+static unsigned int me4000_ai_poll(struct file *file_p, poll_table *wait)
 {
-       me4000_ai_context_t *ai_context;
+       struct me4000_ai_context *ai_context;
        unsigned long mask = 0;
 
        CALL_PDEBUG("me4000_ai_poll() is executed\n");
@@ -4171,7 +4159,7 @@ static unsigned int me4000_ai_poll(struct file *file_p, poll_table * wait)
        return mask;
 }
 
-static int me4000_ai_offset_enable(me4000_ai_context_t * ai_context)
+static int me4000_ai_offset_enable(struct me4000_ai_context *ai_context)
 {
        unsigned long tmp;
 
@@ -4184,7 +4172,7 @@ static int me4000_ai_offset_enable(me4000_ai_context_t * ai_context)
        return 0;
 }
 
-static int me4000_ai_offset_disable(me4000_ai_context_t * ai_context)
+static int me4000_ai_offset_disable(struct me4000_ai_context *ai_context)
 {
        unsigned long tmp;
 
@@ -4197,7 +4185,7 @@ static int me4000_ai_offset_disable(me4000_ai_context_t * ai_context)
        return 0;
 }
 
-static int me4000_ai_fullscale_enable(me4000_ai_context_t * ai_context)
+static int me4000_ai_fullscale_enable(struct me4000_ai_context *ai_context)
 {
        unsigned long tmp;
 
@@ -4210,7 +4198,7 @@ static int me4000_ai_fullscale_enable(me4000_ai_context_t * ai_context)
        return 0;
 }
 
-static int me4000_ai_fullscale_disable(me4000_ai_context_t * ai_context)
+static int me4000_ai_fullscale_disable(struct me4000_ai_context *ai_context)
 {
        unsigned long tmp;
 
@@ -4223,7 +4211,7 @@ static int me4000_ai_fullscale_disable(me4000_ai_context_t * ai_context)
        return 0;
 }
 
-static int me4000_ai_fsm_state(int *arg, me4000_ai_context_t * ai_context)
+static int me4000_ai_fsm_state(int *arg, struct me4000_ai_context *ai_context)
 {
        unsigned long tmp;
 
@@ -4242,7 +4230,7 @@ static int me4000_ai_fsm_state(int *arg, me4000_ai_context_t * ai_context)
 }
 
 static int me4000_ai_get_count_buffer(unsigned long *arg,
-                                     me4000_ai_context_t * ai_context)
+                                     struct me4000_ai_context *ai_context)
 {
        unsigned long c;
        int err;
@@ -4252,7 +4240,7 @@ static int me4000_ai_get_count_buffer(unsigned long *arg,
        err = copy_to_user(arg, &c, sizeof(unsigned long));
        if (err) {
                printk(KERN_ERR
-                      "ME4000:me4000_ai_get_count_buffer():Can't copy to user space\n");
+                      "%s:Can't copy to user space\n", __func__);
                return -EFAULT;
        }
 
@@ -4261,7 +4249,7 @@ static int me4000_ai_get_count_buffer(unsigned long *arg,
 
 /*---------------------------------- EEPROM stuff ---------------------------*/
 
-static int eeprom_write_cmd(me4000_ai_context_t * ai_context, unsigned long cmd,
+static int eeprom_write_cmd(struct me4000_ai_context *ai_context, unsigned long cmd,
                            int length)
 {
        int i;
@@ -4318,7 +4306,7 @@ static int eeprom_write_cmd(me4000_ai_context_t * ai_context, unsigned long cmd,
        return 0;
 }
 
-static unsigned short eeprom_read_cmd(me4000_ai_context_t * ai_context,
+static unsigned short eeprom_read_cmd(struct me4000_ai_context *ai_context,
                                      unsigned long cmd, int length)
 {
        int i;
@@ -4397,11 +4385,11 @@ static unsigned short eeprom_read_cmd(me4000_ai_context_t * ai_context,
        return id;
 }
 
-static int me4000_eeprom_write(me4000_eeprom_t * arg,
-                              me4000_ai_context_t * ai_context)
+static int me4000_eeprom_write(struct me4000_eeprom *arg,
+                              struct me4000_ai_context *ai_context)
 {
        int err;
-       me4000_eeprom_t setup;
+       struct me4000_eeprom setup;
        unsigned long cmd;
        unsigned long date_high;
        unsigned long date_low;
@@ -4594,12 +4582,12 @@ static int me4000_eeprom_write(me4000_eeprom_t * arg,
        return 0;
 }
 
-static int me4000_eeprom_read(me4000_eeprom_t * arg,
-                             me4000_ai_context_t * ai_context)
+static int me4000_eeprom_read(struct me4000_eeprom *arg,
+                             struct me4000_ai_context *ai_context)
 {
        int err;
        unsigned long cmd;
-       me4000_eeprom_t setup;
+       struct me4000_eeprom setup;
 
        CALL_PDEBUG("me4000_eeprom_read() is executed\n");
 
@@ -4687,7 +4675,7 @@ static int me4000_eeprom_read(me4000_eeprom_t * arg,
 static int me4000_dio_ioctl(struct inode *inode_p, struct file *file_p,
                            unsigned int service, unsigned long arg)
 {
-       me4000_dio_context_t *dio_context;
+       struct me4000_dio_context *dio_context;
 
        CALL_PDEBUG("me4000_dio_ioctl() is executed\n");
 
@@ -4704,13 +4692,13 @@ static int me4000_dio_ioctl(struct inode *inode_p, struct file *file_p,
 
        switch (service) {
        case ME4000_DIO_CONFIG:
-               return me4000_dio_config((me4000_dio_config_t *) arg,
+               return me4000_dio_config((struct me4000_dio_config *)arg,
                                         dio_context);
        case ME4000_DIO_SET_BYTE:
-               return me4000_dio_set_byte((me4000_dio_byte_t *) arg,
+               return me4000_dio_set_byte((struct me4000_dio_byte *)arg,
                                           dio_context);
        case ME4000_DIO_GET_BYTE:
-               return me4000_dio_get_byte((me4000_dio_byte_t *) arg,
+               return me4000_dio_get_byte((struct me4000_dio_byte *)arg,
                                           dio_context);
        case ME4000_DIO_RESET:
                return me4000_dio_reset(dio_context);
@@ -4723,17 +4711,17 @@ static int me4000_dio_ioctl(struct inode *inode_p, struct file *file_p,
        return 0;
 }
 
-static int me4000_dio_config(me4000_dio_config_t * arg,
-                            me4000_dio_context_t * dio_context)
+static int me4000_dio_config(struct me4000_dio_config *arg,
+                            struct me4000_dio_context *dio_context)
 {
-       me4000_dio_config_t cmd;
+       struct me4000_dio_config cmd;
        u32 tmp;
        int err;
 
        CALL_PDEBUG("me4000_dio_config() is executed\n");
 
        /* Copy data from user */
-       err = copy_from_user(&cmd, arg, sizeof(me4000_dio_config_t));
+       err = copy_from_user(&cmd, arg, sizeof(struct me4000_dio_config));
        if (err) {
                printk(KERN_ERR
                       "ME4000:me4000_dio_config():Can't copy from user space\n");
@@ -4964,16 +4952,16 @@ static int me4000_dio_config(me4000_dio_config_t * arg,
        return 0;
 }
 
-static int me4000_dio_set_byte(me4000_dio_byte_t * arg,
-                              me4000_dio_context_t * dio_context)
+static int me4000_dio_set_byte(struct me4000_dio_byte *arg,
+                              struct me4000_dio_context *dio_context)
 {
-       me4000_dio_byte_t cmd;
+       struct me4000_dio_byte cmd;
        int err;
 
        CALL_PDEBUG("me4000_dio_set_byte() is executed\n");
 
        /* Copy data from user */
-       err = copy_from_user(&cmd, arg, sizeof(me4000_dio_byte_t));
+       err = copy_from_user(&cmd, arg, sizeof(struct me4000_dio_byte));
        if (err) {
                printk(KERN_ERR
                       "ME4000:me4000_dio_set_byte():Can't copy from user space\n");
@@ -5030,16 +5018,16 @@ static int me4000_dio_set_byte(me4000_dio_byte_t * arg,
        return 0;
 }
 
-static int me4000_dio_get_byte(me4000_dio_byte_t * arg,
-                              me4000_dio_context_t * dio_context)
+static int me4000_dio_get_byte(struct me4000_dio_byte *arg,
+                              struct me4000_dio_context *dio_context)
 {
-       me4000_dio_byte_t cmd;
+       struct me4000_dio_byte cmd;
        int err;
 
        CALL_PDEBUG("me4000_dio_get_byte() is executed\n");
 
        /* Copy data from user */
-       err = copy_from_user(&cmd, arg, sizeof(me4000_dio_byte_t));
+       err = copy_from_user(&cmd, arg, sizeof(struct me4000_dio_byte));
        if (err) {
                printk(KERN_ERR
                       "ME4000:me4000_dio_get_byte():Can't copy from user space\n");
@@ -5070,7 +5058,7 @@ static int me4000_dio_get_byte(me4000_dio_byte_t * arg,
        }
 
        /* Copy result back to user */
-       err = copy_to_user(arg, &cmd, sizeof(me4000_dio_byte_t));
+       err = copy_to_user(arg, &cmd, sizeof(struct me4000_dio_byte));
        if (err) {
                printk(KERN_ERR
                       "ME4000:me4000_dio_get_byte():Can't copy to user space\n");
@@ -5080,7 +5068,7 @@ static int me4000_dio_get_byte(me4000_dio_byte_t * arg,
        return 0;
 }
 
-static int me4000_dio_reset(me4000_dio_context_t * dio_context)
+static int me4000_dio_reset(struct me4000_dio_context *dio_context)
 {
        CALL_PDEBUG("me4000_dio_reset() is executed\n");
 
@@ -5101,7 +5089,7 @@ static int me4000_dio_reset(me4000_dio_context_t * dio_context)
 static int me4000_cnt_ioctl(struct inode *inode_p, struct file *file_p,
                            unsigned int service, unsigned long arg)
 {
-       me4000_cnt_context_t *cnt_context;
+       struct me4000_cnt_context *cnt_context;
 
        CALL_PDEBUG("me4000_cnt_ioctl() is executed\n");
 
@@ -5118,11 +5106,11 @@ static int me4000_cnt_ioctl(struct inode *inode_p, struct file *file_p,
 
        switch (service) {
        case ME4000_CNT_READ:
-               return me4000_cnt_read((me4000_cnt_t *) arg, cnt_context);
+               return me4000_cnt_read((struct me4000_cnt *)arg, cnt_context);
        case ME4000_CNT_WRITE:
-               return me4000_cnt_write((me4000_cnt_t *) arg, cnt_context);
+               return me4000_cnt_write((struct me4000_cnt *)arg, cnt_context);
        case ME4000_CNT_CONFIG:
-               return me4000_cnt_config((me4000_cnt_config_t *) arg,
+               return me4000_cnt_config((struct me4000_cnt_config *)arg,
                                         cnt_context);
        case ME4000_CNT_RESET:
                return me4000_cnt_reset(cnt_context);
@@ -5135,10 +5123,10 @@ static int me4000_cnt_ioctl(struct inode *inode_p, struct file *file_p,
        return 0;
 }
 
-static int me4000_cnt_config(me4000_cnt_config_t * arg,
-                            me4000_cnt_context_t * cnt_context)
+static int me4000_cnt_config(struct me4000_cnt_config *arg,
+                            struct me4000_cnt_context *cnt_context)
 {
-       me4000_cnt_config_t cmd;
+       struct me4000_cnt_config cmd;
        u8 counter;
        u8 mode;
        int err;
@@ -5146,7 +5134,7 @@ static int me4000_cnt_config(me4000_cnt_config_t * arg,
        CALL_PDEBUG("me4000_cnt_config() is executed\n");
 
        /* Copy data from user */
-       err = copy_from_user(&cmd, arg, sizeof(me4000_cnt_config_t));
+       err = copy_from_user(&cmd, arg, sizeof(struct me4000_cnt_config));
        if (err) {
                printk(KERN_ERR
                       "ME4000:me4000_cnt_config():Can't copy from user space\n");
@@ -5204,17 +5192,17 @@ static int me4000_cnt_config(me4000_cnt_config_t * arg,
        return 0;
 }
 
-static int me4000_cnt_read(me4000_cnt_t * arg,
-                          me4000_cnt_context_t * cnt_context)
+static int me4000_cnt_read(struct me4000_cnt *arg,
+                          struct me4000_cnt_context *cnt_context)
 {
-       me4000_cnt_t cmd;
+       struct me4000_cnt cmd;
        u8 tmp;
        int err;
 
        CALL_PDEBUG("me4000_cnt_read() is executed\n");
 
        /* Copy data from user */
-       err = copy_from_user(&cmd, arg, sizeof(me4000_cnt_t));
+       err = copy_from_user(&cmd, arg, sizeof(struct me4000_cnt));
        if (err) {
                printk(KERN_ERR
                       "ME4000:me4000_cnt_read():Can't copy from user space\n");
@@ -5249,7 +5237,7 @@ static int me4000_cnt_read(me4000_cnt_t * arg,
        }
 
        /* Copy result back to user */
-       err = copy_to_user(arg, &cmd, sizeof(me4000_cnt_t));
+       err = copy_to_user(arg, &cmd, sizeof(struct me4000_cnt));
        if (err) {
                printk(KERN_ERR
                       "ME4000:me4000_cnt_read():Can't copy to user space\n");
@@ -5259,17 +5247,17 @@ static int me4000_cnt_read(me4000_cnt_t * arg,
        return 0;
 }
 
-static int me4000_cnt_write(me4000_cnt_t * arg,
-                           me4000_cnt_context_t * cnt_context)
+static int me4000_cnt_write(struct me4000_cnt *arg,
+                           struct me4000_cnt_context *cnt_context)
 {
-       me4000_cnt_t cmd;
+       struct me4000_cnt cmd;
        u8 tmp;
        int err;
 
        CALL_PDEBUG("me4000_cnt_write() is executed\n");
 
        /* Copy data from user */
-       err = copy_from_user(&cmd, arg, sizeof(me4000_cnt_t));
+       err = copy_from_user(&cmd, arg, sizeof(struct me4000_cnt));
        if (err) {
                printk(KERN_ERR
                       "ME4000:me4000_cnt_write():Can't copy from user space\n");
@@ -5306,7 +5294,7 @@ static int me4000_cnt_write(me4000_cnt_t * arg,
        return 0;
 }
 
-static int me4000_cnt_reset(me4000_cnt_context_t * cnt_context)
+static int me4000_cnt_reset(struct me4000_cnt_context *cnt_context)
 {
        CALL_PDEBUG("me4000_cnt_reset() is executed\n");
 
@@ -5333,7 +5321,7 @@ static int me4000_cnt_reset(me4000_cnt_context_t * cnt_context)
 static int me4000_ext_int_ioctl(struct inode *inode_p, struct file *file_p,
                                unsigned int service, unsigned long arg)
 {
-       me4000_ext_int_context_t *ext_int_context;
+       struct me4000_ext_int_context *ext_int_context;
 
        CALL_PDEBUG("me4000_ext_int_ioctl() is executed\n");
 
@@ -5366,7 +5354,7 @@ static int me4000_ext_int_ioctl(struct inode *inode_p, struct file *file_p,
        return 0;
 }
 
-static int me4000_ext_int_enable(me4000_ext_int_context_t * ext_int_context)
+static int me4000_ext_int_enable(struct me4000_ext_int_context *ext_int_context)
 {
        unsigned long tmp;
 
@@ -5379,7 +5367,7 @@ static int me4000_ext_int_enable(me4000_ext_int_context_t * ext_int_context)
        return 0;
 }
 
-static int me4000_ext_int_disable(me4000_ext_int_context_t * ext_int_context)
+static int me4000_ext_int_disable(struct me4000_ext_int_context *ext_int_context)
 {
        unsigned long tmp;
 
@@ -5393,7 +5381,7 @@ static int me4000_ext_int_disable(me4000_ext_int_context_t * ext_int_context)
 }
 
 static int me4000_ext_int_count(unsigned long *arg,
-                               me4000_ext_int_context_t * ext_int_context)
+                               struct me4000_ext_int_context *ext_int_context)
 {
 
        CALL_PDEBUG("me4000_ext_int_count() is executed\n");
@@ -5404,10 +5392,10 @@ static int me4000_ext_int_count(unsigned long *arg,
 
 /*------------------------------------ General stuff ------------------------------------*/
 
-static int me4000_get_user_info(me4000_user_info_t * arg,
-                               me4000_info_t * board_info)
+static int me4000_get_user_info(struct me4000_user_info *arg,
+                               struct me4000_info *board_info)
 {
-       me4000_user_info_t user_info;
+       struct me4000_user_info user_info;
 
        CALL_PDEBUG("me4000_get_user_info() is executed\n");
 
@@ -5437,7 +5425,7 @@ static int me4000_get_user_info(me4000_user_info_t * arg,
 
        user_info.cnt_count = board_info->board_p->cnt.count;
 
-       if (copy_to_user(arg, &user_info, sizeof(me4000_user_info_t)))
+       if (copy_to_user(arg, &user_info, sizeof(struct me4000_user_info)))
                return -EFAULT;
 
        return 0;
@@ -5448,7 +5436,7 @@ static int me4000_get_user_info(me4000_user_info_t * arg,
 static int me4000_ext_int_fasync(int fd, struct file *file_ptr, int mode)
 {
        int result = 0;
-       me4000_ext_int_context_t *ext_int_context;
+       struct me4000_ext_int_context *ext_int_context;
 
        CALL_PDEBUG("me4000_ext_int_fasync() is executed\n");
 
@@ -5465,7 +5453,7 @@ static irqreturn_t me4000_ao_isr(int irq, void *dev_id)
 {
        u32 tmp;
        u32 value;
-       me4000_ao_context_t *ao_context;
+       struct me4000_ao_context *ao_context;
        int i;
        int c = 0;
        int c1 = 0;
@@ -5589,7 +5577,7 @@ static irqreturn_t me4000_ao_isr(int irq, void *dev_id)
 static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
 {
        u32 tmp;
-       me4000_ai_context_t *ai_context;
+       struct me4000_ai_context *ai_context;
        int i;
        int c = 0;
        int c1 = 0;
@@ -5933,7 +5921,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
 
 static irqreturn_t me4000_ext_int_isr(int irq, void *dev_id)
 {
-       me4000_ext_int_context_t *ext_int_context;
+       struct me4000_ext_int_context *ext_int_context;
        unsigned long tmp;
 
        ISR_PDEBUG("me4000_ext_int_isr() is executed\n");
@@ -5969,10 +5957,10 @@ static irqreturn_t me4000_ext_int_isr(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-void __exit me4000_module_exit(void)
+static void __exit me4000_module_exit(void)
 {
        struct list_head *board_p;
-       me4000_info_t *board_info;
+       struct me4000_info *board_info;
 
        CALL_PDEBUG("cleanup_module() is executed\n");
 
@@ -5993,7 +5981,7 @@ void __exit me4000_module_exit(void)
        /* Reset the boards */
        for (board_p = me4000_board_info_list.next;
             board_p != &me4000_board_info_list; board_p = board_p->next) {
-               board_info = list_entry(board_p, me4000_info_t, list);
+               board_info = list_entry(board_p, struct me4000_info, list);
                me4000_reset_board(board_info);
        }
 
@@ -6007,7 +5995,7 @@ static int me4000_read_procmem(char *buf, char **start, off_t offset, int count,
 {
        int len = 0;
        int limit = count - 1000;
-       me4000_info_t *board_info;
+       struct me4000_info *board_info;
        struct list_head *ptr;
 
        len += sprintf(buf + len, "\nME4000 DRIVER VERSION %X.%X.%X\n\n",
@@ -6019,7 +6007,7 @@ static int me4000_read_procmem(char *buf, char **start, off_t offset, int count,
        for (ptr = me4000_board_info_list.next;
             (ptr != &me4000_board_info_list) && (len < limit);
             ptr = ptr->next) {
-               board_info = list_entry(ptr, me4000_info_t, list);
+               board_info = list_entry(ptr, struct me4000_info, list);
 
                len +=
                    sprintf(buf + len, "Board number %d:\n",
@@ -6029,14 +6017,14 @@ static int me4000_read_procmem(char *buf, char **start, off_t offset, int count,
                    sprintf(buf + len, "PLX base register = 0x%lX\n",
                            board_info->plx_regbase);
                len +=
-                   sprintf(buf + len, "PLX base register size = 0x%lX\n",
-                           board_info->plx_regbase_size);
+                   sprintf(buf + len, "PLX base register size = 0x%X\n",
+                           (unsigned int)board_info->plx_regbase_size);
                len +=
-                   sprintf(buf + len, "ME4000 base register = 0x%lX\n",
-                           board_info->me4000_regbase);
+                   sprintf(buf + len, "ME4000 base register = 0x%X\n",
+                           (unsigned int)board_info->me4000_regbase);
                len +=
-                   sprintf(buf + len, "ME4000 base register size = 0x%lX\n",
-                           board_info->me4000_regbase_size);
+                   sprintf(buf + len, "ME4000 base register size = 0x%X\n",
+                           (unsigned int)board_info->me4000_regbase_size);
                len +=
                    sprintf(buf + len, "Serial number = 0x%X\n",
                            board_info->serial_no);
index c35e4b9793a01bd05dfa7c648e4430dae2a0880b..81c6f4d5e25c3da1b597100e89a6d97eaa072e9c 100644 (file)
   Circular buffer used for analog input/output reads/writes.
   ===========================================================================*/
 
-typedef struct me4000_circ_buf {
+struct me4000_circ_buf {
        s16 *buf;
        int volatile head;
        int volatile tail;
-} me4000_circ_buf_t;
+};
 
 /*=============================================================================
   Information about the hardware capabilities
   ===========================================================================*/
 
-typedef struct me4000_ao_info {
+struct me4000_ao_info {
        int count;
        int fifo_count;
-} me4000_ao_info_t;
+};
 
-typedef struct me4000_ai_info {
+struct me4000_ai_info {
        int count;
        int sh_count;
        int diff_count;
        int ex_trig_analog;
-} me4000_ai_info_t;
+};
 
-typedef struct me4000_dio_info {
+struct me4000_dio_info {
        int count;
-} me4000_dio_info_t;
+};
 
-typedef struct me4000_cnt_info {
+struct me4000_cnt_info {
        int count;
-} me4000_cnt_info_t;
+};
 
-typedef struct me4000_board {
+struct me4000_board {
        u16 vendor_id;
        u16 device_id;
-       me4000_ao_info_t ao;
-       me4000_ai_info_t ai;
-       me4000_dio_info_t dio;
-       me4000_cnt_info_t cnt;
-} me4000_board_t;
+       struct me4000_ao_info ao;
+       struct me4000_ai_info ai;
+       struct me4000_dio_info dio;
+       struct me4000_cnt_info cnt;
+};
 
-static me4000_board_t me4000_boards[] = {
+static struct me4000_board me4000_boards[] = {
        {PCI_VENDOR_ID_MEILHAUS, 0x4610, {0, 0}, {16, 0, 0, 0}, {4}, {3}},
 
        {PCI_VENDOR_ID_MEILHAUS, 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0}},
@@ -391,8 +391,6 @@ static me4000_board_t me4000_boards[] = {
        {0},
 };
 
-#define ME4000_BOARD_VERSIONS (sizeof(me4000_boards) / sizeof(me4000_board_t) - 1)
-
 /*=============================================================================
   PCI device table.
   This is used by modprobe to translate PCI IDs to drivers.
@@ -427,19 +425,19 @@ MODULE_DEVICE_TABLE(pci, me4000_pci_table);
   Global board and subdevice information structures
   ===========================================================================*/
 
-typedef struct me4000_info {
+struct me4000_info {
        struct list_head list;  // List of all detected boards
        int board_count;        // Index of the board after detection
 
        unsigned long plx_regbase;      // PLX configuration space base address
-       unsigned long me4000_regbase;   // Base address of the ME4000
-       unsigned long timer_regbase;    // Base address of the timer circuit
-       unsigned long program_regbase;  // Base address to set the program pin for the xilinx
+       resource_size_t me4000_regbase; // Base address of the ME4000
+       resource_size_t timer_regbase;  // Base address of the timer circuit
+       resource_size_t program_regbase;        // Base address to set the program pin for the xilinx
 
        unsigned long plx_regbase_size; // PLX register set space
-       unsigned long me4000_regbase_size;      // ME4000 register set space
-       unsigned long timer_regbase_size;       // Timer circuit register set space
-       unsigned long program_regbase_size;     // Size of program base address of the ME4000
+       resource_size_t me4000_regbase_size;    // ME4000 register set space
+       resource_size_t timer_regbase_size;     // Timer circuit register set space
+       resource_size_t program_regbase_size;   // Size of program base address of the ME4000
 
        unsigned int serial_no; // Serial number of the board
        unsigned char hw_revision;      // Hardware revision of the board
@@ -451,7 +449,7 @@ typedef struct me4000_info {
        int pci_func_no;        // PCI function number
        struct pci_dev *pci_dev_p;      // General PCI information
 
-       me4000_board_t *board_p;        // Holds the board capabilities
+       struct me4000_board *board_p;   // Holds the board capabilities
 
        unsigned int irq;       // IRQ assigned from the PCI BIOS
        unsigned int irq_count; // Count of external interrupts
@@ -464,18 +462,18 @@ typedef struct me4000_info {
        struct me4000_dio_context *dio_context; // Digital I/O specific context
        struct me4000_cnt_context *cnt_context; // Counter specific context
        struct me4000_ext_int_context *ext_int_context; // External interrupt specific context
-} me4000_info_t;
+};
 
-typedef struct me4000_ao_context {
+struct me4000_ao_context {
        struct list_head list;  // linked list of me4000_ao_context_t
        int index;              // Index in the list
        int mode;               // Indicates mode (0 = single, 1 = wraparound, 2 = continous)
        int dac_in_use;         // Indicates if already opend
        spinlock_t use_lock;    // Guards in_use
        spinlock_t int_lock;    // Used when locking out interrupts
-       me4000_circ_buf_t circ_buf;     // Circular buffer
+       struct me4000_circ_buf circ_buf;        // Circular buffer
        wait_queue_head_t wait_queue;   // Wait queue to sleep while blocking write
-       me4000_info_t *board_info;
+       struct me4000_info *board_info;
        unsigned int irq;       // The irq associated with this ADC
        int volatile pipe_flag; // Indicates broken pipe set from me4000_ao_isr()
        unsigned long ctrl_reg;
@@ -486,9 +484,9 @@ typedef struct me4000_ao_context {
        unsigned long irq_status_reg;
        unsigned long preload_reg;
        struct fasync_struct *fasync_p; // Queue for asynchronous notification
-} me4000_ao_context_t;
+};
 
-typedef struct me4000_ai_context {
+struct me4000_ai_context {
        struct list_head list;  // linked list of me4000_ai_info_t
        int mode;               // Indicates mode
        int in_use;             // Indicates if already opend
@@ -496,9 +494,9 @@ typedef struct me4000_ai_context {
        spinlock_t int_lock;    // Used when locking out interrupts
        int number;             // Number of the DAC
        unsigned int irq;       // The irq associated with this ADC
-       me4000_circ_buf_t circ_buf;     // Circular buffer
+       struct me4000_circ_buf circ_buf;        // Circular buffer
        wait_queue_head_t wait_queue;   // Wait queue to sleep while blocking read
-       me4000_info_t *board_info;
+       struct me4000_info *board_info;
 
        struct fasync_struct *fasync_p; // Queue for asynchronous notification
 
@@ -523,48 +521,48 @@ typedef struct me4000_ai_context {
        unsigned long channel_list_count;
        unsigned long sample_counter;
        int sample_counter_reload;
-} me4000_ai_context_t;
+};
 
-typedef struct me4000_dio_context {
+struct me4000_dio_context {
        struct list_head list;  // linked list of me4000_dio_context_t
        int in_use;             // Indicates if already opend
        spinlock_t use_lock;    // Guards in_use
        int number;
        int dio_count;
-       me4000_info_t *board_info;
+       struct me4000_info *board_info;
        unsigned long dir_reg;
        unsigned long ctrl_reg;
        unsigned long port_0_reg;
        unsigned long port_1_reg;
        unsigned long port_2_reg;
        unsigned long port_3_reg;
-} me4000_dio_context_t;
+};
 
-typedef struct me4000_cnt_context {
+struct me4000_cnt_context {
        struct list_head list;  // linked list of me4000_dio_context_t
        int in_use;             // Indicates if already opend
        spinlock_t use_lock;    // Guards in_use
        int number;
        int cnt_count;
-       me4000_info_t *board_info;
+       struct me4000_info *board_info;
        unsigned long ctrl_reg;
        unsigned long counter_0_reg;
        unsigned long counter_1_reg;
        unsigned long counter_2_reg;
-} me4000_cnt_context_t;
+};
 
-typedef struct me4000_ext_int_context {
+struct me4000_ext_int_context {
        struct list_head list;  // linked list of me4000_dio_context_t
        int in_use;             // Indicates if already opend
        spinlock_t use_lock;    // Guards in_use
        int number;
-       me4000_info_t *board_info;
+       struct me4000_info *board_info;
        unsigned int irq;
        unsigned long int_count;
        struct fasync_struct *fasync_ptr;
        unsigned long ctrl_reg;
        unsigned long irq_status_reg;
-} me4000_ext_int_context_t;
+};
 
 #endif
 
@@ -745,12 +743,12 @@ typedef struct me4000_ext_int_context {
   General type definitions
   ----------------------------------------------------------------------------*/
 
-typedef struct me4000_user_info {
+struct me4000_user_info {
        int board_count;        // Index of the board after detection
        unsigned long plx_regbase;      // PLX configuration space base address
-       unsigned long me4000_regbase;   // Base address of the ME4000
+       resource_size_t me4000_regbase; // Base address of the ME4000
        unsigned long plx_regbase_size; // PLX register set space
-       unsigned long me4000_regbase_size;      // ME4000 register set space
+       resource_size_t me4000_regbase_size;    // ME4000 register set space
        unsigned long serial_no;        // Serial number of the board
        unsigned char hw_revision;      // Hardware revision of the board
        unsigned short vendor_id;       // Meilhaus vendor id (0x1402)
@@ -773,62 +771,62 @@ typedef struct me4000_user_info {
        int dio_count;          // Count of digital I/O ports
 
        int cnt_count;          // Count of counters
-} me4000_user_info_t;
+};
 
 /*-----------------------------------------------------------------------------
   Type definitions for analog output
   ----------------------------------------------------------------------------*/
 
-typedef struct me4000_ao_channel_list {
+struct me4000_ao_channel_list {
        unsigned long count;
        unsigned long *list;
-} me4000_ao_channel_list_t;
+};
 
 /*-----------------------------------------------------------------------------
   Type definitions for analog input
   ----------------------------------------------------------------------------*/
 
-typedef struct me4000_ai_channel_list {
+struct me4000_ai_channel_list {
        unsigned long count;
        unsigned long *list;
-} me4000_ai_channel_list_t;
+};
 
-typedef struct me4000_ai_timer {
+struct me4000_ai_timer {
        unsigned long pre_chan;
        unsigned long chan;
        unsigned long scan_low;
        unsigned long scan_high;
-} me4000_ai_timer_t;
+};
 
-typedef struct me4000_ai_config {
-       me4000_ai_timer_t timer;
-       me4000_ai_channel_list_t channel_list;
+struct me4000_ai_config {
+       struct me4000_ai_timer timer;
+       struct me4000_ai_channel_list channel_list;
        int sh;
-} me4000_ai_config_t;
+};
 
-typedef struct me4000_ai_single {
+struct me4000_ai_single {
        int channel;
        int range;
        int mode;
        short value;
        unsigned long timeout;
-} me4000_ai_single_t;
+};
 
-typedef struct me4000_ai_trigger {
+struct me4000_ai_trigger {
        int mode;
        int edge;
-} me4000_ai_trigger_t;
+};
 
-typedef struct me4000_ai_sc {
+struct me4000_ai_sc {
        unsigned long value;
        int reload;
-} me4000_ai_sc_t;
+};
 
 /*-----------------------------------------------------------------------------
   Type definitions for eeprom
   ----------------------------------------------------------------------------*/
 
-typedef struct me4000_eeprom {
+struct me4000_eeprom {
        unsigned long date;
        short uni_10_offset;
        short uni_10_fullscale;
@@ -842,45 +840,45 @@ typedef struct me4000_eeprom {
        short diff_10_fullscale;
        short diff_2_5_offset;
        short diff_2_5_fullscale;
-} me4000_eeprom_t;
+};
 
 /*-----------------------------------------------------------------------------
   Type definitions for digital I/O
   ----------------------------------------------------------------------------*/
 
-typedef struct me4000_dio_config {
+struct me4000_dio_config {
        int port;
        int mode;
        int function;
-} me4000_dio_config_t;
+};
 
-typedef struct me4000_dio_byte {
+struct me4000_dio_byte {
        int port;
        unsigned char byte;
-} me4000_dio_byte_t;
+};
 
 /*-----------------------------------------------------------------------------
   Type definitions for counters
   ----------------------------------------------------------------------------*/
 
-typedef struct me4000_cnt {
+struct me4000_cnt {
        int counter;
        unsigned short value;
-} me4000_cnt_t;
+};
 
-typedef struct me4000_cnt_config {
+struct me4000_cnt_config {
        int counter;
        int mode;
-} me4000_cnt_config_t;
+};
 
 /*-----------------------------------------------------------------------------
   Type definitions for external interrupt
   ----------------------------------------------------------------------------*/
 
-typedef struct {
+struct me4000_int {
        int int1_count;
        int int2_count;
-} me4000_int_type;
+};
 
 /*-----------------------------------------------------------------------------
   The ioctls of the board
@@ -888,7 +886,8 @@ typedef struct {
 
 #define ME4000_IOCTL_MAXNR 50
 #define ME4000_MAGIC 'y'
-#define ME4000_GET_USER_INFO          _IOR (ME4000_MAGIC, 0, me4000_user_info_t)
+#define ME4000_GET_USER_INFO          _IOR (ME4000_MAGIC, 0, \
+                                           struct me4000_user_info)
 
 #define ME4000_AO_START               _IOW (ME4000_MAGIC, 1, unsigned long)
 #define ME4000_AO_STOP                _IO  (ME4000_MAGIC, 2)
@@ -904,25 +903,35 @@ typedef struct {
 #define ME4000_AO_DISABLE_DO          _IO  (ME4000_MAGIC, 12)
 #define ME4000_AO_FSM_STATE           _IOR (ME4000_MAGIC, 13, int)
 
-#define ME4000_AI_SINGLE              _IOR (ME4000_MAGIC, 14, me4000_ai_single_t)
+#define ME4000_AI_SINGLE              _IOR (ME4000_MAGIC, 14, \
+                                           struct me4000_ai_single)
 #define ME4000_AI_START               _IOW (ME4000_MAGIC, 15, unsigned long)
 #define ME4000_AI_STOP                _IO  (ME4000_MAGIC, 16)
 #define ME4000_AI_IMMEDIATE_STOP      _IO  (ME4000_MAGIC, 17)
 #define ME4000_AI_EX_TRIG_ENABLE      _IO  (ME4000_MAGIC, 18)
 #define ME4000_AI_EX_TRIG_DISABLE     _IO  (ME4000_MAGIC, 19)
-#define ME4000_AI_EX_TRIG_SETUP       _IOW (ME4000_MAGIC, 20, me4000_ai_trigger_t)
-#define ME4000_AI_CONFIG              _IOW (ME4000_MAGIC, 21, me4000_ai_config_t)
-#define ME4000_AI_SC_SETUP            _IOW (ME4000_MAGIC, 22, me4000_ai_sc_t)
+#define ME4000_AI_EX_TRIG_SETUP       _IOW (ME4000_MAGIC, 20, \
+                                           struct me4000_ai_trigger)
+#define ME4000_AI_CONFIG              _IOW (ME4000_MAGIC, 21, \
+                                           struct me4000_ai_config)
+#define ME4000_AI_SC_SETUP            _IOW (ME4000_MAGIC, 22, \
+                                           struct me4000_ai_sc)
 #define ME4000_AI_FSM_STATE           _IOR (ME4000_MAGIC, 23, int)
 
-#define ME4000_DIO_CONFIG             _IOW (ME4000_MAGIC, 24, me4000_dio_config_t)
-#define ME4000_DIO_GET_BYTE           _IOR (ME4000_MAGIC, 25, me4000_dio_byte_t)
-#define ME4000_DIO_SET_BYTE           _IOW (ME4000_MAGIC, 26, me4000_dio_byte_t)
+#define ME4000_DIO_CONFIG             _IOW (ME4000_MAGIC, 24, \
+                                           struct me4000_dio_config)
+#define ME4000_DIO_GET_BYTE           _IOR (ME4000_MAGIC, 25, \
+                                           struct me4000_dio_byte)
+#define ME4000_DIO_SET_BYTE           _IOW (ME4000_MAGIC, 26, \
+                                           struct me4000_dio_byte)
 #define ME4000_DIO_RESET              _IO  (ME4000_MAGIC, 27)
 
-#define ME4000_CNT_READ               _IOR (ME4000_MAGIC, 28, me4000_cnt_t)
-#define ME4000_CNT_WRITE              _IOW (ME4000_MAGIC, 29, me4000_cnt_t)
-#define ME4000_CNT_CONFIG             _IOW (ME4000_MAGIC, 30, me4000_cnt_config_t)
+#define ME4000_CNT_READ               _IOR (ME4000_MAGIC, 28, \
+                                           struct me4000_cnt)
+#define ME4000_CNT_WRITE              _IOW (ME4000_MAGIC, 29, \
+                                           struct me4000_cnt)
+#define ME4000_CNT_CONFIG             _IOW (ME4000_MAGIC, 30, \
+                                           struct me4000_cnt_config)
 #define ME4000_CNT_RESET              _IO  (ME4000_MAGIC, 31)
 
 #define ME4000_EXT_INT_DISABLE        _IO  (ME4000_MAGIC, 32)
@@ -934,13 +943,16 @@ typedef struct {
 #define ME4000_AI_FULLSCALE_ENABLE    _IO  (ME4000_MAGIC, 37)
 #define ME4000_AI_FULLSCALE_DISABLE   _IO  (ME4000_MAGIC, 38)
 
-#define ME4000_AI_EEPROM_READ         _IOR (ME4000_MAGIC, 39, me4000_eeprom_t)
-#define ME4000_AI_EEPROM_WRITE        _IOW (ME4000_MAGIC, 40, me4000_eeprom_t)
+#define ME4000_AI_EEPROM_READ         _IOR (ME4000_MAGIC, 39, \
+                                           struct me4000_eeprom)
+#define ME4000_AI_EEPROM_WRITE        _IOW (ME4000_MAGIC, 40, \
+                                           struct me4000_eeprom)
 
 #define ME4000_AO_SIMULTANEOUS_EX_TRIG _IO  (ME4000_MAGIC, 41)
 #define ME4000_AO_SIMULTANEOUS_SW      _IO  (ME4000_MAGIC, 42)
 #define ME4000_AO_SIMULTANEOUS_DISABLE _IO  (ME4000_MAGIC, 43)
-#define ME4000_AO_SIMULTANEOUS_UPDATE  _IOW (ME4000_MAGIC, 44, me4000_ao_channel_list_t)
+#define ME4000_AO_SIMULTANEOUS_UPDATE  _IOW (ME4000_MAGIC, 44, \
+                                            struct me4000_ao_channel_list)
 
 #define ME4000_AO_SYNCHRONOUS_EX_TRIG  _IO  (ME4000_MAGIC, 45)
 #define ME4000_AO_SYNCHRONOUS_SW       _IO  (ME4000_MAGIC, 46)
diff --git a/drivers/staging/poch/Kconfig b/drivers/staging/poch/Kconfig
new file mode 100644 (file)
index 0000000..b3b33b9
--- /dev/null
@@ -0,0 +1,6 @@
+config POCH
+       tristate "Redrapids Pocket Change CardBus support"
+       depends on PCI && UIO
+       default N
+       ---help---
+         Enable support for Redrapids Pocket Change CardBus devices.
diff --git a/drivers/staging/poch/Makefile b/drivers/staging/poch/Makefile
new file mode 100644 (file)
index 0000000..d2b9680
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_POCH)             += poch.o
diff --git a/drivers/staging/poch/README b/drivers/staging/poch/README
new file mode 100644 (file)
index 0000000..f65e979
--- /dev/null
@@ -0,0 +1,7 @@
+TODO:
+       - fix transmit overflows
+       - audit userspace interfaces
+       - get reserved major/minor if needed
+
+Please send patches to Greg Kroah-Hartman <greg@kroah.com> and
+Vijay Kumar <vijaykumar@bravegnu.org> and Jaya Kumar <jayakumar.lkml@gmail.com>
diff --git a/drivers/staging/poch/poch.c b/drivers/staging/poch/poch.c
new file mode 100644 (file)
index 0000000..0e113f9
--- /dev/null
@@ -0,0 +1,1425 @@
+/*
+ * User-space DMA and UIO based Redrapids Pocket Change CardBus driver
+ *
+ * Copyright 2008 Vijay Kumar <vijaykumar@bravegnu.org>
+ *
+ * Licensed under GPL version 2 only.
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/uio_driver.h>
+#include <linux/spinlock.h>
+#include <linux/cdev.h>
+#include <linux/delay.h>
+#include <linux/sysfs.h>
+#include <linux/poll.h>
+#include <linux/idr.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <linux/io.h>
+
+#include "poch.h"
+
+#include <asm/cacheflush.h>
+
+#ifndef PCI_VENDOR_ID_RRAPIDS
+#define PCI_VENDOR_ID_RRAPIDS 0x17D2
+#endif
+
+#ifndef PCI_DEVICE_ID_RRAPIDS_POCKET_CHANGE
+#define PCI_DEVICE_ID_RRAPIDS_POCKET_CHANGE 0x0351
+#endif
+
+#define POCH_NCHANNELS 2
+
+#define MAX_POCH_CARDS 8
+#define MAX_POCH_DEVICES (MAX_POCH_CARDS * POCH_NCHANNELS)
+
+#define DRV_NAME "poch"
+#define PFX      DRV_NAME ": "
+
+/*
+ * BAR0 Bridge Register Definitions
+ */
+
+#define BRIDGE_REV_REG                 0x0
+#define BRIDGE_INT_MASK_REG            0x4
+#define BRIDGE_INT_STAT_REG            0x8
+
+#define BRIDGE_INT_ACTIVE              (0x1 << 31)
+#define BRIDGE_INT_FPGA                        (0x1 << 2)
+#define BRIDGE_INT_TEMP_FAIL           (0x1 << 1)
+#define        BRIDGE_INT_TEMP_WARN            (0x1 << 0)
+
+#define BRIDGE_FPGA_RESET_REG          0xC
+
+#define BRIDGE_CARD_POWER_REG          0x10
+#define BRIDGE_CARD_POWER_EN            (0x1 << 0)
+#define BRIDGE_CARD_POWER_PROG_DONE     (0x1 << 31)
+
+#define BRIDGE_JTAG_REG                        0x14
+#define BRIDGE_DMA_GO_REG              0x18
+#define BRIDGE_STAT_0_REG              0x1C
+#define BRIDGE_STAT_1_REG              0x20
+#define BRIDGE_STAT_2_REG              0x24
+#define BRIDGE_STAT_3_REG              0x28
+#define BRIDGE_TEMP_STAT_REG           0x2C
+#define BRIDGE_TEMP_THRESH_REG         0x30
+#define BRIDGE_EEPROM_REVSEL_REG       0x34
+#define BRIDGE_CIS_STRUCT_REG          0x100
+#define BRIDGE_BOARDREV_REG            0x124
+
+/*
+ * BAR1 FPGA Register Definitions
+ */
+
+#define FPGA_IFACE_REV_REG             0x0
+#define FPGA_RX_BLOCK_SIZE_REG         0x8
+#define FPGA_TX_BLOCK_SIZE_REG         0xC
+#define FPGA_RX_BLOCK_COUNT_REG                0x10
+#define FPGA_TX_BLOCK_COUNT_REG                0x14
+#define FPGA_RX_CURR_DMA_BLOCK_REG     0x18
+#define FPGA_TX_CURR_DMA_BLOCK_REG     0x1C
+#define FPGA_RX_GROUP_COUNT_REG                0x20
+#define FPGA_TX_GROUP_COUNT_REG                0x24
+#define FPGA_RX_CURR_GROUP_REG         0x28
+#define FPGA_TX_CURR_GROUP_REG         0x2C
+#define FPGA_RX_CURR_PCI_REG           0x38
+#define FPGA_TX_CURR_PCI_REG           0x3C
+#define FPGA_RX_GROUP0_START_REG       0x40
+#define FPGA_TX_GROUP0_START_REG       0xC0
+#define FPGA_DMA_DESC_1_REG            0x140
+#define FPGA_DMA_DESC_2_REG            0x144
+#define FPGA_DMA_DESC_3_REG            0x148
+#define FPGA_DMA_DESC_4_REG            0x14C
+
+#define FPGA_DMA_INT_STAT_REG          0x150
+#define FPGA_DMA_INT_MASK_REG          0x154
+#define FPGA_DMA_INT_RX                (1 << 0)
+#define FPGA_DMA_INT_TX                (1 << 1)
+
+#define FPGA_RX_GROUPS_PER_INT_REG     0x158
+#define FPGA_TX_GROUPS_PER_INT_REG     0x15C
+#define FPGA_DMA_ADR_PAGE_REG          0x160
+#define FPGA_FPGA_REV_REG              0x200
+
+#define FPGA_ADC_CLOCK_CTL_REG         0x204
+#define FPGA_ADC_CLOCK_CTL_OSC_EN      (0x1 << 3)
+#define FPGA_ADC_CLOCK_LOCAL_CLK       (0x1 | FPGA_ADC_CLOCK_CTL_OSC_EN)
+#define FPGA_ADC_CLOCK_EXT_SAMP_CLK    0X0
+
+#define FPGA_ADC_DAC_EN_REG            0x208
+#define FPGA_ADC_DAC_EN_DAC_OFF         (0x1 << 1)
+#define FPGA_ADC_DAC_EN_ADC_OFF         (0x1 << 0)
+
+#define FPGA_INT_STAT_REG              0x20C
+#define FPGA_INT_MASK_REG              0x210
+#define FPGA_INT_PLL_UNLOCKED          (0x1 << 9)
+#define FPGA_INT_DMA_CORE              (0x1 << 8)
+#define FPGA_INT_TX_FF_EMPTY           (0x1 << 7)
+#define FPGA_INT_RX_FF_EMPTY           (0x1 << 6)
+#define FPGA_INT_TX_FF_OVRFLW          (0x1 << 3)
+#define FPGA_INT_RX_FF_OVRFLW          (0x1 << 2)
+#define FPGA_INT_TX_ACQ_DONE           (0x1 << 1)
+#define FPGA_INT_RX_ACQ_DONE           (0x1)
+
+#define FPGA_RX_ADC_CTL_REG            0x214
+#define FPGA_RX_ADC_CTL_CONT_CAP       (0x0)
+#define FPGA_RX_ADC_CTL_SNAP_CAP       (0x1)
+
+#define FPGA_RX_ARM_REG                        0x21C
+
+#define FPGA_DOM_REG                   0x224
+#define        FPGA_DOM_DCM_RESET              (0x1 << 5)
+#define FPGA_DOM_SOFT_RESET            (0x1 << 4)
+#define FPGA_DOM_DUAL_M_SG_DMA         (0x0)
+#define FPGA_DOM_TARGET_ACCESS         (0x1)
+
+#define FPGA_TX_CTL_REG                        0x228
+#define FPGA_TX_CTL_FIFO_FLUSH          (0x1 << 9)
+#define FPGA_TX_CTL_OUTPUT_ZERO         (0x0 << 2)
+#define FPGA_TX_CTL_OUTPUT_CARDBUS      (0x1 << 2)
+#define FPGA_TX_CTL_OUTPUT_ADC          (0x2 << 2)
+#define FPGA_TX_CTL_OUTPUT_SNAPSHOT     (0x3 << 2)
+#define FPGA_TX_CTL_LOOPBACK            (0x1 << 0)
+
+#define FPGA_ENDIAN_MODE_REG           0x22C
+#define FPGA_RX_FIFO_COUNT_REG         0x28C
+#define FPGA_TX_ENABLE_REG             0x298
+#define FPGA_TX_TRIGGER_REG            0x29C
+#define FPGA_TX_DATAMEM_COUNT_REG      0x2A8
+#define FPGA_CAP_FIFO_REG              0x300
+#define FPGA_TX_SNAPSHOT_REG           0x8000
+
+/*
+ * Channel Index Definitions
+ */
+
+enum {
+       CHNO_RX_CHANNEL,
+       CHNO_TX_CHANNEL,
+};
+
+struct poch_dev;
+
+enum channel_dir {
+       CHANNEL_DIR_RX,
+       CHANNEL_DIR_TX,
+};
+
+struct poch_group_info {
+       struct page *pg;
+       dma_addr_t dma_addr;
+       unsigned long user_offset;
+};
+
+struct channel_info {
+       unsigned int chno;
+
+       atomic_t sys_block_size;
+       atomic_t sys_group_size;
+       atomic_t sys_group_count;
+
+       enum channel_dir dir;
+
+       unsigned long block_size;
+       unsigned long group_size;
+       unsigned long group_count;
+
+       /* Contains the DMA address and VM offset of each group. */
+       struct poch_group_info *groups;
+
+       /* Contains the header and circular buffer exported to userspace. */
+       spinlock_t group_offsets_lock;
+       struct poch_cbuf_header *header;
+       struct page *header_pg;
+       unsigned long header_size;
+
+       /* Last group indicated as 'complete' to user space. */
+       unsigned int transfer;
+
+       wait_queue_head_t wq;
+
+       union {
+               unsigned int data_available;
+               unsigned int space_available;
+       };
+
+       void __iomem *bridge_iomem;
+       void __iomem *fpga_iomem;
+       spinlock_t *iomem_lock;
+
+       atomic_t free;
+       atomic_t inited;
+
+       /* Error counters */
+       struct poch_counters counters;
+       spinlock_t counters_lock;
+
+       struct device *dev;
+};
+
+struct poch_dev {
+       struct uio_info uio;
+       struct pci_dev *pci_dev;
+       unsigned int nchannels;
+       struct channel_info channels[POCH_NCHANNELS];
+       struct cdev cdev;
+
+       /* Counts the no. of channels that have been opened. On first
+        * open, the card is powered on. On last channel close, the
+        * card is powered off.
+        */
+       atomic_t usage;
+
+       void __iomem *bridge_iomem;
+       void __iomem *fpga_iomem;
+       spinlock_t iomem_lock;
+
+       struct device *dev;
+};
+
+static dev_t poch_first_dev;
+static struct class *poch_cls;
+static DEFINE_IDR(poch_ids);
+
+static ssize_t store_block_size(struct device *dev,
+                               struct device_attribute *attr,
+                               const char *buf, size_t count)
+{
+       struct channel_info *channel = dev_get_drvdata(dev);
+       unsigned long block_size;
+
+       sscanf(buf, "%lu", &block_size);
+       atomic_set(&channel->sys_block_size, block_size);
+
+       return count;
+}
+static DEVICE_ATTR(block_size, S_IWUSR|S_IWGRP, NULL, store_block_size);
+
+static ssize_t store_group_size(struct device *dev,
+                               struct device_attribute *attr,
+                               const char *buf, size_t count)
+{
+       struct channel_info *channel = dev_get_drvdata(dev);
+       unsigned long group_size;
+
+       sscanf(buf, "%lu", &group_size);
+       atomic_set(&channel->sys_group_size, group_size);
+
+       return count;
+}
+static DEVICE_ATTR(group_size, S_IWUSR|S_IWGRP, NULL, store_group_size);
+
+static ssize_t store_group_count(struct device *dev,
+                               struct device_attribute *attr,
+                                const char *buf, size_t count)
+{
+       struct channel_info *channel = dev_get_drvdata(dev);
+       unsigned long group_count;
+
+       sscanf(buf, "%lu", &group_count);
+       atomic_set(&channel->sys_group_count, group_count);
+
+       return count;
+}
+static DEVICE_ATTR(group_count, S_IWUSR|S_IWGRP, NULL, store_group_count);
+
+static ssize_t show_direction(struct device *dev,
+                             struct device_attribute *attr, char *buf)
+{
+       struct channel_info *channel = dev_get_drvdata(dev);
+       int len;
+
+       len = sprintf(buf, "%s\n", (channel->dir ? "tx" : "rx"));
+       return len;
+}
+static DEVICE_ATTR(dir, S_IRUSR|S_IRGRP, show_direction, NULL);
+
+static ssize_t show_mmap_size(struct device *dev,
+                             struct device_attribute *attr, char *buf)
+{
+       struct channel_info *channel = dev_get_drvdata(dev);
+       int len;
+       unsigned long mmap_size;
+       unsigned long group_pages;
+       unsigned long header_pages;
+       unsigned long total_group_pages;
+
+       /* FIXME: We do not have to add 1, if group_size a multiple of
+          PAGE_SIZE. */
+       group_pages = (channel->group_size / PAGE_SIZE) + 1;
+       header_pages = (channel->header_size / PAGE_SIZE) + 1;
+       total_group_pages = group_pages * channel->group_count;
+
+       mmap_size = (header_pages + total_group_pages) * PAGE_SIZE;
+       len = sprintf(buf, "%lu\n", mmap_size);
+       return len;
+}
+static DEVICE_ATTR(mmap_size, S_IRUSR|S_IRGRP, show_mmap_size, NULL);
+
+static struct device_attribute *poch_class_attrs[] = {
+       &dev_attr_block_size,
+       &dev_attr_group_size,
+       &dev_attr_group_count,
+       &dev_attr_dir,
+       &dev_attr_mmap_size,
+};
+
+static void poch_channel_free_groups(struct channel_info *channel)
+{
+       unsigned long i;
+
+       for (i = 0; i < channel->group_count; i++) {
+               struct poch_group_info *group;
+               unsigned int order;
+
+               group = &channel->groups[i];
+               order = get_order(channel->group_size);
+               if (group->pg)
+                       __free_pages(group->pg, order);
+       }
+}
+
+static int poch_channel_alloc_groups(struct channel_info *channel)
+{
+       unsigned long i;
+       unsigned long group_pages;
+       unsigned long header_pages;
+
+       group_pages = (channel->group_size / PAGE_SIZE) + 1;
+       header_pages = (channel->header_size / PAGE_SIZE) + 1;
+
+       for (i = 0; i < channel->group_count; i++) {
+               struct poch_group_info *group;
+               unsigned int order;
+               gfp_t gfp_mask;
+
+               group = &channel->groups[i];
+               order = get_order(channel->group_size);
+
+               /*
+                * __GFP_COMP is required here since we are going to
+                * perform non-linear mapping to userspace. For more
+                * information read the vm_insert_page() function
+                * comments.
+                */
+
+               gfp_mask = GFP_KERNEL | GFP_DMA32 | __GFP_ZERO;
+               group->pg = alloc_pages(gfp_mask, order);
+               if (!group->pg) {
+                       poch_channel_free_groups(channel);
+                       return -ENOMEM;
+               }
+
+               /* FIXME: This is the physical address not the bus
+                * address!  This won't work in architectures that
+                * have an IOMMU. Can we use pci_map_single() for
+                * this?
+                */
+               group->dma_addr = page_to_pfn(group->pg) * PAGE_SIZE;
+               group->user_offset =
+                       (header_pages + (i * group_pages)) * PAGE_SIZE;
+
+               printk(KERN_INFO PFX "%ld: user_offset: 0x%lx dma: 0x%x\n", i,
+                      group->user_offset, group->dma_addr);
+       }
+
+       return 0;
+}
+
+static void channel_latch_attr(struct channel_info *channel)
+{
+       channel->group_count = atomic_read(&channel->sys_group_count);
+       channel->group_size = atomic_read(&channel->sys_group_size);
+       channel->block_size = atomic_read(&channel->sys_block_size);
+}
+
+/*
+ * Configure DMA group registers
+ */
+static void channel_dma_init(struct channel_info *channel)
+{
+       void __iomem *fpga = channel->fpga_iomem;
+       u32 group_regs_base;
+       u32 group_reg;
+       unsigned int page;
+       unsigned int group_in_page;
+       unsigned long i;
+       u32 block_size_reg;
+       u32 block_count_reg;
+       u32 group_count_reg;
+       u32 groups_per_int_reg;
+       u32 curr_pci_reg;
+
+       if (channel->chno == CHNO_RX_CHANNEL) {
+               group_regs_base = FPGA_RX_GROUP0_START_REG;
+               block_size_reg = FPGA_RX_BLOCK_SIZE_REG;
+               block_count_reg = FPGA_RX_BLOCK_COUNT_REG;
+               group_count_reg = FPGA_RX_GROUP_COUNT_REG;
+               groups_per_int_reg = FPGA_RX_GROUPS_PER_INT_REG;
+               curr_pci_reg = FPGA_RX_CURR_PCI_REG;
+       } else {
+               group_regs_base = FPGA_TX_GROUP0_START_REG;
+               block_size_reg = FPGA_TX_BLOCK_SIZE_REG;
+               block_count_reg = FPGA_TX_BLOCK_COUNT_REG;
+               group_count_reg = FPGA_TX_GROUP_COUNT_REG;
+               groups_per_int_reg = FPGA_TX_GROUPS_PER_INT_REG;
+               curr_pci_reg = FPGA_TX_CURR_PCI_REG;
+       }
+
+       printk(KERN_WARNING "block_size, group_size, group_count\n");
+       iowrite32(channel->block_size, fpga + block_size_reg);
+       iowrite32(channel->group_size / channel->block_size,
+                 fpga + block_count_reg);
+       iowrite32(channel->group_count, fpga + group_count_reg);
+       /* FIXME: Hardcoded groups per int. Get it from sysfs? */
+       iowrite32(1, fpga + groups_per_int_reg);
+
+       /* Unlock PCI address? Not defined in the data sheet, but used
+        * in the reference code by Redrapids.
+        */
+       iowrite32(0x1, fpga + curr_pci_reg);
+
+       /* The DMA address page register is shared between the RX and
+        * TX channels, so acquire lock.
+        */
+       spin_lock(channel->iomem_lock);
+       for (i = 0; i < channel->group_count; i++) {
+               page = i / 32;
+               group_in_page = i % 32;
+
+               group_reg = group_regs_base + (group_in_page * 4);
+
+               iowrite32(page, fpga + FPGA_DMA_ADR_PAGE_REG);
+               iowrite32(channel->groups[i].dma_addr, fpga + group_reg);
+       }
+       for (i = 0; i < channel->group_count; i++) {
+               page = i / 32;
+               group_in_page = i % 32;
+
+               group_reg = group_regs_base + (group_in_page * 4);
+
+               iowrite32(page, fpga + FPGA_DMA_ADR_PAGE_REG);
+               printk(KERN_INFO PFX "%ld: read dma_addr: 0x%x\n", i,
+                      ioread32(fpga + group_reg));
+       }
+       spin_unlock(channel->iomem_lock);
+
+}
+
+static int poch_channel_alloc_header(struct channel_info *channel)
+{
+       struct poch_cbuf_header *header = channel->header;
+       unsigned long group_offset_size;
+       unsigned long tot_group_offsets_size;
+
+       /* Allocate memory to hold header exported userspace */
+       group_offset_size = sizeof(header->group_offsets[0]);
+       tot_group_offsets_size = group_offset_size * channel->group_count;
+       channel->header_size = sizeof(*header) + tot_group_offsets_size;
+       channel->header_pg = alloc_pages(GFP_KERNEL | __GFP_ZERO,
+                                        get_order(channel->header_size));
+       if (!channel->header_pg)
+               return -ENOMEM;
+
+       channel->header = page_address(channel->header_pg);
+
+       return 0;
+}
+
+static void poch_channel_free_header(struct channel_info *channel)
+{
+       unsigned int order;
+
+       order = get_order(channel->header_size);
+       __free_pages(channel->header_pg, order);
+}
+
+static void poch_channel_init_header(struct channel_info *channel)
+{
+       int i;
+       struct poch_group_info *groups;
+       s32 *group_offsets;
+
+       channel->header->group_size_bytes = channel->group_size;
+       channel->header->group_count = channel->group_count;
+
+       spin_lock_init(&channel->group_offsets_lock);
+
+       group_offsets = channel->header->group_offsets;
+       groups = channel->groups;
+
+       for (i = 0; i < channel->group_count; i++) {
+               if (channel->dir == CHANNEL_DIR_RX)
+                       group_offsets[i] = -1;
+               else
+                       group_offsets[i] = groups[i].user_offset;
+       }
+}
+
+static void __poch_channel_clear_counters(struct channel_info *channel)
+{
+       channel->counters.pll_unlock = 0;
+       channel->counters.fifo_empty = 0;
+       channel->counters.fifo_overflow = 0;
+}
+
+static int poch_channel_init(struct channel_info *channel,
+                            struct poch_dev *poch_dev)
+{
+       struct pci_dev *pdev = poch_dev->pci_dev;
+       struct device *dev = &pdev->dev;
+       unsigned long alloc_size;
+       int ret;
+
+       printk(KERN_WARNING "channel_latch_attr\n");
+
+       channel_latch_attr(channel);
+
+       channel->transfer = 0;
+
+       /* Allocate memory to hold group information. */
+       alloc_size = channel->group_count * sizeof(struct poch_group_info);
+       channel->groups = kzalloc(alloc_size, GFP_KERNEL);
+       if (!channel->groups) {
+               dev_err(dev, "error allocating memory for group info\n");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       printk(KERN_WARNING "poch_channel_alloc_groups\n");
+
+       ret = poch_channel_alloc_groups(channel);
+       if (ret) {
+               dev_err(dev, "error allocating groups of order %d\n",
+                       get_order(channel->group_size));
+               goto out_free_group_info;
+       }
+
+       ret = poch_channel_alloc_header(channel);
+       if (ret) {
+               dev_err(dev, "error allocating user space header\n");
+               goto out_free_groups;
+       }
+
+       channel->fpga_iomem = poch_dev->fpga_iomem;
+       channel->bridge_iomem = poch_dev->bridge_iomem;
+       channel->iomem_lock = &poch_dev->iomem_lock;
+       spin_lock_init(&channel->counters_lock);
+
+       __poch_channel_clear_counters(channel);
+
+       printk(KERN_WARNING "poch_channel_init_header\n");
+
+       poch_channel_init_header(channel);
+
+       return 0;
+
+ out_free_groups:
+       poch_channel_free_groups(channel);
+ out_free_group_info:
+       kfree(channel->groups);
+ out:
+       return ret;
+}
+
+static int poch_wait_fpga_prog(void __iomem *bridge)
+{
+       unsigned long total_wait;
+       const unsigned long wait_period = 100;
+       /* FIXME: Get the actual timeout */
+       const unsigned long prog_timeo = 10000; /* 10 Seconds */
+       u32 card_power;
+
+       printk(KERN_WARNING "poch_wait_fpg_prog\n");
+
+       printk(KERN_INFO PFX "programming fpga ...\n");
+       total_wait = 0;
+       while (1) {
+               msleep(wait_period);
+               total_wait += wait_period;
+
+               card_power = ioread32(bridge + BRIDGE_CARD_POWER_REG);
+               if (card_power & BRIDGE_CARD_POWER_PROG_DONE) {
+                       printk(KERN_INFO PFX "programming done\n");
+                       return 0;
+               }
+               if (total_wait > prog_timeo) {
+                       printk(KERN_ERR PFX
+                              "timed out while programming FPGA\n");
+                       return -EIO;
+               }
+       }
+}
+
+static void poch_card_power_off(struct poch_dev *poch_dev)
+{
+       void __iomem *bridge = poch_dev->bridge_iomem;
+       u32 card_power;
+
+       iowrite32(0, bridge + BRIDGE_INT_MASK_REG);
+       iowrite32(0, bridge + BRIDGE_DMA_GO_REG);
+
+       card_power = ioread32(bridge + BRIDGE_CARD_POWER_REG);
+       iowrite32(card_power & ~BRIDGE_CARD_POWER_EN,
+                 bridge + BRIDGE_CARD_POWER_REG);
+}
+
+enum clk_src {
+       CLK_SRC_ON_BOARD,
+       CLK_SRC_EXTERNAL
+};
+
+static void poch_card_clock_on(void __iomem *fpga)
+{
+       /* FIXME: Get this data through sysfs? */
+       enum clk_src clk_src = CLK_SRC_ON_BOARD;
+
+       if (clk_src == CLK_SRC_ON_BOARD) {
+               iowrite32(FPGA_ADC_CLOCK_LOCAL_CLK | FPGA_ADC_CLOCK_CTL_OSC_EN,
+                         fpga + FPGA_ADC_CLOCK_CTL_REG);
+       } else if (clk_src == CLK_SRC_EXTERNAL) {
+               iowrite32(FPGA_ADC_CLOCK_EXT_SAMP_CLK,
+                         fpga + FPGA_ADC_CLOCK_CTL_REG);
+       }
+}
+
+static int poch_card_power_on(struct poch_dev *poch_dev)
+{
+       void __iomem *bridge = poch_dev->bridge_iomem;
+       void __iomem *fpga = poch_dev->fpga_iomem;
+
+       iowrite32(BRIDGE_CARD_POWER_EN, bridge + BRIDGE_CARD_POWER_REG);
+
+       if (poch_wait_fpga_prog(bridge) != 0) {
+               poch_card_power_off(poch_dev);
+               return -EIO;
+       }
+
+       poch_card_clock_on(fpga);
+
+       /* Sync to new clock, reset state machines, set DMA mode. */
+       iowrite32(FPGA_DOM_DCM_RESET | FPGA_DOM_SOFT_RESET
+                 | FPGA_DOM_DUAL_M_SG_DMA, fpga + FPGA_DOM_REG);
+
+       /* FIXME: The time required for sync. needs to be tuned. */
+       msleep(1000);
+
+       return 0;
+}
+
+static void poch_channel_analog_on(struct channel_info *channel)
+{
+       void __iomem *fpga = channel->fpga_iomem;
+       u32 adc_dac_en;
+
+       spin_lock(channel->iomem_lock);
+       adc_dac_en = ioread32(fpga + FPGA_ADC_DAC_EN_REG);
+       switch (channel->chno) {
+       case CHNO_RX_CHANNEL:
+               iowrite32(adc_dac_en & ~FPGA_ADC_DAC_EN_ADC_OFF,
+                         fpga + FPGA_ADC_DAC_EN_REG);
+               break;
+       case CHNO_TX_CHANNEL:
+               iowrite32(adc_dac_en & ~FPGA_ADC_DAC_EN_DAC_OFF,
+                         fpga + FPGA_ADC_DAC_EN_REG);
+               break;
+       }
+       spin_unlock(channel->iomem_lock);
+}
+
+static int poch_open(struct inode *inode, struct file *filp)
+{
+       struct poch_dev *poch_dev;
+       struct channel_info *channel;
+       void __iomem *bridge;
+       void __iomem *fpga;
+       int chno;
+       int usage;
+       int ret;
+
+       poch_dev = container_of(inode->i_cdev, struct poch_dev, cdev);
+       bridge = poch_dev->bridge_iomem;
+       fpga = poch_dev->fpga_iomem;
+
+       chno = iminor(inode) % poch_dev->nchannels;
+       channel = &poch_dev->channels[chno];
+
+       if (!atomic_dec_and_test(&channel->free)) {
+               atomic_inc(&channel->free);
+               ret = -EBUSY;
+               goto out;
+       }
+
+       usage = atomic_inc_return(&poch_dev->usage);
+
+       printk(KERN_WARNING "poch_card_power_on\n");
+
+       if (usage == 1) {
+               ret = poch_card_power_on(poch_dev);
+               if (ret)
+                       goto out_dec_usage;
+       }
+
+       printk(KERN_INFO "CardBus Bridge Revision: %x\n",
+              ioread32(bridge + BRIDGE_REV_REG));
+       printk(KERN_INFO "CardBus Interface Revision: %x\n",
+              ioread32(fpga + FPGA_IFACE_REV_REG));
+
+       channel->chno = chno;
+       filp->private_data = channel;
+
+       printk(KERN_WARNING "poch_channel_init\n");
+
+       ret = poch_channel_init(channel, poch_dev);
+       if (ret)
+               goto out_power_off;
+
+       poch_channel_analog_on(channel);
+
+       printk(KERN_WARNING "channel_dma_init\n");
+
+       channel_dma_init(channel);
+
+       printk(KERN_WARNING "poch_channel_analog_on\n");
+
+       if (usage == 1) {
+               printk(KERN_WARNING "setting up DMA\n");
+
+               /* Initialize DMA Controller. */
+               iowrite32(FPGA_CAP_FIFO_REG, bridge + BRIDGE_STAT_2_REG);
+               iowrite32(FPGA_DMA_DESC_1_REG, bridge + BRIDGE_STAT_3_REG);
+
+               ioread32(fpga + FPGA_DMA_INT_STAT_REG);
+               ioread32(fpga + FPGA_INT_STAT_REG);
+               ioread32(bridge + BRIDGE_INT_STAT_REG);
+
+               /* Initialize Interrupts. FIXME: Enable temperature
+                * handling We are enabling both Tx and Rx channel
+                * interrupts here. Do we need to enable interrupts
+                * only for the current channel? Anyways we won't get
+                * the interrupt unless the DMA is activated.
+                */
+               iowrite32(BRIDGE_INT_FPGA, bridge + BRIDGE_INT_MASK_REG);
+               iowrite32(FPGA_INT_DMA_CORE
+                         | FPGA_INT_PLL_UNLOCKED
+                         | FPGA_INT_TX_FF_EMPTY
+                         | FPGA_INT_RX_FF_EMPTY
+                         | FPGA_INT_TX_FF_OVRFLW
+                         | FPGA_INT_RX_FF_OVRFLW,
+                         fpga + FPGA_INT_MASK_REG);
+               iowrite32(FPGA_DMA_INT_RX | FPGA_DMA_INT_TX,
+                         fpga + FPGA_DMA_INT_MASK_REG);
+       }
+
+       if (channel->dir == CHANNEL_DIR_TX) {
+               /* Flush TX FIFO and output data from cardbus. */
+               iowrite32(FPGA_TX_CTL_FIFO_FLUSH
+                         | FPGA_TX_CTL_OUTPUT_CARDBUS,
+                         fpga + FPGA_TX_CTL_REG);
+       }
+
+       atomic_inc(&channel->inited);
+
+       return 0;
+
+ out_power_off:
+       if (usage == 1)
+               poch_card_power_off(poch_dev);
+ out_dec_usage:
+       atomic_dec(&poch_dev->usage);
+       atomic_inc(&channel->free);
+ out:
+       return ret;
+}
+
+static int poch_release(struct inode *inode, struct file *filp)
+{
+       struct channel_info *channel = filp->private_data;
+       struct poch_dev *poch_dev;
+       int usage;
+
+       poch_dev = container_of(inode->i_cdev, struct poch_dev, cdev);
+
+       usage = atomic_dec_return(&poch_dev->usage);
+       if (usage == 0) {
+               printk(KERN_WARNING "poch_card_power_off\n");
+               poch_card_power_off(poch_dev);
+       }
+
+       atomic_dec(&channel->inited);
+       poch_channel_free_header(channel);
+       poch_channel_free_groups(channel);
+       kfree(channel->groups);
+       atomic_inc(&channel->free);
+
+       return 0;
+}
+
+/*
+ * Map the header and the group buffers, to user space.
+ */
+static int poch_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+       struct channel_info *channel = filp->private_data;
+
+       unsigned long start;
+       unsigned long size;
+
+       unsigned long group_pages;
+       unsigned long header_pages;
+       unsigned long total_group_pages;
+
+       int pg_num;
+       struct page *pg;
+
+       int i;
+       int ret;
+
+       printk(KERN_WARNING "poch_mmap\n");
+
+       if (vma->vm_pgoff) {
+               printk(KERN_WARNING PFX "page offset: %lu\n", vma->vm_pgoff);
+               return -EINVAL;
+       }
+
+       group_pages = (channel->group_size / PAGE_SIZE) + 1;
+       header_pages = (channel->header_size / PAGE_SIZE) + 1;
+       total_group_pages = group_pages * channel->group_count;
+
+       size = vma->vm_end - vma->vm_start;
+       if (size != (header_pages + total_group_pages) * PAGE_SIZE) {
+               printk(KERN_WARNING PFX "required %lu bytes\n", size);
+               return -EINVAL;
+       }
+
+       start = vma->vm_start;
+
+       /* FIXME: Cleanup required on failure? */
+       pg = channel->header_pg;
+       for (pg_num = 0; pg_num < header_pages; pg_num++, pg++) {
+               printk(KERN_DEBUG PFX "page_count: %d\n", page_count(pg));
+               printk(KERN_DEBUG PFX "%d: header: 0x%lx\n", pg_num, start);
+               ret = vm_insert_page(vma, start, pg);
+               if (ret) {
+                       printk(KERN_DEBUG "vm_insert 1 failed at %lx\n", start);
+                       return ret;
+               }
+               start += PAGE_SIZE;
+       }
+
+       for (i = 0; i < channel->group_count; i++) {
+               pg = channel->groups[i].pg;
+               for (pg_num = 0; pg_num < group_pages; pg_num++, pg++) {
+                       printk(KERN_DEBUG PFX "%d: group %d: 0x%lx\n",
+                              pg_num, i, start);
+                       ret = vm_insert_page(vma, start, pg);
+                       if (ret) {
+                               printk(KERN_DEBUG PFX
+                                      "vm_insert 2 failed at %d\n", pg_num);
+                               return ret;
+                       }
+                       start += PAGE_SIZE;
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * Check whether there is some group that the user space has not
+ * consumed yet. When the user space consumes a group, it sets it to
+ * -1. Cosuming could be reading data in case of RX and filling a
+ * buffer in case of TX.
+ */
+static int poch_channel_available(struct channel_info *channel)
+{
+       int i;
+
+       spin_lock_irq(&channel->group_offsets_lock);
+
+       for (i = 0; i < channel->group_count; i++) {
+               if (channel->dir == CHANNEL_DIR_RX
+                   && channel->header->group_offsets[i] == -1) {
+                       spin_unlock_irq(&channel->group_offsets_lock);
+                       return 1;
+               }
+
+               if (channel->dir == CHANNEL_DIR_TX
+                   && channel->header->group_offsets[i] != -1) {
+                       spin_unlock_irq(&channel->group_offsets_lock);
+                       return 1;
+               }
+       }
+
+       spin_unlock_irq(&channel->group_offsets_lock);
+
+       return 0;
+}
+
+static unsigned int poch_poll(struct file *filp, poll_table *pt)
+{
+       struct channel_info *channel = filp->private_data;
+       unsigned int ret = 0;
+
+       poll_wait(filp, &channel->wq, pt);
+
+       if (poch_channel_available(channel)) {
+               if (channel->dir == CHANNEL_DIR_RX)
+                       ret = POLLIN | POLLRDNORM;
+               else
+                       ret = POLLOUT | POLLWRNORM;
+       }
+
+       return ret;
+}
+
+static int poch_ioctl(struct inode *inode, struct file *filp,
+                     unsigned int cmd, unsigned long arg)
+{
+       struct channel_info *channel = filp->private_data;
+       void __iomem *fpga = channel->fpga_iomem;
+       void __iomem *bridge = channel->bridge_iomem;
+       void __user *argp = (void __user *)arg;
+       struct vm_area_struct *vms;
+       struct poch_counters counters;
+       int ret;
+
+       switch (cmd) {
+       case POCH_IOC_TRANSFER_START:
+               switch (channel->chno) {
+               case CHNO_TX_CHANNEL:
+                       printk(KERN_INFO PFX "ioctl: Tx start\n");
+                       iowrite32(0x1, fpga + FPGA_TX_TRIGGER_REG);
+                       iowrite32(0x1, fpga + FPGA_TX_ENABLE_REG);
+
+                       /* FIXME: Does it make sense to do a DMA GO
+                        * twice, once in Tx and once in Rx.
+                        */
+                       iowrite32(0x1, bridge + BRIDGE_DMA_GO_REG);
+                       break;
+               case CHNO_RX_CHANNEL:
+                       printk(KERN_INFO PFX "ioctl: Rx start\n");
+                       iowrite32(0x1, fpga + FPGA_RX_ARM_REG);
+                       iowrite32(0x1, bridge + BRIDGE_DMA_GO_REG);
+                       break;
+               }
+               break;
+       case POCH_IOC_TRANSFER_STOP:
+               switch (channel->chno) {
+               case CHNO_TX_CHANNEL:
+                       printk(KERN_INFO PFX "ioctl: Tx stop\n");
+                       iowrite32(0x0, fpga + FPGA_TX_ENABLE_REG);
+                       iowrite32(0x0, fpga + FPGA_TX_TRIGGER_REG);
+                       iowrite32(0x0, bridge + BRIDGE_DMA_GO_REG);
+                       break;
+               case CHNO_RX_CHANNEL:
+                       printk(KERN_INFO PFX "ioctl: Rx stop\n");
+                       iowrite32(0x0, fpga + FPGA_RX_ARM_REG);
+                       iowrite32(0x0, bridge + BRIDGE_DMA_GO_REG);
+                       break;
+               }
+               break;
+       case POCH_IOC_GET_COUNTERS:
+               if (access_ok(VERIFY_WRITE, argp, sizeof(struct poch_counters)))
+                       return -EFAULT;
+
+               spin_lock_irq(&channel->counters_lock);
+               counters = channel->counters;
+               __poch_channel_clear_counters(channel);
+               spin_unlock_irq(&channel->counters_lock);
+
+               ret = copy_to_user(argp, &counters,
+                                  sizeof(struct poch_counters));
+               if (ret)
+                       return ret;
+
+               break;
+       case POCH_IOC_SYNC_GROUP_FOR_USER:
+       case POCH_IOC_SYNC_GROUP_FOR_DEVICE:
+               vms = find_vma(current->mm, arg);
+               if (!vms)
+                       /* Address not mapped. */
+                       return -EINVAL;
+               if (vms->vm_file != filp)
+                       /* Address mapped from different device/file. */
+                       return -EINVAL;
+
+               flush_cache_range(vms, arg, arg + channel->group_size);
+               break;
+       }
+       return 0;
+}
+
+static struct file_operations poch_fops = {
+       .owner = THIS_MODULE,
+       .open = poch_open,
+       .release = poch_release,
+       .ioctl = poch_ioctl,
+       .poll = poch_poll,
+       .mmap = poch_mmap
+};
+
+static void poch_irq_dma(struct channel_info *channel)
+{
+       u32 prev_transfer;
+       u32 curr_transfer;
+       long groups_done;
+       unsigned long i, j;
+       struct poch_group_info *groups;
+       s32 *group_offsets;
+       u32 curr_group_reg;
+
+       if (!atomic_read(&channel->inited))
+               return;
+
+       prev_transfer = channel->transfer;
+
+       if (channel->chno == CHNO_RX_CHANNEL)
+               curr_group_reg = FPGA_RX_CURR_GROUP_REG;
+       else
+               curr_group_reg = FPGA_TX_CURR_GROUP_REG;
+
+       curr_transfer = ioread32(channel->fpga_iomem + curr_group_reg);
+
+       groups_done = curr_transfer - prev_transfer;
+       /* Check wrap over, and handle it. */
+       if (groups_done <= 0)
+               groups_done += channel->group_count;
+
+       group_offsets = channel->header->group_offsets;
+       groups = channel->groups;
+
+       spin_lock(&channel->group_offsets_lock);
+
+       for (i = 0; i < groups_done; i++) {
+               j = (prev_transfer + i) % channel->group_count;
+               if (channel->dir == CHANNEL_DIR_RX)
+                       group_offsets[j] = -1;
+               else
+                       group_offsets[j] = groups[j].user_offset;
+       }
+
+       spin_unlock(&channel->group_offsets_lock);
+
+       channel->transfer = curr_transfer;
+
+       wake_up_interruptible(&channel->wq);
+}
+
+static irqreturn_t poch_irq_handler(int irq, void *p)
+{
+       struct poch_dev *poch_dev = p;
+       void __iomem *bridge = poch_dev->bridge_iomem;
+       void __iomem *fpga = poch_dev->fpga_iomem;
+       struct channel_info *channel_rx = &poch_dev->channels[CHNO_RX_CHANNEL];
+       struct channel_info *channel_tx = &poch_dev->channels[CHNO_TX_CHANNEL];
+       u32 bridge_stat;
+       u32 fpga_stat;
+       u32 dma_stat;
+
+       bridge_stat = ioread32(bridge + BRIDGE_INT_STAT_REG);
+       fpga_stat = ioread32(fpga + FPGA_INT_STAT_REG);
+       dma_stat = ioread32(fpga + FPGA_DMA_INT_STAT_REG);
+
+       ioread32(fpga + FPGA_DMA_INT_STAT_REG);
+       ioread32(fpga + FPGA_INT_STAT_REG);
+       ioread32(bridge + BRIDGE_INT_STAT_REG);
+
+       if (bridge_stat & BRIDGE_INT_FPGA) {
+               if (fpga_stat & FPGA_INT_DMA_CORE) {
+                       if (dma_stat & FPGA_DMA_INT_RX)
+                               poch_irq_dma(channel_rx);
+                       if (dma_stat & FPGA_DMA_INT_TX)
+                               poch_irq_dma(channel_tx);
+               }
+               if (fpga_stat & FPGA_INT_PLL_UNLOCKED) {
+                       channel_tx->counters.pll_unlock++;
+                       channel_rx->counters.pll_unlock++;
+                       if (printk_ratelimit())
+                               printk(KERN_WARNING PFX "PLL unlocked\n");
+               }
+               if (fpga_stat & FPGA_INT_TX_FF_EMPTY)
+                       channel_tx->counters.fifo_empty++;
+               if (fpga_stat & FPGA_INT_TX_FF_OVRFLW)
+                       channel_tx->counters.fifo_overflow++;
+               if (fpga_stat & FPGA_INT_RX_FF_EMPTY)
+                       channel_rx->counters.fifo_empty++;
+               if (fpga_stat & FPGA_INT_RX_FF_OVRFLW)
+                       channel_rx->counters.fifo_overflow++;
+
+               /*
+                * FIXME: These errors should be notified through the
+                * poll interface as POLLERR.
+                */
+
+               /* Re-enable interrupts. */
+               iowrite32(BRIDGE_INT_FPGA, bridge + BRIDGE_INT_MASK_REG);
+
+               return IRQ_HANDLED;
+       }
+
+       return IRQ_NONE;
+}
+
+static void poch_class_dev_unregister(struct poch_dev *poch_dev, int id)
+{
+       int i, j;
+       int nattrs;
+       struct channel_info *channel;
+       dev_t devno;
+
+       if (poch_dev->dev == NULL)
+               return;
+
+       for (i = 0; i < poch_dev->nchannels; i++) {
+               channel = &poch_dev->channels[i];
+               devno = poch_first_dev + (id * poch_dev->nchannels) + i;
+
+               if (!channel->dev)
+                       continue;
+
+               nattrs = sizeof(poch_class_attrs)/sizeof(poch_class_attrs[0]);
+               for (j = 0; j < nattrs; j++)
+                       device_remove_file(channel->dev, poch_class_attrs[j]);
+
+               device_unregister(channel->dev);
+       }
+
+       device_unregister(poch_dev->dev);
+}
+
+static int __devinit poch_class_dev_register(struct poch_dev *poch_dev,
+                                            int id)
+{
+       struct device *dev = &poch_dev->pci_dev->dev;
+       int i, j;
+       int nattrs;
+       int ret;
+       struct channel_info *channel;
+       dev_t devno;
+
+       poch_dev->dev = device_create(poch_cls, &poch_dev->pci_dev->dev,
+                                     MKDEV(0, 0), NULL, "poch%d", id);
+       if (IS_ERR(poch_dev->dev)) {
+               dev_err(dev, "error creating parent class device");
+               ret = PTR_ERR(poch_dev->dev);
+               poch_dev->dev = NULL;
+               return ret;
+       }
+
+       for (i = 0; i < poch_dev->nchannels; i++) {
+               channel = &poch_dev->channels[i];
+
+               devno = poch_first_dev + (id * poch_dev->nchannels) + i;
+               channel->dev = device_create(poch_cls, poch_dev->dev, devno,
+                                            NULL, "ch%d", i);
+               if (IS_ERR(channel->dev)) {
+                       dev_err(dev, "error creating channel class device");
+                       ret = PTR_ERR(channel->dev);
+                       channel->dev = NULL;
+                       poch_class_dev_unregister(poch_dev, id);
+                       return ret;
+               }
+
+               dev_set_drvdata(channel->dev, channel);
+               nattrs = sizeof(poch_class_attrs)/sizeof(poch_class_attrs[0]);
+               for (j = 0; j < nattrs; j++) {
+                       ret = device_create_file(channel->dev,
+                                                poch_class_attrs[j]);
+                       if (ret) {
+                               dev_err(dev, "error creating attribute file");
+                               poch_class_dev_unregister(poch_dev, id);
+                               return ret;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static int __devinit poch_pci_probe(struct pci_dev *pdev,
+                                   const struct pci_device_id *pci_id)
+{
+       struct device *dev = &pdev->dev;
+       struct poch_dev *poch_dev;
+       struct uio_info *uio;
+       int ret;
+       int id;
+       int i;
+
+       poch_dev = kzalloc(sizeof(struct poch_dev), GFP_KERNEL);
+       if (!poch_dev) {
+               dev_err(dev, "error allocating priv. data memory\n");
+               return -ENOMEM;
+       }
+
+       poch_dev->pci_dev = pdev;
+       uio = &poch_dev->uio;
+
+       pci_set_drvdata(pdev, poch_dev);
+
+       spin_lock_init(&poch_dev->iomem_lock);
+
+       poch_dev->nchannels = POCH_NCHANNELS;
+       poch_dev->channels[CHNO_RX_CHANNEL].dir = CHANNEL_DIR_RX;
+       poch_dev->channels[CHNO_TX_CHANNEL].dir = CHANNEL_DIR_TX;
+
+       for (i = 0; i < poch_dev->nchannels; i++) {
+               init_waitqueue_head(&poch_dev->channels[i].wq);
+               atomic_set(&poch_dev->channels[i].free, 1);
+               atomic_set(&poch_dev->channels[i].inited, 0);
+       }
+
+       ret = pci_enable_device(pdev);
+       if (ret) {
+               dev_err(dev, "error enabling device\n");
+               goto out_free;
+       }
+
+       ret = pci_request_regions(pdev, "poch");
+       if (ret) {
+               dev_err(dev, "error requesting resources\n");
+               goto out_disable;
+       }
+
+       uio->mem[0].addr = pci_resource_start(pdev, 1);
+       if (!uio->mem[0].addr) {
+               dev_err(dev, "invalid BAR1\n");
+               ret = -ENODEV;
+               goto out_release;
+       }
+
+       uio->mem[0].size = pci_resource_len(pdev, 1);
+       uio->mem[0].memtype = UIO_MEM_PHYS;
+
+       uio->name = "poch";
+       uio->version = "0.0.1";
+       uio->irq = -1;
+       ret = uio_register_device(dev, uio);
+       if (ret) {
+               dev_err(dev, "error register UIO device: %d\n", ret);
+               goto out_release;
+       }
+
+       poch_dev->bridge_iomem = ioremap(pci_resource_start(pdev, 0),
+                                        pci_resource_len(pdev, 0));
+       if (poch_dev->bridge_iomem == NULL) {
+               dev_err(dev, "error mapping bridge (bar0) registers\n");
+               ret = -ENOMEM;
+               goto out_uio_unreg;
+       }
+
+       poch_dev->fpga_iomem = ioremap(pci_resource_start(pdev, 1),
+                                      pci_resource_len(pdev, 1));
+       if (poch_dev->fpga_iomem == NULL) {
+               dev_err(dev, "error mapping fpga (bar1) registers\n");
+               ret = -ENOMEM;
+               goto out_bar0_unmap;
+       }
+
+       ret = request_irq(pdev->irq, poch_irq_handler, IRQF_SHARED,
+                         dev->bus_id, poch_dev);
+       if (ret) {
+               dev_err(dev, "error requesting IRQ %u\n", pdev->irq);
+               ret = -ENOMEM;
+               goto out_bar1_unmap;
+       }
+
+       if (!idr_pre_get(&poch_ids, GFP_KERNEL)) {
+               dev_err(dev, "error allocating memory ids\n");
+               ret = -ENOMEM;
+               goto out_free_irq;
+       }
+
+       idr_get_new(&poch_ids, poch_dev, &id);
+       if (id >= MAX_POCH_CARDS) {
+               dev_err(dev, "minors exhausted\n");
+               ret = -EBUSY;
+               goto out_free_irq;
+       }
+
+       cdev_init(&poch_dev->cdev, &poch_fops);
+       poch_dev->cdev.owner = THIS_MODULE;
+       ret = cdev_add(&poch_dev->cdev,
+                      poch_first_dev + (id * poch_dev->nchannels),
+                      poch_dev->nchannels);
+       if (ret) {
+               dev_err(dev, "error register character device\n");
+               goto out_idr_remove;
+       }
+
+       ret = poch_class_dev_register(poch_dev, id);
+       if (ret)
+               goto out_cdev_del;
+
+       return 0;
+
+ out_cdev_del:
+       cdev_del(&poch_dev->cdev);
+ out_idr_remove:
+       idr_remove(&poch_ids, id);
+ out_free_irq:
+       free_irq(pdev->irq, poch_dev);
+ out_bar1_unmap:
+       iounmap(poch_dev->fpga_iomem);
+ out_bar0_unmap:
+       iounmap(poch_dev->bridge_iomem);
+ out_uio_unreg:
+       uio_unregister_device(uio);
+ out_release:
+       pci_release_regions(pdev);
+ out_disable:
+       pci_disable_device(pdev);
+ out_free:
+       kfree(poch_dev);
+       return ret;
+}
+
+/*
+ * FIXME: We are yet to handle the hot unplug case.
+ */
+static void poch_pci_remove(struct pci_dev *pdev)
+{
+       struct poch_dev *poch_dev = pci_get_drvdata(pdev);
+       struct uio_info *uio = &poch_dev->uio;
+       unsigned int minor = MINOR(poch_dev->cdev.dev);
+       unsigned int id = minor / poch_dev->nchannels;
+
+       /* FIXME: unmap fpga_iomem and bridge_iomem */
+
+       poch_class_dev_unregister(poch_dev, id);
+       cdev_del(&poch_dev->cdev);
+       idr_remove(&poch_ids, id);
+       free_irq(pdev->irq, poch_dev);
+       uio_unregister_device(uio);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+       pci_set_drvdata(pdev, NULL);
+       iounmap(uio->mem[0].internal_addr);
+
+       kfree(poch_dev);
+}
+
+static const struct pci_device_id poch_pci_ids[] /* __devinitconst */ = {
+       { PCI_DEVICE(PCI_VENDOR_ID_RRAPIDS,
+                    PCI_DEVICE_ID_RRAPIDS_POCKET_CHANGE) },
+       { 0, }
+};
+
+static struct pci_driver poch_pci_driver = {
+       .name = DRV_NAME,
+       .id_table = poch_pci_ids,
+       .probe = poch_pci_probe,
+       .remove = poch_pci_remove,
+};
+
+static int __init poch_init_module(void)
+{
+       int ret = 0;
+
+       ret = alloc_chrdev_region(&poch_first_dev, 0,
+                                 MAX_POCH_DEVICES, DRV_NAME);
+       if (ret) {
+               printk(KERN_ERR PFX "error allocating device no.");
+               return ret;
+       }
+
+       poch_cls = class_create(THIS_MODULE, "pocketchange");
+       if (IS_ERR(poch_cls)) {
+               ret = PTR_ERR(poch_cls);
+               goto out_unreg_chrdev;
+       }
+
+       ret = pci_register_driver(&poch_pci_driver);
+       if (ret) {
+               printk(KERN_ERR PFX "error register PCI device");
+               goto out_class_destroy;
+       }
+
+       return 0;
+
+ out_class_destroy:
+       class_destroy(poch_cls);
+
+ out_unreg_chrdev:
+       unregister_chrdev_region(poch_first_dev, MAX_POCH_DEVICES);
+
+       return ret;
+}
+
+static void __exit poch_exit_module(void)
+{
+       pci_unregister_driver(&poch_pci_driver);
+       class_destroy(poch_cls);
+       unregister_chrdev_region(poch_first_dev, MAX_POCH_DEVICES);
+}
+
+module_init(poch_init_module);
+module_exit(poch_exit_module);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/poch/poch.h b/drivers/staging/poch/poch.h
new file mode 100644 (file)
index 0000000..51a2d14
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * User-space DMA and UIO based Redrapids Pocket Change CardBus driver
+ *
+ * Copyright 2008 Vijay Kumar <vijaykumar@bravegnu.org>
+ *
+ * Part of userspace API. Should be moved to a header file in
+ * include/linux for final version.
+ *
+ */
+struct poch_cbuf_header {
+       __s32 group_size_bytes;
+       __s32 group_count;
+       __s32 group_offsets[0];
+};
+
+struct poch_counters {
+       __u32 fifo_empty;
+       __u32 fifo_overflow;
+       __u32 pll_unlock;
+};
+
+#define POCH_IOC_NUM                   '9'
+
+#define POCH_IOC_TRANSFER_START                _IO(POCH_IOC_NUM, 0)
+#define POCH_IOC_TRANSFER_STOP         _IO(POCH_IOC_NUM, 1)
+#define POCH_IOC_GET_COUNTERS          _IOR(POCH_IOC_NUM, 2, \
+                                            struct poch_counters)
+#define POCH_IOC_SYNC_GROUP_FOR_USER   _IO(POCH_IOC_NUM, 3)
+#define POCH_IOC_SYNC_GROUP_FOR_DEVICE _IO(POCH_IOC_NUM, 4)
index b61ac4b2db9e1cc3f4b72ae081f442cc94790ee2..8fa9490b3e2ca707320e3ccafc28d21089a07b26 100644 (file)
@@ -54,7 +54,6 @@
  *       IS-NIC driver.
  */
 
-#include <linux/version.h>
 
 #define SLIC_DUMP_ENABLED               0
 #define KLUDGE_FOR_4GB_BOUNDARY         1
 #include <linux/moduleparam.h>
 
 #include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/pci.h>
 #include <linux/dma-mapping.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
 #include <linux/mii.h>
 #include <linux/if_vlan.h>
-#include <linux/skbuff.h>
-#include <linux/string.h>
 #include <asm/unaligned.h>
 
 #include <linux/ethtool.h>
@@ -275,7 +266,6 @@ static void slic_dbg_register_trace(struct adapter *adapter,
                          card->reg_value[i], card->reg_valueh[i]);
        }
 }
-}
 #endif
 
 static void slic_init_adapter(struct net_device *netdev,
@@ -606,6 +596,7 @@ static void __devexit slic_entry_remove(struct pci_dev *pcidev)
        uint mmio_len = 0;
        struct adapter *adapter = (struct adapter *) netdev_priv(dev);
        struct sliccard *card;
+       struct mcast_address *mcaddr, *mlist;
 
        ASSERT(adapter);
        DBG_MSG("slicoss: %s ENTER dev[%p] adapter[%p]\n", __func__, dev,
@@ -625,6 +616,13 @@ static void __devexit slic_entry_remove(struct pci_dev *pcidev)
        DBG_MSG("slicoss: %s iounmap dev->base_addr[%x]\n", __func__,
                (uint) dev->base_addr);
        iounmap((void __iomem *)dev->base_addr);
+       /* free multicast addresses */
+       mlist = adapter->mcastaddrs;
+       while (mlist) {
+               mcaddr = mlist;
+               mlist = mlist->next;
+               kfree(mcaddr);
+       }
        ASSERT(adapter->card);
        card = adapter->card;
        ASSERT(card->adapters_allocated);
index 4d1ddbe4c33527326c5188f1bbe8f3c0fdd41598..d514d1848803e0e5381c816f49d3c70e997d6bb9 100644 (file)
@@ -7,6 +7,7 @@ TODO:
        - remove wrappers
        - checkpatch.pl cleanups
        - new functionality that the card needs
+       - remove reliance on x86
 
 Please send patches to:
         Greg Kroah-Hartman <gregkh@suse.de>
index 6ccbee875ab3d6bd6bbfb080c8ae4e02d0b2ef8c..5272a18e2043ec3539fabc91e050d298820d83f2 100644 (file)
@@ -112,12 +112,16 @@ static bool sxg_mac_filter(p_adapter_t adapter,
 static struct net_device_stats *sxg_get_stats(p_net_device dev);
 #endif
 
+#define XXXTODO 0
+
+#if XXXTODO
 static int sxg_mac_set_address(p_net_device dev, void *ptr);
+static void sxg_mcast_set_list(p_net_device dev);
+#endif
 
 static void sxg_adapter_set_hwaddr(p_adapter_t adapter);
 
 static void sxg_unmap_mmio_space(p_adapter_t adapter);
-static void sxg_mcast_set_mask(p_adapter_t adapter);
 
 static int sxg_initialize_adapter(p_adapter_t adapter);
 static void sxg_stock_rcv_buffers(p_adapter_t adapter);
@@ -132,9 +136,6 @@ static int sxg_write_mdio_reg(p_adapter_t adapter,
                              u32 DevAddr, u32 RegAddr, u32 Value);
 static int sxg_read_mdio_reg(p_adapter_t adapter,
                             u32 DevAddr, u32 RegAddr, u32 *pValue);
-static void sxg_mcast_set_list(p_net_device dev);
-
-#define XXXTODO 0
 
 static unsigned int sxg_first_init = 1;
 static char *sxg_banner =
@@ -202,7 +203,7 @@ static void sxg_init_driver(void)
 {
        if (sxg_first_init) {
                DBG_ERROR("sxg: %s sxg_first_init set jiffies[%lx]\n",
-                         __FUNCTION__, jiffies);
+                         __func__, jiffies);
                sxg_first_init = 0;
                spin_lock_init(&sxg_global.driver_lock);
        }
@@ -223,7 +224,7 @@ static void sxg_dbg_macaddrs(p_adapter_t adapter)
        return;
 }
 
-// SXG Globals
+/* SXG Globals */
 static SXG_DRIVER SxgDriver;
 
 #ifdef  ATKDBG
@@ -250,7 +251,7 @@ static bool sxg_download_microcode(p_adapter_t adapter, SXG_UCODE_SEL UcodeSel)
        u32 ThisSectionSize;
        u32 *Instruction = NULL;
        u32 BaseAddress, AddressOffset, Address;
-//      u32                         Failure;
+/*      u32                         Failure; */
        u32 ValueRead;
        u32 i;
        u32 numSections = 0;
@@ -259,10 +260,10 @@ static bool sxg_download_microcode(p_adapter_t adapter, SXG_UCODE_SEL UcodeSel)
 
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DnldUcod",
                  adapter, 0, 0, 0);
-       DBG_ERROR("sxg: %s ENTER\n", __FUNCTION__);
+       DBG_ERROR("sxg: %s ENTER\n", __func__);
 
        switch (UcodeSel) {
-       case SXG_UCODE_SAHARA:  // Sahara operational ucode
+       case SXG_UCODE_SAHARA:  /* Sahara operational ucode */
                numSections = SNumSections;
                for (i = 0; i < numSections; i++) {
                        sectionSize[i] = SSectionSize[i];
@@ -276,13 +277,13 @@ static bool sxg_download_microcode(p_adapter_t adapter, SXG_UCODE_SEL UcodeSel)
        }
 
        DBG_ERROR("sxg: RESET THE CARD\n");
-       // First, reset the card
+       /* First, reset the card */
        WRITE_REG(HwRegs->Reset, 0xDEAD, FLUSH);
 
-       // Download each section of the microcode as specified in
-       // its download file.  The *download.c file is generated using
-       // the saharaobjtoc facility which converts the metastep .obj
-       // file to a .c file which contains a two dimentional array.
+       /* Download each section of the microcode as specified in */
+       /* its download file.  The *download.c file is generated using */
+       /* the saharaobjtoc facility which converts the metastep .obj */
+       /* file to a .c file which contains a two dimentional array. */
        for (Section = 0; Section < numSections; Section++) {
                DBG_ERROR("sxg: SECTION # %d\n", Section);
                switch (UcodeSel) {
@@ -294,35 +295,35 @@ static bool sxg_download_microcode(p_adapter_t adapter, SXG_UCODE_SEL UcodeSel)
                        break;
                }
                BaseAddress = sectionStart[Section];
-               ThisSectionSize = sectionSize[Section] / 12;    // Size in instructions
+               ThisSectionSize = sectionSize[Section] / 12;    /* Size in instructions */
                for (AddressOffset = 0; AddressOffset < ThisSectionSize;
                     AddressOffset++) {
                        Address = BaseAddress + AddressOffset;
                        ASSERT((Address & ~MICROCODE_ADDRESS_MASK) == 0);
-                       // Write instruction bits 31 - 0
+                       /* Write instruction bits 31 - 0 */
                        WRITE_REG(HwRegs->UcodeDataLow, *Instruction, FLUSH);
-                       // Write instruction bits 63-32
+                       /* Write instruction bits 63-32 */
                        WRITE_REG(HwRegs->UcodeDataMiddle, *(Instruction + 1),
                                  FLUSH);
-                       // Write instruction bits 95-64
+                       /* Write instruction bits 95-64 */
                        WRITE_REG(HwRegs->UcodeDataHigh, *(Instruction + 2),
                                  FLUSH);
-                       // Write instruction address with the WRITE bit set
+                       /* Write instruction address with the WRITE bit set */
                        WRITE_REG(HwRegs->UcodeAddr,
                                  (Address | MICROCODE_ADDRESS_WRITE), FLUSH);
-                       // Sahara bug in the ucode download logic - the write to DataLow
-                       // for the next instruction could get corrupted.  To avoid this,
-                       // write to DataLow again for this instruction (which may get
-                       // corrupted, but it doesn't matter), then increment the address
-                       // and write the data for the next instruction to DataLow.  That
-                       // write should succeed.
+                       /* Sahara bug in the ucode download logic - the write to DataLow */
+                       /* for the next instruction could get corrupted.  To avoid this, */
+                       /* write to DataLow again for this instruction (which may get */
+                       /* corrupted, but it doesn't matter), then increment the address */
+                       /* and write the data for the next instruction to DataLow.  That */
+                       /* write should succeed. */
                        WRITE_REG(HwRegs->UcodeDataLow, *Instruction, TRUE);
-                       // Advance 3 u32S to start of next instruction
+                       /* Advance 3 u32S to start of next instruction */
                        Instruction += 3;
                }
        }
-       // Now repeat the entire operation reading the instruction back and
-       // checking for parity errors
+       /* Now repeat the entire operation reading the instruction back and */
+       /* checking for parity errors */
        for (Section = 0; Section < numSections; Section++) {
                DBG_ERROR("sxg: check SECTION # %d\n", Section);
                switch (UcodeSel) {
@@ -334,74 +335,74 @@ static bool sxg_download_microcode(p_adapter_t adapter, SXG_UCODE_SEL UcodeSel)
                        break;
                }
                BaseAddress = sectionStart[Section];
-               ThisSectionSize = sectionSize[Section] / 12;    // Size in instructions
+               ThisSectionSize = sectionSize[Section] / 12;    /* Size in instructions */
                for (AddressOffset = 0; AddressOffset < ThisSectionSize;
                     AddressOffset++) {
                        Address = BaseAddress + AddressOffset;
-                       // Write the address with the READ bit set
+                       /* Write the address with the READ bit set */
                        WRITE_REG(HwRegs->UcodeAddr,
                                  (Address | MICROCODE_ADDRESS_READ), FLUSH);
-                       // Read it back and check parity bit.
+                       /* Read it back and check parity bit. */
                        READ_REG(HwRegs->UcodeAddr, ValueRead);
                        if (ValueRead & MICROCODE_ADDRESS_PARITY) {
                                DBG_ERROR("sxg: %s PARITY ERROR\n",
-                                         __FUNCTION__);
+                                         __func__);
 
-                               return (FALSE); // Parity error
+                               return (FALSE); /* Parity error */
                        }
                        ASSERT((ValueRead & MICROCODE_ADDRESS_MASK) == Address);
-                       // Read the instruction back and compare
+                       /* Read the instruction back and compare */
                        READ_REG(HwRegs->UcodeDataLow, ValueRead);
                        if (ValueRead != *Instruction) {
                                DBG_ERROR("sxg: %s MISCOMPARE LOW\n",
-                                         __FUNCTION__);
-                               return (FALSE); // Miscompare
+                                         __func__);
+                               return (FALSE); /* Miscompare */
                        }
                        READ_REG(HwRegs->UcodeDataMiddle, ValueRead);
                        if (ValueRead != *(Instruction + 1)) {
                                DBG_ERROR("sxg: %s MISCOMPARE MIDDLE\n",
-                                         __FUNCTION__);
-                               return (FALSE); // Miscompare
+                                         __func__);
+                               return (FALSE); /* Miscompare */
                        }
                        READ_REG(HwRegs->UcodeDataHigh, ValueRead);
                        if (ValueRead != *(Instruction + 2)) {
                                DBG_ERROR("sxg: %s MISCOMPARE HIGH\n",
-                                         __FUNCTION__);
-                               return (FALSE); // Miscompare
+                                         __func__);
+                               return (FALSE); /* Miscompare */
                        }
-                       // Advance 3 u32S to start of next instruction
+                       /* Advance 3 u32S to start of next instruction */
                        Instruction += 3;
                }
        }
 
-       // Everything OK, Go.
+       /* Everything OK, Go. */
        WRITE_REG(HwRegs->UcodeAddr, MICROCODE_ADDRESS_GO, FLUSH);
 
-       // Poll the CardUp register to wait for microcode to initialize
-       // Give up after 10,000 attemps (500ms).
+       /* Poll the CardUp register to wait for microcode to initialize */
+       /* Give up after 10,000 attemps (500ms). */
        for (i = 0; i < 10000; i++) {
                udelay(50);
                READ_REG(adapter->UcodeRegs[0].CardUp, ValueRead);
                if (ValueRead == 0xCAFE) {
-                       DBG_ERROR("sxg: %s BOO YA 0xCAFE\n", __FUNCTION__);
+                       DBG_ERROR("sxg: %s BOO YA 0xCAFE\n", __func__);
                        break;
                }
        }
        if (i == 10000) {
-               DBG_ERROR("sxg: %s TIMEOUT\n", __FUNCTION__);
+               DBG_ERROR("sxg: %s TIMEOUT\n", __func__);
 
-               return (FALSE); // Timeout
+               return (FALSE); /* Timeout */
        }
-       // Now write the LoadSync register.  This is used to
-       // synchronize with the card so it can scribble on the memory
-       // that contained 0xCAFE from the "CardUp" step above
+       /* Now write the LoadSync register.  This is used to */
+       /* synchronize with the card so it can scribble on the memory */
+       /* that contained 0xCAFE from the "CardUp" step above */
        if (UcodeSel == SXG_UCODE_SAHARA) {
                WRITE_REG(adapter->UcodeRegs[0].LoadSync, 0, FLUSH);
        }
 
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDnldUcd",
                  adapter, 0, 0, 0);
-       DBG_ERROR("sxg: %s EXIT\n", __FUNCTION__);
+       DBG_ERROR("sxg: %s EXIT\n", __func__);
 
        return (TRUE);
 }
@@ -420,29 +421,29 @@ static int sxg_allocate_resources(p_adapter_t adapter)
        int status;
        u32 i;
        u32 RssIds, IsrCount;
-//      PSXG_XMT_RING                                   XmtRing;
-//      PSXG_RCV_RING                                   RcvRing;
+/*      PSXG_XMT_RING                                   XmtRing; */
+/*      PSXG_RCV_RING                                   RcvRing; */
 
-       DBG_ERROR("%s ENTER\n", __FUNCTION__);
+       DBG_ERROR("%s ENTER\n", __func__);
 
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocRes",
                  adapter, 0, 0, 0);
 
-       // Windows tells us how many CPUs it plans to use for
-       // RSS
+       /* Windows tells us how many CPUs it plans to use for */
+       /* RSS */
        RssIds = SXG_RSS_CPU_COUNT(adapter);
        IsrCount = adapter->MsiEnabled ? RssIds : 1;
 
-       DBG_ERROR("%s Setup the spinlocks\n", __FUNCTION__);
+       DBG_ERROR("%s Setup the spinlocks\n", __func__);
 
-       // Allocate spinlocks and initialize listheads first.
+       /* Allocate spinlocks and initialize listheads first. */
        spin_lock_init(&adapter->RcvQLock);
        spin_lock_init(&adapter->SglQLock);
        spin_lock_init(&adapter->XmtZeroLock);
        spin_lock_init(&adapter->Bit64RegLock);
        spin_lock_init(&adapter->AdapterLock);
 
-       DBG_ERROR("%s Setup the lists\n", __FUNCTION__);
+       DBG_ERROR("%s Setup the lists\n", __func__);
 
        InitializeListHead(&adapter->FreeRcvBuffers);
        InitializeListHead(&adapter->FreeRcvBlocks);
@@ -450,39 +451,39 @@ static int sxg_allocate_resources(p_adapter_t adapter)
        InitializeListHead(&adapter->FreeSglBuffers);
        InitializeListHead(&adapter->AllSglBuffers);
 
-       // Mark these basic allocations done.  This flags essentially
-       // tells the SxgFreeResources routine that it can grab spinlocks
-       // and reference listheads.
+       /* Mark these basic allocations done.  This flags essentially */
+       /* tells the SxgFreeResources routine that it can grab spinlocks */
+       /* and reference listheads. */
        adapter->BasicAllocations = TRUE;
-       // Main allocation loop.  Start with the maximum supported by
-       // the microcode and back off if memory allocation
-       // fails.  If we hit a minimum, fail.
+       /* Main allocation loop.  Start with the maximum supported by */
+       /* the microcode and back off if memory allocation */
+       /* fails.  If we hit a minimum, fail. */
 
        for (;;) {
-               DBG_ERROR("%s Allocate XmtRings size[%lx]\n", __FUNCTION__,
-                         (sizeof(SXG_XMT_RING) * 1));
+               DBG_ERROR("%s Allocate XmtRings size[%x]\n", __func__,
+                         (unsigned int)(sizeof(SXG_XMT_RING) * 1));
 
-               // Start with big items first - receive and transmit rings.  At the moment
-               // I'm going to keep the ring size fixed and adjust the number of
-               // TCBs if we fail.  Later we might consider reducing the ring size as well..
+               /* Start with big items first - receive and transmit rings.  At the moment */
+               /* I'm going to keep the ring size fixed and adjust the number of */
+               /* TCBs if we fail.  Later we might consider reducing the ring size as well.. */
                adapter->XmtRings = pci_alloc_consistent(adapter->pcidev,
                                                         sizeof(SXG_XMT_RING) *
                                                         1,
                                                         &adapter->PXmtRings);
-               DBG_ERROR("%s XmtRings[%p]\n", __FUNCTION__, adapter->XmtRings);
+               DBG_ERROR("%s XmtRings[%p]\n", __func__, adapter->XmtRings);
 
                if (!adapter->XmtRings) {
                        goto per_tcb_allocation_failed;
                }
                memset(adapter->XmtRings, 0, sizeof(SXG_XMT_RING) * 1);
 
-               DBG_ERROR("%s Allocate RcvRings size[%lx]\n", __FUNCTION__,
-                         (sizeof(SXG_RCV_RING) * 1));
+               DBG_ERROR("%s Allocate RcvRings size[%x]\n", __func__,
+                         (unsigned int)(sizeof(SXG_RCV_RING) * 1));
                adapter->RcvRings =
                    pci_alloc_consistent(adapter->pcidev,
                                         sizeof(SXG_RCV_RING) * 1,
                                         &adapter->PRcvRings);
-               DBG_ERROR("%s RcvRings[%p]\n", __FUNCTION__, adapter->RcvRings);
+               DBG_ERROR("%s RcvRings[%p]\n", __func__, adapter->RcvRings);
                if (!adapter->RcvRings) {
                        goto per_tcb_allocation_failed;
                }
@@ -490,7 +491,7 @@ static int sxg_allocate_resources(p_adapter_t adapter)
                break;
 
              per_tcb_allocation_failed:
-               // an allocation failed.  Free any successful allocations.
+               /* an allocation failed.  Free any successful allocations. */
                if (adapter->XmtRings) {
                        pci_free_consistent(adapter->pcidev,
                                            sizeof(SXG_XMT_RING) * 4096,
@@ -505,22 +506,22 @@ static int sxg_allocate_resources(p_adapter_t adapter)
                                            adapter->PRcvRings);
                        adapter->RcvRings = NULL;
                }
-               // Loop around and try again....
+               /* Loop around and try again.... */
        }
 
-       DBG_ERROR("%s Initialize RCV ZERO and XMT ZERO rings\n", __FUNCTION__);
-       // Initialize rcv zero and xmt zero rings
+       DBG_ERROR("%s Initialize RCV ZERO and XMT ZERO rings\n", __func__);
+       /* Initialize rcv zero and xmt zero rings */
        SXG_INITIALIZE_RING(adapter->RcvRingZeroInfo, SXG_RCV_RING_SIZE);
        SXG_INITIALIZE_RING(adapter->XmtRingZeroInfo, SXG_XMT_RING_SIZE);
 
-       // Sanity check receive data structure format
+       /* Sanity check receive data structure format */
        ASSERT((adapter->ReceiveBufferSize == SXG_RCV_DATA_BUFFER_SIZE) ||
               (adapter->ReceiveBufferSize == SXG_RCV_JUMBO_BUFFER_SIZE));
        ASSERT(sizeof(SXG_RCV_DESCRIPTOR_BLOCK) ==
               SXG_RCV_DESCRIPTOR_BLOCK_SIZE);
 
-       // Allocate receive data buffers.  We allocate a block of buffers and
-       // a corresponding descriptor block at once.  See sxghw.h:SXG_RCV_BLOCK
+       /* Allocate receive data buffers.  We allocate a block of buffers and */
+       /* a corresponding descriptor block at once.  See sxghw.h:SXG_RCV_BLOCK */
        for (i = 0; i < SXG_INITIAL_RCV_DATA_BUFFERS;
             i += SXG_RCV_DESCRIPTORS_PER_BLOCK) {
                sxg_allocate_buffer_memory(adapter,
@@ -528,8 +529,8 @@ static int sxg_allocate_resources(p_adapter_t adapter)
                                                              ReceiveBufferSize),
                                           SXG_BUFFER_TYPE_RCV);
        }
-       // NBL resource allocation can fail in the 'AllocateComplete' routine, which
-       // doesn't return status.  Make sure we got the number of buffers we requested
+       /* NBL resource allocation can fail in the 'AllocateComplete' routine, which */
+       /* doesn't return status.  Make sure we got the number of buffers we requested */
        if (adapter->FreeRcvBufferCount < SXG_INITIAL_RCV_DATA_BUFFERS) {
                SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF6",
                          adapter, adapter->FreeRcvBufferCount, SXG_MAX_ENTRIES,
@@ -537,17 +538,17 @@ static int sxg_allocate_resources(p_adapter_t adapter)
                return (STATUS_RESOURCES);
        }
 
-       DBG_ERROR("%s Allocate EventRings size[%lx]\n", __FUNCTION__,
-                 (sizeof(SXG_EVENT_RING) * RssIds));
+       DBG_ERROR("%s Allocate EventRings size[%x]\n", __func__,
+                 (unsigned int)(sizeof(SXG_EVENT_RING) * RssIds));
 
-       // Allocate event queues.
+       /* Allocate event queues. */
        adapter->EventRings = pci_alloc_consistent(adapter->pcidev,
                                                   sizeof(SXG_EVENT_RING) *
                                                   RssIds,
                                                   &adapter->PEventRings);
 
        if (!adapter->EventRings) {
-               // Caller will call SxgFreeAdapter to clean up above allocations
+               /* Caller will call SxgFreeAdapter to clean up above allocations */
                SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF8",
                          adapter, SXG_MAX_ENTRIES, 0, 0);
                status = STATUS_RESOURCES;
@@ -555,12 +556,12 @@ static int sxg_allocate_resources(p_adapter_t adapter)
        }
        memset(adapter->EventRings, 0, sizeof(SXG_EVENT_RING) * RssIds);
 
-       DBG_ERROR("%s Allocate ISR size[%x]\n", __FUNCTION__, IsrCount);
-       // Allocate ISR
+       DBG_ERROR("%s Allocate ISR size[%x]\n", __func__, IsrCount);
+       /* Allocate ISR */
        adapter->Isr = pci_alloc_consistent(adapter->pcidev,
                                            IsrCount, &adapter->PIsr);
        if (!adapter->Isr) {
-               // Caller will call SxgFreeAdapter to clean up above allocations
+               /* Caller will call SxgFreeAdapter to clean up above allocations */
                SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF9",
                          adapter, SXG_MAX_ENTRIES, 0, 0);
                status = STATUS_RESOURCES;
@@ -568,10 +569,10 @@ static int sxg_allocate_resources(p_adapter_t adapter)
        }
        memset(adapter->Isr, 0, sizeof(u32) * IsrCount);
 
-       DBG_ERROR("%s Allocate shared XMT ring zero index location size[%lx]\n",
-                 __FUNCTION__, sizeof(u32));
+       DBG_ERROR("%s Allocate shared XMT ring zero index location size[%x]\n",
+                 __func__, (unsigned int)sizeof(u32));
 
-       // Allocate shared XMT ring zero index location
+       /* Allocate shared XMT ring zero index location */
        adapter->XmtRingZeroIndex = pci_alloc_consistent(adapter->pcidev,
                                                         sizeof(u32),
                                                         &adapter->
@@ -587,7 +588,7 @@ static int sxg_allocate_resources(p_adapter_t adapter)
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlcResS",
                  adapter, SXG_MAX_ENTRIES, 0, 0);
 
-       DBG_ERROR("%s EXIT\n", __FUNCTION__);
+       DBG_ERROR("%s EXIT\n", __func__);
        return (STATUS_SUCCESS);
 }
 
@@ -606,17 +607,17 @@ static void sxg_config_pci(struct pci_dev *pcidev)
        u16 new_command;
 
        pci_read_config_word(pcidev, PCI_COMMAND, &pci_command);
-       DBG_ERROR("sxg: %s  PCI command[%4.4x]\n", __FUNCTION__, pci_command);
-       // Set the command register
-       new_command = pci_command | (PCI_COMMAND_MEMORY |       // Memory Space Enable
-                                    PCI_COMMAND_MASTER |       // Bus master enable
-                                    PCI_COMMAND_INVALIDATE |   // Memory write and invalidate
-                                    PCI_COMMAND_PARITY |       // Parity error response
-                                    PCI_COMMAND_SERR | // System ERR
-                                    PCI_COMMAND_FAST_BACK);    // Fast back-to-back
+       DBG_ERROR("sxg: %s  PCI command[%4.4x]\n", __func__, pci_command);
+       /* Set the command register */
+       new_command = pci_command | (PCI_COMMAND_MEMORY |       /* Memory Space Enable */
+                                    PCI_COMMAND_MASTER |       /* Bus master enable */
+                                    PCI_COMMAND_INVALIDATE |   /* Memory write and invalidate */
+                                    PCI_COMMAND_PARITY |       /* Parity error response */
+                                    PCI_COMMAND_SERR | /* System ERR */
+                                    PCI_COMMAND_FAST_BACK);    /* Fast back-to-back */
        if (pci_command != new_command) {
                DBG_ERROR("%s -- Updating PCI COMMAND register %4.4x->%4.4x.\n",
-                         __FUNCTION__, pci_command, new_command);
+                         __func__, pci_command, new_command);
                pci_write_config_word(pcidev, PCI_COMMAND, new_command);
        }
 }
@@ -634,9 +635,9 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
        ulong mmio_len = 0;
 
        DBG_ERROR("sxg: %s 2.6 VERSION ENTER jiffies[%lx] cpu %d\n",
-                 __FUNCTION__, jiffies, smp_processor_id());
+                 __func__, jiffies, smp_processor_id());
 
-       // Initialize trace buffer
+       /* Initialize trace buffer */
 #ifdef ATKDBG
        SxgTraceBuffer = &LSxgTraceBuffer;
        SXG_TRACE_INIT(SxgTraceBuffer, TRACE_NOISY);
@@ -701,11 +702,11 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
                  mmio_start, mmio_len);
 
        memmapped_ioaddr = ioremap(mmio_start, mmio_len);
-       DBG_ERROR("sxg: %s MEMMAPPED_IOADDR [%p]\n", __FUNCTION__,
+       DBG_ERROR("sxg: %s MEMMAPPED_IOADDR [%p]\n", __func__,
                  memmapped_ioaddr);
        if (!memmapped_ioaddr) {
                DBG_ERROR("%s cannot remap MMIO region %lx @ %lx\n",
-                         __FUNCTION__, mmio_len, mmio_start);
+                         __func__, mmio_len, mmio_start);
                goto err_out_free_mmio_region;
        }
 
@@ -727,7 +728,7 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
                  memmapped_ioaddr);
        if (!memmapped_ioaddr) {
                DBG_ERROR("%s cannot remap MMIO region %lx @ %lx\n",
-                         __FUNCTION__, mmio_len, mmio_start);
+                         __func__, mmio_len, mmio_start);
                goto err_out_free_mmio_region;
        }
 
@@ -738,13 +739,13 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
        adapter->UcodeRegs = (void *)memmapped_ioaddr;
 
        adapter->State = SXG_STATE_INITIALIZING;
-       // Maintain a list of all adapters anchored by
-       // the global SxgDriver structure.
+       /* Maintain a list of all adapters anchored by */
+       /* the global SxgDriver structure. */
        adapter->Next = SxgDriver.Adapters;
        SxgDriver.Adapters = adapter;
        adapter->AdapterID = ++SxgDriver.AdapterID;
 
-       // Initialize CRC table used to determine multicast hash
+       /* Initialize CRC table used to determine multicast hash */
        sxg_mcast_init_crc32();
 
        adapter->JumboEnabled = FALSE;
@@ -757,18 +758,18 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
                adapter->ReceiveBufferSize = SXG_RCV_DATA_BUFFER_SIZE;
        }
 
-//    status = SXG_READ_EEPROM(adapter);
-//    if (!status) {
-//        goto sxg_init_bad;
-//    }
+/*    status = SXG_READ_EEPROM(adapter); */
+/*    if (!status) { */
+/*        goto sxg_init_bad; */
+/*    } */
 
-       DBG_ERROR("sxg: %s ENTER sxg_config_pci\n", __FUNCTION__);
+       DBG_ERROR("sxg: %s ENTER sxg_config_pci\n", __func__);
        sxg_config_pci(pcidev);
-       DBG_ERROR("sxg: %s EXIT sxg_config_pci\n", __FUNCTION__);
+       DBG_ERROR("sxg: %s EXIT sxg_config_pci\n", __func__);
 
-       DBG_ERROR("sxg: %s ENTER sxg_init_driver\n", __FUNCTION__);
+       DBG_ERROR("sxg: %s ENTER sxg_init_driver\n", __func__);
        sxg_init_driver();
-       DBG_ERROR("sxg: %s EXIT sxg_init_driver\n", __FUNCTION__);
+       DBG_ERROR("sxg: %s EXIT sxg_init_driver\n", __func__);
 
        adapter->vendid = pci_tbl_entry->vendor;
        adapter->devid = pci_tbl_entry->device;
@@ -780,23 +781,23 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
        adapter->irq = pcidev->irq;
        adapter->next_netdevice = head_netdevice;
        head_netdevice = netdev;
-//      adapter->chipid = chip_idx;
-       adapter->port = 0;      //adapter->functionnumber;
+/*      adapter->chipid = chip_idx; */
+       adapter->port = 0;      /*adapter->functionnumber; */
        adapter->cardindex = adapter->port;
 
-       // Allocate memory and other resources
-       DBG_ERROR("sxg: %s ENTER sxg_allocate_resources\n", __FUNCTION__);
+       /* Allocate memory and other resources */
+       DBG_ERROR("sxg: %s ENTER sxg_allocate_resources\n", __func__);
        status = sxg_allocate_resources(adapter);
        DBG_ERROR("sxg: %s EXIT sxg_allocate_resources status %x\n",
-                 __FUNCTION__, status);
+                 __func__, status);
        if (status != STATUS_SUCCESS) {
                goto err_out_unmap;
        }
 
-       DBG_ERROR("sxg: %s ENTER sxg_download_microcode\n", __FUNCTION__);
+       DBG_ERROR("sxg: %s ENTER sxg_download_microcode\n", __func__);
        if (sxg_download_microcode(adapter, SXG_UCODE_SAHARA)) {
                DBG_ERROR("sxg: %s ENTER sxg_adapter_set_hwaddr\n",
-                         __FUNCTION__);
+                         __func__);
                sxg_adapter_set_hwaddr(adapter);
        } else {
                adapter->state = ADAPT_FAIL;
@@ -819,7 +820,7 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
 #endif
 
        strcpy(netdev->name, "eth%d");
-//  strcpy(netdev->name, pci_name(pcidev));
+/*  strcpy(netdev->name, pci_name(pcidev)); */
        if ((err = register_netdev(netdev))) {
                DBG_ERROR("Cannot register net device, aborting. %s\n",
                          netdev->name);
@@ -832,11 +833,11 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
             netdev->dev_addr[1], netdev->dev_addr[2], netdev->dev_addr[3],
             netdev->dev_addr[4], netdev->dev_addr[5]);
 
-//sxg_init_bad:
+/*sxg_init_bad: */
        ASSERT(status == FALSE);
-//      sxg_free_adapter(adapter);
+/*      sxg_free_adapter(adapter); */
 
-       DBG_ERROR("sxg: %s EXIT status[%x] jiffies[%lx] cpu %d\n", __FUNCTION__,
+       DBG_ERROR("sxg: %s EXIT status[%x] jiffies[%lx] cpu %d\n", __func__,
                  status, jiffies, smp_processor_id());
        return status;
 
@@ -848,7 +849,7 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
 
       err_out_exit_sxg_probe:
 
-       DBG_ERROR("%s EXIT jiffies[%lx] cpu %d\n", __FUNCTION__, jiffies,
+       DBG_ERROR("%s EXIT jiffies[%lx] cpu %d\n", __func__, jiffies,
                  smp_processor_id());
 
        return -ENODEV;
@@ -874,12 +875,12 @@ static void sxg_disable_interrupt(p_adapter_t adapter)
 {
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DisIntr",
                  adapter, adapter->InterruptsEnabled, 0, 0);
-       // For now, RSS is disabled with line based interrupts
+       /* For now, RSS is disabled with line based interrupts */
        ASSERT(adapter->RssEnabled == FALSE);
        ASSERT(adapter->MsiEnabled == FALSE);
-       //
-       // Turn off interrupts by writing to the icr register.
-       //
+       /* */
+       /* Turn off interrupts by writing to the icr register. */
+       /* */
        WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_DISABLE), TRUE);
 
        adapter->InterruptsEnabled = 0;
@@ -905,12 +906,12 @@ static void sxg_enable_interrupt(p_adapter_t adapter)
 {
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "EnIntr",
                  adapter, adapter->InterruptsEnabled, 0, 0);
-       // For now, RSS is disabled with line based interrupts
+       /* For now, RSS is disabled with line based interrupts */
        ASSERT(adapter->RssEnabled == FALSE);
        ASSERT(adapter->MsiEnabled == FALSE);
-       //
-       // Turn on interrupts by writing to the icr register.
-       //
+       /* */
+       /* Turn on interrupts by writing to the icr register. */
+       /* */
        WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_ENABLE), TRUE);
 
        adapter->InterruptsEnabled = 1;
@@ -935,29 +936,29 @@ static irqreturn_t sxg_isr(int irq, void *dev_id)
 {
        p_net_device dev = (p_net_device) dev_id;
        p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
-//      u32                 CpuMask = 0, i;
+/*      u32                 CpuMask = 0, i; */
 
        adapter->Stats.NumInts++;
        if (adapter->Isr[0] == 0) {
-               // The SLIC driver used to experience a number of spurious interrupts
-               // due to the delay associated with the masking of the interrupt
-               // (we'd bounce back in here).  If we see that again with Sahara,
-               // add a READ_REG of the Icr register after the WRITE_REG below.
+               /* The SLIC driver used to experience a number of spurious interrupts */
+               /* due to the delay associated with the masking of the interrupt */
+               /* (we'd bounce back in here).  If we see that again with Sahara, */
+               /* add a READ_REG of the Icr register after the WRITE_REG below. */
                adapter->Stats.FalseInts++;
                return IRQ_NONE;
        }
-       //
-       // Move the Isr contents and clear the value in
-       // shared memory, and mask interrupts
-       //
+       /* */
+       /* Move the Isr contents and clear the value in */
+       /* shared memory, and mask interrupts */
+       /* */
        adapter->IsrCopy[0] = adapter->Isr[0];
        adapter->Isr[0] = 0;
        WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_MASK), TRUE);
-//      ASSERT(adapter->IsrDpcsPending == 0);
-#if XXXTODO                    // RSS Stuff
-       // If RSS is enabled and the ISR specifies
-       // SXG_ISR_EVENT, then schedule DPC's
-       // based on event queues.
+/*      ASSERT(adapter->IsrDpcsPending == 0); */
+#if XXXTODO                    /* RSS Stuff */
+       /* If RSS is enabled and the ISR specifies */
+       /* SXG_ISR_EVENT, then schedule DPC's */
+       /* based on event queues. */
        if (adapter->RssEnabled && (adapter->IsrCopy[0] & SXG_ISR_EVENT)) {
                for (i = 0;
                     i < adapter->RssSystemInfo->ProcessorInfo.RssCpuCount;
@@ -973,8 +974,8 @@ static irqreturn_t sxg_isr(int irq, void *dev_id)
                        }
                }
        }
-       // Now, either schedule the CPUs specified by the CpuMask,
-       // or queue default
+       /* Now, either schedule the CPUs specified by the CpuMask, */
+       /* or queue default */
        if (CpuMask) {
                *QueueDefault = FALSE;
        } else {
@@ -983,9 +984,9 @@ static irqreturn_t sxg_isr(int irq, void *dev_id)
        }
        *TargetCpus = CpuMask;
 #endif
-       //
-       //  There are no DPCs in Linux, so call the handler now
-       //
+       /* */
+       /*  There are no DPCs in Linux, so call the handler now */
+       /* */
        sxg_handle_interrupt(adapter);
 
        return IRQ_HANDLED;
@@ -993,7 +994,7 @@ static irqreturn_t sxg_isr(int irq, void *dev_id)
 
 static void sxg_handle_interrupt(p_adapter_t adapter)
 {
-//    unsigned char           RssId   = 0;
+/*    unsigned char           RssId   = 0; */
        u32 NewIsr;
 
        if (adapter->Stats.RcvNoBuffer < 5) {
@@ -1002,32 +1003,32 @@ static void sxg_handle_interrupt(p_adapter_t adapter)
        }
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "HndlIntr",
                  adapter, adapter->IsrCopy[0], 0, 0);
-       // For now, RSS is disabled with line based interrupts
+       /* For now, RSS is disabled with line based interrupts */
        ASSERT(adapter->RssEnabled == FALSE);
        ASSERT(adapter->MsiEnabled == FALSE);
        ASSERT(adapter->IsrCopy[0]);
-/////////////////////////////
+/*/////////////////////////// */
 
-       // Always process the event queue.
+       /* Always process the event queue. */
        sxg_process_event_queue(adapter,
                                (adapter->RssEnabled ? /*RssId */ 0 : 0));
 
-#if XXXTODO                    // RSS stuff
+#if XXXTODO                    /* RSS stuff */
        if (--adapter->IsrDpcsPending) {
-               // We're done.
+               /* We're done. */
                ASSERT(adapter->RssEnabled);
                SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DPCsPend",
                          adapter, 0, 0, 0);
                return;
        }
 #endif
-       //
-       // Last (or only) DPC processes the ISR and clears the interrupt.
-       //
+       /* */
+       /* Last (or only) DPC processes the ISR and clears the interrupt. */
+       /* */
        NewIsr = sxg_process_isr(adapter, 0);
-       //
-       // Reenable interrupts
-       //
+       /* */
+       /* Reenable interrupts */
+       /* */
        adapter->IsrCopy[0] = 0;
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "ClearIsr",
                  adapter, NewIsr, 0, 0);
@@ -1063,75 +1064,75 @@ static int sxg_process_isr(p_adapter_t adapter, u32 MessageId)
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "ProcIsr",
                  adapter, Isr, 0, 0);
 
-       // Error
+       /* Error */
        if (Isr & SXG_ISR_ERR) {
                if (Isr & SXG_ISR_PDQF) {
                        adapter->Stats.PdqFull++;
-                       DBG_ERROR("%s: SXG_ISR_ERR  PDQF!!\n", __FUNCTION__);
+                       DBG_ERROR("%s: SXG_ISR_ERR  PDQF!!\n", __func__);
                }
-               // No host buffer
+               /* No host buffer */
                if (Isr & SXG_ISR_RMISS) {
-                       // There is a bunch of code in the SLIC driver which
-                       // attempts to process more receive events per DPC
-                       // if we start to fall behind.  We'll probably
-                       // need to do something similar here, but hold
-                       // off for now.  I don't want to make the code more
-                       // complicated than strictly needed.
+                       /* There is a bunch of code in the SLIC driver which */
+                       /* attempts to process more receive events per DPC */
+                       /* if we start to fall behind.  We'll probably */
+                       /* need to do something similar here, but hold */
+                       /* off for now.  I don't want to make the code more */
+                       /* complicated than strictly needed. */
                        adapter->Stats.RcvNoBuffer++;
                        if (adapter->Stats.RcvNoBuffer < 5) {
                                DBG_ERROR("%s: SXG_ISR_ERR  RMISS!!\n",
-                                         __FUNCTION__);
+                                         __func__);
                        }
                }
-               // Card crash
+               /* Card crash */
                if (Isr & SXG_ISR_DEAD) {
-                       // Set aside the crash info and set the adapter state to RESET
+                       /* Set aside the crash info and set the adapter state to RESET */
                        adapter->CrashCpu =
                            (unsigned char)((Isr & SXG_ISR_CPU) >>
                                            SXG_ISR_CPU_SHIFT);
                        adapter->CrashLocation = (ushort) (Isr & SXG_ISR_CRASH);
                        adapter->Dead = TRUE;
-                       DBG_ERROR("%s: ISR_DEAD %x, CPU: %d\n", __FUNCTION__,
+                       DBG_ERROR("%s: ISR_DEAD %x, CPU: %d\n", __func__,
                                  adapter->CrashLocation, adapter->CrashCpu);
                }
-               // Event ring full
+               /* Event ring full */
                if (Isr & SXG_ISR_ERFULL) {
-                       // Same issue as RMISS, really.  This means the
-                       // host is falling behind the card.  Need to increase
-                       // event ring size, process more events per interrupt,
-                       // and/or reduce/remove interrupt aggregation.
+                       /* Same issue as RMISS, really.  This means the */
+                       /* host is falling behind the card.  Need to increase */
+                       /* event ring size, process more events per interrupt, */
+                       /* and/or reduce/remove interrupt aggregation. */
                        adapter->Stats.EventRingFull++;
                        DBG_ERROR("%s: SXG_ISR_ERR  EVENT RING FULL!!\n",
-                                 __FUNCTION__);
+                                 __func__);
                }
-               // Transmit drop - no DRAM buffers or XMT error
+               /* Transmit drop - no DRAM buffers or XMT error */
                if (Isr & SXG_ISR_XDROP) {
                        adapter->Stats.XmtDrops++;
                        adapter->Stats.XmtErrors++;
-                       DBG_ERROR("%s: SXG_ISR_ERR  XDROP!!\n", __FUNCTION__);
+                       DBG_ERROR("%s: SXG_ISR_ERR  XDROP!!\n", __func__);
                }
        }
-       // Slowpath send completions
+       /* Slowpath send completions */
        if (Isr & SXG_ISR_SPSEND) {
                sxg_complete_slow_send(adapter);
        }
-       // Dump
+       /* Dump */
        if (Isr & SXG_ISR_UPC) {
-               ASSERT(adapter->DumpCmdRunning);        // Maybe change when debug is added..
+               ASSERT(adapter->DumpCmdRunning);        /* Maybe change when debug is added.. */
                adapter->DumpCmdRunning = FALSE;
        }
-       // Link event
+       /* Link event */
        if (Isr & SXG_ISR_LINK) {
                sxg_link_event(adapter);
        }
-       // Debug - breakpoint hit
+       /* Debug - breakpoint hit */
        if (Isr & SXG_ISR_BREAK) {
-               // At the moment AGDB isn't written to support interactive
-               // debug sessions.  When it is, this interrupt will be used
-               // to signal AGDB that it has hit a breakpoint.  For now, ASSERT.
+               /* At the moment AGDB isn't written to support interactive */
+               /* debug sessions.  When it is, this interrupt will be used */
+               /* to signal AGDB that it has hit a breakpoint.  For now, ASSERT. */
                ASSERT(0);
        }
-       // Heartbeat response
+       /* Heartbeat response */
        if (Isr & SXG_ISR_PING) {
                adapter->PingOutstanding = FALSE;
        }
@@ -1171,39 +1172,39 @@ static u32 sxg_process_event_queue(p_adapter_t adapter, u32 RssId)
               (adapter->State == SXG_STATE_PAUSING) ||
               (adapter->State == SXG_STATE_PAUSED) ||
               (adapter->State == SXG_STATE_HALTING));
-       // We may still have unprocessed events on the queue if
-       // the card crashed.  Don't process them.
+       /* We may still have unprocessed events on the queue if */
+       /* the card crashed.  Don't process them. */
        if (adapter->Dead) {
                return (0);
        }
-       // In theory there should only be a single processor that
-       // accesses this queue, and only at interrupt-DPC time.  So
-       // we shouldn't need a lock for any of this.
+       /* In theory there should only be a single processor that */
+       /* accesses this queue, and only at interrupt-DPC time.  So */
+       /* we shouldn't need a lock for any of this. */
        while (Event->Status & EVENT_STATUS_VALID) {
                SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "Event",
                          Event, Event->Code, Event->Status,
                          adapter->NextEvent);
                switch (Event->Code) {
                case EVENT_CODE_BUFFERS:
-                       ASSERT(!(Event->CommandIndex & 0xFF00));        // SXG_RING_INFO Head & Tail == unsigned char
-                       //
+                       ASSERT(!(Event->CommandIndex & 0xFF00));        /* SXG_RING_INFO Head & Tail == unsigned char */
+                       /* */
                        sxg_complete_descriptor_blocks(adapter,
                                                       Event->CommandIndex);
-                       //
+                       /* */
                        break;
                case EVENT_CODE_SLOWRCV:
                        --adapter->RcvBuffersOnCard;
                        if ((skb = sxg_slow_receive(adapter, Event))) {
                                u32 rx_bytes;
 #ifdef LINUX_HANDLES_RCV_INDICATION_LISTS
-                               // Add it to our indication list
+                               /* Add it to our indication list */
                                SXG_ADD_RCV_PACKET(adapter, skb, prev_skb,
                                                   IndicationList, num_skbs);
-                               //  In Linux, we just pass up each skb to the protocol above at this point,
-                               //  there is no capability of an indication list.
+                               /*  In Linux, we just pass up each skb to the protocol above at this point, */
+                               /*  there is no capability of an indication list. */
 #else
-// CHECK            skb_pull(skb, INIC_RCVBUF_HEADSIZE);
-                               rx_bytes = Event->Length;       // (rcvbuf->length & IRHDDR_FLEN_MSK);
+/* CHECK            skb_pull(skb, INIC_RCVBUF_HEADSIZE); */
+                               rx_bytes = Event->Length;       /* (rcvbuf->length & IRHDDR_FLEN_MSK); */
                                skb_put(skb, rx_bytes);
                                adapter->stats.rx_packets++;
                                adapter->stats.rx_bytes += rx_bytes;
@@ -1218,43 +1219,43 @@ static u32 sxg_process_event_queue(p_adapter_t adapter, u32 RssId)
                        break;
                default:
                        DBG_ERROR("%s: ERROR  Invalid EventCode %d\n",
-                                 __FUNCTION__, Event->Code);
-//                      ASSERT(0);
+                                 __func__, Event->Code);
+/*                      ASSERT(0); */
                }
-               // See if we need to restock card receive buffers.
-               // There are two things to note here:
-               //      First - This test is not SMP safe.  The
-               //              adapter->BuffersOnCard field is protected via atomic interlocked calls, but
-               //              we do not protect it with respect to these tests.  The only way to do that
-               //      is with a lock, and I don't want to grab a lock every time we adjust the
-               //      BuffersOnCard count.  Instead, we allow the buffer replenishment to be off
-               //      once in a while.  The worst that can happen is the card is given one
-               //      more-or-less descriptor block than the arbitrary value we've chosen.
-               //      No big deal
-               //      In short DO NOT ADD A LOCK HERE, OR WHERE RcvBuffersOnCard is adjusted.
-               //      Second - We expect this test to rarely evaluate to true.  We attempt to
-               //      refill descriptor blocks as they are returned to us
-               //      (sxg_complete_descriptor_blocks), so The only time this should evaluate
-               //      to true is when sxg_complete_descriptor_blocks failed to allocate
-               //              receive buffers.
+               /* See if we need to restock card receive buffers. */
+               /* There are two things to note here: */
+               /*      First - This test is not SMP safe.  The */
+               /*              adapter->BuffersOnCard field is protected via atomic interlocked calls, but */
+               /*              we do not protect it with respect to these tests.  The only way to do that */
+               /*      is with a lock, and I don't want to grab a lock every time we adjust the */
+               /*      BuffersOnCard count.  Instead, we allow the buffer replenishment to be off */
+               /*      once in a while.  The worst that can happen is the card is given one */
+               /*      more-or-less descriptor block than the arbitrary value we've chosen. */
+               /*      No big deal */
+               /*      In short DO NOT ADD A LOCK HERE, OR WHERE RcvBuffersOnCard is adjusted. */
+               /*      Second - We expect this test to rarely evaluate to true.  We attempt to */
+               /*      refill descriptor blocks as they are returned to us */
+               /*      (sxg_complete_descriptor_blocks), so The only time this should evaluate */
+               /*      to true is when sxg_complete_descriptor_blocks failed to allocate */
+               /*              receive buffers. */
                if (adapter->RcvBuffersOnCard < SXG_RCV_DATA_BUFFERS) {
                        sxg_stock_rcv_buffers(adapter);
                }
-               // It's more efficient to just set this to zero.
-               // But clearing the top bit saves potential debug info...
+               /* It's more efficient to just set this to zero. */
+               /* But clearing the top bit saves potential debug info... */
                Event->Status &= ~EVENT_STATUS_VALID;
-               // Advanct to the next event
+               /* Advanct to the next event */
                SXG_ADVANCE_INDEX(adapter->NextEvent[RssId], EVENT_RING_SIZE);
                Event = &EventRing->Ring[adapter->NextEvent[RssId]];
                EventsProcessed++;
                if (EventsProcessed == EVENT_RING_BATCH) {
-                       // Release a batch of events back to the card
+                       /* Release a batch of events back to the card */
                        WRITE_REG(adapter->UcodeRegs[RssId].EventRelease,
                                  EVENT_RING_BATCH, FALSE);
                        EventsProcessed = 0;
-                       // If we've processed our batch limit, break out of the
-                       // loop and return SXG_ISR_EVENT to arrange for us to
-                       // be called again
+                       /* If we've processed our batch limit, break out of the */
+                       /* loop and return SXG_ISR_EVENT to arrange for us to */
+                       /* be called again */
                        if (Batches++ == EVENT_BATCH_LIMIT) {
                                SXG_TRACE(TRACE_SXG, SxgTraceBuffer,
                                          TRACE_NOISY, "EvtLimit", Batches,
@@ -1265,14 +1266,14 @@ static u32 sxg_process_event_queue(p_adapter_t adapter, u32 RssId)
                }
        }
 #ifdef LINUX_HANDLES_RCV_INDICATION_LISTS
-       //
-       // Indicate any received dumb-nic frames
-       //
+       /* */
+       /* Indicate any received dumb-nic frames */
+       /* */
        SXG_INDICATE_PACKETS(adapter, IndicationList, num_skbs);
 #endif
-       //
-       // Release events back to the card.
-       //
+       /* */
+       /* Release events back to the card. */
+       /* */
        if (EventsProcessed) {
                WRITE_REG(adapter->UcodeRegs[RssId].EventRelease,
                          EventsProcessed, FALSE);
@@ -1299,43 +1300,43 @@ static void sxg_complete_slow_send(p_adapter_t adapter)
        u32 *ContextType;
        PSXG_CMD XmtCmd;
 
-       // NOTE - This lock is dropped and regrabbed in this loop.
-       // This means two different processors can both be running
-       // through this loop. Be *very* careful.
+       /* NOTE - This lock is dropped and regrabbed in this loop. */
+       /* This means two different processors can both be running */
+       /* through this loop. Be *very* careful. */
        spin_lock(&adapter->XmtZeroLock);
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnds",
                  adapter, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
 
        while (XmtRingInfo->Tail != *adapter->XmtRingZeroIndex) {
-               // Locate the current Cmd (ring descriptor entry), and
-               // associated SGL, and advance the tail
+               /* Locate the current Cmd (ring descriptor entry), and */
+               /* associated SGL, and advance the tail */
                SXG_RETURN_CMD(XmtRing, XmtRingInfo, XmtCmd, ContextType);
                ASSERT(ContextType);
                SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnd",
                          XmtRingInfo->Head, XmtRingInfo->Tail, XmtCmd, 0);
-               // Clear the SGL field.
+               /* Clear the SGL field. */
                XmtCmd->Sgl = 0;
 
                switch (*ContextType) {
                case SXG_SGL_DUMB:
                        {
                                struct sk_buff *skb;
-                               // Dumb-nic send.  Command context is the dumb-nic SGL
+                               /* Dumb-nic send.  Command context is the dumb-nic SGL */
                                skb = (struct sk_buff *)ContextType;
-                               // Complete the send
+                               /* Complete the send */
                                SXG_TRACE(TRACE_SXG, SxgTraceBuffer,
                                          TRACE_IMPORTANT, "DmSndCmp", skb, 0,
                                          0, 0);
                                ASSERT(adapter->Stats.XmtQLen);
-                               adapter->Stats.XmtQLen--;       // within XmtZeroLock
+                               adapter->Stats.XmtQLen--;       /* within XmtZeroLock */
                                adapter->Stats.XmtOk++;
-                               // Now drop the lock and complete the send back to
-                               // Microsoft.  We need to drop the lock because
-                               // Microsoft can come back with a chimney send, which
-                               // results in a double trip in SxgTcpOuput
+                               /* Now drop the lock and complete the send back to */
+                               /* Microsoft.  We need to drop the lock because */
+                               /* Microsoft can come back with a chimney send, which */
+                               /* results in a double trip in SxgTcpOuput */
                                spin_unlock(&adapter->XmtZeroLock);
                                SXG_COMPLETE_DUMB_SEND(adapter, skb);
-                               // and reacquire..
+                               /* and reacquire.. */
                                spin_lock(&adapter->XmtZeroLock);
                        }
                        break;
@@ -1371,7 +1372,7 @@ static struct sk_buff *sxg_slow_receive(p_adapter_t adapter, PSXG_EVENT Event)
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "SlowRcv", Event,
                  RcvDataBufferHdr, RcvDataBufferHdr->State,
                  RcvDataBufferHdr->VirtualAddress);
-       // Drop rcv frames in non-running state
+       /* Drop rcv frames in non-running state */
        switch (adapter->State) {
        case SXG_STATE_RUNNING:
                break;
@@ -1384,12 +1385,12 @@ static struct sk_buff *sxg_slow_receive(p_adapter_t adapter, PSXG_EVENT Event)
                goto drop;
        }
 
-       // Change buffer state to UPSTREAM
+       /* Change buffer state to UPSTREAM */
        RcvDataBufferHdr->State = SXG_BUFFER_UPSTREAM;
        if (Event->Status & EVENT_STATUS_RCVERR) {
                SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RcvError",
                          Event, Event->Status, Event->HostHandle, 0);
-               // XXXTODO - Remove this print later
+               /* XXXTODO - Remove this print later */
                DBG_ERROR("SXG: Receive error %x\n", *(u32 *)
                          SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr));
                sxg_process_rcv_error(adapter, *(u32 *)
@@ -1397,8 +1398,8 @@ static struct sk_buff *sxg_slow_receive(p_adapter_t adapter, PSXG_EVENT Event)
                                      (RcvDataBufferHdr));
                goto drop;
        }
-#if XXXTODO                    // VLAN stuff
-       // If there's a VLAN tag, extract it and validate it
+#if XXXTODO                    /* VLAN stuff */
+       /* If there's a VLAN tag, extract it and validate it */
        if (((p_ether_header) (SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr)))->
            EtherType == ETHERTYPE_VLAN) {
                if (SxgExtractVlanHeader(adapter, RcvDataBufferHdr, Event) !=
@@ -1411,9 +1412,9 @@ static struct sk_buff *sxg_slow_receive(p_adapter_t adapter, PSXG_EVENT Event)
                }
        }
 #endif
-       //
-       // Dumb-nic frame.  See if it passes our mac filter and update stats
-       //
+       /* */
+       /* Dumb-nic frame.  See if it passes our mac filter and update stats */
+       /* */
        if (!sxg_mac_filter(adapter, (p_ether_header)
                            SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
                            Event->Length)) {
@@ -1427,9 +1428,9 @@ static struct sk_buff *sxg_slow_receive(p_adapter_t adapter, PSXG_EVENT Event)
 
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "DumbRcv",
                  RcvDataBufferHdr, Packet, Event->Length, 0);
-       //
-       // Lastly adjust the receive packet length.
-       //
+       /* */
+       /* Lastly adjust the receive packet length. */
+       /* */
        SXG_ADJUST_RCV_PACKET(Packet, RcvDataBufferHdr, Event);
 
        return (Packet);
@@ -1541,7 +1542,7 @@ static bool sxg_mac_filter(p_adapter_t adapter, p_ether_header EtherHdr,
 
        if (SXG_MULTICAST_PACKET(EtherHdr)) {
                if (SXG_BROADCAST_PACKET(EtherHdr)) {
-                       // broadcast
+                       /* broadcast */
                        if (adapter->MacFilter & MAC_BCAST) {
                                adapter->Stats.DumbRcvBcastPkts++;
                                adapter->Stats.DumbRcvBcastBytes += length;
@@ -1550,7 +1551,7 @@ static bool sxg_mac_filter(p_adapter_t adapter, p_ether_header EtherHdr,
                                return (TRUE);
                        }
                } else {
-                       // multicast
+                       /* multicast */
                        if (adapter->MacFilter & MAC_ALLMCAST) {
                                adapter->Stats.DumbRcvMcastPkts++;
                                adapter->Stats.DumbRcvMcastBytes += length;
@@ -1580,9 +1581,9 @@ static bool sxg_mac_filter(p_adapter_t adapter, p_ether_header EtherHdr,
                        }
                }
        } else if (adapter->MacFilter & MAC_DIRECTED) {
-               // Not broadcast or multicast.  Must be directed at us or
-               // the card is in promiscuous mode.  Either way, consider it
-               // ours if MAC_DIRECTED is set
+               /* Not broadcast or multicast.  Must be directed at us or */
+               /* the card is in promiscuous mode.  Either way, consider it */
+               /* ours if MAC_DIRECTED is set */
                adapter->Stats.DumbRcvUcastPkts++;
                adapter->Stats.DumbRcvUcastBytes += length;
                adapter->Stats.DumbRcvPkts++;
@@ -1590,7 +1591,7 @@ static bool sxg_mac_filter(p_adapter_t adapter, p_ether_header EtherHdr,
                return (TRUE);
        }
        if (adapter->MacFilter & MAC_PROMISC) {
-               // Whatever it is, keep it.
+               /* Whatever it is, keep it. */
                adapter->Stats.DumbRcvPkts++;
                adapter->Stats.DumbRcvBytes += length;
                return (TRUE);
@@ -1606,7 +1607,7 @@ static int sxg_register_interrupt(p_adapter_t adapter)
 
                DBG_ERROR
                    ("sxg: %s AllocAdaptRsrcs adapter[%p] dev->irq[%x] %x\n",
-                    __FUNCTION__, adapter, adapter->netdev->irq, NR_IRQS);
+                    __func__, adapter, adapter->netdev->irq, NR_IRQS);
 
                spin_unlock_irqrestore(&sxg_global.driver_lock,
                                       sxg_global.flags);
@@ -1625,18 +1626,18 @@ static int sxg_register_interrupt(p_adapter_t adapter)
                }
                adapter->intrregistered = 1;
                adapter->IntRegistered = TRUE;
-               // Disable RSS with line-based interrupts
+               /* Disable RSS with line-based interrupts */
                adapter->MsiEnabled = FALSE;
                adapter->RssEnabled = FALSE;
                DBG_ERROR("sxg: %s AllocAdaptRsrcs adapter[%p] dev->irq[%x]\n",
-                         __FUNCTION__, adapter, adapter->netdev->irq);
+                         __func__, adapter, adapter->netdev->irq);
        }
        return (STATUS_SUCCESS);
 }
 
 static void sxg_deregister_interrupt(p_adapter_t adapter)
 {
-       DBG_ERROR("sxg: %s ENTER adapter[%p]\n", __FUNCTION__, adapter);
+       DBG_ERROR("sxg: %s ENTER adapter[%p]\n", __func__, adapter);
 #if XXXTODO
        slic_init_cleanup(adapter);
 #endif
@@ -1651,7 +1652,7 @@ static void sxg_deregister_interrupt(p_adapter_t adapter)
        adapter->rcv_broadcasts = 0;
        adapter->rcv_multicasts = 0;
        adapter->rcv_unicasts = 0;
-       DBG_ERROR("sxg: %s EXIT\n", __FUNCTION__);
+       DBG_ERROR("sxg: %s EXIT\n", __func__);
 }
 
 /*
@@ -1666,7 +1667,7 @@ static int sxg_if_init(p_adapter_t adapter)
        int status = 0;
 
        DBG_ERROR("sxg: %s (%s) ENTER states[%d:%d:%d] flags[%x]\n",
-                 __FUNCTION__, adapter->netdev->name,
+                 __func__, adapter->netdev->name,
                  adapter->queues_initialized, adapter->state,
                  adapter->linkstate, dev->flags);
 
@@ -1680,7 +1681,7 @@ static int sxg_if_init(p_adapter_t adapter)
        adapter->devflags_prev = dev->flags;
        adapter->macopts = MAC_DIRECTED;
        if (dev->flags) {
-               DBG_ERROR("sxg: %s (%s) Set MAC options: ", __FUNCTION__,
+               DBG_ERROR("sxg: %s (%s) Set MAC options: ", __func__,
                          adapter->netdev->name);
                if (dev->flags & IFF_BROADCAST) {
                        adapter->macopts |= MAC_BCAST;
@@ -1713,7 +1714,7 @@ static int sxg_if_init(p_adapter_t adapter)
        /*
         *    clear any pending events, then enable interrupts
         */
-       DBG_ERROR("sxg: %s ENABLE interrupts(slic)\n", __FUNCTION__);
+       DBG_ERROR("sxg: %s ENABLE interrupts(slic)\n", __func__);
 
        return (STATUS_SUCCESS);
 }
@@ -1724,11 +1725,11 @@ static int sxg_entry_open(p_net_device dev)
        int status;
 
        ASSERT(adapter);
-       DBG_ERROR("sxg: %s adapter->activated[%d]\n", __FUNCTION__,
+       DBG_ERROR("sxg: %s adapter->activated[%d]\n", __func__,
                  adapter->activated);
        DBG_ERROR
            ("sxg: %s (%s): [jiffies[%lx] cpu %d] dev[%p] adapt[%p] port[%d]\n",
-            __FUNCTION__, adapter->netdev->name, jiffies, smp_processor_id(),
+            __func__, adapter->netdev->name, jiffies, smp_processor_id(),
             adapter->netdev, adapter, adapter->port);
 
        netif_stop_queue(adapter->netdev);
@@ -1738,16 +1739,16 @@ static int sxg_entry_open(p_net_device dev)
                sxg_global.num_sxg_ports_active++;
                adapter->activated = 1;
        }
-       // Initialize the adapter
-       DBG_ERROR("sxg: %s ENTER sxg_initialize_adapter\n", __FUNCTION__);
+       /* Initialize the adapter */
+       DBG_ERROR("sxg: %s ENTER sxg_initialize_adapter\n", __func__);
        status = sxg_initialize_adapter(adapter);
        DBG_ERROR("sxg: %s EXIT sxg_initialize_adapter status[%x]\n",
-                 __FUNCTION__, status);
+                 __func__, status);
 
        if (status == STATUS_SUCCESS) {
-               DBG_ERROR("sxg: %s ENTER sxg_if_init\n", __FUNCTION__);
+               DBG_ERROR("sxg: %s ENTER sxg_if_init\n", __func__);
                status = sxg_if_init(adapter);
-               DBG_ERROR("sxg: %s EXIT sxg_if_init status[%x]\n", __FUNCTION__,
+               DBG_ERROR("sxg: %s EXIT sxg_if_init status[%x]\n", __func__,
                          status);
        }
 
@@ -1760,12 +1761,12 @@ static int sxg_entry_open(p_net_device dev)
                                       sxg_global.flags);
                return (status);
        }
-       DBG_ERROR("sxg: %s ENABLE ALL INTERRUPTS\n", __FUNCTION__);
+       DBG_ERROR("sxg: %s ENABLE ALL INTERRUPTS\n", __func__);
 
-       // Enable interrupts
+       /* Enable interrupts */
        SXG_ENABLE_ALL_INTERRUPTS(adapter);
 
-       DBG_ERROR("sxg: %s EXIT\n", __FUNCTION__);
+       DBG_ERROR("sxg: %s EXIT\n", __func__);
 
        spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
        return STATUS_SUCCESS;
@@ -1779,27 +1780,27 @@ static void __devexit sxg_entry_remove(struct pci_dev *pcidev)
        p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
 
        ASSERT(adapter);
-       DBG_ERROR("sxg: %s ENTER dev[%p] adapter[%p]\n", __FUNCTION__, dev,
+       DBG_ERROR("sxg: %s ENTER dev[%p] adapter[%p]\n", __func__, dev,
                  adapter);
        sxg_deregister_interrupt(adapter);
        sxg_unmap_mmio_space(adapter);
-       DBG_ERROR("sxg: %s unregister_netdev\n", __FUNCTION__);
+       DBG_ERROR("sxg: %s unregister_netdev\n", __func__);
        unregister_netdev(dev);
 
        mmio_start = pci_resource_start(pcidev, 0);
        mmio_len = pci_resource_len(pcidev, 0);
 
-       DBG_ERROR("sxg: %s rel_region(0) start[%x] len[%x]\n", __FUNCTION__,
+       DBG_ERROR("sxg: %s rel_region(0) start[%x] len[%x]\n", __func__,
                  mmio_start, mmio_len);
        release_mem_region(mmio_start, mmio_len);
 
-       DBG_ERROR("sxg: %s iounmap dev->base_addr[%x]\n", __FUNCTION__,
+       DBG_ERROR("sxg: %s iounmap dev->base_addr[%x]\n", __func__,
                  (unsigned int)dev->base_addr);
        iounmap((char *)dev->base_addr);
 
-       DBG_ERROR("sxg: %s deallocate device\n", __FUNCTION__);
+       DBG_ERROR("sxg: %s deallocate device\n", __func__);
        kfree(dev);
-       DBG_ERROR("sxg: %s EXIT\n", __FUNCTION__);
+       DBG_ERROR("sxg: %s EXIT\n", __func__);
 }
 
 static int sxg_entry_halt(p_net_device dev)
@@ -1807,17 +1808,17 @@ static int sxg_entry_halt(p_net_device dev)
        p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
 
        spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags);
-       DBG_ERROR("sxg: %s (%s) ENTER\n", __FUNCTION__, dev->name);
+       DBG_ERROR("sxg: %s (%s) ENTER\n", __func__, dev->name);
 
        netif_stop_queue(adapter->netdev);
        adapter->state = ADAPT_DOWN;
        adapter->linkstate = LINK_DOWN;
        adapter->devflags_prev = 0;
        DBG_ERROR("sxg: %s (%s) set adapter[%p] state to ADAPT_DOWN(%d)\n",
-                 __FUNCTION__, dev->name, adapter, adapter->state);
+                 __func__, dev->name, adapter, adapter->state);
 
-       DBG_ERROR("sxg: %s (%s) EXIT\n", __FUNCTION__, dev->name);
-       DBG_ERROR("sxg: %s EXIT\n", __FUNCTION__);
+       DBG_ERROR("sxg: %s (%s) EXIT\n", __func__, dev->name);
+       DBG_ERROR("sxg: %s EXIT\n", __func__);
        spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
        return (STATUS_SUCCESS);
 }
@@ -1825,11 +1826,11 @@ static int sxg_entry_halt(p_net_device dev)
 static int sxg_ioctl(p_net_device dev, struct ifreq *rq, int cmd)
 {
        ASSERT(rq);
-//      DBG_ERROR("sxg: %s cmd[%x] rq[%p] dev[%p]\n", __FUNCTION__, cmd, rq, dev);
+/*      DBG_ERROR("sxg: %s cmd[%x] rq[%p] dev[%p]\n", __func__, cmd, rq, dev); */
        switch (cmd) {
        case SIOCSLICSETINTAGG:
                {
-//                      p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
+/*                      p_adapter_t adapter = (p_adapter_t) netdev_priv(dev); */
                        u32 data[7];
                        u32 intagg;
 
@@ -1841,12 +1842,12 @@ static int sxg_ioctl(p_net_device dev, struct ifreq *rq, int cmd)
                        intagg = data[0];
                        printk(KERN_EMERG
                               "%s: set interrupt aggregation to %d\n",
-                              __FUNCTION__, intagg);
+                              __func__, intagg);
                        return 0;
                }
 
        default:
-//              DBG_ERROR("sxg: %s UNSUPPORTED[%x]\n", __FUNCTION__, cmd);
+/*              DBG_ERROR("sxg: %s UNSUPPORTED[%x]\n", __func__, cmd); */
                return -EOPNOTSUPP;
        }
        return 0;
@@ -1870,15 +1871,15 @@ static int sxg_send_packets(struct sk_buff *skb, p_net_device dev)
        p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
        u32 status = STATUS_SUCCESS;
 
-       DBG_ERROR("sxg: %s ENTER sxg_send_packets skb[%p]\n", __FUNCTION__,
+       DBG_ERROR("sxg: %s ENTER sxg_send_packets skb[%p]\n", __func__,
                  skb);
-       // Check the adapter state
+       /* Check the adapter state */
        switch (adapter->State) {
        case SXG_STATE_INITIALIZING:
        case SXG_STATE_HALTED:
        case SXG_STATE_SHUTDOWN:
-               ASSERT(0);      // unexpected
-               // fall through
+               ASSERT(0);      /* unexpected */
+               /* fall through */
        case SXG_STATE_RESETTING:
        case SXG_STATE_SLEEP:
        case SXG_STATE_BOOTDIAG:
@@ -1898,23 +1899,23 @@ static int sxg_send_packets(struct sk_buff *skb, p_net_device dev)
        if (status != STATUS_SUCCESS) {
                goto xmit_fail;
        }
-       // send a packet
+       /* send a packet */
        status = sxg_transmit_packet(adapter, skb);
        if (status == STATUS_SUCCESS) {
                goto xmit_done;
        }
 
       xmit_fail:
-       // reject & complete all the packets if they cant be sent
+       /* reject & complete all the packets if they cant be sent */
        if (status != STATUS_SUCCESS) {
 #if XXXTODO
-//      sxg_send_packets_fail(adapter, skb, status);
+/*      sxg_send_packets_fail(adapter, skb, status); */
 #else
                SXG_DROP_DUMB_SEND(adapter, skb);
                adapter->stats.tx_dropped++;
 #endif
        }
-       DBG_ERROR("sxg: %s EXIT sxg_send_packets status[%x]\n", __FUNCTION__,
+       DBG_ERROR("sxg: %s EXIT sxg_send_packets status[%x]\n", __func__,
                  status);
 
       xmit_done:
@@ -1940,12 +1941,12 @@ static int sxg_transmit_packet(p_adapter_t adapter, struct sk_buff *skb)
        void *SglBuffer;
        u32 SglBufferLength;
 
-       // The vast majority of work is done in the shared
-       // sxg_dumb_sgl routine.
+       /* The vast majority of work is done in the shared */
+       /* sxg_dumb_sgl routine. */
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSend",
                  adapter, skb, 0, 0);
 
-       // Allocate a SGL buffer
+       /* Allocate a SGL buffer */
        SXG_GET_SGL_BUFFER(adapter, SxgSgl);
        if (!SxgSgl) {
                adapter->Stats.NoSglBuf++;
@@ -1963,9 +1964,9 @@ static int sxg_transmit_packet(p_adapter_t adapter, struct sk_buff *skb)
        SxgSgl->DumbPacket = skb;
        pSgl = NULL;
 
-       // Call the common sxg_dumb_sgl routine to complete the send.
+       /* Call the common sxg_dumb_sgl routine to complete the send. */
        sxg_dumb_sgl(pSgl, SxgSgl);
-       // Return success   sxg_dumb_sgl (or something later) will complete it.
+       /* Return success   sxg_dumb_sgl (or something later) will complete it. */
        return (STATUS_SUCCESS);
 }
 
@@ -1983,39 +1984,39 @@ static void sxg_dumb_sgl(PSCATTER_GATHER_LIST pSgl, PSXG_SCATTER_GATHER SxgSgl)
 {
        p_adapter_t adapter = SxgSgl->adapter;
        struct sk_buff *skb = SxgSgl->DumbPacket;
-       // For now, all dumb-nic sends go on RSS queue zero
+       /* For now, all dumb-nic sends go on RSS queue zero */
        PSXG_XMT_RING XmtRing = &adapter->XmtRings[0];
        PSXG_RING_INFO XmtRingInfo = &adapter->XmtRingZeroInfo;
        PSXG_CMD XmtCmd = NULL;
-//      u32                         Index = 0;
+/*      u32                         Index = 0; */
        u32 DataLength = skb->len;
-//  unsigned int                                BufLen;
-//      u32                         SglOffset;
+/*  unsigned int                                BufLen; */
+/*      u32                         SglOffset; */
        u64 phys_addr;
 
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSgl",
                  pSgl, SxgSgl, 0, 0);
 
-       // Set aside a pointer to the sgl
+       /* Set aside a pointer to the sgl */
        SxgSgl->pSgl = pSgl;
 
-       // Sanity check that our SGL format is as we expect.
+       /* Sanity check that our SGL format is as we expect. */
        ASSERT(sizeof(SXG_X64_SGE) == sizeof(SCATTER_GATHER_ELEMENT));
-       // Shouldn't be a vlan tag on this frame
+       /* Shouldn't be a vlan tag on this frame */
        ASSERT(SxgSgl->VlanTag.VlanTci == 0);
        ASSERT(SxgSgl->VlanTag.VlanTpid == 0);
 
-       // From here below we work with the SGL placed in our
-       // buffer.
+       /* From here below we work with the SGL placed in our */
+       /* buffer. */
 
        SxgSgl->Sgl.NumberOfElements = 1;
 
-       // Grab the spinlock and acquire a command
+       /* Grab the spinlock and acquire a command */
        spin_lock(&adapter->XmtZeroLock);
        SXG_GET_CMD(XmtRing, XmtRingInfo, XmtCmd, SxgSgl);
        if (XmtCmd == NULL) {
-               // Call sxg_complete_slow_send to see if we can
-               // free up any XmtRingZero entries and then try again
+               /* Call sxg_complete_slow_send to see if we can */
+               /* free up any XmtRingZero entries and then try again */
                spin_unlock(&adapter->XmtZeroLock);
                sxg_complete_slow_send(adapter);
                spin_lock(&adapter->XmtZeroLock);
@@ -2027,10 +2028,10 @@ static void sxg_dumb_sgl(PSCATTER_GATHER_LIST pSgl, PSXG_SCATTER_GATHER SxgSgl)
        }
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbCmd",
                  XmtCmd, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
-       // Update stats
+       /* Update stats */
        adapter->Stats.DumbXmtPkts++;
        adapter->Stats.DumbXmtBytes += DataLength;
-#if XXXTODO                    // Stats stuff
+#if XXXTODO                    /* Stats stuff */
        if (SXG_MULTICAST_PACKET(EtherHdr)) {
                if (SXG_BROADCAST_PACKET(EtherHdr)) {
                        adapter->Stats.DumbXmtBcastPkts++;
@@ -2044,8 +2045,8 @@ static void sxg_dumb_sgl(PSCATTER_GATHER_LIST pSgl, PSXG_SCATTER_GATHER SxgSgl)
                adapter->Stats.DumbXmtUcastBytes += DataLength;
        }
 #endif
-       // Fill in the command
-       // Copy out the first SGE to the command and adjust for offset
+       /* Fill in the command */
+       /* Copy out the first SGE to the command and adjust for offset */
        phys_addr =
            pci_map_single(adapter->pcidev, skb->data, skb->len,
                           PCI_DMA_TODEVICE);
@@ -2053,54 +2054,54 @@ static void sxg_dumb_sgl(PSCATTER_GATHER_LIST pSgl, PSXG_SCATTER_GATHER SxgSgl)
        XmtCmd->Buffer.FirstSgeAddress = XmtCmd->Buffer.FirstSgeAddress << 32;
        XmtCmd->Buffer.FirstSgeAddress =
            XmtCmd->Buffer.FirstSgeAddress | SXG_GET_ADDR_LOW(phys_addr);
-//      XmtCmd->Buffer.FirstSgeAddress = SxgSgl->Sgl.Elements[Index].Address;
-//      XmtCmd->Buffer.FirstSgeAddress.LowPart += MdlOffset;
+/*      XmtCmd->Buffer.FirstSgeAddress = SxgSgl->Sgl.Elements[Index].Address; */
+/*      XmtCmd->Buffer.FirstSgeAddress.LowPart += MdlOffset; */
        XmtCmd->Buffer.FirstSgeLength = DataLength;
-       // Set a pointer to the remaining SGL entries
-//      XmtCmd->Sgl = SxgSgl->PhysicalAddress;
-       // Advance the physical address of the SxgSgl structure to
-       // the second SGE
-//      SglOffset = (u32)((u32 *)(&SxgSgl->Sgl.Elements[Index+1]) -
-//                                              (u32 *)SxgSgl);
-//      XmtCmd->Sgl.LowPart += SglOffset;
+       /* Set a pointer to the remaining SGL entries */
+/*      XmtCmd->Sgl = SxgSgl->PhysicalAddress; */
+       /* Advance the physical address of the SxgSgl structure to */
+       /* the second SGE */
+/*      SglOffset = (u32)((u32 *)(&SxgSgl->Sgl.Elements[Index+1]) - */
+/*                                              (u32 *)SxgSgl); */
+/*      XmtCmd->Sgl.LowPart += SglOffset; */
        XmtCmd->Buffer.SgeOffset = 0;
-       // Note - TotalLength might be overwritten with MSS below..
+       /* Note - TotalLength might be overwritten with MSS below.. */
        XmtCmd->Buffer.TotalLength = DataLength;
-       XmtCmd->SgEntries = 1;  //(ushort)(SxgSgl->Sgl.NumberOfElements - Index);
+       XmtCmd->SgEntries = 1;  /*(ushort)(SxgSgl->Sgl.NumberOfElements - Index); */
        XmtCmd->Flags = 0;
-       //
-       // Advance transmit cmd descripter by 1.
-       // NOTE - See comments in SxgTcpOutput where we write
-       // to the XmtCmd register regarding CPU ID values and/or
-       // multiple commands.
-       //
-       //
+       /* */
+       /* Advance transmit cmd descripter by 1. */
+       /* NOTE - See comments in SxgTcpOutput where we write */
+       /* to the XmtCmd register regarding CPU ID values and/or */
+       /* multiple commands. */
+       /* */
+       /* */
        WRITE_REG(adapter->UcodeRegs[0].XmtCmd, 1, TRUE);
-       //
-       //
-       adapter->Stats.XmtQLen++;       // Stats within lock
+       /* */
+       /* */
+       adapter->Stats.XmtQLen++;       /* Stats within lock */
        spin_unlock(&adapter->XmtZeroLock);
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDumSgl2",
                  XmtCmd, pSgl, SxgSgl, 0);
        return;
 
       abortcmd:
-       // NOTE - Only jump to this label AFTER grabbing the
-       // XmtZeroLock, and DO NOT DROP IT between the
-       // command allocation and the following abort.
+       /* NOTE - Only jump to this label AFTER grabbing the */
+       /* XmtZeroLock, and DO NOT DROP IT between the */
+       /* command allocation and the following abort. */
        if (XmtCmd) {
                SXG_ABORT_CMD(XmtRingInfo);
        }
        spin_unlock(&adapter->XmtZeroLock);
 
-// failsgl:
-       // Jump to this label if failure occurs before the
-       // XmtZeroLock is grabbed
+/* failsgl: */
+       /* Jump to this label if failure occurs before the */
+       /* XmtZeroLock is grabbed */
        adapter->Stats.XmtErrors++;
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "DumSGFal",
                  pSgl, SxgSgl, XmtRingInfo->Head, XmtRingInfo->Tail);
 
-       SXG_COMPLETE_DUMB_SEND(adapter, SxgSgl->DumbPacket);    // SxgSgl->DumbPacket is the skb
+       SXG_COMPLETE_DUMB_SEND(adapter, SxgSgl->DumbPacket);    /* SxgSgl->DumbPacket is the skb */
 }
 
 /***************************************************************
@@ -2127,122 +2128,122 @@ static int sxg_initialize_link(p_adapter_t adapter)
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "InitLink",
                  adapter, 0, 0, 0);
 
-       // Reset PHY and XGXS module
+       /* Reset PHY and XGXS module */
        WRITE_REG(HwRegs->LinkStatus, LS_SERDES_POWER_DOWN, TRUE);
 
-       // Reset transmit configuration register
+       /* Reset transmit configuration register */
        WRITE_REG(HwRegs->XmtConfig, XMT_CONFIG_RESET, TRUE);
 
-       // Reset receive configuration register
+       /* Reset receive configuration register */
        WRITE_REG(HwRegs->RcvConfig, RCV_CONFIG_RESET, TRUE);
 
-       // Reset all MAC modules
+       /* Reset all MAC modules */
        WRITE_REG(HwRegs->MacConfig0, AXGMAC_CFG0_SUB_RESET, TRUE);
 
-       // Link address 0
-       // XXXTODO - This assumes the MAC address (0a:0b:0c:0d:0e:0f)
-       // is stored with the first nibble (0a) in the byte 0
-       // of the Mac address.  Possibly reverse?
+       /* Link address 0 */
+       /* XXXTODO - This assumes the MAC address (0a:0b:0c:0d:0e:0f) */
+       /* is stored with the first nibble (0a) in the byte 0 */
+       /* of the Mac address.  Possibly reverse? */
        Value = *(u32 *) adapter->MacAddr;
        WRITE_REG(HwRegs->LinkAddress0Low, Value, TRUE);
-       // also write the MAC address to the MAC.  Endian is reversed.
+       /* also write the MAC address to the MAC.  Endian is reversed. */
        WRITE_REG(HwRegs->MacAddressLow, ntohl(Value), TRUE);
        Value = (*(u16 *) & adapter->MacAddr[4] & 0x0000FFFF);
        WRITE_REG(HwRegs->LinkAddress0High, Value | LINK_ADDRESS_ENABLE, TRUE);
-       // endian swap for the MAC (put high bytes in bits [31:16], swapped)
+       /* endian swap for the MAC (put high bytes in bits [31:16], swapped) */
        Value = ntohl(Value);
        WRITE_REG(HwRegs->MacAddressHigh, Value, TRUE);
-       // Link address 1
+       /* Link address 1 */
        WRITE_REG(HwRegs->LinkAddress1Low, 0, TRUE);
        WRITE_REG(HwRegs->LinkAddress1High, 0, TRUE);
-       // Link address 2
+       /* Link address 2 */
        WRITE_REG(HwRegs->LinkAddress2Low, 0, TRUE);
        WRITE_REG(HwRegs->LinkAddress2High, 0, TRUE);
-       // Link address 3
+       /* Link address 3 */
        WRITE_REG(HwRegs->LinkAddress3Low, 0, TRUE);
        WRITE_REG(HwRegs->LinkAddress3High, 0, TRUE);
 
-       // Enable MAC modules
+       /* Enable MAC modules */
        WRITE_REG(HwRegs->MacConfig0, 0, TRUE);
 
-       // Configure MAC
-       WRITE_REG(HwRegs->MacConfig1, (AXGMAC_CFG1_XMT_PAUSE |  // Allow sending of pause
-                                      AXGMAC_CFG1_XMT_EN |     // Enable XMT
-                                      AXGMAC_CFG1_RCV_PAUSE |  // Enable detection of pause
-                                      AXGMAC_CFG1_RCV_EN |     // Enable receive
-                                      AXGMAC_CFG1_SHORT_ASSERT |       // short frame detection
-                                      AXGMAC_CFG1_CHECK_LEN |  // Verify frame length
-                                      AXGMAC_CFG1_GEN_FCS |    // Generate FCS
-                                      AXGMAC_CFG1_PAD_64),     // Pad frames to 64 bytes
+       /* Configure MAC */
+       WRITE_REG(HwRegs->MacConfig1, (AXGMAC_CFG1_XMT_PAUSE |  /* Allow sending of pause */
+                                      AXGMAC_CFG1_XMT_EN |     /* Enable XMT */
+                                      AXGMAC_CFG1_RCV_PAUSE |  /* Enable detection of pause */
+                                      AXGMAC_CFG1_RCV_EN |     /* Enable receive */
+                                      AXGMAC_CFG1_SHORT_ASSERT |       /* short frame detection */
+                                      AXGMAC_CFG1_CHECK_LEN |  /* Verify frame length */
+                                      AXGMAC_CFG1_GEN_FCS |    /* Generate FCS */
+                                      AXGMAC_CFG1_PAD_64),     /* Pad frames to 64 bytes */
                  TRUE);
 
-       // Set AXGMAC max frame length if jumbo.  Not needed for standard MTU
+       /* Set AXGMAC max frame length if jumbo.  Not needed for standard MTU */
        if (adapter->JumboEnabled) {
                WRITE_REG(HwRegs->MacMaxFrameLen, AXGMAC_MAXFRAME_JUMBO, TRUE);
        }
-       // AMIIM Configuration Register -
-       // The value placed in the AXGMAC_AMIIM_CFG_HALF_CLOCK portion
-       // (bottom bits) of this register is used to determine the
-       // MDC frequency as specified in the A-XGMAC Design Document.
-       // This value must not be zero.  The following value (62 or 0x3E)
-       // is based on our MAC transmit clock frequency (MTCLK) of 312.5 MHz.
-       // Given a maximum MDIO clock frequency of 2.5 MHz (see the PHY spec),
-       // we get:  312.5/(2*(X+1)) < 2.5  ==> X = 62.
-       // This value happens to be the default value for this register,
-       // so we really don't have to do this.
+       /* AMIIM Configuration Register - */
+       /* The value placed in the AXGMAC_AMIIM_CFG_HALF_CLOCK portion */
+       /* (bottom bits) of this register is used to determine the */
+       /* MDC frequency as specified in the A-XGMAC Design Document. */
+       /* This value must not be zero.  The following value (62 or 0x3E) */
+       /* is based on our MAC transmit clock frequency (MTCLK) of 312.5 MHz. */
+       /* Given a maximum MDIO clock frequency of 2.5 MHz (see the PHY spec), */
+       /* we get:  312.5/(2*(X+1)) < 2.5  ==> X = 62. */
+       /* This value happens to be the default value for this register, */
+       /* so we really don't have to do this. */
        WRITE_REG(HwRegs->MacAmiimConfig, 0x0000003E, TRUE);
 
-       // Power up and enable PHY and XAUI/XGXS/Serdes logic
+       /* Power up and enable PHY and XAUI/XGXS/Serdes logic */
        WRITE_REG(HwRegs->LinkStatus,
                  (LS_PHY_CLR_RESET |
                   LS_XGXS_ENABLE |
                   LS_XGXS_CTL | LS_PHY_CLK_EN | LS_ATTN_ALARM), TRUE);
        DBG_ERROR("After Power Up and enable PHY in sxg_initialize_link\n");
 
-       // Per information given by Aeluros, wait 100 ms after removing reset.
-       // It's not enough to wait for the self-clearing reset bit in reg 0 to clear.
+       /* Per information given by Aeluros, wait 100 ms after removing reset. */
+       /* It's not enough to wait for the self-clearing reset bit in reg 0 to clear. */
        mdelay(100);
 
-       // Verify the PHY has come up by checking that the Reset bit has cleared.
-       status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,   // PHY PMA/PMD module
-                                  PHY_PMA_CONTROL1,    // PMA/PMD control register
+       /* Verify the PHY has come up by checking that the Reset bit has cleared. */
+       status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,   /* PHY PMA/PMD module */
+                                  PHY_PMA_CONTROL1,    /* PMA/PMD control register */
                                   &Value);
        if (status != STATUS_SUCCESS)
                return (STATUS_FAILURE);
-       if (Value & PMA_CONTROL1_RESET) // reset complete if bit is 0
+       if (Value & PMA_CONTROL1_RESET) /* reset complete if bit is 0 */
                return (STATUS_FAILURE);
 
-       // The SERDES should be initialized by now - confirm
+       /* The SERDES should be initialized by now - confirm */
        READ_REG(HwRegs->LinkStatus, Value);
-       if (Value & LS_SERDES_DOWN)     // verify SERDES is initialized
+       if (Value & LS_SERDES_DOWN)     /* verify SERDES is initialized */
                return (STATUS_FAILURE);
 
-       // The XAUI link should also be up - confirm
-       if (!(Value & LS_XAUI_LINK_UP)) // verify XAUI link is up
+       /* The XAUI link should also be up - confirm */
+       if (!(Value & LS_XAUI_LINK_UP)) /* verify XAUI link is up */
                return (STATUS_FAILURE);
 
-       // Initialize the PHY
+       /* Initialize the PHY */
        status = sxg_phy_init(adapter);
        if (status != STATUS_SUCCESS)
                return (STATUS_FAILURE);
 
-       // Enable the Link Alarm
-       status = sxg_write_mdio_reg(adapter, MIIM_DEV_PHY_PMA,  // PHY PMA/PMD module
-                                   LASI_CONTROL,       // LASI control register
-                                   LASI_CTL_LS_ALARM_ENABLE);  // enable link alarm bit
+       /* Enable the Link Alarm */
+       status = sxg_write_mdio_reg(adapter, MIIM_DEV_PHY_PMA,  /* PHY PMA/PMD module */
+                                   LASI_CONTROL,       /* LASI control register */
+                                   LASI_CTL_LS_ALARM_ENABLE);  /* enable link alarm bit */
        if (status != STATUS_SUCCESS)
                return (STATUS_FAILURE);
 
-       // XXXTODO - temporary - verify bit is set
-       status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,   // PHY PMA/PMD module
-                                  LASI_CONTROL,        // LASI control register
+       /* XXXTODO - temporary - verify bit is set */
+       status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,   /* PHY PMA/PMD module */
+                                  LASI_CONTROL,        /* LASI control register */
                                   &Value);
        if (status != STATUS_SUCCESS)
                return (STATUS_FAILURE);
        if (!(Value & LASI_CTL_LS_ALARM_ENABLE)) {
                DBG_ERROR("Error!  LASI Control Alarm Enable bit not set!\n");
        }
-       // Enable receive
+       /* Enable receive */
        MaxFrame = adapter->JumboEnabled ? JUMBOMAXFRAME : ETHERMAXFRAME;
        ConfigData = (RCV_CONFIG_ENABLE |
                      RCV_CONFIG_ENPARSE |
@@ -2256,7 +2257,7 @@ static int sxg_initialize_link(p_adapter_t adapter)
 
        WRITE_REG(HwRegs->XmtConfig, XMT_CONFIG_ENABLE, TRUE);
 
-       // Mark the link as down.  We'll get a link event when it comes up.
+       /* Mark the link as down.  We'll get a link event when it comes up. */
        sxg_link_state(adapter, SXG_LINK_DOWN);
 
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XInitLnk",
@@ -2279,35 +2280,35 @@ static int sxg_phy_init(p_adapter_t adapter)
        PPHY_UCODE p;
        int status;
 
-       DBG_ERROR("ENTER %s\n", __FUNCTION__);
+       DBG_ERROR("ENTER %s\n", __func__);
 
-       // Read a register to identify the PHY type
-       status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,   // PHY PMA/PMD module
-                                  0xC205,      // PHY ID register (?)
-                                  &Value);     //    XXXTODO - add def
+       /* Read a register to identify the PHY type */
+       status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,   /* PHY PMA/PMD module */
+                                  0xC205,      /* PHY ID register (?) */
+                                  &Value);     /*    XXXTODO - add def */
        if (status != STATUS_SUCCESS)
                return (STATUS_FAILURE);
 
-       if (Value == 0x0012) {  // 0x0012 == AEL2005C PHY(?) - XXXTODO - add def
+       if (Value == 0x0012) {  /* 0x0012 == AEL2005C PHY(?) - XXXTODO - add def */
                DBG_ERROR
                    ("AEL2005C PHY detected.  Downloading PHY microcode.\n");
 
-               // Initialize AEL2005C PHY and download PHY microcode
+               /* Initialize AEL2005C PHY and download PHY microcode */
                for (p = PhyUcode; p->Addr != 0xFFFF; p++) {
                        if (p->Addr == 0) {
-                               // if address == 0, data == sleep time in ms
+                               /* if address == 0, data == sleep time in ms */
                                mdelay(p->Data);
                        } else {
-                               // write the given data to the specified address
-                               status = sxg_write_mdio_reg(adapter, MIIM_DEV_PHY_PMA,  // PHY PMA/PMD module
-                                                           p->Addr,    // PHY address
-                                                           p->Data);   // PHY data
+                               /* write the given data to the specified address */
+                               status = sxg_write_mdio_reg(adapter, MIIM_DEV_PHY_PMA,  /* PHY PMA/PMD module */
+                                                           p->Addr,    /* PHY address */
+                                                           p->Data);   /* PHY data */
                                if (status != STATUS_SUCCESS)
                                        return (STATUS_FAILURE);
                        }
                }
        }
-       DBG_ERROR("EXIT %s\n", __FUNCTION__);
+       DBG_ERROR("EXIT %s\n", __func__);
 
        return (STATUS_SUCCESS);
 }
@@ -2330,42 +2331,42 @@ static void sxg_link_event(p_adapter_t adapter)
 
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "LinkEvnt",
                  adapter, 0, 0, 0);
-       DBG_ERROR("ENTER %s\n", __FUNCTION__);
+       DBG_ERROR("ENTER %s\n", __func__);
 
-       // Check the Link Status register.  We should have a Link Alarm.
+       /* Check the Link Status register.  We should have a Link Alarm. */
        READ_REG(HwRegs->LinkStatus, Value);
        if (Value & LS_LINK_ALARM) {
-               // We got a Link Status alarm.  First, pause to let the
-               // link state settle (it can bounce a number of times)
+               /* We got a Link Status alarm.  First, pause to let the */
+               /* link state settle (it can bounce a number of times) */
                mdelay(10);
 
-               // Now clear the alarm by reading the LASI status register.
-               status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,   // PHY PMA/PMD module
-                                          LASI_STATUS, // LASI status register
+               /* Now clear the alarm by reading the LASI status register. */
+               status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,   /* PHY PMA/PMD module */
+                                          LASI_STATUS, /* LASI status register */
                                           &Value);
                if (status != STATUS_SUCCESS) {
                        DBG_ERROR("Error reading LASI Status MDIO register!\n");
                        sxg_link_state(adapter, SXG_LINK_DOWN);
-//                      ASSERT(0);
+/*                      ASSERT(0); */
                }
                ASSERT(Value & LASI_STATUS_LS_ALARM);
 
-               // Now get and set the link state
+               /* Now get and set the link state */
                LinkState = sxg_get_link_state(adapter);
                sxg_link_state(adapter, LinkState);
                DBG_ERROR("SXG: Link Alarm occurred.  Link is %s\n",
                          ((LinkState == SXG_LINK_UP) ? "UP" : "DOWN"));
        } else {
-               // XXXTODO - Assuming Link Attention is only being generated for the
-               // Link Alarm pin (and not for a XAUI Link Status change), then it's
-               // impossible to get here.  Yet we've gotten here twice (under extreme
-               // conditions - bouncing the link up and down many times a second).
-               // Needs further investigation.
+               /* XXXTODO - Assuming Link Attention is only being generated for the */
+               /* Link Alarm pin (and not for a XAUI Link Status change), then it's */
+               /* impossible to get here.  Yet we've gotten here twice (under extreme */
+               /* conditions - bouncing the link up and down many times a second). */
+               /* Needs further investigation. */
                DBG_ERROR("SXG: sxg_link_event: Can't get here!\n");
                DBG_ERROR("SXG: Link Status == 0x%08X.\n", Value);
-//              ASSERT(0);
+/*              ASSERT(0); */
        }
-       DBG_ERROR("EXIT %s\n", __FUNCTION__);
+       DBG_ERROR("EXIT %s\n", __func__);
 
 }
 
@@ -2383,50 +2384,50 @@ static SXG_LINK_STATE sxg_get_link_state(p_adapter_t adapter)
        int status;
        u32 Value;
 
-       DBG_ERROR("ENTER %s\n", __FUNCTION__);
+       DBG_ERROR("ENTER %s\n", __func__);
 
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "GetLink",
                  adapter, 0, 0, 0);
 
-       // Per the Xenpak spec (and the IEEE 10Gb spec?), the link is up if
-       // the following 3 bits (from 3 different MDIO registers) are all true.
-       status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,   // PHY PMA/PMD module
-                                  PHY_PMA_RCV_DET,     // PMA/PMD Receive Signal Detect register
+       /* Per the Xenpak spec (and the IEEE 10Gb spec?), the link is up if */
+       /* the following 3 bits (from 3 different MDIO registers) are all true. */
+       status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,   /* PHY PMA/PMD module */
+                                  PHY_PMA_RCV_DET,     /* PMA/PMD Receive Signal Detect register */
                                   &Value);
        if (status != STATUS_SUCCESS)
                goto bad;
 
-       // If PMA/PMD receive signal detect is 0, then the link is down
+       /* If PMA/PMD receive signal detect is 0, then the link is down */
        if (!(Value & PMA_RCV_DETECT))
                return (SXG_LINK_DOWN);
 
-       status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PCS,   // PHY PCS module
-                                  PHY_PCS_10G_STATUS1, // PCS 10GBASE-R Status 1 register
+       status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PCS,   /* PHY PCS module */
+                                  PHY_PCS_10G_STATUS1, /* PCS 10GBASE-R Status 1 register */
                                   &Value);
        if (status != STATUS_SUCCESS)
                goto bad;
 
-       // If PCS is not locked to receive blocks, then the link is down
+       /* If PCS is not locked to receive blocks, then the link is down */
        if (!(Value & PCS_10B_BLOCK_LOCK))
                return (SXG_LINK_DOWN);
 
-       status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_XS,    // PHY XS module
-                                  PHY_XS_LANE_STATUS,  // XS Lane Status register
+       status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_XS,    /* PHY XS module */
+                                  PHY_XS_LANE_STATUS,  /* XS Lane Status register */
                                   &Value);
        if (status != STATUS_SUCCESS)
                goto bad;
 
-       // If XS transmit lanes are not aligned, then the link is down
+       /* If XS transmit lanes are not aligned, then the link is down */
        if (!(Value & XS_LANE_ALIGN))
                return (SXG_LINK_DOWN);
 
-       // All 3 bits are true, so the link is up
-       DBG_ERROR("EXIT %s\n", __FUNCTION__);
+       /* All 3 bits are true, so the link is up */
+       DBG_ERROR("EXIT %s\n", __func__);
 
        return (SXG_LINK_UP);
 
       bad:
-       // An error occurred reading an MDIO register.  This shouldn't happen.
+       /* An error occurred reading an MDIO register.  This shouldn't happen. */
        DBG_ERROR("Error reading an MDIO register!\n");
        ASSERT(0);
        return (SXG_LINK_DOWN);
@@ -2437,11 +2438,11 @@ static void sxg_indicate_link_state(p_adapter_t adapter,
 {
        if (adapter->LinkState == SXG_LINK_UP) {
                DBG_ERROR("%s: LINK now UP, call netif_start_queue\n",
-                         __FUNCTION__);
+                         __func__);
                netif_start_queue(adapter->netdev);
        } else {
                DBG_ERROR("%s: LINK now DOWN, call netif_stop_queue\n",
-                         __FUNCTION__);
+                         __func__);
                netif_stop_queue(adapter->netdev);
        }
 }
@@ -2464,23 +2465,23 @@ static void sxg_link_state(p_adapter_t adapter, SXG_LINK_STATE LinkState)
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "LnkINDCT",
                  adapter, LinkState, adapter->LinkState, adapter->State);
 
-       DBG_ERROR("ENTER %s\n", __FUNCTION__);
+       DBG_ERROR("ENTER %s\n", __func__);
 
-       // Hold the adapter lock during this routine.  Maybe move
-       // the lock to the caller.
+       /* Hold the adapter lock during this routine.  Maybe move */
+       /* the lock to the caller. */
        spin_lock(&adapter->AdapterLock);
        if (LinkState == adapter->LinkState) {
-               // Nothing changed..
+               /* Nothing changed.. */
                spin_unlock(&adapter->AdapterLock);
-               DBG_ERROR("EXIT #0 %s\n", __FUNCTION__);
+               DBG_ERROR("EXIT #0 %s\n", __func__);
                return;
        }
-       // Save the adapter state
+       /* Save the adapter state */
        adapter->LinkState = LinkState;
 
-       // Drop the lock and indicate link state
+       /* Drop the lock and indicate link state */
        spin_unlock(&adapter->AdapterLock);
-       DBG_ERROR("EXIT #1 %s\n", __FUNCTION__);
+       DBG_ERROR("EXIT #1 %s\n", __func__);
 
        sxg_indicate_link_state(adapter, LinkState);
 }
@@ -2501,76 +2502,76 @@ static int sxg_write_mdio_reg(p_adapter_t adapter,
                              u32 DevAddr, u32 RegAddr, u32 Value)
 {
        PSXG_HW_REGS HwRegs = adapter->HwRegs;
-       u32 AddrOp;             // Address operation (written to MIIM field reg)
-       u32 WriteOp;            // Write operation (written to MIIM field reg)
-       u32 Cmd;                // Command (written to MIIM command reg)
+       u32 AddrOp;             /* Address operation (written to MIIM field reg) */
+       u32 WriteOp;            /* Write operation (written to MIIM field reg) */
+       u32 Cmd;                /* Command (written to MIIM command reg) */
        u32 ValueRead;
        u32 Timeout;
 
-//  DBG_ERROR("ENTER %s\n", __FUNCTION__);
+/*  DBG_ERROR("ENTER %s\n", __func__); */
 
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "WrtMDIO",
                  adapter, 0, 0, 0);
 
-       // Ensure values don't exceed field width
-       DevAddr &= 0x001F;      // 5-bit field
-       RegAddr &= 0xFFFF;      // 16-bit field
-       Value &= 0xFFFF;        // 16-bit field
+       /* Ensure values don't exceed field width */
+       DevAddr &= 0x001F;      /* 5-bit field */
+       RegAddr &= 0xFFFF;      /* 16-bit field */
+       Value &= 0xFFFF;        /* 16-bit field */
 
-       // Set MIIM field register bits for an MIIM address operation
+       /* Set MIIM field register bits for an MIIM address operation */
        AddrOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) |
            (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) |
            (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) |
            (MIIM_OP_ADDR << AXGMAC_AMIIM_FIELD_OP_SHIFT) | RegAddr;
 
-       // Set MIIM field register bits for an MIIM write operation
+       /* Set MIIM field register bits for an MIIM write operation */
        WriteOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) |
            (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) |
            (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) |
            (MIIM_OP_WRITE << AXGMAC_AMIIM_FIELD_OP_SHIFT) | Value;
 
-       // Set MIIM command register bits to execute an MIIM command
+       /* Set MIIM command register bits to execute an MIIM command */
        Cmd = AXGMAC_AMIIM_CMD_START | AXGMAC_AMIIM_CMD_10G_OPERATION;
 
-       // Reset the command register command bit (in case it's not 0)
+       /* Reset the command register command bit (in case it's not 0) */
        WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE);
 
-       // MIIM write to set the address of the specified MDIO register
+       /* MIIM write to set the address of the specified MDIO register */
        WRITE_REG(HwRegs->MacAmiimField, AddrOp, TRUE);
 
-       // Write to MIIM Command Register to execute to address operation
+       /* Write to MIIM Command Register to execute to address operation */
        WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE);
 
-       // Poll AMIIM Indicator register to wait for completion
+       /* Poll AMIIM Indicator register to wait for completion */
        Timeout = SXG_LINK_TIMEOUT;
        do {
-               udelay(100);    // Timeout in 100us units
+               udelay(100);    /* Timeout in 100us units */
                READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
                if (--Timeout == 0) {
                        return (STATUS_FAILURE);
                }
        } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
 
-       // Reset the command register command bit
+       /* Reset the command register command bit */
        WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE);
 
-       // MIIM write to set up an MDIO write operation
+       /* MIIM write to set up an MDIO write operation */
        WRITE_REG(HwRegs->MacAmiimField, WriteOp, TRUE);
 
-       // Write to MIIM Command Register to execute the write operation
+       /* Write to MIIM Command Register to execute the write operation */
        WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE);
 
-       // Poll AMIIM Indicator register to wait for completion
+       /* Poll AMIIM Indicator register to wait for completion */
        Timeout = SXG_LINK_TIMEOUT;
        do {
-               udelay(100);    // Timeout in 100us units
+               udelay(100);    /* Timeout in 100us units */
                READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
                if (--Timeout == 0) {
                        return (STATUS_FAILURE);
                }
        } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
 
-//  DBG_ERROR("EXIT %s\n", __FUNCTION__);
+/*  DBG_ERROR("EXIT %s\n", __func__); */
 
        return (STATUS_SUCCESS);
 }
@@ -2591,110 +2592,78 @@ static int sxg_read_mdio_reg(p_adapter_t adapter,
                             u32 DevAddr, u32 RegAddr, u32 *pValue)
 {
        PSXG_HW_REGS HwRegs = adapter->HwRegs;
-       u32 AddrOp;             // Address operation (written to MIIM field reg)
-       u32 ReadOp;             // Read operation (written to MIIM field reg)
-       u32 Cmd;                // Command (written to MIIM command reg)
+       u32 AddrOp;             /* Address operation (written to MIIM field reg) */
+       u32 ReadOp;             /* Read operation (written to MIIM field reg) */
+       u32 Cmd;                /* Command (written to MIIM command reg) */
        u32 ValueRead;
        u32 Timeout;
 
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "WrtMDIO",
                  adapter, 0, 0, 0);
-//  DBG_ERROR("ENTER %s\n", __FUNCTION__);
+/*  DBG_ERROR("ENTER %s\n", __func__); */
 
-       // Ensure values don't exceed field width
-       DevAddr &= 0x001F;      // 5-bit field
-       RegAddr &= 0xFFFF;      // 16-bit field
+       /* Ensure values don't exceed field width */
+       DevAddr &= 0x001F;      /* 5-bit field */
+       RegAddr &= 0xFFFF;      /* 16-bit field */
 
-       // Set MIIM field register bits for an MIIM address operation
+       /* Set MIIM field register bits for an MIIM address operation */
        AddrOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) |
            (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) |
            (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) |
            (MIIM_OP_ADDR << AXGMAC_AMIIM_FIELD_OP_SHIFT) | RegAddr;
 
-       // Set MIIM field register bits for an MIIM read operation
+       /* Set MIIM field register bits for an MIIM read operation */
        ReadOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) |
            (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) |
            (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) |
            (MIIM_OP_READ << AXGMAC_AMIIM_FIELD_OP_SHIFT);
 
-       // Set MIIM command register bits to execute an MIIM command
+       /* Set MIIM command register bits to execute an MIIM command */
        Cmd = AXGMAC_AMIIM_CMD_START | AXGMAC_AMIIM_CMD_10G_OPERATION;
 
-       // Reset the command register command bit (in case it's not 0)
+       /* Reset the command register command bit (in case it's not 0) */
        WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE);
 
-       // MIIM write to set the address of the specified MDIO register
+       /* MIIM write to set the address of the specified MDIO register */
        WRITE_REG(HwRegs->MacAmiimField, AddrOp, TRUE);
 
-       // Write to MIIM Command Register to execute to address operation
+       /* Write to MIIM Command Register to execute to address operation */
        WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE);
 
-       // Poll AMIIM Indicator register to wait for completion
+       /* Poll AMIIM Indicator register to wait for completion */
        Timeout = SXG_LINK_TIMEOUT;
        do {
-               udelay(100);    // Timeout in 100us units
+               udelay(100);    /* Timeout in 100us units */
                READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
                if (--Timeout == 0) {
                        return (STATUS_FAILURE);
                }
        } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
 
-       // Reset the command register command bit
+       /* Reset the command register command bit */
        WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE);
 
-       // MIIM write to set up an MDIO register read operation
+       /* MIIM write to set up an MDIO register read operation */
        WRITE_REG(HwRegs->MacAmiimField, ReadOp, TRUE);
 
-       // Write to MIIM Command Register to execute the read operation
+       /* Write to MIIM Command Register to execute the read operation */
        WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE);
 
-       // Poll AMIIM Indicator register to wait for completion
+       /* Poll AMIIM Indicator register to wait for completion */
        Timeout = SXG_LINK_TIMEOUT;
        do {
-               udelay(100);    // Timeout in 100us units
+               udelay(100);    /* Timeout in 100us units */
                READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
                if (--Timeout == 0) {
                        return (STATUS_FAILURE);
                }
        } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
 
-       // Read the MDIO register data back from the field register
+       /* Read the MDIO register data back from the field register */
        READ_REG(HwRegs->MacAmiimField, *pValue);
-       *pValue &= 0xFFFF;      // data is in the lower 16 bits
+       *pValue &= 0xFFFF;      /* data is in the lower 16 bits */
 
-//  DBG_ERROR("EXIT %s\n", __FUNCTION__);
-
-       return (STATUS_SUCCESS);
-}
-
-/*
- *  Allocate a mcast_address structure to hold the multicast address.
- *  Link it in.
- */
-static int sxg_mcast_add_list(p_adapter_t adapter, char *address)
-{
-       p_mcast_address_t mcaddr, mlist;
-       bool equaladdr;
-
-       /* Check to see if it already exists */
-       mlist = adapter->mcastaddrs;
-       while (mlist) {
-               ETHER_EQ_ADDR(mlist->address, address, equaladdr);
-               if (equaladdr) {
-                       return (STATUS_SUCCESS);
-               }
-               mlist = mlist->next;
-       }
-
-       /* Doesn't already exist.  Allocate a structure to hold it */
-       mcaddr = kmalloc(sizeof(mcast_address_t), GFP_ATOMIC);
-       if (mcaddr == NULL)
-               return 1;
-
-       memcpy(mcaddr->address, address, 6);
-
-       mcaddr->next = adapter->mcastaddrs;
-       adapter->mcastaddrs = mcaddr;
+/*  DBG_ERROR("EXIT %s\n", __func__); */
 
        return (STATUS_SUCCESS);
 }
@@ -2710,7 +2679,6 @@ static int sxg_mcast_add_list(p_adapter_t adapter, char *address)
  *
  */
 static u32 sxg_crc_table[256]; /* Table of CRC's for all possible byte values */
-static u32 sxg_crc_init;       /* Is table initialized                        */
 
 /*
  *  Contruct the CRC32 table
@@ -2737,6 +2705,8 @@ static void sxg_mcast_init_crc32(void)
        }
 }
 
+#if XXXTODO
+static u32 sxg_crc_init;       /* Is table initialized */
 /*
  *  Return the MAC hast as described above.
  */
@@ -2765,6 +2735,74 @@ static unsigned char sxg_mcast_get_mac_hash(char *macaddr)
        return (machash);
 }
 
+static void sxg_mcast_set_mask(p_adapter_t adapter)
+{
+       PSXG_UCODE_REGS sxg_regs = adapter->UcodeRegs;
+
+       DBG_ERROR("%s ENTER (%s) macopts[%x] mask[%llx]\n", __func__,
+                 adapter->netdev->name, (unsigned int)adapter->MacFilter,
+                 adapter->MulticastMask);
+
+       if (adapter->MacFilter & (MAC_ALLMCAST | MAC_PROMISC)) {
+               /* Turn on all multicast addresses. We have to do this for promiscuous
+                * mode as well as ALLMCAST mode.  It saves the Microcode from having
+                * to keep state about the MAC configuration.
+                */
+/*              DBG_ERROR("sxg: %s macopts = MAC_ALLMCAST | MAC_PROMISC\n      SLUT MODE!!!\n",__func__); */
+               WRITE_REG(sxg_regs->McastLow, 0xFFFFFFFF, FLUSH);
+               WRITE_REG(sxg_regs->McastHigh, 0xFFFFFFFF, FLUSH);
+/*        DBG_ERROR("%s (%s) WRITE to slic_regs slic_mcastlow&high 0xFFFFFFFF\n",__func__, adapter->netdev->name); */
+
+       } else {
+               /* Commit our multicast mast to the SLIC by writing to the multicast
+                * address mask registers
+                */
+               DBG_ERROR("%s (%s) WRITE mcastlow[%lx] mcasthigh[%lx]\n",
+                         __func__, adapter->netdev->name,
+                         ((ulong) (adapter->MulticastMask & 0xFFFFFFFF)),
+                         ((ulong)
+                          ((adapter->MulticastMask >> 32) & 0xFFFFFFFF)));
+
+               WRITE_REG(sxg_regs->McastLow,
+                         (u32) (adapter->MulticastMask & 0xFFFFFFFF), FLUSH);
+               WRITE_REG(sxg_regs->McastHigh,
+                         (u32) ((adapter->
+                                 MulticastMask >> 32) & 0xFFFFFFFF), FLUSH);
+       }
+}
+
+/*
+ *  Allocate a mcast_address structure to hold the multicast address.
+ *  Link it in.
+ */
+static int sxg_mcast_add_list(p_adapter_t adapter, char *address)
+{
+       p_mcast_address_t mcaddr, mlist;
+       bool equaladdr;
+
+       /* Check to see if it already exists */
+       mlist = adapter->mcastaddrs;
+       while (mlist) {
+               ETHER_EQ_ADDR(mlist->address, address, equaladdr);
+               if (equaladdr) {
+                       return (STATUS_SUCCESS);
+               }
+               mlist = mlist->next;
+       }
+
+       /* Doesn't already exist.  Allocate a structure to hold it */
+       mcaddr = kmalloc(sizeof(mcast_address_t), GFP_ATOMIC);
+       if (mcaddr == NULL)
+               return 1;
+
+       memcpy(mcaddr->address, address, 6);
+
+       mcaddr->next = adapter->mcastaddrs;
+       adapter->mcastaddrs = mcaddr;
+
+       return (STATUS_SUCCESS);
+}
+
 static void sxg_mcast_set_bit(p_adapter_t adapter, char *address)
 {
        unsigned char crcpoly;
@@ -2783,7 +2821,6 @@ static void sxg_mcast_set_bit(p_adapter_t adapter, char *address)
 
 static void sxg_mcast_set_list(p_net_device dev)
 {
-#if XXXTODO
        p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
        int status = STATUS_SUCCESS;
        int i;
@@ -2809,7 +2846,7 @@ static void sxg_mcast_set_list(p_net_device dev)
        }
 
        DBG_ERROR("%s a->devflags_prev[%x] dev->flags[%x] status[%x]\n",
-                 __FUNCTION__, adapter->devflags_prev, dev->flags, status);
+                 __func__, adapter->devflags_prev, dev->flags, status);
        if (adapter->devflags_prev != dev->flags) {
                adapter->macopts = MAC_DIRECTED;
                if (dev->flags) {
@@ -2828,60 +2865,24 @@ static void sxg_mcast_set_list(p_net_device dev)
                }
                adapter->devflags_prev = dev->flags;
                DBG_ERROR("%s call sxg_config_set adapter->macopts[%x]\n",
-                         __FUNCTION__, adapter->macopts);
+                         __func__, adapter->macopts);
                sxg_config_set(adapter, TRUE);
        } else {
                if (status == STATUS_SUCCESS) {
                        sxg_mcast_set_mask(adapter);
                }
        }
-#endif
        return;
 }
-
-static void sxg_mcast_set_mask(p_adapter_t adapter)
-{
-       PSXG_UCODE_REGS sxg_regs = adapter->UcodeRegs;
-
-       DBG_ERROR("%s ENTER (%s) macopts[%x] mask[%llx]\n", __FUNCTION__,
-                 adapter->netdev->name, (unsigned int)adapter->MacFilter,
-                 adapter->MulticastMask);
-
-       if (adapter->MacFilter & (MAC_ALLMCAST | MAC_PROMISC)) {
-               /* Turn on all multicast addresses. We have to do this for promiscuous
-                * mode as well as ALLMCAST mode.  It saves the Microcode from having
-                * to keep state about the MAC configuration.
-                */
-//              DBG_ERROR("sxg: %s macopts = MAC_ALLMCAST | MAC_PROMISC\n      SLUT MODE!!!\n",__FUNCTION__);
-               WRITE_REG(sxg_regs->McastLow, 0xFFFFFFFF, FLUSH);
-               WRITE_REG(sxg_regs->McastHigh, 0xFFFFFFFF, FLUSH);
-//        DBG_ERROR("%s (%s) WRITE to slic_regs slic_mcastlow&high 0xFFFFFFFF\n",__FUNCTION__, adapter->netdev->name);
-
-       } else {
-               /* Commit our multicast mast to the SLIC by writing to the multicast
-                * address mask registers
-                */
-               DBG_ERROR("%s (%s) WRITE mcastlow[%lx] mcasthigh[%lx]\n",
-                         __FUNCTION__, adapter->netdev->name,
-                         ((ulong) (adapter->MulticastMask & 0xFFFFFFFF)),
-                         ((ulong)
-                          ((adapter->MulticastMask >> 32) & 0xFFFFFFFF)));
-
-               WRITE_REG(sxg_regs->McastLow,
-                         (u32) (adapter->MulticastMask & 0xFFFFFFFF), FLUSH);
-               WRITE_REG(sxg_regs->McastHigh,
-                         (u32) ((adapter->
-                                 MulticastMask >> 32) & 0xFFFFFFFF), FLUSH);
-       }
-}
+#endif
 
 static void sxg_unmap_mmio_space(p_adapter_t adapter)
 {
 #if LINUX_FREES_ADAPTER_RESOURCES
-//      if (adapter->Regs) {
-//              iounmap(adapter->Regs);
-//      }
-//      adapter->slic_regs = NULL;
+/*      if (adapter->Regs) { */
+/*              iounmap(adapter->Regs); */
+/*      } */
+/*      adapter->slic_regs = NULL; */
 #endif
 }
 
@@ -2909,8 +2910,8 @@ void SxgFreeResources(p_adapter_t adapter)
        IsrCount = adapter->MsiEnabled ? RssIds : 1;
 
        if (adapter->BasicAllocations == FALSE) {
-               // No allocations have been made, including spinlocks,
-               // or listhead initializations.  Return.
+               /* No allocations have been made, including spinlocks, */
+               /* or listhead initializations.  Return. */
                return;
        }
 
@@ -2920,7 +2921,7 @@ void SxgFreeResources(p_adapter_t adapter)
        if (!(IsListEmpty(&adapter->AllSglBuffers))) {
                SxgFreeSglBuffers(adapter);
        }
-       // Free event queues.
+       /* Free event queues. */
        if (adapter->EventRings) {
                pci_free_consistent(adapter->pcidev,
                                    sizeof(SXG_EVENT_RING) * RssIds,
@@ -2947,17 +2948,17 @@ void SxgFreeResources(p_adapter_t adapter)
        SXG_FREE_PACKET_POOL(adapter->PacketPoolHandle);
        SXG_FREE_BUFFER_POOL(adapter->BufferPoolHandle);
 
-       // Unmap register spaces
+       /* Unmap register spaces */
        SxgUnmapResources(adapter);
 
-       // Deregister DMA
+       /* Deregister DMA */
        if (adapter->DmaHandle) {
                SXG_DEREGISTER_DMA(adapter->DmaHandle);
        }
-       // Deregister interrupt
+       /* Deregister interrupt */
        SxgDeregisterInterrupt(adapter);
 
-       // Possibly free system info (5.2 only)
+       /* Possibly free system info (5.2 only) */
        SXG_RELEASE_SYSTEM_INFO(adapter);
 
        SxgDiagFreeResources(adapter);
@@ -3047,23 +3048,23 @@ static int sxg_allocate_buffer_memory(p_adapter_t adapter,
 
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocMem",
                  adapter, Size, BufferType, 0);
-       // Grab the adapter lock and check the state.
-       // If we're in anything other than INITIALIZING or
-       // RUNNING state, fail.  This is to prevent
-       // allocations in an improper driver state
+       /* Grab the adapter lock and check the state. */
+       /* If we're in anything other than INITIALIZING or */
+       /* RUNNING state, fail.  This is to prevent */
+       /* allocations in an improper driver state */
        spin_lock(&adapter->AdapterLock);
 
-       // Increment the AllocationsPending count while holding
-       // the lock.  Pause processing relies on this
+       /* Increment the AllocationsPending count while holding */
+       /* the lock.  Pause processing relies on this */
        ++adapter->AllocationsPending;
        spin_unlock(&adapter->AdapterLock);
 
-       // At initialization time allocate resources synchronously.
+       /* At initialization time allocate resources synchronously. */
        Buffer = pci_alloc_consistent(adapter->pcidev, Size, &pBuffer);
        if (Buffer == NULL) {
                spin_lock(&adapter->AdapterLock);
-               // Decrement the AllocationsPending count while holding
-               // the lock.  Pause processing relies on this
+               /* Decrement the AllocationsPending count while holding */
+               /* the lock.  Pause processing relies on this */
                --adapter->AllocationsPending;
                spin_unlock(&adapter->AdapterLock);
                SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlcMemF1",
@@ -3113,10 +3114,10 @@ static void sxg_allocate_rcvblock_complete(p_adapter_t adapter,
        ASSERT((BufferSize == SXG_RCV_DATA_BUFFER_SIZE) ||
               (BufferSize == SXG_RCV_JUMBO_BUFFER_SIZE));
        ASSERT(Length == SXG_RCV_BLOCK_SIZE(BufferSize));
-       // First, initialize the contained pool of receive data
-       // buffers.  This initialization requires NBL/NB/MDL allocations,
-       // If any of them fail, free the block and return without
-       // queueing the shared memory
+       /* First, initialize the contained pool of receive data */
+       /* buffers.  This initialization requires NBL/NB/MDL allocations, */
+       /* If any of them fail, free the block and return without */
+       /* queueing the shared memory */
        RcvDataBuffer = RcvBlock;
 #if 0
        for (i = 0, Paddr = *PhysicalAddress;
@@ -3126,14 +3127,14 @@ static void sxg_allocate_rcvblock_complete(p_adapter_t adapter,
                for (i = 0, Paddr = PhysicalAddress;
                     i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
                     i++, Paddr += BufferSize, RcvDataBuffer += BufferSize) {
-                       //
+                       /* */
                        RcvDataBufferHdr =
                            (PSXG_RCV_DATA_BUFFER_HDR) (RcvDataBuffer +
                                                        SXG_RCV_DATA_BUFFER_HDR_OFFSET
                                                        (BufferSize));
                        RcvDataBufferHdr->VirtualAddress = RcvDataBuffer;
                        RcvDataBufferHdr->PhysicalAddress = Paddr;
-                       RcvDataBufferHdr->State = SXG_BUFFER_UPSTREAM;  // For FREE macro assertion
+                       RcvDataBufferHdr->State = SXG_BUFFER_UPSTREAM;  /* For FREE macro assertion */
                        RcvDataBufferHdr->Size =
                            SXG_RCV_BUFFER_DATA_SIZE(BufferSize);
 
@@ -3143,8 +3144,8 @@ static void sxg_allocate_rcvblock_complete(p_adapter_t adapter,
 
                }
 
-       // Place this entire block of memory on the AllRcvBlocks queue so it can be
-       // free later
+       /* Place this entire block of memory on the AllRcvBlocks queue so it can be */
+       /* free later */
        RcvBlockHdr =
            (PSXG_RCV_BLOCK_HDR) ((unsigned char *)RcvBlock +
                                  SXG_RCV_BLOCK_HDR_OFFSET(BufferSize));
@@ -3155,7 +3156,7 @@ static void sxg_allocate_rcvblock_complete(p_adapter_t adapter,
        InsertTailList(&adapter->AllRcvBlocks, &RcvBlockHdr->AllList);
        spin_unlock(&adapter->RcvQLock);
 
-       // Now free the contained receive data buffers that we initialized above
+       /* Now free the contained receive data buffers that we initialized above */
        RcvDataBuffer = RcvBlock;
        for (i = 0, Paddr = PhysicalAddress;
             i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
@@ -3168,7 +3169,7 @@ static void sxg_allocate_rcvblock_complete(p_adapter_t adapter,
                spin_unlock(&adapter->RcvQLock);
        }
 
-       // Locate the descriptor block and put it on a separate free queue
+       /* Locate the descriptor block and put it on a separate free queue */
        RcvDescriptorBlock =
            (PSXG_RCV_DESCRIPTOR_BLOCK) ((unsigned char *)RcvBlock +
                                         SXG_RCV_DESCRIPTOR_BLOCK_OFFSET
@@ -3186,7 +3187,7 @@ static void sxg_allocate_rcvblock_complete(p_adapter_t adapter,
                  adapter, RcvBlock, Length, 0);
        return;
       fail:
-       // Free any allocated resources
+       /* Free any allocated resources */
        if (RcvBlock) {
                RcvDataBuffer = RcvBlock;
                for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
@@ -3200,7 +3201,7 @@ static void sxg_allocate_rcvblock_complete(p_adapter_t adapter,
                pci_free_consistent(adapter->pcidev,
                                    Length, RcvBlock, PhysicalAddress);
        }
-       DBG_ERROR("%s: OUT OF RESOURCES\n", __FUNCTION__);
+       DBG_ERROR("%s: OUT OF RESOURCES\n", __func__);
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "RcvAFail",
                  adapter, adapter->FreeRcvBufferCount,
                  adapter->FreeRcvBlockCount, adapter->AllRcvBlockCount);
@@ -3230,7 +3231,7 @@ static void sxg_allocate_sgl_buffer_complete(p_adapter_t adapter,
        adapter->AllSglBufferCount++;
        memset(SxgSgl, 0, sizeof(SXG_SCATTER_GATHER));
        SxgSgl->PhysicalAddress = PhysicalAddress;      /* *PhysicalAddress; */
-       SxgSgl->adapter = adapter;      // Initialize backpointer once
+       SxgSgl->adapter = adapter;      /* Initialize backpointer once */
        InsertTailList(&adapter->AllSglBuffers, &SxgSgl->AllList);
        spin_unlock(&adapter->SglQLock);
        SxgSgl->State = SXG_BUFFER_BUSY;
@@ -3244,14 +3245,14 @@ static unsigned char temp_mac_address[6] =
 
 static void sxg_adapter_set_hwaddr(p_adapter_t adapter)
 {
-//  DBG_ERROR ("%s ENTER card->config_set[%x] port[%d] physport[%d] funct#[%d]\n", __FUNCTION__,
-//             card->config_set, adapter->port, adapter->physport, adapter->functionnumber);
-//
-//  sxg_dbg_macaddrs(adapter);
+/*  DBG_ERROR ("%s ENTER card->config_set[%x] port[%d] physport[%d] funct#[%d]\n", __func__, */
+/*             card->config_set, adapter->port, adapter->physport, adapter->functionnumber); */
+/* */
+/*  sxg_dbg_macaddrs(adapter); */
 
        memcpy(adapter->macaddr, temp_mac_address, sizeof(SXG_CONFIG_MAC));
-//      DBG_ERROR ("%s AFTER copying from config.macinfo into currmacaddr\n", __FUNCTION__);
-//      sxg_dbg_macaddrs(adapter);
+/*      DBG_ERROR ("%s AFTER copying from config.macinfo into currmacaddr\n", __func__); */
+/*      sxg_dbg_macaddrs(adapter); */
        if (!(adapter->currmacaddr[0] ||
              adapter->currmacaddr[1] ||
              adapter->currmacaddr[2] ||
@@ -3262,18 +3263,18 @@ static void sxg_adapter_set_hwaddr(p_adapter_t adapter)
        if (adapter->netdev) {
                memcpy(adapter->netdev->dev_addr, adapter->currmacaddr, 6);
        }
-//  DBG_ERROR ("%s EXIT port %d\n", __FUNCTION__, adapter->port);
+/*  DBG_ERROR ("%s EXIT port %d\n", __func__, adapter->port); */
        sxg_dbg_macaddrs(adapter);
 
 }
 
+#if XXXTODO
 static int sxg_mac_set_address(p_net_device dev, void *ptr)
 {
-#if XXXTODO
        p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
        struct sockaddr *addr = ptr;
 
-       DBG_ERROR("%s ENTER (%s)\n", __FUNCTION__, adapter->netdev->name);
+       DBG_ERROR("%s ENTER (%s)\n", __func__, adapter->netdev->name);
 
        if (netif_running(dev)) {
                return -EBUSY;
@@ -3282,22 +3283,22 @@ static int sxg_mac_set_address(p_net_device dev, void *ptr)
                return -EBUSY;
        }
        DBG_ERROR("sxg: %s (%s) curr %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
-                 __FUNCTION__, adapter->netdev->name, adapter->currmacaddr[0],
+                 __func__, adapter->netdev->name, adapter->currmacaddr[0],
                  adapter->currmacaddr[1], adapter->currmacaddr[2],
                  adapter->currmacaddr[3], adapter->currmacaddr[4],
                  adapter->currmacaddr[5]);
        memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
        memcpy(adapter->currmacaddr, addr->sa_data, dev->addr_len);
        DBG_ERROR("sxg: %s (%s) new %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
-                 __FUNCTION__, adapter->netdev->name, adapter->currmacaddr[0],
+                 __func__, adapter->netdev->name, adapter->currmacaddr[0],
                  adapter->currmacaddr[1], adapter->currmacaddr[2],
                  adapter->currmacaddr[3], adapter->currmacaddr[4],
                  adapter->currmacaddr[5]);
 
        sxg_config_set(adapter, TRUE);
-#endif
        return 0;
 }
+#endif
 
 /*****************************************************************************/
 /*************  SXG DRIVER FUNCTIONS  (below) ********************************/
@@ -3321,77 +3322,77 @@ static int sxg_initialize_adapter(p_adapter_t adapter)
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "InitAdpt",
                  adapter, 0, 0, 0);
 
-       RssIds = 1;             //  XXXTODO  SXG_RSS_CPU_COUNT(adapter);
+       RssIds = 1;             /*  XXXTODO  SXG_RSS_CPU_COUNT(adapter); */
        IsrCount = adapter->MsiEnabled ? RssIds : 1;
 
-       // Sanity check SXG_UCODE_REGS structure definition to
-       // make sure the length is correct
+       /* Sanity check SXG_UCODE_REGS structure definition to */
+       /* make sure the length is correct */
        ASSERT(sizeof(SXG_UCODE_REGS) == SXG_REGISTER_SIZE_PER_CPU);
 
-       // Disable interrupts
+       /* Disable interrupts */
        SXG_DISABLE_ALL_INTERRUPTS(adapter);
 
-       // Set MTU
+       /* Set MTU */
        ASSERT((adapter->FrameSize == ETHERMAXFRAME) ||
               (adapter->FrameSize == JUMBOMAXFRAME));
        WRITE_REG(adapter->UcodeRegs[0].LinkMtu, adapter->FrameSize, TRUE);
 
-       // Set event ring base address and size
+       /* Set event ring base address and size */
        WRITE_REG64(adapter,
                    adapter->UcodeRegs[0].EventBase, adapter->PEventRings, 0);
        WRITE_REG(adapter->UcodeRegs[0].EventSize, EVENT_RING_SIZE, TRUE);
 
-       // Per-ISR initialization
+       /* Per-ISR initialization */
        for (i = 0; i < IsrCount; i++) {
                u64 Addr;
-               // Set interrupt status pointer
+               /* Set interrupt status pointer */
                Addr = adapter->PIsr + (i * sizeof(u32));
                WRITE_REG64(adapter, adapter->UcodeRegs[i].Isp, Addr, i);
        }
 
-       // XMT ring zero index
+       /* XMT ring zero index */
        WRITE_REG64(adapter,
                    adapter->UcodeRegs[0].SPSendIndex,
                    adapter->PXmtRingZeroIndex, 0);
 
-       // Per-RSS initialization
+       /* Per-RSS initialization */
        for (i = 0; i < RssIds; i++) {
-               // Release all event ring entries to the Microcode
+               /* Release all event ring entries to the Microcode */
                WRITE_REG(adapter->UcodeRegs[i].EventRelease, EVENT_RING_SIZE,
                          TRUE);
        }
 
-       // Transmit ring base and size
+       /* Transmit ring base and size */
        WRITE_REG64(adapter,
                    adapter->UcodeRegs[0].XmtBase, adapter->PXmtRings, 0);
        WRITE_REG(adapter->UcodeRegs[0].XmtSize, SXG_XMT_RING_SIZE, TRUE);
 
-       // Receive ring base and size
+       /* Receive ring base and size */
        WRITE_REG64(adapter,
                    adapter->UcodeRegs[0].RcvBase, adapter->PRcvRings, 0);
        WRITE_REG(adapter->UcodeRegs[0].RcvSize, SXG_RCV_RING_SIZE, TRUE);
 
-       // Populate the card with receive buffers
+       /* Populate the card with receive buffers */
        sxg_stock_rcv_buffers(adapter);
 
-       // Initialize checksum offload capabilities.  At the moment
-       // we always enable IP and TCP receive checksums on the card.
-       // Depending on the checksum configuration specified by the
-       // user, we can choose to report or ignore the checksum
-       // information provided by the card.
+       /* Initialize checksum offload capabilities.  At the moment */
+       /* we always enable IP and TCP receive checksums on the card. */
+       /* Depending on the checksum configuration specified by the */
+       /* user, we can choose to report or ignore the checksum */
+       /* information provided by the card. */
        WRITE_REG(adapter->UcodeRegs[0].ReceiveChecksum,
                  SXG_RCV_TCP_CSUM_ENABLED | SXG_RCV_IP_CSUM_ENABLED, TRUE);
 
-       // Initialize the MAC, XAUI
-       DBG_ERROR("sxg: %s ENTER sxg_initialize_link\n", __FUNCTION__);
+       /* Initialize the MAC, XAUI */
+       DBG_ERROR("sxg: %s ENTER sxg_initialize_link\n", __func__);
        status = sxg_initialize_link(adapter);
-       DBG_ERROR("sxg: %s EXIT sxg_initialize_link status[%x]\n", __FUNCTION__,
+       DBG_ERROR("sxg: %s EXIT sxg_initialize_link status[%x]\n", __func__,
                  status);
        if (status != STATUS_SUCCESS) {
                return (status);
        }
-       // Initialize Dead to FALSE.
-       // SlicCheckForHang or SlicDumpThread will take it from here.
+       /* Initialize Dead to FALSE. */
+       /* SlicCheckForHang or SlicDumpThread will take it from here. */
        adapter->Dead = FALSE;
        adapter->PingOutstanding = FALSE;
 
@@ -3428,14 +3429,14 @@ static int sxg_fill_descriptor_block(p_adapter_t adapter,
 
        ASSERT(RcvDescriptorBlockHdr);
 
-       // If we don't have the resources to fill the descriptor block,
-       // return failure
+       /* If we don't have the resources to fill the descriptor block, */
+       /* return failure */
        if ((adapter->FreeRcvBufferCount < SXG_RCV_DESCRIPTORS_PER_BLOCK) ||
            SXG_RING_FULL(RcvRingInfo)) {
                adapter->Stats.NoMem++;
                return (STATUS_FAILURE);
        }
-       // Get a ring descriptor command
+       /* Get a ring descriptor command */
        SXG_GET_CMD(RingZero,
                    RcvRingInfo, RingDescriptorCmd, RcvDescriptorBlockHdr);
        ASSERT(RingDescriptorCmd);
@@ -3443,7 +3444,7 @@ static int sxg_fill_descriptor_block(p_adapter_t adapter,
        RcvDescriptorBlock =
            (PSXG_RCV_DESCRIPTOR_BLOCK) RcvDescriptorBlockHdr->VirtualAddress;
 
-       // Fill in the descriptor block
+       /* Fill in the descriptor block */
        for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK; i++) {
                SXG_GET_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
                ASSERT(RcvDataBufferHdr);
@@ -3454,13 +3455,13 @@ static int sxg_fill_descriptor_block(p_adapter_t adapter,
                RcvDescriptorBlock->Descriptors[i].PhysicalAddress =
                    RcvDataBufferHdr->PhysicalAddress;
        }
-       // Add the descriptor block to receive descriptor ring 0
+       /* Add the descriptor block to receive descriptor ring 0 */
        RingDescriptorCmd->Sgl = RcvDescriptorBlockHdr->PhysicalAddress;
 
-       // RcvBuffersOnCard is not protected via the receive lock (see
-       // sxg_process_event_queue) We don't want to grap a lock every time a
-       // buffer is returned to us, so we use atomic interlocked functions
-       // instead.
+       /* RcvBuffersOnCard is not protected via the receive lock (see */
+       /* sxg_process_event_queue) We don't want to grap a lock every time a */
+       /* buffer is returned to us, so we use atomic interlocked functions */
+       /* instead. */
        adapter->RcvBuffersOnCard += SXG_RCV_DESCRIPTORS_PER_BLOCK;
 
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DscBlk",
@@ -3490,10 +3491,10 @@ static void sxg_stock_rcv_buffers(p_adapter_t adapter)
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "StockBuf",
                  adapter, adapter->RcvBuffersOnCard,
                  adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount);
-       // First, see if we've got less than our minimum threshold of
-       // receive buffers, there isn't an allocation in progress, and
-       // we haven't exceeded our maximum.. get another block of buffers
-       // None of this needs to be SMP safe.  It's round numbers.
+       /* First, see if we've got less than our minimum threshold of */
+       /* receive buffers, there isn't an allocation in progress, and */
+       /* we haven't exceeded our maximum.. get another block of buffers */
+       /* None of this needs to be SMP safe.  It's round numbers. */
        if ((adapter->FreeRcvBufferCount < SXG_MIN_RCV_DATA_BUFFERS) &&
            (adapter->AllRcvBlockCount < SXG_MAX_RCV_BLOCKS) &&
            (adapter->AllocationsPending == 0)) {
@@ -3502,12 +3503,12 @@ static void sxg_stock_rcv_buffers(p_adapter_t adapter)
                                                              ReceiveBufferSize),
                                           SXG_BUFFER_TYPE_RCV);
        }
-       // Now grab the RcvQLock lock and proceed
+       /* Now grab the RcvQLock lock and proceed */
        spin_lock(&adapter->RcvQLock);
        while (adapter->RcvBuffersOnCard < SXG_RCV_DATA_BUFFERS) {
                PLIST_ENTRY _ple;
 
-               // Get a descriptor block
+               /* Get a descriptor block */
                RcvDescriptorBlockHdr = NULL;
                if (adapter->FreeRcvBlockCount) {
                        _ple = RemoveHeadList(&adapter->FreeRcvBlocks);
@@ -3519,14 +3520,14 @@ static void sxg_stock_rcv_buffers(p_adapter_t adapter)
                }
 
                if (RcvDescriptorBlockHdr == NULL) {
-                       // Bail out..
+                       /* Bail out.. */
                        adapter->Stats.NoMem++;
                        break;
                }
-               // Fill in the descriptor block and give it to the card
+               /* Fill in the descriptor block and give it to the card */
                if (sxg_fill_descriptor_block(adapter, RcvDescriptorBlockHdr) ==
                    STATUS_FAILURE) {
-                       // Free the descriptor block
+                       /* Free the descriptor block */
                        SXG_FREE_RCV_DESCRIPTOR_BLOCK(adapter,
                                                      RcvDescriptorBlockHdr);
                        break;
@@ -3560,15 +3561,15 @@ static void sxg_complete_descriptor_blocks(p_adapter_t adapter,
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpRBlks",
                  adapter, Index, RcvRingInfo->Head, RcvRingInfo->Tail);
 
-       // Now grab the RcvQLock lock and proceed
+       /* Now grab the RcvQLock lock and proceed */
        spin_lock(&adapter->RcvQLock);
        ASSERT(Index != RcvRingInfo->Tail);
        while (RcvRingInfo->Tail != Index) {
-               //
-               // Locate the current Cmd (ring descriptor entry), and
-               // associated receive descriptor block, and advance
-               // the tail
-               //
+               /* */
+               /* Locate the current Cmd (ring descriptor entry), and */
+               /* associated receive descriptor block, and advance */
+               /* the tail */
+               /* */
                SXG_RETURN_CMD(RingZero,
                               RcvRingInfo,
                               RingDescriptorCmd, RcvDescriptorBlockHdr);
@@ -3576,12 +3577,12 @@ static void sxg_complete_descriptor_blocks(p_adapter_t adapter,
                          RcvRingInfo->Head, RcvRingInfo->Tail,
                          RingDescriptorCmd, RcvDescriptorBlockHdr);
 
-               // Clear the SGL field
+               /* Clear the SGL field */
                RingDescriptorCmd->Sgl = 0;
-               // Attempt to refill it and hand it right back to the
-               // card.  If we fail to refill it, free the descriptor block
-               // header.  The card will be restocked later via the
-               // RcvBuffersOnCard test
+               /* Attempt to refill it and hand it right back to the */
+               /* card.  If we fail to refill it, free the descriptor block */
+               /* header.  The card will be restocked later via the */
+               /* RcvBuffersOnCard test */
                if (sxg_fill_descriptor_block(adapter, RcvDescriptorBlockHdr) ==
                    STATUS_FAILURE) {
                        SXG_FREE_RCV_DESCRIPTOR_BLOCK(adapter,
index 26fb0ffafa5c7285f1c5cb78907cb4137486cdb4..01182689aabad2aba8dfd80d5ac9ce0f86ccd6c2 100644 (file)
@@ -44,7 +44,6 @@
 #define FALSE  (0)
 #define TRUE   (1)
 
-
 typedef struct _LIST_ENTRY {
        struct _LIST_ENTRY *nle_flink;
        struct _LIST_ENTRY *nle_blink;
@@ -69,35 +68,32 @@ typedef struct _LIST_ENTRY {
 
 /* These two have to be inlined since they return things. */
 
-static __inline PLIST_ENTRY
-RemoveHeadList(list_entry *l)
+static __inline PLIST_ENTRY RemoveHeadList(list_entry * l)
 {
-        list_entry              *f;
-        list_entry              *e;
+       list_entry *f;
+       list_entry *e;
 
-        e = l->nle_flink;
-        f = e->nle_flink;
-        l->nle_flink = f;
-        f->nle_blink = l;
+       e = l->nle_flink;
+       f = e->nle_flink;
+       l->nle_flink = f;
+       f->nle_blink = l;
 
-        return (e);
+       return (e);
 }
 
-static __inline PLIST_ENTRY
-RemoveTailList(list_entry *l)
+static __inline PLIST_ENTRY RemoveTailList(list_entry * l)
 {
-        list_entry              *b;
-        list_entry              *e;
+       list_entry *b;
+       list_entry *e;
 
-        e = l->nle_blink;
-        b = e->nle_blink;
-        l->nle_blink = b;
-        b->nle_flink = l;
+       e = l->nle_blink;
+       b = e->nle_blink;
+       l->nle_blink = b;
+       b->nle_flink = l;
 
-        return (e);
+       return (e);
 }
 
-
 #define InsertTailList(l, e)                    \
         do {                                    \
                 list_entry              *b;     \
@@ -120,7 +116,6 @@ RemoveTailList(list_entry *l)
                 (l)->nle_flink = (e);           \
         } while (0)
 
-
 #define ATK_DEBUG  1
 
 #if ATK_DEBUG
@@ -133,7 +128,6 @@ RemoveTailList(list_entry *l)
 #define SLIC_TIMESTAMP(value)
 #endif
 
-
 /******************  SXG DEFINES  *****************************************/
 
 #ifdef  ATKDBG
@@ -150,5 +144,4 @@ RemoveTailList(list_entry *l)
 #define WRITE_REG64(a,reg,value,cpu)                sxg_reg64_write((a),(&reg),(value),(cpu))
 #define READ_REG(reg,value)   (value) = readl((void __iomem *)(&reg))
 
-#endif  /* _SLIC_OS_SPECIFIC_H_  */
-
+#endif /* _SLIC_OS_SPECIFIC_H_  */
index cfb6c7c77a9efd26af452549c49a38cb3146e75d..4522b8d714953affd9e3797ff72bc6b902316f10 100644 (file)
@@ -58,7 +58,7 @@
     {                                                                             \
         if (!(a)) {                                                               \
             DBG_ERROR("ASSERT() Failure: file %s, function %s  line %d\n",\
-                __FILE__, __FUNCTION__, __LINE__);                                \
+                __FILE__, __func__, __LINE__);                                \
         }                                                                         \
     }
 #endif
index ed26ceaa1315de506c89bfdf69136b89dfddc5e2..88bffbaa3be8b3070643610938906de48e79d91d 100644 (file)
  *******************************************************************************/
 typedef struct _SXG_UCODE_REGS {
        // Address 0 - 0x3F = Command codes 0-15 for TCB 0.  Excode 0
-       u32             Icr;                    // Code = 0 (extended), ExCode = 0 - Int control
-       u32             RsvdReg1;               // Code = 1 - TOE -NA
-       u32             RsvdReg2;               // Code = 2 - TOE -NA
-       u32             RsvdReg3;               // Code = 3 - TOE -NA
-       u32             RsvdReg4;               // Code = 4 - TOE -NA
-       u32             RsvdReg5;               // Code = 5 - TOE -NA
-       u32             CardUp;                 // Code = 6 - Microcode initialized when 1
-       u32             RsvdReg7;               // Code = 7 - TOE -NA
-       u32             CodeNotUsed[8];         // Codes 8-15 not used.  ExCode = 0
+       u32 Icr;                // Code = 0 (extended), ExCode = 0 - Int control
+       u32 RsvdReg1;           // Code = 1 - TOE -NA
+       u32 RsvdReg2;           // Code = 2 - TOE -NA
+       u32 RsvdReg3;           // Code = 3 - TOE -NA
+       u32 RsvdReg4;           // Code = 4 - TOE -NA
+       u32 RsvdReg5;           // Code = 5 - TOE -NA
+       u32 CardUp;             // Code = 6 - Microcode initialized when 1
+       u32 RsvdReg7;           // Code = 7 - TOE -NA
+       u32 CodeNotUsed[8];     // Codes 8-15 not used.  ExCode = 0
        // This brings us to ExCode 1 at address 0x40 = Interrupt status pointer
-       u32             Isp;                    // Code = 0 (extended), ExCode = 1
-       u32             PadEx1[15];             // Codes 1-15 not used with extended codes
+       u32 Isp;                // Code = 0 (extended), ExCode = 1
+       u32 PadEx1[15];         // Codes 1-15 not used with extended codes
        // ExCode 2 = Interrupt Status Register
-       u32             Isr;                    // Code = 0 (extended), ExCode = 2
-       u32             PadEx2[15];
+       u32 Isr;                // Code = 0 (extended), ExCode = 2
+       u32 PadEx2[15];
        // ExCode 3 = Event base register.  Location of event rings
-       u32             EventBase;              // Code = 0 (extended), ExCode = 3
-       u32             PadEx3[15];
+       u32 EventBase;          // Code = 0 (extended), ExCode = 3
+       u32 PadEx3[15];
        // ExCode 4 = Event ring size
-       u32             EventSize;              // Code = 0 (extended), ExCode = 4
-       u32             PadEx4[15];
+       u32 EventSize;          // Code = 0 (extended), ExCode = 4
+       u32 PadEx4[15];
        // ExCode 5 = TCB Buffers base address
-       u32             TcbBase;                // Code = 0 (extended), ExCode = 5
-       u32             PadEx5[15];
+       u32 TcbBase;            // Code = 0 (extended), ExCode = 5
+       u32 PadEx5[15];
        // ExCode 6 = TCB Composite Buffers base address
-       u32             TcbCompBase;            // Code = 0 (extended), ExCode = 6
-       u32             PadEx6[15];
+       u32 TcbCompBase;        // Code = 0 (extended), ExCode = 6
+       u32 PadEx6[15];
        // ExCode 7 = Transmit ring base address
-       u32             XmtBase;                // Code = 0 (extended), ExCode = 7
-       u32             PadEx7[15];
+       u32 XmtBase;            // Code = 0 (extended), ExCode = 7
+       u32 PadEx7[15];
        // ExCode 8 = Transmit ring size
-       u32             XmtSize;                // Code = 0 (extended), ExCode = 8
-       u32             PadEx8[15];
+       u32 XmtSize;            // Code = 0 (extended), ExCode = 8
+       u32 PadEx8[15];
        // ExCode 9 = Receive ring base address
-       u32             RcvBase;                // Code = 0 (extended), ExCode = 9
-       u32             PadEx9[15];
+       u32 RcvBase;            // Code = 0 (extended), ExCode = 9
+       u32 PadEx9[15];
        // ExCode 10 = Receive ring size
-       u32             RcvSize;                // Code = 0 (extended), ExCode = 10
-       u32             PadEx10[15];
+       u32 RcvSize;            // Code = 0 (extended), ExCode = 10
+       u32 PadEx10[15];
        // ExCode 11 = Read EEPROM Config
-       u32             Config;                 // Code = 0 (extended), ExCode = 11
-       u32             PadEx11[15];
+       u32 Config;             // Code = 0 (extended), ExCode = 11
+       u32 PadEx11[15];
        // ExCode 12 = Multicast bits 31:0
-       u32             McastLow;               // Code = 0 (extended), ExCode = 12
-       u32             PadEx12[15];
+       u32 McastLow;           // Code = 0 (extended), ExCode = 12
+       u32 PadEx12[15];
        // ExCode 13 = Multicast bits 63:32
-       u32             McastHigh;              // Code = 0 (extended), ExCode = 13
-       u32             PadEx13[15];
+       u32 McastHigh;          // Code = 0 (extended), ExCode = 13
+       u32 PadEx13[15];
        // ExCode 14 = Ping
-       u32             Ping;                   // Code = 0 (extended), ExCode = 14
-       u32             PadEx14[15];
+       u32 Ping;               // Code = 0 (extended), ExCode = 14
+       u32 PadEx14[15];
        // ExCode 15 = Link MTU
-       u32             LinkMtu;                // Code = 0 (extended), ExCode = 15
-       u32             PadEx15[15];
+       u32 LinkMtu;            // Code = 0 (extended), ExCode = 15
+       u32 PadEx15[15];
        // ExCode 16 = Download synchronization
-       u32             LoadSync;               // Code = 0 (extended), ExCode = 16
-       u32             PadEx16[15];
+       u32 LoadSync;           // Code = 0 (extended), ExCode = 16
+       u32 PadEx16[15];
        // ExCode 17 = Upper DRAM address bits on 32-bit systems
-       u32             Upper;                  // Code = 0 (extended), ExCode = 17
-       u32             PadEx17[15];
+       u32 Upper;              // Code = 0 (extended), ExCode = 17
+       u32 PadEx17[15];
        // ExCode 18 = Slowpath Send Index Address
-       u32             SPSendIndex;            // Code = 0 (extended), ExCode = 18
-       u32             PadEx18[15];
-       u32             RsvdXF;                 // Code = 0 (extended), ExCode = 19
-       u32             PadEx19[15];
+       u32 SPSendIndex;        // Code = 0 (extended), ExCode = 18
+       u32 PadEx18[15];
+       u32 RsvdXF;             // Code = 0 (extended), ExCode = 19
+       u32 PadEx19[15];
        // ExCode 20 = Aggregation
-       u32             Aggregation;            // Code = 0 (extended), ExCode = 20
-       u32             PadEx20[15];
+       u32 Aggregation;        // Code = 0 (extended), ExCode = 20
+       u32 PadEx20[15];
        // ExCode 21 = Receive MDL push timer
-       u32             PushTicks;              // Code = 0 (extended), ExCode = 21
-       u32             PadEx21[15];
+       u32 PushTicks;          // Code = 0 (extended), ExCode = 21
+       u32 PadEx21[15];
        // ExCode 22 = TOE NA
-       u32             AckFrequency;           // Code = 0 (extended), ExCode = 22
-       u32             PadEx22[15];
+       u32 AckFrequency;       // Code = 0 (extended), ExCode = 22
+       u32 PadEx22[15];
        // ExCode 23 = TOE NA
-       u32             RsvdReg23;
-       u32             PadEx23[15];
+       u32 RsvdReg23;
+       u32 PadEx23[15];
        // ExCode 24 = TOE NA
-       u32             RsvdReg24;
-       u32             PadEx24[15];
+       u32 RsvdReg24;
+       u32 PadEx24[15];
        // ExCode 25 = TOE NA
-       u32             RsvdReg25;              // Code = 0 (extended), ExCode = 25
-       u32             PadEx25[15];
+       u32 RsvdReg25;          // Code = 0 (extended), ExCode = 25
+       u32 PadEx25[15];
        // ExCode 26 = Receive checksum requirements
-       u32             ReceiveChecksum;        // Code = 0 (extended), ExCode = 26
-       u32             PadEx26[15];
+       u32 ReceiveChecksum;    // Code = 0 (extended), ExCode = 26
+       u32 PadEx26[15];
        // ExCode 27 = RSS Requirements
-       u32             Rss;                    // Code = 0 (extended), ExCode = 27
-       u32             PadEx27[15];
+       u32 Rss;                // Code = 0 (extended), ExCode = 27
+       u32 PadEx27[15];
        // ExCode 28 = RSS Table
-       u32             RssTable;               // Code = 0 (extended), ExCode = 28
-       u32             PadEx28[15];
+       u32 RssTable;           // Code = 0 (extended), ExCode = 28
+       u32 PadEx28[15];
        // ExCode 29 = Event ring release entries
-       u32             EventRelease;           // Code = 0 (extended), ExCode = 29
-       u32             PadEx29[15];
+       u32 EventRelease;       // Code = 0 (extended), ExCode = 29
+       u32 PadEx29[15];
        // ExCode 30 = Number of receive bufferlist commands on ring 0
-       u32             RcvCmd;                 // Code = 0 (extended), ExCode = 30
-       u32             PadEx30[15];
+       u32 RcvCmd;             // Code = 0 (extended), ExCode = 30
+       u32 PadEx30[15];
        // ExCode 31 = slowpath transmit command - Data[31:0] = 1
-       u32             XmtCmd;                 // Code = 0 (extended), ExCode = 31
-       u32             PadEx31[15];
+       u32 XmtCmd;             // Code = 0 (extended), ExCode = 31
+       u32 PadEx31[15];
        // ExCode 32 = Dump command
-       u32             DumpCmd;                // Code = 0 (extended), ExCode = 32
-       u32             PadEx32[15];
+       u32 DumpCmd;            // Code = 0 (extended), ExCode = 32
+       u32 PadEx32[15];
        // ExCode 33 = Debug command
-       u32             DebugCmd;               // Code = 0 (extended), ExCode = 33
-       u32             PadEx33[15];
+       u32 DebugCmd;           // Code = 0 (extended), ExCode = 33
+       u32 PadEx33[15];
        // There are 128 possible extended commands - each of account for 16
        // words (including the non-relevent base command codes 1-15).
        // Pad for the remainder of these here to bring us to the next CPU
        // base.  As extended codes are added, reduce the first array value in
        // the following field
-       u32             PadToNextCpu[94][16];   // 94 = 128 - 34 (34 = Excodes 0 - 33)
+       u32 PadToNextCpu[94][16];       // 94 = 128 - 34 (34 = Excodes 0 - 33)
 } SXG_UCODE_REGS, *PSXG_UCODE_REGS;
 
 // Interrupt control register (0) values
@@ -141,7 +141,7 @@ typedef struct _SXG_UCODE_REGS {
 
 // The Microcode supports up to 16 RSS queues
 #define SXG_MAX_RSS                            16
-#define SXG_MAX_RSS_TABLE_SIZE 256             // 256-byte max
+#define SXG_MAX_RSS_TABLE_SIZE 256     // 256-byte max
 
 #define SXG_RSS_TCP6                           0x00000001      // RSS TCP over IPv6
 #define SXG_RSS_TCP4                           0x00000002      // RSS TCP over IPv4
@@ -170,16 +170,16 @@ typedef struct _SXG_UCODE_REGS {
  * SXG_UCODE_REGS definition above
  */
 typedef struct _SXG_TCB_REGS {
-       u32             ExCode;         /* Extended codes - see SXG_UCODE_REGS */
-       u32             Xmt;            /* Code = 1 - # of Xmt descriptors added to ring */
-       u32             Rcv;            /* Code = 2 - # of Rcv descriptors added to ring */
-       u32             Rsvd1;          /* Code = 3 - TOE NA */
-       u32             Rsvd2;          /* Code = 4 - TOE NA */
-       u32             Rsvd3;          /* Code = 5 - TOE NA */
-       u32             Invalid;        /* Code = 6 - Reserved for "CardUp" see above */
-       u32             Rsvd4;          /* Code = 7 - TOE NA */
-       u32             Rsvd5;          /* Code = 8 - TOE NA */
-       u32             Pad[7];         /* Codes 8-15 - Not used. */
+       u32 ExCode;             /* Extended codes - see SXG_UCODE_REGS */
+       u32 Xmt;                /* Code = 1 - # of Xmt descriptors added to ring */
+       u32 Rcv;                /* Code = 2 - # of Rcv descriptors added to ring */
+       u32 Rsvd1;              /* Code = 3 - TOE NA */
+       u32 Rsvd2;              /* Code = 4 - TOE NA */
+       u32 Rsvd3;              /* Code = 5 - TOE NA */
+       u32 Invalid;            /* Code = 6 - Reserved for "CardUp" see above */
+       u32 Rsvd4;              /* Code = 7 - TOE NA */
+       u32 Rsvd5;              /* Code = 8 - TOE NA */
+       u32 Pad[7];             /* Codes 8-15 - Not used. */
 } SXG_TCB_REGS, *PSXG_TCB_REGS;
 
 /***************************************************************************
@@ -273,27 +273,27 @@ typedef struct _SXG_TCB_REGS {
  */
 #pragma pack(push, 1)
 typedef struct _SXG_EVENT {
-       u32                     Pad[1];         // not used
-       u32                     SndUna;         // SndUna value
-       u32                     Resid;          // receive MDL resid
+       u32 Pad[1];             // not used
+       u32 SndUna;             // SndUna value
+       u32 Resid;              // receive MDL resid
        union {
-               void *          HostHandle;     // Receive host handle
-               u32             Rsvd1;          // TOE NA
+               void *HostHandle;       // Receive host handle
+               u32 Rsvd1;      // TOE NA
                struct {
-                       u32     NotUsed;
-                       u32     Rsvd2;          // TOE NA
+                       u32 NotUsed;
+                       u32 Rsvd2;      // TOE NA
                } Flush;
        };
-       u32                     Toeplitz;       // RSS Toeplitz hash
+       u32 Toeplitz;           // RSS Toeplitz hash
        union {
-               ushort          Rsvd3;          // TOE NA
-               ushort          HdrOffset;      // Slowpath
+               ushort Rsvd3;   // TOE NA
+               ushort HdrOffset;       // Slowpath
        };
-       ushort                  Length;         //
-       unsigned char           Rsvd4;          // TOE NA
-       unsigned char           Code;           // Event code
-       unsigned char           CommandIndex;   // New ring index
-       unsigned char           Status;         // Event status
+       ushort Length;          //
+       unsigned char Rsvd4;    // TOE NA
+       unsigned char Code;     // Event code
+       unsigned char CommandIndex;     // New ring index
+       unsigned char Status;   // Event status
 } SXG_EVENT, *PSXG_EVENT;
 #pragma pack(pop)
 
@@ -318,12 +318,12 @@ typedef struct _SXG_EVENT {
 // Event ring
 // Size must be power of 2, between 128 and 16k
 #define EVENT_RING_SIZE                4096    // ??
-#define EVENT_RING_BATCH       16              // Hand entries back 16 at a time.
-#define EVENT_BATCH_LIMIT      256         // Stop processing events after 256 (16 * 16)
+#define EVENT_RING_BATCH       16      // Hand entries back 16 at a time.
+#define EVENT_BATCH_LIMIT      256     // Stop processing events after 256 (16 * 16)
 
 typedef struct _SXG_EVENT_RING {
-       SXG_EVENT       Ring[EVENT_RING_SIZE];
-}SXG_EVENT_RING, *PSXG_EVENT_RING;
+       SXG_EVENT Ring[EVENT_RING_SIZE];
+} SXG_EVENT_RING, *PSXG_EVENT_RING;
 
 /***************************************************************************
  *
@@ -341,7 +341,7 @@ typedef struct _SXG_EVENT_RING {
 #define SXG_TCB_PER_BUCKET             16
 #define SXG_TCB_BUCKET_MASK            0xFF0   // Bucket portion of TCB ID
 #define SXG_TCB_ELEMENT_MASK   0x00F   // Element within bucket
-#define SXG_TCB_BUCKETS                        256             // 256 * 16 = 4k
+#define SXG_TCB_BUCKETS                        256     // 256 * 16 = 4k
 
 #define SXG_TCB_BUFFER_SIZE    512     // ASSERT format is correct
 
@@ -368,7 +368,6 @@ typedef struct _SXG_EVENT_RING {
        &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp6.Ip                              :               \
        &(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp6.Ip
 
-
 #if DBG
 // Horrible kludge to distinguish dumb-nic, slowpath, and
 // fastpath traffic.  Decrement the HopLimit by one
@@ -396,16 +395,16 @@ typedef struct _SXG_EVENT_RING {
  * Receive and transmit rings
  ***************************************************************************/
 #define SXG_MAX_RING_SIZE      256
-#define SXG_XMT_RING_SIZE      128             // Start with 128
-#define SXG_RCV_RING_SIZE      128             // Start with 128
+#define SXG_XMT_RING_SIZE      128     // Start with 128
+#define SXG_RCV_RING_SIZE      128     // Start with 128
 #define SXG_MAX_ENTRIES     4096
 
 // Structure and macros to manage a ring
 typedef struct _SXG_RING_INFO {
-       unsigned char                   Head;           // Where we add entries - Note unsigned char:RING_SIZE
-       unsigned char                   Tail;           // Where we pull off completed entries
-       ushort                  Size;           // Ring size - Must be multiple of 2
-       void *                  Context[SXG_MAX_RING_SIZE];     // Shadow ring
+       unsigned char Head;     // Where we add entries - Note unsigned char:RING_SIZE
+       unsigned char Tail;     // Where we pull off completed entries
+       ushort Size;            // Ring size - Must be multiple of 2
+       void *Context[SXG_MAX_RING_SIZE];       // Shadow ring
 } SXG_RING_INFO, *PSXG_RING_INFO;
 
 #define SXG_INITIALIZE_RING(_ring, _size) {                                                    \
@@ -483,40 +482,40 @@ typedef struct _SXG_RING_INFO {
  */
 #pragma pack(push, 1)
 typedef struct _SXG_CMD {
-       dma_addr_t                              Sgl;                    // Physical address of SGL
+       dma_addr_t Sgl;         // Physical address of SGL
        union {
                struct {
-                       dma64_addr_t            FirstSgeAddress;// Address of first SGE
-                       u32                                     FirstSgeLength; // Length of first SGE
+                       dma64_addr_t FirstSgeAddress;   // Address of first SGE
+                       u32 FirstSgeLength;     // Length of first SGE
                        union {
-                               u32                             Rsvd1;          // TOE NA
-                               u32                             SgeOffset;              // Slowpath - 2nd SGE offset
-                               u32                             Resid;                  // MDL completion - clobbers update
+                               u32 Rsvd1;      // TOE NA
+                               u32 SgeOffset;  // Slowpath - 2nd SGE offset
+                               u32 Resid;      // MDL completion - clobbers update
                        };
                        union {
-                               u32                             TotalLength;    // Total transfer length
-                               u32                             Mss;                    // LSO MSS
+                               u32 TotalLength;        // Total transfer length
+                               u32 Mss;        // LSO MSS
                        };
                } Buffer;
        };
        union {
                struct {
-                       unsigned char                                   Flags:4;                // slowpath flags
-                       unsigned char                                   IpHl:4;                 // Ip header length (>>2)
-                       unsigned char                                   MacLen;                 // Mac header len
+                       unsigned char Flags:4;  // slowpath flags
+                       unsigned char IpHl:4;   // Ip header length (>>2)
+                       unsigned char MacLen;   // Mac header len
                } CsumFlags;
                struct {
-                       ushort                                  Flags:4;                // slowpath flags
-                       ushort                                  TcpHdrOff:7;    // TCP
-                       ushort                                  MacLen:5;               // Mac header len
+                       ushort Flags:4; // slowpath flags
+                       ushort TcpHdrOff:7;     // TCP
+                       ushort MacLen:5;        // Mac header len
                } LsoFlags;
-               ushort                                          Flags;                  // flags
+               ushort Flags;   // flags
        };
        union {
-               ushort                                          SgEntries;              // SG entry count including first sge
+               ushort SgEntries;       // SG entry count including first sge
                struct {
-                       unsigned char                                   Status;             // Copied from event status
-                       unsigned char                                   NotUsed;
+                       unsigned char Status;   // Copied from event status
+                       unsigned char NotUsed;
                } Status;
        };
 } SXG_CMD, *PSXG_CMD;
@@ -524,8 +523,8 @@ typedef struct _SXG_CMD {
 
 #pragma pack(push, 1)
 typedef struct _VLAN_HDR {
-       ushort  VlanTci;
-       ushort  VlanTpid;
+       ushort VlanTci;
+       ushort VlanTpid;
 } VLAN_HDR, *PVLAN_HDR;
 #pragma pack(pop)
 
@@ -561,16 +560,16 @@ typedef struct _VLAN_HDR {
  *
  */
 // Slowpath CMD flags
-#define SXG_SLOWCMD_CSUM_IP                    0x01            // Checksum IP
-#define SXG_SLOWCMD_CSUM_TCP           0x02            // Checksum TCP
-#define SXG_SLOWCMD_LSO                                0x04            // Large segment send
+#define SXG_SLOWCMD_CSUM_IP                    0x01    // Checksum IP
+#define SXG_SLOWCMD_CSUM_TCP           0x02    // Checksum TCP
+#define SXG_SLOWCMD_LSO                                0x04    // Large segment send
 
 typedef struct _SXG_XMT_RING {
-       SXG_CMD         Descriptors[SXG_XMT_RING_SIZE];
+       SXG_CMD Descriptors[SXG_XMT_RING_SIZE];
 } SXG_XMT_RING, *PSXG_XMT_RING;
 
 typedef struct _SXG_RCV_RING {
-       SXG_CMD         Descriptors[SXG_RCV_RING_SIZE];
+       SXG_CMD Descriptors[SXG_RCV_RING_SIZE];
 } SXG_RCV_RING, *PSXG_RCV_RING;
 
 /***************************************************************************
@@ -578,8 +577,8 @@ typedef struct _SXG_RCV_RING {
  * shared memory allocation
  ***************************************************************************/
 typedef enum {
-       SXG_BUFFER_TYPE_RCV,            // Receive buffer
-       SXG_BUFFER_TYPE_SGL                     // SGL buffer
+       SXG_BUFFER_TYPE_RCV,    // Receive buffer
+       SXG_BUFFER_TYPE_SGL     // SGL buffer
 } SXG_BUFFER_TYPE;
 
 // State for SXG buffers
@@ -668,60 +667,60 @@ typedef enum {
 #define SXG_RCV_DATA_BUFFERS                   4096    // Amount to give to the card
 #define SXG_INITIAL_RCV_DATA_BUFFERS   8192    // Initial pool of buffers
 #define SXG_MIN_RCV_DATA_BUFFERS               2048    // Minimum amount and when to get more
-#define SXG_MAX_RCV_BLOCKS                             128             // = 16384 receive buffers
+#define SXG_MAX_RCV_BLOCKS                             128     // = 16384 receive buffers
 
 // Receive buffer header
 typedef struct _SXG_RCV_DATA_BUFFER_HDR {
-       dma_addr_t                              PhysicalAddress;        // Buffer physical address
+       dma_addr_t PhysicalAddress;     // Buffer physical address
        // Note - DO NOT USE the VirtualAddress field to locate data.
        // Use the sxg.h:SXG_RECEIVE_DATA_LOCATION macro instead.
-       void *VirtualAddress;           // Start of buffer
-       LIST_ENTRY                                              FreeList;                       // Free queue of buffers
-       struct _SXG_RCV_DATA_BUFFER_HDR *Next;                          // Fastpath data buffer queue
-       u32                                                     Size;                           // Buffer size
-       u32                                                     ByteOffset;                     // See SXG_RESTORE_MDL_OFFSET
-       unsigned char                                                   State;                          // See SXG_BUFFER state above
-       unsigned char                                                   Status;                         // Event status (to log PUSH)
-       struct sk_buff                * skb;                            // Double mapped (nbl and pkt)
+       void *VirtualAddress;   // Start of buffer
+       LIST_ENTRY FreeList;    // Free queue of buffers
+       struct _SXG_RCV_DATA_BUFFER_HDR *Next;  // Fastpath data buffer queue
+       u32 Size;               // Buffer size
+       u32 ByteOffset;         // See SXG_RESTORE_MDL_OFFSET
+       unsigned char State;    // See SXG_BUFFER state above
+       unsigned char Status;   // Event status (to log PUSH)
+       struct sk_buff *skb;    // Double mapped (nbl and pkt)
 } SXG_RCV_DATA_BUFFER_HDR, *PSXG_RCV_DATA_BUFFER_HDR;
 
 // SxgSlowReceive uses the PACKET (skb) contained
 // in the SXG_RCV_DATA_BUFFER_HDR when indicating dumb-nic data
 #define SxgDumbRcvPacket               skb
 
-#define SXG_RCV_DATA_HDR_SIZE                  256             // Space for SXG_RCV_DATA_BUFFER_HDR
+#define SXG_RCV_DATA_HDR_SIZE                  256     // Space for SXG_RCV_DATA_BUFFER_HDR
 #define SXG_RCV_DATA_BUFFER_SIZE               2048    // Non jumbo = 2k including HDR
 #define SXG_RCV_JUMBO_BUFFER_SIZE              10240   // jumbo = 10k including HDR
 
 // Receive data descriptor
 typedef struct _SXG_RCV_DATA_DESCRIPTOR {
        union {
-               struct sk_buff    *     VirtualAddress;                 // Host handle
-               u64                     ForceTo8Bytes;                  // Force x86 to 8-byte boundary
+               struct sk_buff *VirtualAddress; // Host handle
+               u64 ForceTo8Bytes;      // Force x86 to 8-byte boundary
        };
-       dma_addr_t              PhysicalAddress;
+       dma_addr_t PhysicalAddress;
 } SXG_RCV_DATA_DESCRIPTOR, *PSXG_RCV_DATA_DESCRIPTOR;
 
 // Receive descriptor block
 #define SXG_RCV_DESCRIPTORS_PER_BLOCK          128
 #define SXG_RCV_DESCRIPTOR_BLOCK_SIZE          2048    // For sanity check
 typedef struct _SXG_RCV_DESCRIPTOR_BLOCK {
-       SXG_RCV_DATA_DESCRIPTOR         Descriptors[SXG_RCV_DESCRIPTORS_PER_BLOCK];
+       SXG_RCV_DATA_DESCRIPTOR Descriptors[SXG_RCV_DESCRIPTORS_PER_BLOCK];
 } SXG_RCV_DESCRIPTOR_BLOCK, *PSXG_RCV_DESCRIPTOR_BLOCK;
 
 // Receive descriptor block header
 typedef struct _SXG_RCV_DESCRIPTOR_BLOCK_HDR {
-       void *                                  VirtualAddress;                 // Start of 2k buffer
-       dma_addr_t                  PhysicalAddress;            // ..and it's physical address
-       LIST_ENTRY                              FreeList;                               // Free queue of descriptor blocks
-       unsigned char                                   State;                                  // See SXG_BUFFER state above
+       void *VirtualAddress;   // Start of 2k buffer
+       dma_addr_t PhysicalAddress;     // ..and it's physical address
+       LIST_ENTRY FreeList;    // Free queue of descriptor blocks
+       unsigned char State;    // See SXG_BUFFER state above
 } SXG_RCV_DESCRIPTOR_BLOCK_HDR, *PSXG_RCV_DESCRIPTOR_BLOCK_HDR;
 
 // Receive block header
 typedef struct _SXG_RCV_BLOCK_HDR {
-       void *                                  VirtualAddress;                 // Start of virtual memory
-       dma_addr_t                  PhysicalAddress;            // ..and it's physical address
-       LIST_ENTRY                              AllList;                                // Queue of all SXG_RCV_BLOCKS
+       void *VirtualAddress;   // Start of virtual memory
+       dma_addr_t PhysicalAddress;     // ..and it's physical address
+       LIST_ENTRY AllList;     // Queue of all SXG_RCV_BLOCKS
 } SXG_RCV_BLOCK_HDR, *PSXG_RCV_BLOCK_HDR;
 
 // Macros to determine data structure offsets into receive block
@@ -747,8 +746,8 @@ typedef struct _SXG_RCV_BLOCK_HDR {
 // Use the miniport reserved portion of the NBL to locate
 // our SXG_RCV_DATA_BUFFER_HDR structure.
 typedef struct _SXG_RCV_NBL_RESERVED {
-       PSXG_RCV_DATA_BUFFER_HDR        RcvDataBufferHdr;
-       void *                                          Available;
+       PSXG_RCV_DATA_BUFFER_HDR RcvDataBufferHdr;
+       void *Available;
 } SXG_RCV_NBL_RESERVED, *PSXG_RCV_NBL_RESERVED;
 
 #define SXG_RCV_NBL_BUFFER_HDR(_NBL) (((PSXG_RCV_NBL_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(_NBL))->RcvDataBufferHdr)
@@ -760,12 +759,11 @@ typedef struct _SXG_RCV_NBL_RESERVED {
 #define SXG_MIN_SGL_BUFFERS                    2048    // Minimum amount and when to get more
 #define SXG_MAX_SGL_BUFFERS                    16384   // Maximum to allocate (note ADAPT:ushort)
 
-
 // Self identifying structure type
 typedef enum _SXG_SGL_TYPE {
-       SXG_SGL_DUMB,                           // Dumb NIC SGL
-       SXG_SGL_SLOW,                           // Slowpath protocol header - see below
-       SXG_SGL_CHIMNEY                         // Chimney offload SGL
+       SXG_SGL_DUMB,           // Dumb NIC SGL
+       SXG_SGL_SLOW,           // Slowpath protocol header - see below
+       SXG_SGL_CHIMNEY         // Chimney offload SGL
 } SXG_SGL_TYPE, PSXG_SGL_TYPE;
 
 // Note - the description below is Microsoft specific
@@ -774,14 +772,14 @@ typedef enum _SXG_SGL_TYPE {
 // for the SCATTER_GATHER_LIST portion of the SXG_SCATTER_GATHER data structure.
 // The following considerations apply when setting this value:
 // - First, the Sahara card is designed to read the Microsoft SGL structure
-//      straight out of host memory.  This means that the SGL must reside in
-//      shared memory.  If the length here is smaller than the SGL for the
-//      NET_BUFFER, then NDIS will allocate its own buffer.  The buffer
-//      that NDIS allocates is not in shared memory, so when this happens,
-//      the SGL will need to be copied to a set of SXG_SCATTER_GATHER buffers.
-//      In other words.. we don't want this value to be too small.
+//       straight out of host memory.  This means that the SGL must reside in
+//       shared memory.  If the length here is smaller than the SGL for the
+//       NET_BUFFER, then NDIS will allocate its own buffer.  The buffer
+//       that NDIS allocates is not in shared memory, so when this happens,
+//       the SGL will need to be copied to a set of SXG_SCATTER_GATHER buffers.
+//       In other words.. we don't want this value to be too small.
 // - On the other hand.. we're allocating up to 16k of these things.  If
-//      we make this too big, we start to consume a ton of memory..
+//       we make this too big, we start to consume a ton of memory..
 // At the moment, I'm going to limit the number of SG entries to 150.
 // If each entry maps roughly 4k, then this should cover roughly 600kB
 // NET_BUFFERs.  Furthermore, since each entry is 24 bytes, the total
@@ -801,24 +799,23 @@ typedef enum _SXG_SGL_TYPE {
 // the SGL.  The following structure defines an x64
 // formatted SGL entry
 typedef struct _SXG_X64_SGE {
-    dma64_addr_t       Address;        // same as wdm.h
-    u32                                Length;         // same as wdm.h
-       u32                             CompilerPad;// The compiler pads to 8-bytes
-    u64                        Reserved;       // u32 * in wdm.h.  Force to 8 bytes
+       dma64_addr_t Address;   // same as wdm.h
+       u32 Length;             // same as wdm.h
+       u32 CompilerPad;        // The compiler pads to 8-bytes
+       u64 Reserved;           // u32 * in wdm.h.  Force to 8 bytes
 } SXG_X64_SGE, *PSXG_X64_SGE;
 
 typedef struct _SCATTER_GATHER_ELEMENT {
-    dma64_addr_t       Address;        // same as wdm.h
-    u32                                Length;         // same as wdm.h
-       u32                             CompilerPad;// The compiler pads to 8-bytes
-    u64                        Reserved;       // u32 * in wdm.h.  Force to 8 bytes
+       dma64_addr_t Address;   // same as wdm.h
+       u32 Length;             // same as wdm.h
+       u32 CompilerPad;        // The compiler pads to 8-bytes
+       u64 Reserved;           // u32 * in wdm.h.  Force to 8 bytes
 } SCATTER_GATHER_ELEMENT, *PSCATTER_GATHER_ELEMENT;
 
-
 typedef struct _SCATTER_GATHER_LIST {
-    u32                                        NumberOfElements;
-    u32 *                              Reserved;
-    SCATTER_GATHER_ELEMENT     Elements[];
+       u32 NumberOfElements;
+       u32 *Reserved;
+       SCATTER_GATHER_ELEMENT Elements[];
 } SCATTER_GATHER_LIST, *PSCATTER_GATHER_LIST;
 
 // The card doesn't care about anything except elements, so
@@ -826,26 +823,26 @@ typedef struct _SCATTER_GATHER_LIST {
 // SGL structure.  But redefine from wdm.h:SCATTER_GATHER_LIST so
 // we can specify SXG_X64_SGE and define a fixed number of elements
 typedef struct _SXG_X64_SGL {
-    u32                                        NumberOfElements;
-    u32 *                              Reserved;
-    SXG_X64_SGE                                Elements[SXG_SGL_ENTRIES];
+       u32 NumberOfElements;
+       u32 *Reserved;
+       SXG_X64_SGE Elements[SXG_SGL_ENTRIES];
 } SXG_X64_SGL, *PSXG_X64_SGL;
 
 typedef struct _SXG_SCATTER_GATHER {
-       SXG_SGL_TYPE                                            Type;                   // FIRST! Dumb-nic or offload
-       void *                                                          adapter;                // Back pointer to adapter
-       LIST_ENTRY                                                      FreeList;               // Free SXG_SCATTER_GATHER blocks
-       LIST_ENTRY                                                      AllList;                // All SXG_SCATTER_GATHER blocks
-       dma_addr_t                                          PhysicalAddress;// physical address
-       unsigned char                                                           State;                  // See SXG_BUFFER state above
-       unsigned char                                                           CmdIndex;               // Command ring index
-       struct sk_buff                    *     DumbPacket;             // Associated Packet
-       u32                                                             Direction;              // For asynchronous completions
-       u32                                                             CurOffset;              // Current SGL offset
-       u32                                                             SglRef;                 // SGL reference count
-       VLAN_HDR                                                        VlanTag;                // VLAN tag to be inserted into SGL
-       PSCATTER_GATHER_LIST                            pSgl;                   // SGL Addr. Possibly &Sgl
-       SXG_X64_SGL                                                     Sgl;                    // SGL handed to card
+       SXG_SGL_TYPE Type;      // FIRST! Dumb-nic or offload
+       void *adapter;          // Back pointer to adapter
+       LIST_ENTRY FreeList;    // Free SXG_SCATTER_GATHER blocks
+       LIST_ENTRY AllList;     // All SXG_SCATTER_GATHER blocks
+       dma_addr_t PhysicalAddress;     // physical address
+       unsigned char State;    // See SXG_BUFFER state above
+       unsigned char CmdIndex; // Command ring index
+       struct sk_buff *DumbPacket;     // Associated Packet
+       u32 Direction;          // For asynchronous completions
+       u32 CurOffset;          // Current SGL offset
+       u32 SglRef;             // SGL reference count
+       VLAN_HDR VlanTag;       // VLAN tag to be inserted into SGL
+       PSCATTER_GATHER_LIST pSgl;      // SGL Addr. Possibly &Sgl
+       SXG_X64_SGL Sgl;        // SGL handed to card
 } SXG_SCATTER_GATHER, *PSXG_SCATTER_GATHER;
 
 #if defined(CONFIG_X86_64)
@@ -856,6 +853,5 @@ typedef struct _SXG_SCATTER_GATHER {
 #define SXG_SGL_BUFFER(_SxgSgl)                NULL
 #define SXG_SGL_BUF_SIZE                       0
 #else
-    Stop Compilation;
+Stop Compilation;
 #endif
-
index 8f4f6effdd98e0b9047e37218e3d5b92ec6999d1..2222ae91fd97f9b4f606f5c255562df609cf266f 100644 (file)
 /*******************************************************************************
  * Configuration space
  *******************************************************************************/
-//  PCI Vendor ID
-#define SXG_VENDOR_ID                  0x139A  // Alacritech's Vendor ID
+/*  PCI Vendor ID */
+#define SXG_VENDOR_ID                  0x139A  /* Alacritech's Vendor ID */
 
 //  PCI Device ID
-#define SXG_DEVICE_ID                  0x0009  // Sahara Device ID
+#define SXG_DEVICE_ID                  0x0009  /* Sahara Device ID */
 
 //
 // Subsystem IDs.
@@ -141,7 +141,7 @@ typedef struct _SXG_HW_REGS {
 #define SXG_REGISTER_SIZE_PER_CPU      0x00002000      // Used to sanity check UCODE_REGS structure
 
 // Sahara receive sequencer status values
-#define SXG_RCV_STATUS_ATTN                                    0x80000000      // Attention
+#define SXG_RCV_STATUS_ATTN                    0x80000000      // Attention
 #define SXG_RCV_STATUS_TRANSPORT_MASK          0x3F000000      // Transport mask
 #define SXG_RCV_STATUS_TRANSPORT_ERROR         0x20000000      // Transport error
 #define SXG_RCV_STATUS_TRANSPORT_CSUM          0x23000000      // Transport cksum error
@@ -156,9 +156,9 @@ typedef struct _SXG_HW_REGS {
 #define SXG_RCV_STATUS_TRANSPORT_FTP           0x03000000      // Transport FTP
 #define SXG_RCV_STATUS_TRANSPORT_HTTP          0x02000000      // Transport HTTP
 #define SXG_RCV_STATUS_TRANSPORT_SMB           0x01000000      // Transport SMB
-#define SXG_RCV_STATUS_NETWORK_MASK                    0x00FF0000      // Network mask
+#define SXG_RCV_STATUS_NETWORK_MASK            0x00FF0000      // Network mask
 #define SXG_RCV_STATUS_NETWORK_ERROR           0x00800000      // Network error
-#define SXG_RCV_STATUS_NETWORK_CSUM                    0x00830000      // Network cksum error
+#define SXG_RCV_STATUS_NETWORK_CSUM            0x00830000      // Network cksum error
 #define SXG_RCV_STATUS_NETWORK_UFLOW           0x00820000      // Network underflow error
 #define SXG_RCV_STATUS_NETWORK_HDRLEN          0x00800000      // Network header length
 #define SXG_RCV_STATUS_NETWORK_OFLOW           0x00400000      // Network overflow detected
@@ -167,67 +167,67 @@ typedef struct _SXG_HW_REGS {
 #define SXG_RCV_STATUS_NETWORK_OFFSET          0x00080000      // Network offset detected
 #define SXG_RCV_STATUS_NETWORK_FRAGMENT                0x00040000      // Network fragment detected
 #define SXG_RCV_STATUS_NETWORK_TRANS_MASK      0x00030000      // Network transport type mask
-#define SXG_RCV_STATUS_NETWORK_UDP                     0x00020000      // UDP
-#define SXG_RCV_STATUS_NETWORK_TCP                     0x00010000      // TCP
-#define SXG_RCV_STATUS_IPONLY                          0x00008000      // IP-only not TCP
-#define SXG_RCV_STATUS_PKT_PRI                         0x00006000      // Receive priority
-#define SXG_RCV_STATUS_PKT_PRI_SHFT                                    13      // Receive priority shift
-#define SXG_RCV_STATUS_PARITY                          0x00001000      // MAC Receive RAM parity error
-#define SXG_RCV_STATUS_ADDRESS_MASK                    0x00000F00      // Link address detection mask
-#define SXG_RCV_STATUS_ADDRESS_D                       0x00000B00      // Link address D
-#define SXG_RCV_STATUS_ADDRESS_C                       0x00000A00      // Link address C
-#define SXG_RCV_STATUS_ADDRESS_B                       0x00000900      // Link address B
-#define SXG_RCV_STATUS_ADDRESS_A                       0x00000800      // Link address A
+#define SXG_RCV_STATUS_NETWORK_UDP             0x00020000      // UDP
+#define SXG_RCV_STATUS_NETWORK_TCP             0x00010000      // TCP
+#define SXG_RCV_STATUS_IPONLY                  0x00008000      // IP-only not TCP
+#define SXG_RCV_STATUS_PKT_PRI                 0x00006000      // Receive priority
+#define SXG_RCV_STATUS_PKT_PRI_SHFT                    13      // Receive priority shift
+#define SXG_RCV_STATUS_PARITY                  0x00001000      // MAC Receive RAM parity error
+#define SXG_RCV_STATUS_ADDRESS_MASK            0x00000F00      // Link address detection mask
+#define SXG_RCV_STATUS_ADDRESS_D               0x00000B00      // Link address D
+#define SXG_RCV_STATUS_ADDRESS_C               0x00000A00      // Link address C
+#define SXG_RCV_STATUS_ADDRESS_B               0x00000900      // Link address B
+#define SXG_RCV_STATUS_ADDRESS_A               0x00000800      // Link address A
 #define SXG_RCV_STATUS_ADDRESS_BCAST           0x00000300      // Link address broadcast
 #define SXG_RCV_STATUS_ADDRESS_MCAST           0x00000200      // Link address multicast
 #define SXG_RCV_STATUS_ADDRESS_CMCAST          0x00000100      // Link control multicast
-#define SXG_RCV_STATUS_LINK_MASK                       0x000000FF      // Link status mask
-#define SXG_RCV_STATUS_LINK_ERROR                      0x00000080      // Link error
-#define SXG_RCV_STATUS_LINK_MASK                       0x000000FF      // Link status mask
-#define SXG_RCV_STATUS_LINK_PARITY                     0x00000087      // RcvMacQ parity error
-#define SXG_RCV_STATUS_LINK_EARLY                      0x00000086      // Data early
+#define SXG_RCV_STATUS_LINK_MASK               0x000000FF      // Link status mask
+#define SXG_RCV_STATUS_LINK_ERROR              0x00000080      // Link error
+#define SXG_RCV_STATUS_LINK_MASK               0x000000FF      // Link status mask
+#define SXG_RCV_STATUS_LINK_PARITY             0x00000087      // RcvMacQ parity error
+#define SXG_RCV_STATUS_LINK_EARLY              0x00000086      // Data early
 #define SXG_RCV_STATUS_LINK_BUFOFLOW           0x00000085      // Buffer overflow
-#define SXG_RCV_STATUS_LINK_CODE                       0x00000084      // Link code error
-#define SXG_RCV_STATUS_LINK_DRIBBLE                    0x00000083      // Dribble nibble
-#define SXG_RCV_STATUS_LINK_CRC                                0x00000082      // CRC error
-#define SXG_RCV_STATUS_LINK_OFLOW                      0x00000081      // Link overflow
-#define SXG_RCV_STATUS_LINK_UFLOW                      0x00000080      // Link underflow
-#define SXG_RCV_STATUS_LINK_8023                       0x00000020      // 802.3
-#define SXG_RCV_STATUS_LINK_SNAP                       0x00000010      // Snap
-#define SXG_RCV_STATUS_LINK_VLAN                       0x00000008      // VLAN
+#define SXG_RCV_STATUS_LINK_CODE               0x00000084      // Link code error
+#define SXG_RCV_STATUS_LINK_DRIBBLE            0x00000083      // Dribble nibble
+#define SXG_RCV_STATUS_LINK_CRC                        0x00000082      // CRC error
+#define SXG_RCV_STATUS_LINK_OFLOW              0x00000081      // Link overflow
+#define SXG_RCV_STATUS_LINK_UFLOW              0x00000080      // Link underflow
+#define SXG_RCV_STATUS_LINK_8023               0x00000020      // 802.3
+#define SXG_RCV_STATUS_LINK_SNAP               0x00000010      // Snap
+#define SXG_RCV_STATUS_LINK_VLAN               0x00000008      // VLAN
 #define SXG_RCV_STATUS_LINK_TYPE_MASK          0x00000007      // Network type mask
-#define SXG_RCV_STATUS_LINK_CONTROL                    0x00000003      // Control packet
-#define SXG_RCV_STATUS_LINK_IPV6                       0x00000002      // IPv6 packet
-#define SXG_RCV_STATUS_LINK_IPV4                       0x00000001      // IPv4 packet
+#define SXG_RCV_STATUS_LINK_CONTROL            0x00000003      // Control packet
+#define SXG_RCV_STATUS_LINK_IPV6               0x00000002      // IPv6 packet
+#define SXG_RCV_STATUS_LINK_IPV4               0x00000001      // IPv4 packet
 
 /***************************************************************************
  * Sahara receive and transmit configuration registers
  ***************************************************************************/
-#define        RCV_CONFIG_RESET                        0x80000000      // RcvConfig register reset
-#define        RCV_CONFIG_ENABLE                       0x40000000      // Enable the receive logic
-#define        RCV_CONFIG_ENPARSE                      0x20000000      // Enable the receive parser
-#define        RCV_CONFIG_SOCKET                       0x10000000      // Enable the socket detector
-#define        RCV_CONFIG_RCVBAD                       0x08000000      // Receive all bad frames
-#define        RCV_CONFIG_CONTROL                      0x04000000      // Receive all control frames
-#define        RCV_CONFIG_RCVPAUSE                     0x02000000      // Enable pause transmit when attn
-#define        RCV_CONFIG_TZIPV6                       0x01000000      // Include TCP port w/ IPv6 toeplitz
-#define        RCV_CONFIG_TZIPV4                       0x00800000      // Include TCP port w/ IPv4 toeplitz
-#define        RCV_CONFIG_FLUSH                        0x00400000      // Flush buffers
+#define        RCV_CONFIG_RESET                0x80000000      // RcvConfig register reset
+#define        RCV_CONFIG_ENABLE               0x40000000      // Enable the receive logic
+#define        RCV_CONFIG_ENPARSE              0x20000000      // Enable the receive parser
+#define        RCV_CONFIG_SOCKET               0x10000000      // Enable the socket detector
+#define        RCV_CONFIG_RCVBAD               0x08000000      // Receive all bad frames
+#define        RCV_CONFIG_CONTROL              0x04000000      // Receive all control frames
+#define        RCV_CONFIG_RCVPAUSE             0x02000000      // Enable pause transmit when attn
+#define        RCV_CONFIG_TZIPV6               0x01000000      // Include TCP port w/ IPv6 toeplitz
+#define        RCV_CONFIG_TZIPV4               0x00800000      // Include TCP port w/ IPv4 toeplitz
+#define        RCV_CONFIG_FLUSH                0x00400000      // Flush buffers
 #define        RCV_CONFIG_PRIORITY_MASK        0x00300000      // Priority level
 #define        RCV_CONFIG_HASH_MASK            0x00030000      // Hash depth
-#define        RCV_CONFIG_HASH_8                       0x00000000      // Hash depth 8
-#define        RCV_CONFIG_HASH_16                      0x00010000      // Hash depth 16
-#define        RCV_CONFIG_HASH_4                       0x00020000      // Hash depth 4
-#define        RCV_CONFIG_HASH_2                       0x00030000      // Hash depth 2
+#define        RCV_CONFIG_HASH_8               0x00000000      // Hash depth 8
+#define        RCV_CONFIG_HASH_16              0x00010000      // Hash depth 16
+#define        RCV_CONFIG_HASH_4               0x00020000      // Hash depth 4
+#define        RCV_CONFIG_HASH_2               0x00030000      // Hash depth 2
 #define        RCV_CONFIG_BUFLEN_MASK          0x0000FFF0      // Buffer length bits 15:4. ie multiple of 16.
-#define RCV_CONFIG_SKT_DIS                     0x00000008      // Disable socket detection on attn
+#define RCV_CONFIG_SKT_DIS             0x00000008      // Disable socket detection on attn
 // Macro to determine RCV_CONFIG_BUFLEN based on maximum frame size.
 // We add 18 bytes for Sahara receive status and padding, plus 4 bytes for CRC,
 // and round up to nearest 16 byte boundary
 #define RCV_CONFIG_BUFSIZE(_MaxFrame) ((((_MaxFrame) + 22) + 15) & RCV_CONFIG_BUFLEN_MASK)
 
-#define        XMT_CONFIG_RESET                        0x80000000      // XmtConfig register reset
-#define        XMT_CONFIG_ENABLE                       0x40000000      // Enable transmit logic
+#define        XMT_CONFIG_RESET                0x80000000      // XmtConfig register reset
+#define        XMT_CONFIG_ENABLE               0x40000000      // Enable transmit logic
 #define        XMT_CONFIG_MAC_PARITY           0x20000000      // Inhibit MAC RAM parity error
 #define        XMT_CONFIG_BUF_PARITY           0x10000000      // Inhibit D2F buffer parity error
 #define        XMT_CONFIG_MEM_PARITY           0x08000000      // Inhibit 1T SRAM parity error
@@ -249,9 +249,9 @@ typedef struct _SXG_HW_REGS {
 
 // A-XGMAC Configuration Register 1
 #define AXGMAC_CFG1_XMT_PAUSE          0x80000000              // Allow the sending of Pause frames
-#define AXGMAC_CFG1_XMT_EN                     0x40000000              // Enable transmit
+#define AXGMAC_CFG1_XMT_EN             0x40000000              // Enable transmit
 #define AXGMAC_CFG1_RCV_PAUSE          0x20000000              // Allow the detection of Pause frames
-#define AXGMAC_CFG1_RCV_EN                     0x10000000              // Enable receive
+#define AXGMAC_CFG1_RCV_EN             0x10000000              // Enable receive
 #define AXGMAC_CFG1_XMT_STATE          0x04000000              // Current transmit state - READ ONLY
 #define AXGMAC_CFG1_RCV_STATE          0x01000000              // Current receive state - READ ONLY
 #define AXGMAC_CFG1_XOFF_SHORT         0x00001000              // Only pause for 64 slot on XOFF
@@ -262,24 +262,24 @@ typedef struct _SXG_HW_REGS {
 #define AXGMAC_CFG1_RCV_FCS2           0x00000200              // Delay receive FCS 2 4-byte words
 #define AXGMAC_CFG1_RCV_FCS3           0x00000300              // Delay receive FCS 3 4-byte words
 #define AXGMAC_CFG1_PKT_OVERRIDE       0x00000080              // Per-packet override enable
-#define AXGMAC_CFG1_SWAP                       0x00000040              // Byte swap enable
+#define AXGMAC_CFG1_SWAP               0x00000040              // Byte swap enable
 #define AXGMAC_CFG1_SHORT_ASSERT       0x00000020              // ASSERT srdrpfrm on short frame (<64)
 #define AXGMAC_CFG1_RCV_STRICT         0x00000010              // RCV only 802.3AE when CLEAR
 #define AXGMAC_CFG1_CHECK_LEN          0x00000008              // Verify frame length
-#define AXGMAC_CFG1_GEN_FCS                    0x00000004              // Generate FCS
+#define AXGMAC_CFG1_GEN_FCS            0x00000004              // Generate FCS
 #define AXGMAC_CFG1_PAD_MASK           0x00000003              // Mask for pad bits
-#define AXGMAC_CFG1_PAD_64                     0x00000001              // Pad frames to 64 bytes
+#define AXGMAC_CFG1_PAD_64             0x00000001              // Pad frames to 64 bytes
 #define AXGMAC_CFG1_PAD_VLAN           0x00000002              // Detect VLAN and pad to 68 bytes
-#define AXGMAC_CFG1_PAD_68                     0x00000003              // Pad to 68 bytes
+#define AXGMAC_CFG1_PAD_68             0x00000003              // Pad to 68 bytes
 
 // A-XGMAC Configuration Register 2
 #define AXGMAC_CFG2_GEN_PAUSE          0x80000000              // Generate single pause frame (test)
 #define AXGMAC_CFG2_LF_MANUAL          0x08000000              // Manual link fault sequence
-#define AXGMAC_CFG2_LF_AUTO                    0x04000000              // Auto link fault sequence
+#define AXGMAC_CFG2_LF_AUTO            0x04000000              // Auto link fault sequence
 #define AXGMAC_CFG2_LF_REMOTE          0x02000000              // Remote link fault (READ ONLY)
 #define AXGMAC_CFG2_LF_LOCAL           0x01000000              // Local link fault (READ ONLY)
 #define AXGMAC_CFG2_IPG_MASK           0x001F0000              // Inter packet gap
-#define AXGMAC_CFG2_IPG_SHIFT          16
+#define AXGMAC_CFG2_IPG_SHIFT                  16
 #define AXGMAC_CFG2_PAUSE_XMT          0x00008000              // Pause transmit module
 #define AXGMAC_CFG2_IPG_EXTEN          0x00000020              // Enable IPG extension algorithm
 #define AXGMAC_CFG2_IPGEX_MASK         0x0000001F              // IPG extension
@@ -299,9 +299,9 @@ typedef struct _SXG_HW_REGS {
 #define AXGMAC_SARHIGH_OCTET_SIX       0x00FF0000              // Sixth octet
 
 // A-XGMAC Maximum frame length register
-#define AXGMAC_MAXFRAME_XMT                    0x3FFF0000              // Maximum transmit frame length
+#define AXGMAC_MAXFRAME_XMT            0x3FFF0000              // Maximum transmit frame length
 #define AXGMAC_MAXFRAME_XMT_SHIFT      16
-#define AXGMAC_MAXFRAME_RCV                    0x0000FFFF              // Maximum receive frame length
+#define AXGMAC_MAXFRAME_RCV            0x0000FFFF              // Maximum receive frame length
 // This register doesn't need to be written for standard MTU.
 // For jumbo, I'll just statically define the value here.  This
 // value sets the receive byte count to 9036 (0x234C) and the
@@ -324,34 +324,34 @@ typedef struct _SXG_HW_REGS {
 
 // A-XGMAC AMIIM Field Register
 #define AXGMAC_AMIIM_FIELD_ST          0xC0000000              // 2-bit ST field
-#define AXGMAC_AMIIM_FIELD_ST_SHIFT                    30
+#define AXGMAC_AMIIM_FIELD_ST_SHIFT            30
 #define AXGMAC_AMIIM_FIELD_OP          0x30000000              // 2-bit OP field
-#define AXGMAC_AMIIM_FIELD_OP_SHIFT                    28
-#define AXGMAC_AMIIM_FIELD_PORT_ADDR 0x0F800000                // Port address field (hstphyadx in spec)
+#define AXGMAC_AMIIM_FIELD_OP_SHIFT            28
+#define AXGMAC_AMIIM_FIELD_PORT_ADDR   0x0F800000              // Port address field (hstphyadx in spec)
 #define AXGMAC_AMIIM_FIELD_PORT_SHIFT          23
 #define AXGMAC_AMIIM_FIELD_DEV_ADDR    0x007C0000              // Device address field (hstregadx in spec)
 #define AXGMAC_AMIIM_FIELD_DEV_SHIFT           18
 #define AXGMAC_AMIIM_FIELD_TA          0x00030000              // 2-bit TA field
-#define AXGMAC_AMIIM_FIELD_TA_SHIFT                    16
+#define AXGMAC_AMIIM_FIELD_TA_SHIFT            16
 #define AXGMAC_AMIIM_FIELD_DATA                0x0000FFFF              // Data field
 
 // Values for the AXGMAC_AMIIM_FIELD_OP field in the A-XGMAC AMIIM Field Register
-#define        MIIM_OP_ADDR                                            0               // MIIM Address set operation
-#define        MIIM_OP_WRITE                                           1               // MIIM Write register operation
-#define        MIIM_OP_READ                                            2               // MIIM Read register operation
+#define        MIIM_OP_ADDR                            0               // MIIM Address set operation
+#define        MIIM_OP_WRITE                           1               // MIIM Write register operation
+#define        MIIM_OP_READ                            2               // MIIM Read register operation
 #define        MIIM_OP_ADDR_SHIFT      (MIIM_OP_ADDR << AXGMAC_AMIIM_FIELD_OP_SHIFT)
 
 // Values for the AXGMAC_AMIIM_FIELD_PORT_ADDR field in the A-XGMAC AMIIM Field Register
-#define        MIIM_PORT_NUM                                           1               // All Sahara MIIM modules use port 1
+#define        MIIM_PORT_NUM                           1               // All Sahara MIIM modules use port 1
 
 // Values for the AXGMAC_AMIIM_FIELD_DEV_ADDR field in the A-XGMAC AMIIM Field Register
-#define        MIIM_DEV_PHY_PMA                                        1               // PHY PMA/PMD module MIIM device number
-#define        MIIM_DEV_PHY_PCS                                        3               // PHY PCS module MIIM device number
-#define        MIIM_DEV_PHY_XS                                         4               // PHY XS module MIIM device number
-#define        MIIM_DEV_XGXS                                           5               // XGXS MIIM device number
+#define        MIIM_DEV_PHY_PMA                        1               // PHY PMA/PMD module MIIM device number
+#define        MIIM_DEV_PHY_PCS                        3               // PHY PCS module MIIM device number
+#define        MIIM_DEV_PHY_XS                         4               // PHY XS module MIIM device number
+#define        MIIM_DEV_XGXS                           5               // XGXS MIIM device number
 
 // Values for the AXGMAC_AMIIM_FIELD_TA field in the A-XGMAC AMIIM Field Register
-#define        MIIM_TA_10GB                                            2               // set to 2 for 10 GB operation
+#define        MIIM_TA_10GB                            2               // set to 2 for 10 GB operation
 
 // A-XGMAC AMIIM Configuration Register
 #define AXGMAC_AMIIM_CFG_NOPREAM       0x00000080              // Bypass preamble of mngmt frame
@@ -365,25 +365,25 @@ typedef struct _SXG_HW_REGS {
 #define AXGMAC_AMIIM_INDC_BUSY         0x00000001              // Set until cmd operation complete
 
 // Link Status and Control Register
-#define        LS_PHY_CLR_RESET                        0x80000000              // Clear reset signal to PHY
+#define        LS_PHY_CLR_RESET                0x80000000              // Clear reset signal to PHY
 #define        LS_SERDES_POWER_DOWN            0x40000000              // Power down the Sahara Serdes
-#define        LS_XGXS_ENABLE                          0x20000000              // Enable the XAUI XGXS logic
-#define        LS_XGXS_CTL                                     0x10000000              // Hold XAUI XGXS logic reset until Serdes is up
-#define        LS_SERDES_DOWN                          0x08000000              // When 0, XAUI Serdes is up and initialization is complete
-#define        LS_TRACE_DOWN                           0x04000000              // When 0, Trace Serdes is up and initialization is complete
-#define        LS_PHY_CLK_25MHZ                        0x02000000              // Set PHY clock to 25 MHz (else 156.125 MHz)
-#define        LS_PHY_CLK_EN                           0x01000000              // Enable clock to PHY
-#define        LS_XAUI_LINK_UP                         0x00000010              // XAUI link is up
-#define        LS_XAUI_LINK_CHNG                       0x00000008              // XAUI link status has changed
-#define        LS_LINK_ALARM                           0x00000004              // Link alarm pin
-#define        LS_ATTN_CTRL_MASK                       0x00000003              // Mask link attention control bits
-#define        LS_ATTN_ALARM                           0x00000000              // 00 => Attn on link alarm
+#define        LS_XGXS_ENABLE                  0x20000000              // Enable the XAUI XGXS logic
+#define        LS_XGXS_CTL                     0x10000000              // Hold XAUI XGXS logic reset until Serdes is up
+#define        LS_SERDES_DOWN                  0x08000000              // When 0, XAUI Serdes is up and initialization is complete
+#define        LS_TRACE_DOWN                   0x04000000              // When 0, Trace Serdes is up and initialization is complete
+#define        LS_PHY_CLK_25MHZ                0x02000000              // Set PHY clock to 25 MHz (else 156.125 MHz)
+#define        LS_PHY_CLK_EN                   0x01000000              // Enable clock to PHY
+#define        LS_XAUI_LINK_UP                 0x00000010              // XAUI link is up
+#define        LS_XAUI_LINK_CHNG               0x00000008              // XAUI link status has changed
+#define        LS_LINK_ALARM                   0x00000004              // Link alarm pin
+#define        LS_ATTN_CTRL_MASK               0x00000003              // Mask link attention control bits
+#define        LS_ATTN_ALARM                   0x00000000              // 00 => Attn on link alarm
 #define        LS_ATTN_ALARM_OR_STAT_CHNG      0x00000001              // 01 => Attn on link alarm or status change
-#define        LS_ATTN_STAT_CHNG                       0x00000002              // 10 => Attn on link status change
-#define        LS_ATTN_NONE                            0x00000003              // 11 => no Attn
+#define        LS_ATTN_STAT_CHNG               0x00000002              // 10 => Attn on link status change
+#define        LS_ATTN_NONE                    0x00000003              // 11 => no Attn
 
 // Link Address High Registers
-#define        LINK_ADDR_ENABLE                        0x80000000              // Enable this link address
+#define        LINK_ADDR_ENABLE                0x80000000              // Enable this link address
 
 
 /***************************************************************************
@@ -396,7 +396,7 @@ typedef struct _SXG_HW_REGS {
 #define XGXS_ADDRESS_STATUS1           0x0001                  // XS Status 1
 #define XGXS_ADDRESS_DEVID_LOW         0x0002                  // XS Device ID (low)
 #define XGXS_ADDRESS_DEVID_HIGH                0x0003                  // XS Device ID (high)
-#define XGXS_ADDRESS_SPEED                     0x0004                  // XS Speed ability
+#define XGXS_ADDRESS_SPEED             0x0004                  // XS Speed ability
 #define XGXS_ADDRESS_DEV_LOW           0x0005                  // XS Devices in package
 #define XGXS_ADDRESS_DEV_HIGH          0x0006                  // XS Devices in package
 #define XGXS_ADDRESS_STATUS2           0x0008                  // XS Status 2
@@ -410,27 +410,27 @@ typedef struct _SXG_HW_REGS {
 #define XGXS_ADDRESS_RESET_HI2         0x8003                  // Vendor-Specific Reset Hi 2
 
 // XS Control 1 register bit definitions
-#define XGXS_CONTROL1_RESET                    0x8000                  // Reset - self clearing
+#define XGXS_CONTROL1_RESET            0x8000                  // Reset - self clearing
 #define XGXS_CONTROL1_LOOPBACK         0x4000                  // Enable loopback
 #define XGXS_CONTROL1_SPEED1           0x2000                  // 0 = unspecified, 1 = 10Gb+
 #define XGXS_CONTROL1_LOWPOWER         0x0400                  // 1 = Low power mode
 #define XGXS_CONTROL1_SPEED2           0x0040                  // Same as SPEED1 (?)
-#define XGXS_CONTROL1_SPEED                    0x003C                  // Everything reserved except zero (?)
+#define XGXS_CONTROL1_SPEED            0x003C                  // Everything reserved except zero (?)
 
 // XS Status 1 register bit definitions
-#define XGXS_STATUS1_FAULT                     0x0080                  // Fault detected
-#define XGXS_STATUS1_LINK                      0x0004                  // 1 = Link up
+#define XGXS_STATUS1_FAULT             0x0080                  // Fault detected
+#define XGXS_STATUS1_LINK              0x0004                  // 1 = Link up
 #define XGXS_STATUS1_LOWPOWER          0x0002                  // 1 = Low power supported
 
 // XS Speed register bit definitions
-#define XGXS_SPEED_10G                         0x0001                  // 1 = 10G capable
+#define XGXS_SPEED_10G                 0x0001                  // 1 = 10G capable
 
 // XS Devices register bit definitions
-#define XGXS_DEVICES_DTE                       0x0020                  // DTE XS Present
-#define XGXS_DEVICES_PHY                       0x0010                  // PHY XS Present
-#define XGXS_DEVICES_PCS                       0x0008                  // PCS Present
-#define XGXS_DEVICES_WIS                       0x0004                  // WIS Present
-#define XGXS_DEVICES_PMD                       0x0002                  // PMD/PMA Present
+#define XGXS_DEVICES_DTE               0x0020                  // DTE XS Present
+#define XGXS_DEVICES_PHY               0x0010                  // PHY XS Present
+#define XGXS_DEVICES_PCS               0x0008                  // PCS Present
+#define XGXS_DEVICES_WIS               0x0004                  // WIS Present
+#define XGXS_DEVICES_PMD               0x0002                  // PMD/PMA Present
 #define XGXS_DEVICES_CLAUSE22          0x0001                  // Clause 22 registers present
 
 // XS Devices High register bit definitions
@@ -444,18 +444,18 @@ typedef struct _SXG_HW_REGS {
 #define XGXS_STATUS2_RCV_FAULT         0x0400                  // Receive fault
 
 // XS Package ID High register bit definitions
-#define XGXS_PKGID_HIGH_ORG                    0xFC00                  // Organizationally Unique
-#define XGXS_PKGID_HIGH_MFG                    0x03F0                  // Manufacturer Model
-#define XGXS_PKGID_HIGH_REV                    0x000F                  // Revision Number
+#define XGXS_PKGID_HIGH_ORG            0xFC00                  // Organizationally Unique
+#define XGXS_PKGID_HIGH_MFG            0x03F0                  // Manufacturer Model
+#define XGXS_PKGID_HIGH_REV            0x000F                  // Revision Number
 
 // XS Lane Status register bit definitions
-#define XGXS_LANE_PHY                          0x1000                  // PHY/DTE lane alignment status
-#define XGXS_LANE_PATTERN                      0x0800                  // Pattern testing ability
-#define XGXS_LANE_LOOPBACK                     0x0400                  // PHY loopback ability
-#define XGXS_LANE_SYNC3                                0x0008                  // Lane 3 sync
-#define XGXS_LANE_SYNC2                                0x0004                  // Lane 2 sync
-#define XGXS_LANE_SYNC1                                0x0002                  // Lane 1 sync
-#define XGXS_LANE_SYNC0                                0x0001                  // Lane 0 sync
+#define XGXS_LANE_PHY                  0x1000                  // PHY/DTE lane alignment status
+#define XGXS_LANE_PATTERN              0x0800                  // Pattern testing ability
+#define XGXS_LANE_LOOPBACK             0x0400                  // PHY loopback ability
+#define XGXS_LANE_SYNC3                        0x0008                  // Lane 3 sync
+#define XGXS_LANE_SYNC2                        0x0004                  // Lane 2 sync
+#define XGXS_LANE_SYNC1                        0x0002                  // Lane 1 sync
+#define XGXS_LANE_SYNC0                        0x0001                  // Lane 0 sync
 
 // XS Test Control register bit definitions
 #define XGXS_TEST_PATTERN_ENABLE       0x0004                  // Test pattern enabled
@@ -473,10 +473,10 @@ typedef struct _SXG_HW_REGS {
 // LASI (Link Alarm Status Interrupt) Registers (located in MIIM_DEV_PHY_PMA device)
 #define LASI_RX_ALARM_CONTROL          0x9000                  // LASI RX_ALARM Control
 #define LASI_TX_ALARM_CONTROL          0x9001                  // LASI TX_ALARM Control
-#define LASI_CONTROL                           0x9002                  // LASI Control
+#define LASI_CONTROL                   0x9002                  // LASI Control
 #define LASI_RX_ALARM_STATUS           0x9003                  // LASI RX_ALARM Status
 #define LASI_TX_ALARM_STATUS           0x9004                  // LASI TX_ALARM Status
-#define LASI_STATUS                                    0x9005                  // LASI Status
+#define LASI_STATUS                    0x9005                  // LASI Status
 
 // LASI_CONTROL bit definitions
 #define        LASI_CTL_RX_ALARM_ENABLE        0x0004                  // Enable RX_ALARM interrupts
@@ -489,34 +489,34 @@ typedef struct _SXG_HW_REGS {
 #define        LASI_STATUS_LS_ALARM            0x0001                  // Link Status
 
 // PHY registers - PMA/PMD (device 1)
-#define        PHY_PMA_CONTROL1                        0x0000                  // PMA/PMD Control 1
-#define        PHY_PMA_STATUS1                         0x0001                  // PMA/PMD Status 1
-#define        PHY_PMA_RCV_DET                         0x000A                  // PMA/PMD Receive Signal Detect
+#define        PHY_PMA_CONTROL1                0x0000                  // PMA/PMD Control 1
+#define        PHY_PMA_STATUS1                 0x0001                  // PMA/PMD Status 1
+#define        PHY_PMA_RCV_DET                 0x000A                  // PMA/PMD Receive Signal Detect
                // other PMA/PMD registers exist and can be defined as needed
 
 // PHY registers - PCS (device 3)
-#define        PHY_PCS_CONTROL1                        0x0000                  // PCS Control 1
-#define        PHY_PCS_STATUS1                         0x0001                  // PCS Status 1
-#define        PHY_PCS_10G_STATUS1                     0x0020                  // PCS 10GBASE-R Status 1
+#define        PHY_PCS_CONTROL1                0x0000                  // PCS Control 1
+#define        PHY_PCS_STATUS1                 0x0001                  // PCS Status 1
+#define        PHY_PCS_10G_STATUS1             0x0020                  // PCS 10GBASE-R Status 1
                // other PCS registers exist and can be defined as needed
 
 // PHY registers - XS (device 4)
-#define        PHY_XS_CONTROL1                         0x0000                  // XS Control 1
-#define        PHY_XS_STATUS1                          0x0001                  // XS Status 1
-#define        PHY_XS_LANE_STATUS                      0x0018                  // XS Lane Status
+#define        PHY_XS_CONTROL1                 0x0000                  // XS Control 1
+#define        PHY_XS_STATUS1                  0x0001                  // XS Status 1
+#define        PHY_XS_LANE_STATUS              0x0018                  // XS Lane Status
                // other XS registers exist and can be defined as needed
 
 // PHY_PMA_CONTROL1 register bit definitions
-#define        PMA_CONTROL1_RESET                      0x8000                  // PMA/PMD reset
+#define        PMA_CONTROL1_RESET              0x8000                  // PMA/PMD reset
 
 // PHY_PMA_RCV_DET register bit definitions
-#define        PMA_RCV_DETECT                          0x0001                  // PMA/PMD receive signal detect
+#define        PMA_RCV_DETECT                  0x0001                  // PMA/PMD receive signal detect
 
 // PHY_PCS_10G_STATUS1 register bit definitions
-#define        PCS_10B_BLOCK_LOCK                      0x0001                  // PCS 10GBASE-R locked to receive blocks
+#define        PCS_10B_BLOCK_LOCK              0x0001                  // PCS 10GBASE-R locked to receive blocks
 
 // PHY_XS_LANE_STATUS register bit definitions
-#define        XS_LANE_ALIGN                           0x1000                  // XS transmit lanes aligned
+#define        XS_LANE_ALIGN                   0x1000                  // XS transmit lanes aligned
 
 // PHY Microcode download data structure
 typedef struct _PHY_UCODE {
@@ -558,8 +558,8 @@ typedef struct _XMT_DESC {
                // command codes
 #define XMT_DESC_CMD_RAW_SEND          0               // raw send descriptor
 #define XMT_DESC_CMD_CSUM_INSERT       1               // checksum insert descriptor
-#define XMT_DESC_CMD_FORMAT                    2               // format descriptor
-#define XMT_DESC_CMD_PRIME                     3               // prime descriptor
+#define XMT_DESC_CMD_FORMAT            2               // format descriptor
+#define XMT_DESC_CMD_PRIME             3               // prime descriptor
 #define XMT_DESC_CMD_CODE_SHFT         6               // comand code shift (shift to bits [31:30] in word 0)
                // shifted command codes
 #define XMT_RAW_SEND           (XMT_DESC_CMD_RAW_SEND    << XMT_DESC_CMD_CODE_SHFT)
@@ -569,22 +569,22 @@ typedef struct _XMT_DESC {
 
 // XMT_DESC Control Byte (XmtCtl) definitions
 // NOTE:  These bits do not work on Sahara (Rev A)!
-#define        XMT_CTL_PAUSE_FRAME                     0x80    // current frame is a pause control frame (for statistics)
+#define        XMT_CTL_PAUSE_FRAME             0x80    // current frame is a pause control frame (for statistics)
 #define        XMT_CTL_CONTROL_FRAME           0x40    // current frame is a control frame (for statistics)
 #define        XMT_CTL_PER_PKT_QUAL            0x20    // per packet qualifier
 #define        XMT_CTL_PAD_MODE_NONE           0x00    // do not pad frame
-#define        XMT_CTL_PAD_MODE_64                     0x08    // pad frame to 64 bytes
+#define        XMT_CTL_PAD_MODE_64             0x08    // pad frame to 64 bytes
 #define        XMT_CTL_PAD_MODE_VLAN_68        0x10    // pad frame to 64 bytes, and VLAN frames to 68 bytes
-#define        XMT_CTL_PAD_MODE_68                     0x18    // pad frame to 68 bytes
-#define        XMT_CTL_GEN_FCS                         0x04    // generate FCS (CRC) for this frame
-#define        XMT_CTL_DELAY_FCS_0                     0x00    // do not delay FCS calcution
-#define        XMT_CTL_DELAY_FCS_1                     0x01    // delay FCS calculation by 1 (4-byte) word
-#define        XMT_CTL_DELAY_FCS_2                     0x02    // delay FCS calculation by 2 (4-byte) words
-#define        XMT_CTL_DELAY_FCS_3                     0x03    // delay FCS calculation by 3 (4-byte) words
+#define        XMT_CTL_PAD_MODE_68             0x18    // pad frame to 68 bytes
+#define        XMT_CTL_GEN_FCS                 0x04    // generate FCS (CRC) for this frame
+#define        XMT_CTL_DELAY_FCS_0             0x00    // do not delay FCS calcution
+#define        XMT_CTL_DELAY_FCS_1             0x01    // delay FCS calculation by 1 (4-byte) word
+#define        XMT_CTL_DELAY_FCS_2             0x02    // delay FCS calculation by 2 (4-byte) words
+#define        XMT_CTL_DELAY_FCS_3             0x03    // delay FCS calculation by 3 (4-byte) words
 
 // XMT_DESC XmtBufId definition
-#define XMT_BUF_ID_SHFT                8                       // The Xmt buffer ID is formed by dividing
-                                                                               // the buffer (DRAM) address by 256 (or << 8)
+#define XMT_BUF_ID_SHFT                8       // The Xmt buffer ID is formed by dividing
+                                       // the buffer (DRAM) address by 256 (or << 8)
 
 /*****************************************************************************
  * Receiver Sequencer Definitions
@@ -594,8 +594,8 @@ typedef struct _XMT_DESC {
 #define        RCV_EVTQ_RBFID_MASK             0x0000FFFF      // bit mask for the Receive Buffer ID
 
 // Receive Buffer ID definition
-#define RCV_BUF_ID_SHFT                5                       // The Rcv buffer ID is formed by dividing
-                                                                               // the buffer (DRAM) address by 32 (or << 5)
+#define RCV_BUF_ID_SHFT                5       // The Rcv buffer ID is formed by dividing
+                                       // the buffer (DRAM) address by 32 (or << 5)
 
 // Format of the 18 byte Receive Buffer returned by the
 // Receive Sequencer for received packets
@@ -623,48 +623,48 @@ typedef struct _RCV_BUF_HDR {
  * Queue definitions
  *****************************************************************************/
 
-// Ingress (read only) queue numbers
-#define PXY_BUF_Q              0               // Proxy Buffer Queue
-#define HST_EVT_Q              1               // Host Event Queue
-#define XMT_BUF_Q              2               // Transmit Buffer Queue
-#define SKT_EVL_Q              3               // RcvSqr Socket Event Low Priority Queue
-#define RCV_EVL_Q              4               // RcvSqr Rcv Event Low Priority Queue
-#define SKT_EVH_Q              5               // RcvSqr Socket Event High Priority Queue
-#define RCV_EVH_Q              6               // RcvSqr Rcv Event High Priority Queue
-#define DMA_RSP_Q              7               // Dma Response Queue - one per CPU context
-// Local (read/write) queue numbers
-#define LOCAL_A_Q              8               // Spare local Queue
-#define LOCAL_B_Q              9               // Spare local Queue
-#define LOCAL_C_Q              10              // Spare local Queue
-#define FSM_EVT_Q              11              // Finite-State-Machine Event Queue
-#define SBF_PAL_Q              12              // System Buffer Physical Address (low) Queue
-#define SBF_PAH_Q              13              // System Buffer Physical Address (high) Queue
-#define SBF_VAL_Q              14              // System Buffer Virtual Address (low) Queue
-#define SBF_VAH_Q              15              // System Buffer Virtual Address (high) Queue
-// Egress (write only) queue numbers
-#define H2G_CMD_Q              16              // Host to GlbRam DMA Command Queue
-#define H2D_CMD_Q              17              // Host to DRAM DMA Command Queue
-#define G2H_CMD_Q              18              // GlbRam to Host DMA Command Queue
-#define G2D_CMD_Q              19              // GlbRam to DRAM DMA Command Queue
-#define D2H_CMD_Q              20              // DRAM to Host DMA Command Queue
-#define D2G_CMD_Q              21              // DRAM to GlbRam DMA Command Queue
-#define D2D_CMD_Q              22              // DRAM to DRAM DMA Command Queue
-#define PXL_CMD_Q              23              // Low Priority Proxy Command Queue
-#define PXH_CMD_Q              24              // High Priority Proxy Command Queue
-#define RSQ_CMD_Q              25              // Receive Sequencer Command Queue
-#define RCV_BUF_Q              26              // Receive Buffer Queue
-
-// Bit definitions for the Proxy Command queues (PXL_CMD_Q and PXH_CMD_Q)
-#define PXY_COPY_EN            0x00200000              // enable copy of xmt descriptor to xmt command queue
-#define PXY_SIZE_16            0x00000000              // copy 16 bytes
-#define PXY_SIZE_32            0x00100000              // copy 32 bytes
+/* Ingress (read only) queue numbers */
+#define PXY_BUF_Q              0               /* Proxy Buffer Queue */
+#define HST_EVT_Q              1               /* Host Event Queue */
+#define XMT_BUF_Q              2               /* Transmit Buffer Queue */
+#define SKT_EVL_Q              3               /* RcvSqr Socket Event Low Priority Queue */
+#define RCV_EVL_Q              4               /* RcvSqr Rcv Event Low Priority Queue */
+#define SKT_EVH_Q              5               /* RcvSqr Socket Event High Priority Queue */
+#define RCV_EVH_Q              6               /* RcvSqr Rcv Event High Priority Queue */
+#define DMA_RSP_Q              7               /* Dma Response Queue - one per CPU context */
+/* Local (read/write) queue numbers */
+#define LOCAL_A_Q              8               /* Spare local Queue */
+#define LOCAL_B_Q              9               /* Spare local Queue */
+#define LOCAL_C_Q              10              /* Spare local Queue */
+#define FSM_EVT_Q              11              /* Finite-State-Machine Event Queue */
+#define SBF_PAL_Q              12              /* System Buffer Physical Address (low) Queue */
+#define SBF_PAH_Q              13              /* System Buffer Physical Address (high) Queue */
+#define SBF_VAL_Q              14              /* System Buffer Virtual Address (low) Queue */
+#define SBF_VAH_Q              15              /* System Buffer Virtual Address (high) Queue */
+/* Egress (write only) queue numbers */
+#define H2G_CMD_Q              16              /* Host to GlbRam DMA Command Queue */
+#define H2D_CMD_Q              17              /* Host to DRAM DMA Command Queue */
+#define G2H_CMD_Q              18              /* GlbRam to Host DMA Command Queue */
+#define G2D_CMD_Q              19              /* GlbRam to DRAM DMA Command Queue */
+#define D2H_CMD_Q              20              /* DRAM to Host DMA Command Queue */
+#define D2G_CMD_Q              21              /* DRAM to GlbRam DMA Command Queue */
+#define D2D_CMD_Q              22              /* DRAM to DRAM DMA Command Queue */
+#define PXL_CMD_Q              23              /* Low Priority Proxy Command Queue */
+#define PXH_CMD_Q              24              /* High Priority Proxy Command Queue */
+#define RSQ_CMD_Q              25              /* Receive Sequencer Command Queue */
+#define RCV_BUF_Q              26              /* Receive Buffer Queue */
+
+/* Bit definitions for the Proxy Command queues (PXL_CMD_Q and PXH_CMD_Q) */
+#define PXY_COPY_EN            0x00200000              /* enable copy of xmt descriptor to xmt command queue */
+#define PXY_SIZE_16            0x00000000              /* copy 16 bytes */
+#define PXY_SIZE_32            0x00100000              /* copy 32 bytes */
 
 /*****************************************************************************
  * SXG EEPROM/Flash Configuration Definitions
  *****************************************************************************/
 #pragma pack(push, 1)
 
-//
+/* */
 typedef struct _HW_CFG_DATA {
        ushort          Addr;
        union {
@@ -673,22 +673,22 @@ typedef struct _HW_CFG_DATA {
        };
 } HW_CFG_DATA, *PHW_CFG_DATA;
 
-//
+/* */
 #define        NUM_HW_CFG_ENTRIES      ((128/sizeof(HW_CFG_DATA)) - 4)
 
-// MAC address
+/* MAC address */
 typedef struct _SXG_CONFIG_MAC {
-       unsigned char           MacAddr[6];                     // MAC Address
+       unsigned char           MacAddr[6];                     /* MAC Address */
 } SXG_CONFIG_MAC, *PSXG_CONFIG_MAC;
 
-//
+/* */
 typedef struct _ATK_FRU {
        unsigned char           PartNum[6];
        unsigned char           Revision[2];
        unsigned char           Serial[14];
 } ATK_FRU, *PATK_FRU;
 
-// OEM FRU Format types
+/* OEM FRU Format types */
 #define        ATK_FRU_FORMAT          0x0000
 #define CPQ_FRU_FORMAT         0x0001
 #define DELL_FRU_FORMAT                0x0002
@@ -697,24 +697,24 @@ typedef struct _ATK_FRU {
 #define EMC_FRU_FORMAT         0x0005
 #define NO_FRU_FORMAT          0xFFFF
 
-// EEPROM/Flash Format
+/* EEPROM/Flash Format */
 typedef struct _SXG_CONFIG {
-       //
-       // Section 1 (128 bytes)
-       //
-       ushort                  MagicWord;                      // EEPROM/FLASH Magic code 'A5A5'
-       ushort                  SpiClks;                        // SPI bus clock dividers
+       /* */
+       /* Section 1 (128 bytes) */
+       /* */
+       ushort                  MagicWord;                      /* EEPROM/FLASH Magic code 'A5A5' */
+       ushort                  SpiClks;                        /* SPI bus clock dividers */
        HW_CFG_DATA             HwCfg[NUM_HW_CFG_ENTRIES];
-       //
-       //
-       //
-       ushort                  Version;                        // EEPROM format version
-       SXG_CONFIG_MAC  MacAddr[4];                     // space for 4 MAC addresses
-       ATK_FRU                 AtkFru;                         // FRU information
-       ushort                  OemFruFormat;           // OEM FRU format type
-       unsigned char                   OemFru[76];                     // OEM FRU information (optional)
-       ushort                  Checksum;                       // Checksum of section 2
-       // CS info XXXTODO
+       /* */
+       /* */
+       /* */
+       ushort                  Version;                        /* EEPROM format version */
+       SXG_CONFIG_MAC  MacAddr[4];                     /* space for 4 MAC addresses */
+       ATK_FRU                 AtkFru;                         /* FRU information */
+       ushort                  OemFruFormat;           /* OEM FRU format type */
+       unsigned char                   OemFru[76];                     /* OEM FRU information (optional) */
+       ushort                  Checksum;                       /* Checksum of section 2 */
+       /* CS info XXXTODO */
 } SXG_CONFIG, *PSXG_CONFIG;
 #pragma pack(pop)
 
@@ -723,12 +723,12 @@ typedef struct _SXG_CONFIG {
  *****************************************************************************/
 
 // Sahara (ASIC level) defines
-#define SAHARA_GRAM_SIZE                       0x020000                // GRAM size - 128 KB
-#define SAHARA_DRAM_SIZE                       0x200000                // DRAM size - 2 MB
-#define SAHARA_QRAM_SIZE                       0x004000                // QRAM size - 16K entries (64 KB)
-#define SAHARA_WCS_SIZE                                0x002000                // WCS - 8K instructions (x 108 bits)
+#define SAHARA_GRAM_SIZE               0x020000                // GRAM size - 128 KB
+#define SAHARA_DRAM_SIZE               0x200000                // DRAM size - 2 MB
+#define SAHARA_QRAM_SIZE               0x004000                // QRAM size - 16K entries (64 KB)
+#define SAHARA_WCS_SIZE                        0x002000                // WCS - 8K instructions (x 108 bits)
 
 // Arabia (board level) defines
-#define        FLASH_SIZE                              0x080000                // 512 KB (4 Mb)
-#define        EEPROM_SIZE_XFMR                512                             // true EEPROM size (bytes), including xfmr area
-#define        EEPROM_SIZE_NO_XFMR             256                             // EEPROM size excluding xfmr area
+#define        FLASH_SIZE                      0x080000                // 512 KB (4 Mb)
+#define        EEPROM_SIZE_XFMR                512                     // true EEPROM size (bytes), including xfmr area
+#define        EEPROM_SIZE_NO_XFMR             256                     // EEPROM size excluding xfmr area
index 26b36c81eb1a0f749112d453715b77e44b84ec71..8dbaeda7eca478fd60785e95599ca886e27518b8 100644 (file)
@@ -34,7 +34,7 @@ static PHY_UCODE PhyUcode[] = {
         */
        /* Addr, Data */
        {0xc017, 0xfeb0},       /* flip RX_LOS polarity (mandatory */
-                               /*  patch for SFP+ applications) */
+       /*  patch for SFP+ applications) */
        {0xC001, 0x0428},       /* flip RX serial polarity */
 
        {0xc013, 0xf341},       /* invert lxmit clock (mandatory patch) */
@@ -43,7 +43,7 @@ static PHY_UCODE PhyUcode[] = {
        {0xc210, 0x8000},       /* reset datapath (mandatory patch) */
        {0xc210, 0x0000},       /* reset datapath (mandatory patch) */
        {0x0000, 0x0032},       /* wait for 50ms for datapath reset to */
-                               /* complete. (mandatory patch) */
+       /* complete. (mandatory patch) */
 
        /* Configure the LED's */
        {0xc214, 0x0099},       /* configure the LED drivers */
@@ -52,15 +52,15 @@ static PHY_UCODE PhyUcode[] = {
 
        /* Transceiver-specific MDIO Patches: */
        {0xc010, 0x448a},       /* (bit 14) mask out high BER input from the */
-                               /* LOS signal in 1.000A */
-                               /* (mandatory patch for SR code)*/
+       /* LOS signal in 1.000A */
+       /* (mandatory patch for SR code) */
        {0xc003, 0x0181},       /* (bit 7) enable the CDR inc setting in */
-                               /* 1.C005 (mandatory patch for SR code) */
+       /* 1.C005 (mandatory patch for SR code) */
 
        /* Transceiver-specific Microcontroller Initialization: */
        {0xc04a, 0x5200},       /* activate microcontroller and pause */
        {0x0000, 0x0032},       /* wait 50ms for microcontroller before */
-                               /* writing in code. */
+       /* writing in code. */
 
        /* code block starts here: */
        {0xcc00, 0x2009},
index e64918f42ff7c5e982824689f94935f6593d4179..72e209276ea74b6af2bef0b439f053ff3689c9b6 100644 (file)
@@ -221,7 +221,7 @@ static void usbip_dump_request_type(__u8 rt)
 static void usbip_dump_usb_ctrlrequest(struct usb_ctrlrequest *cmd)
 {
        if (!cmd) {
-               printk("      %s : null pointer\n", __FUNCTION__);
+               printk("      %s : null pointer\n", __func__);
                return;
        }
 
index 933ccaf50afbb737bc09e2d615e9c639eed6f511..58e3995d0e2ce169ba9bea352b97271315ca9cf4 100644 (file)
@@ -202,7 +202,7 @@ static void vhci_rx_pdu(struct usbip_device *ud)
        ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu), 0);
        if (ret != sizeof(pdu)) {
                uerr("receiving pdu failed! size is %d, should be %d\n",
-                               ret, sizeof(pdu));
+                               ret, (unsigned int)sizeof(pdu));
                usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
                return;
        }
index 10d72bec88a948fd4869266b1200a10488834227..425219ed7ab9c4cedf30a721734c9aaeee6755c7 100644 (file)
@@ -1,6 +1,6 @@
 config W35UND
        tristate "Winbond driver"
-       depends on MAC80211 && WLAN_80211 && EXPERIMENTAL && !4KSTACKS
+       depends on MAC80211 && WLAN_80211 && USB && EXPERIMENTAL && !4KSTACKS
        default n
        ---help---
          This is highly experimental driver for winbond wifi card on some Kohjinsha notebooks
index 707b6b354dc592a59bfbb2d1a7acb731720b09ae..cb944e4bf1744ecb6b1ef40739745f0122911b61 100644 (file)
@@ -5,6 +5,7 @@ TODO:
        - remove typedefs
        - remove unused ioctls
        - use cfg80211 for regulatory stuff
+       - fix 4k stack problems
 
 Please send patches to Greg Kroah-Hartman <greg@kroah.com> and
 Pavel Machek <pavel@suse.cz>
index c957bc94f08d99bc5b9306f792b5b365d927d7dc..013183153993705a311a5a0b467408cf284dcfca 100644 (file)
@@ -24,7 +24,7 @@ void DesiredRate2InfoElement(PWB32_ADAPTER Adapter, u8        *addr, u16 *iFildOffset,
                                                         u8 *pBasicRateSet, u8 BasicRateCount,
                                                         u8 *pOperationRateSet, u8 OperationRateCount);
 void BSSAddIBSSdata(PWB32_ADAPTER Adapter, PWB_BSSDESCRIPTION psDesData);
-unsigned char boCmpMacAddr( PUCHAR, PUCHAR );
+unsigned char boCmpMacAddr( u8 *, u8 *);
 unsigned char boCmpSSID(struct SSID_Element *psSSID1, struct SSID_Element *psSSID2);
 u16 wBSSfindSSID(PWB32_ADAPTER Adapter, struct SSID_Element *psSsid);
 u16 wRoamingQuery(PWB32_ADAPTER Adapter);
@@ -42,11 +42,11 @@ void RateReSortForSRate(PWB32_ADAPTER Adapter, u8 *RateArray, u8 num);
 void Assemble_IE(PWB32_ADAPTER Adapter, u16 wBssIdx);
 void SetMaxTxRate(PWB32_ADAPTER Adapter);
 
-void CreateWpaIE(PWB32_ADAPTER Adapter, u16* iFildOffset, PUCHAR msg, struct  Management_Frame* msgHeader,
+void CreateWpaIE(PWB32_ADAPTER Adapter, u16* iFildOffset, u8 *msg, struct  Management_Frame* msgHeader,
                                 struct Association_Request_Frame_Body* msgBody, u16 iMSindex); //added by WS 05/14/05
 
 #ifdef _WPA2_
-void CreateRsnIE(PWB32_ADAPTER Adapter, u16* iFildOffset, PUCHAR msg, struct  Management_Frame* msgHeader,
+void CreateRsnIE(PWB32_ADAPTER Adapter, u16* iFildOffset, u8 *msg, struct  Management_Frame* msgHeader,
                                 struct Association_Request_Frame_Body* msgBody, u16 iMSindex);//added by WS 05/14/05
 
 u16 SearchPmkid(PWB32_ADAPTER Adapter, struct  Management_Frame* msgHeader,
index 29e5055b45a1ef59ebb200f907cce873dd806793..6841d66e7e8cfe831e271ad171b10dceb36bc001 100644 (file)
@@ -25,9 +25,9 @@ typedef struct tkip
        s32             bytes_in_M;     // # bytes in M
 } tkip_t;
 
-//void _append_data( PUCHAR pData, u16 size, tkip_t *p );
-void Mds_MicGet(  void* Adapter,  void* pRxLayer1,  PUCHAR pKey,  PUCHAR pMic );
-void Mds_MicFill(  void* Adapter,  void* pDes,  PUCHAR XmitBufAddress );
+//void _append_data( u8 *pData, u16 size, tkip_t *p );
+void Mds_MicGet(  void* Adapter,  void* pRxLayer1,  u8 *pKey,  u8 *pMic );
+void Mds_MicFill(  void* Adapter,  void* pDes,  u8 *XmitBufAddress );
 
 
 
index 6b00bad74f78ed5afb929d9a272422768e2ab5db..712a86cfa68b5650c1c0396f7914e4a31ed8fa0a 100644 (file)
 // Common type definition
 //===============================================================
 
-typedef u8*            PUCHAR;
-typedef s8*            PCHAR;
-typedef u8*            PBOOLEAN;
-typedef u16*           PUSHORT;
-typedef u32*           PULONG;
-typedef s16*   PSHORT;
-
-
 //===========================================
 #define IGNORE      2
 #define        SUCCESS     1
@@ -110,16 +102,9 @@ typedef struct urb * PURB;
 #define OS_ATOMIC_READ( _A, _V )       _V
 #define OS_ATOMIC_INC( _A, _V )                EncapAtomicInc( _A, (void*)_V )
 #define OS_ATOMIC_DEC( _A, _V )                EncapAtomicDec( _A, (void*)_V )
-#define OS_MEMORY_CLEAR( _A, _S )      memset( (PUCHAR)_A,0,_S)
+#define OS_MEMORY_CLEAR( _A, _S )      memset( (u8 *)_A,0,_S)
 #define OS_MEMORY_COMPARE( _A, _B, _S )        (memcmp(_A,_B,_S)? 0 : 1) // Definition is reverse with Ndis 1: the same 0: different
 
-
-#define OS_SPIN_LOCK                           spinlock_t
-#define OS_SPIN_LOCK_ALLOCATE( _S )            spin_lock_init( _S );
-#define OS_SPIN_LOCK_FREE( _S )
-#define OS_SPIN_LOCK_ACQUIRED( _S )            spin_lock_irq( _S )
-#define OS_SPIN_LOCK_RELEASED( _S )            spin_unlock_irq( _S );
-
 #define OS_TIMER       struct timer_list
 #define OS_TIMER_INITIAL( _T, _F, _P )                 \
 {                                                      \
index 2c0b454e8cad9d3685a94988b170bc1370ad1aae..ebb6db5438a4ed07e21a3a08ec152600bf89ad1c 100644 (file)
@@ -10,7 +10,7 @@ extern void phy_calibration_winbond(hw_data_t *phw_data, u32 frequency);
 // Flag : AUTO_INCREMENT - RegisterNo will auto increment 4
 //               NO_INCREMENT - Function will write data into the same register
 unsigned char
-Wb35Reg_BurstWrite(phw_data_t pHwData, u16 RegisterNo, PULONG pRegisterData, u8 NumberOfData, u8 Flag)
+Wb35Reg_BurstWrite(phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterData, u8 NumberOfData, u8 Flag)
 {
        PWB35REG pWb35Reg = &pHwData->Wb35Reg;
        PURB            pUrb = NULL;
@@ -30,13 +30,13 @@ Wb35Reg_BurstWrite(phw_data_t pHwData, u16 RegisterNo, PULONG pRegisterData, u8
        if( pUrb && pRegQueue ) {
                pRegQueue->DIRECT = 2;// burst write register
                pRegQueue->INDEX = RegisterNo;
-               pRegQueue->pBuffer = (PULONG)((PUCHAR)pRegQueue + sizeof(REG_QUEUE));
+               pRegQueue->pBuffer = (u32 *)((u8 *)pRegQueue + sizeof(REG_QUEUE));
                memcpy( pRegQueue->pBuffer, pRegisterData, DataSize );
                //the function for reversing register data from little endian to big endian
                for( i=0; i<NumberOfData ; i++ )
                        pRegQueue->pBuffer[i] = cpu_to_le32( pRegQueue->pBuffer[i] );
 
-               dr = (struct usb_ctrlrequest *)((PUCHAR)pRegQueue + sizeof(REG_QUEUE) + DataSize);
+               dr = (struct usb_ctrlrequest *)((u8 *)pRegQueue + sizeof(REG_QUEUE) + DataSize);
                dr->bRequestType = USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE;
                dr->bRequest = 0x04; // USB or vendor-defined request code, burst mode
                dr->wValue = cpu_to_le16( Flag ); // 0: Register number auto-increment, 1: No auto increment
@@ -46,14 +46,14 @@ Wb35Reg_BurstWrite(phw_data_t pHwData, u16 RegisterNo, PULONG pRegisterData, u8
                pRegQueue->pUsbReq = dr;
                pRegQueue->pUrb = pUrb;
 
-               OS_SPIN_LOCK_ACQUIRED( &pWb35Reg->EP0VM_spin_lock );
+               spin_lock_irq( &pWb35Reg->EP0VM_spin_lock );
                if (pWb35Reg->pRegFirst == NULL)
                        pWb35Reg->pRegFirst = pRegQueue;
                else
                        pWb35Reg->pRegLast->Next = pRegQueue;
                pWb35Reg->pRegLast = pRegQueue;
 
-               OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
+               spin_unlock_irq( &pWb35Reg->EP0VM_spin_lock );
 
                // Start EP0VM
                Wb35Reg_EP0VM_start(pHwData);
@@ -181,7 +181,7 @@ Wb35Reg_Write(  phw_data_t pHwData,  u16 RegisterNo,  u32 RegisterValue )
                pRegQueue->INDEX = RegisterNo;
                pRegQueue->VALUE = cpu_to_le32(RegisterValue);
                pRegQueue->RESERVED_VALID = FALSE;
-               dr = (struct usb_ctrlrequest *)((PUCHAR)pRegQueue + sizeof(REG_QUEUE));
+               dr = (struct usb_ctrlrequest *)((u8 *)pRegQueue + sizeof(REG_QUEUE));
                dr->bRequestType = USB_TYPE_VENDOR|USB_DIR_OUT |USB_RECIP_DEVICE;
                dr->bRequest = 0x03; // USB or vendor-defined request code, burst mode
                dr->wValue = cpu_to_le16(0x0);
@@ -193,14 +193,14 @@ Wb35Reg_Write(  phw_data_t pHwData,  u16 RegisterNo,  u32 RegisterValue )
                pRegQueue->pUsbReq = dr;
                pRegQueue->pUrb = pUrb;
 
-               OS_SPIN_LOCK_ACQUIRED(&pWb35Reg->EP0VM_spin_lock );
+               spin_lock_irq(&pWb35Reg->EP0VM_spin_lock );
                if (pWb35Reg->pRegFirst == NULL)
                        pWb35Reg->pRegFirst = pRegQueue;
                else
                        pWb35Reg->pRegLast->Next = pRegQueue;
                pWb35Reg->pRegLast = pRegQueue;
 
-               OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
+               spin_unlock_irq( &pWb35Reg->EP0VM_spin_lock );
 
                // Start EP0VM
                Wb35Reg_EP0VM_start(pHwData);
@@ -220,7 +220,7 @@ Wb35Reg_Write(  phw_data_t pHwData,  u16 RegisterNo,  u32 RegisterValue )
 // FALSE : register not support
 unsigned char
 Wb35Reg_WriteWithCallbackValue( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue,
-                               PCHAR pValue, s8 Len)
+                               s8 *pValue, s8 Len)
 {
        PWB35REG        pWb35Reg = &pHwData->Wb35Reg;
        struct usb_ctrlrequest *dr;
@@ -243,7 +243,7 @@ Wb35Reg_WriteWithCallbackValue( phw_data_t pHwData, u16 RegisterNo, u32 Register
                //NOTE : Users must guarantee the size of value will not exceed the buffer size.
                memcpy(pRegQueue->RESERVED, pValue, Len);
                pRegQueue->RESERVED_VALID = TRUE;
-               dr = (struct usb_ctrlrequest *)((PUCHAR)pRegQueue + sizeof(REG_QUEUE));
+               dr = (struct usb_ctrlrequest *)((u8 *)pRegQueue + sizeof(REG_QUEUE));
                dr->bRequestType = USB_TYPE_VENDOR|USB_DIR_OUT |USB_RECIP_DEVICE;
                dr->bRequest = 0x03; // USB or vendor-defined request code, burst mode
                dr->wValue = cpu_to_le16(0x0);
@@ -254,14 +254,14 @@ Wb35Reg_WriteWithCallbackValue( phw_data_t pHwData, u16 RegisterNo, u32 Register
                pRegQueue->Next = NULL;
                pRegQueue->pUsbReq = dr;
                pRegQueue->pUrb = pUrb;
-               OS_SPIN_LOCK_ACQUIRED (&pWb35Reg->EP0VM_spin_lock );
+               spin_lock_irq (&pWb35Reg->EP0VM_spin_lock );
                if( pWb35Reg->pRegFirst == NULL )
                        pWb35Reg->pRegFirst = pRegQueue;
                else
                        pWb35Reg->pRegLast->Next = pRegQueue;
                pWb35Reg->pRegLast = pRegQueue;
 
-               OS_SPIN_LOCK_RELEASED ( &pWb35Reg->EP0VM_spin_lock );
+               spin_unlock_irq ( &pWb35Reg->EP0VM_spin_lock );
 
                // Start EP0VM
                Wb35Reg_EP0VM_start(pHwData);
@@ -278,10 +278,10 @@ Wb35Reg_WriteWithCallbackValue( phw_data_t pHwData, u16 RegisterNo, u32 Register
 // FALSE : register not support
 // pRegisterValue : It must be a resident buffer due to asynchronous read register.
 unsigned char
-Wb35Reg_ReadSync(  phw_data_t pHwData,  u16 RegisterNo,   PULONG pRegisterValue )
+Wb35Reg_ReadSync(  phw_data_t pHwData,  u16 RegisterNo,   u32 * pRegisterValue )
 {
        PWB35REG pWb35Reg = &pHwData->Wb35Reg;
-       PULONG  pltmp = pRegisterValue;
+       u32 *   pltmp = pRegisterValue;
        int ret = -1;
 
        // Module shutdown
@@ -327,7 +327,7 @@ Wb35Reg_ReadSync(  phw_data_t pHwData,  u16 RegisterNo,   PULONG pRegisterValue
 // FALSE : register not support
 // pRegisterValue : It must be a resident buffer due to asynchronous read register.
 unsigned char
-Wb35Reg_Read(phw_data_t pHwData, u16 RegisterNo,  PULONG pRegisterValue )
+Wb35Reg_Read(phw_data_t pHwData, u16 RegisterNo,  u32 * pRegisterValue )
 {
        PWB35REG        pWb35Reg = &pHwData->Wb35Reg;
        struct usb_ctrlrequest * dr;
@@ -348,7 +348,7 @@ Wb35Reg_Read(phw_data_t pHwData, u16 RegisterNo,  PULONG pRegisterValue )
                pRegQueue->DIRECT = 0;// read register
                pRegQueue->INDEX = RegisterNo;
                pRegQueue->pBuffer = pRegisterValue;
-               dr = (struct usb_ctrlrequest *)((PUCHAR)pRegQueue + sizeof(REG_QUEUE));
+               dr = (struct usb_ctrlrequest *)((u8 *)pRegQueue + sizeof(REG_QUEUE));
                dr->bRequestType = USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN;
                dr->bRequest = 0x01; // USB or vendor-defined request code, burst mode
                dr->wValue = cpu_to_le16(0x0);
@@ -359,14 +359,14 @@ Wb35Reg_Read(phw_data_t pHwData, u16 RegisterNo,  PULONG pRegisterValue )
                pRegQueue->Next = NULL;
                pRegQueue->pUsbReq = dr;
                pRegQueue->pUrb = pUrb;
-               OS_SPIN_LOCK_ACQUIRED ( &pWb35Reg->EP0VM_spin_lock );
+               spin_lock_irq ( &pWb35Reg->EP0VM_spin_lock );
                if( pWb35Reg->pRegFirst == NULL )
                        pWb35Reg->pRegFirst = pRegQueue;
                else
                        pWb35Reg->pRegLast->Next = pRegQueue;
                pWb35Reg->pRegLast = pRegQueue;
 
-               OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
+               spin_unlock_irq( &pWb35Reg->EP0VM_spin_lock );
 
                // Start EP0VM
                Wb35Reg_EP0VM_start( pHwData );
@@ -399,7 +399,7 @@ Wb35Reg_EP0VM(phw_data_t pHwData )
        PWB35REG        pWb35Reg = &pHwData->Wb35Reg;
        PURB            pUrb;
        struct usb_ctrlrequest *dr;
-       PULONG          pBuffer;
+       u32 *           pBuffer;
        int                     ret = -1;
        PREG_QUEUE      pRegQueue;
 
@@ -411,9 +411,9 @@ Wb35Reg_EP0VM(phw_data_t pHwData )
                goto cleanup;
 
        // Get the register data and send to USB through Irp
-       OS_SPIN_LOCK_ACQUIRED( &pWb35Reg->EP0VM_spin_lock );
+       spin_lock_irq( &pWb35Reg->EP0VM_spin_lock );
        pRegQueue = pWb35Reg->pRegFirst;
-       OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
+       spin_unlock_irq( &pWb35Reg->EP0VM_spin_lock );
 
        if (!pRegQueue)
                goto cleanup;
@@ -429,7 +429,7 @@ Wb35Reg_EP0VM(phw_data_t pHwData )
 
        usb_fill_control_urb( pUrb, pHwData->WbUsb.udev,
                              REG_DIRECTION(pHwData->WbUsb.udev,pRegQueue),
-                             (PUCHAR)dr,pBuffer,cpu_to_le16(dr->wLength),
+                             (u8 *)dr,pBuffer,cpu_to_le16(dr->wLength),
                              Wb35Reg_EP0VM_complete, (void*)pHwData);
 
        pWb35Reg->EP0vm_state = VM_RUNNING;
@@ -468,12 +468,12 @@ Wb35Reg_EP0VM_complete(PURB pUrb)
                OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Reg->RegFireCount );
        } else {
                // Complete to send, remove the URB from the first
-               OS_SPIN_LOCK_ACQUIRED( &pWb35Reg->EP0VM_spin_lock );
+               spin_lock_irq( &pWb35Reg->EP0VM_spin_lock );
                pRegQueue = pWb35Reg->pRegFirst;
                if (pRegQueue == pWb35Reg->pRegLast)
                        pWb35Reg->pRegLast = NULL;
                pWb35Reg->pRegFirst = pWb35Reg->pRegFirst->Next;
-               OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
+               spin_unlock_irq( &pWb35Reg->EP0VM_spin_lock );
 
                if (pWb35Reg->EP0VM_status) {
 #ifdef _PE_REG_DUMP_
@@ -513,7 +513,7 @@ Wb35Reg_destroy(phw_data_t pHwData)
        OS_SLEEP(10000);  // Delay for waiting function enter 940623.1.b
 
        // Release all the data in RegQueue
-       OS_SPIN_LOCK_ACQUIRED( &pWb35Reg->EP0VM_spin_lock );
+       spin_lock_irq( &pWb35Reg->EP0VM_spin_lock );
        pRegQueue = pWb35Reg->pRegFirst;
        while (pRegQueue) {
                if (pRegQueue == pWb35Reg->pRegLast)
@@ -521,7 +521,7 @@ Wb35Reg_destroy(phw_data_t pHwData)
                pWb35Reg->pRegFirst = pWb35Reg->pRegFirst->Next;
 
                pUrb = pRegQueue->pUrb;
-               OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
+               spin_unlock_irq( &pWb35Reg->EP0VM_spin_lock );
                if (pUrb) {
                        usb_free_urb(pUrb);
                        kfree(pRegQueue);
@@ -530,14 +530,11 @@ Wb35Reg_destroy(phw_data_t pHwData)
                        WBDEBUG(("EP0 queue release error\n"));
                        #endif
                }
-               OS_SPIN_LOCK_ACQUIRED( &pWb35Reg->EP0VM_spin_lock );
+               spin_lock_irq( &pWb35Reg->EP0VM_spin_lock );
 
                pRegQueue = pWb35Reg->pRegFirst;
        }
-       OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
-
-       // Free resource
-       OS_SPIN_LOCK_FREE(  &pWb35Reg->EP0VM_spin_lock );
+       spin_unlock_irq( &pWb35Reg->EP0VM_spin_lock );
 }
 
 //====================================================================================
@@ -550,7 +547,7 @@ unsigned char Wb35Reg_initial(phw_data_t pHwData)
        u32 SoftwareSet, VCO_trim, TxVga, Region_ScanInterval;
 
        // Spin lock is acquired for read and write IRP command
-       OS_SPIN_LOCK_ALLOCATE( &pWb35Reg->EP0VM_spin_lock );
+       spin_lock_init( &pWb35Reg->EP0VM_spin_lock );
 
        // Getting RF module type from EEPROM ------------------------------------
        Wb35Reg_WriteSync( pHwData, 0x03b4, 0x080d0000 ); // Start EEPROM access + Read + address(0x0d)
@@ -655,7 +652,7 @@ unsigned char Wb35Reg_initial(phw_data_t pHwData)
 //    version in _GENREQ.ASM of the DWB NE1000/2000 driver.
 //==================================================================================
 u32
-CardComputeCrc(PUCHAR Buffer, u32 Length)
+CardComputeCrc(u8 * Buffer, u32 Length)
 {
     u32 Crc, Carry;
     u32  i, j;
index 38e2906b51a7d04785d7ae89c8c0bacc11ce632d..3006cfe99ccdd53447214ee89950dca4d893a24f 100644 (file)
@@ -29,16 +29,16 @@ void EEPROMTxVgaAdjust(  phw_data_t pHwData ); // 20060619.5 Add
 
 void Wb35Reg_destroy(  phw_data_t pHwData );
 
-unsigned char Wb35Reg_Read(  phw_data_t pHwData,  u16 RegisterNo,   PULONG pRegisterValue );
-unsigned char Wb35Reg_ReadSync(  phw_data_t pHwData,  u16 RegisterNo,   PULONG pRegisterValue );
+unsigned char Wb35Reg_Read(  phw_data_t pHwData,  u16 RegisterNo,   u32 * pRegisterValue );
+unsigned char Wb35Reg_ReadSync(  phw_data_t pHwData,  u16 RegisterNo,   u32 * pRegisterValue );
 unsigned char Wb35Reg_Write(  phw_data_t pHwData,  u16 RegisterNo,  u32 RegisterValue );
 unsigned char Wb35Reg_WriteSync(  phw_data_t pHwData,  u16 RegisterNo,  u32 RegisterValue );
 unsigned char Wb35Reg_WriteWithCallbackValue(  phw_data_t pHwData,
                                                                 u16 RegisterNo,
                                                                 u32 RegisterValue,
-                                                                PCHAR pValue,
-                                                                s8     Len);
-unsigned char Wb35Reg_BurstWrite(  phw_data_t pHwData,  u16 RegisterNo,  PULONG pRegisterData,  u8 NumberOfData,  u8 Flag );
+                                                                s8 *pValue,
+                                                                s8 Len);
+unsigned char Wb35Reg_BurstWrite(  phw_data_t pHwData,  u16 RegisterNo,  u32 * pRegisterData,  u8 NumberOfData,  u8 Flag );
 
 void Wb35Reg_EP0VM(  phw_data_t pHwData );
 void Wb35Reg_EP0VM_start(  phw_data_t pHwData );
@@ -47,7 +47,7 @@ void Wb35Reg_EP0VM_complete(  PURB pUrb );
 u32 BitReverse( u32 dwData, u32 DataLength);
 
 void CardGetMulticastBit(   u8 Address[MAC_ADDR_LENGTH],  u8 *Byte,  u8 *Value );
-u32 CardComputeCrc(  PUCHAR Buffer,  u32 Length );
+u32 CardComputeCrc(  u8 * Buffer,  u32 Length );
 
 void Wb35Reg_phy_calibration(  phw_data_t pHwData );
 void Wb35Reg_Update(  phw_data_t pHwData,  u16 RegisterNo,  u32 RegisterValue );
index a7595b1e73368ddcb743237065f323a5f92eecbb..8b35b93f7f0256f5119fbb37a35ff0aeab25fb40 100644 (file)
@@ -75,7 +75,7 @@ typedef struct _REG_QUEUE
        union
        {
                u32     VALUE;
-               PULONG  pBuffer;
+               u32 *   pBuffer;
        };
        u8      RESERVED[4];// space reserved for communication
 
@@ -143,7 +143,7 @@ typedef struct _WB35REG
        //-------------------
        // VM
        //-------------------
-       OS_SPIN_LOCK    EP0VM_spin_lock; // 4B
+       spinlock_t      EP0VM_spin_lock; // 4B
        u32             EP0VM_status;//$$
        PREG_QUEUE          pRegFirst;
        PREG_QUEUE          pRegLast;
index 26157eb3d5a29fa49860967ccee36fd081c4bf7a..b4b9f5f371d9691fbf4ca7955285f98eee49f1b3 100644 (file)
@@ -27,7 +27,7 @@ void Wb35Rx_start(phw_data_t pHwData)
 void Wb35Rx(  phw_data_t pHwData )
 {
        PWB35RX pWb35Rx = &pHwData->Wb35Rx;
-       PUCHAR  pRxBufferAddress;
+       u8 *    pRxBufferAddress;
        PURB    pUrb = (PURB)pWb35Rx->RxUrb;
        int     retv;
        u32     RxBufferId;
@@ -35,51 +35,50 @@ void Wb35Rx(  phw_data_t pHwData )
        //
        // Issuing URB
        //
-       do {
-               if (pHwData->SurpriseRemove || pHwData->HwStop)
-                       break;
+       if (pHwData->SurpriseRemove || pHwData->HwStop)
+               goto error;
 
-               if (pWb35Rx->rx_halt)
-                       break;
+       if (pWb35Rx->rx_halt)
+               goto error;
 
-               // Get RxBuffer's ID
-               RxBufferId = pWb35Rx->RxBufferId;
-               if (!pWb35Rx->RxOwner[RxBufferId]) {
-                       // It's impossible to run here.
-                       #ifdef _PE_RX_DUMP_
-                       WBDEBUG(("Rx driver fifo unavailable\n"));
-                       #endif
-                       break;
-               }
+       // Get RxBuffer's ID
+       RxBufferId = pWb35Rx->RxBufferId;
+       if (!pWb35Rx->RxOwner[RxBufferId]) {
+               // It's impossible to run here.
+               #ifdef _PE_RX_DUMP_
+               WBDEBUG(("Rx driver fifo unavailable\n"));
+               #endif
+               goto error;
+       }
 
-               // Update buffer point, then start to bulkin the data from USB
-               pWb35Rx->RxBufferId++;
-               pWb35Rx->RxBufferId %= MAX_USB_RX_BUFFER_NUMBER;
+       // Update buffer point, then start to bulkin the data from USB
+       pWb35Rx->RxBufferId++;
+       pWb35Rx->RxBufferId %= MAX_USB_RX_BUFFER_NUMBER;
 
-               pWb35Rx->CurrentRxBufferId = RxBufferId;
+       pWb35Rx->CurrentRxBufferId = RxBufferId;
 
-               if (1 != OS_MEMORY_ALLOC((void* *)&pWb35Rx->pDRx, MAX_USB_RX_BUFFER)) {
-                       printk("w35und: Rx memory alloc failed\n");
-                       break;
-               }
-               pRxBufferAddress = pWb35Rx->pDRx;
+       if (1 != OS_MEMORY_ALLOC((void* *)&pWb35Rx->pDRx, MAX_USB_RX_BUFFER)) {
+               printk("w35und: Rx memory alloc failed\n");
+               goto error;
+       }
+       pRxBufferAddress = pWb35Rx->pDRx;
 
-               usb_fill_bulk_urb(pUrb, pHwData->WbUsb.udev,
-                                 usb_rcvbulkpipe(pHwData->WbUsb.udev, 3),
-                                 pRxBufferAddress, MAX_USB_RX_BUFFER,
-                                 Wb35Rx_Complete, pHwData);
+       usb_fill_bulk_urb(pUrb, pHwData->WbUsb.udev,
+                         usb_rcvbulkpipe(pHwData->WbUsb.udev, 3),
+                         pRxBufferAddress, MAX_USB_RX_BUFFER,
+                         Wb35Rx_Complete, pHwData);
 
-               pWb35Rx->EP3vm_state = VM_RUNNING;
+       pWb35Rx->EP3vm_state = VM_RUNNING;
 
-               retv = wb_usb_submit_urb(pUrb);
+       retv = wb_usb_submit_urb(pUrb);
 
-               if (retv != 0) {
-                       printk("Rx URB sending error\n");
-                       break;
-               }
-               return;
-       } while(FALSE);
+       if (retv != 0) {
+               printk("Rx URB sending error\n");
+               goto error;
+       }
+       return;
 
+error:
        // VM stop
        pWb35Rx->EP3vm_state = VM_STOP;
        OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Rx->RxFireCounter );
@@ -89,7 +88,7 @@ void Wb35Rx_Complete(PURB pUrb)
 {
        phw_data_t      pHwData = pUrb->context;
        PWB35RX         pWb35Rx = &pHwData->Wb35Rx;
-       PUCHAR          pRxBufferAddress;
+       u8 *            pRxBufferAddress;
        u32             SizeCheck;
        u16             BulkLength;
        u32             RxBufferId;
@@ -99,65 +98,63 @@ void Wb35Rx_Complete(PURB pUrb)
        pWb35Rx->EP3vm_state = VM_COMPLETED;
        pWb35Rx->EP3VM_status = pUrb->status;//Store the last result of Irp
 
-       do {
-               RxBufferId = pWb35Rx->CurrentRxBufferId;
+       RxBufferId = pWb35Rx->CurrentRxBufferId;
 
-               pRxBufferAddress = pWb35Rx->pDRx;
-               BulkLength = (u16)pUrb->actual_length;
+       pRxBufferAddress = pWb35Rx->pDRx;
+       BulkLength = (u16)pUrb->actual_length;
 
-               // The IRP is completed
-               pWb35Rx->EP3vm_state = VM_COMPLETED;
+       // The IRP is completed
+       pWb35Rx->EP3vm_state = VM_COMPLETED;
 
-               if (pHwData->SurpriseRemove || pHwData->HwStop) // Must be here, or RxBufferId is invalid
-                       break;
+       if (pHwData->SurpriseRemove || pHwData->HwStop) // Must be here, or RxBufferId is invalid
+               goto error;
 
-               if (pWb35Rx->rx_halt)
-                       break;
+       if (pWb35Rx->rx_halt)
+               goto error;
 
-               // Start to process the data only in successful condition
-               pWb35Rx->RxOwner[ RxBufferId ] = 0; // Set the owner to driver
-               R00.value = le32_to_cpu(*(PULONG)pRxBufferAddress);
+       // Start to process the data only in successful condition
+       pWb35Rx->RxOwner[ RxBufferId ] = 0; // Set the owner to driver
+       R00.value = le32_to_cpu(*(u32 *)pRxBufferAddress);
 
-               // The URB is completed, check the result
-               if (pWb35Rx->EP3VM_status != 0) {
-                       #ifdef _PE_USB_STATE_DUMP_
-                       WBDEBUG(("EP3 IoCompleteRoutine return error\n"));
-                       DebugUsbdStatusInformation( pWb35Rx->EP3VM_status );
-                       #endif
-                       pWb35Rx->EP3vm_state = VM_STOP;
-                       break;
-               }
+       // The URB is completed, check the result
+       if (pWb35Rx->EP3VM_status != 0) {
+               #ifdef _PE_USB_STATE_DUMP_
+               WBDEBUG(("EP3 IoCompleteRoutine return error\n"));
+               DebugUsbdStatusInformation( pWb35Rx->EP3VM_status );
+               #endif
+               pWb35Rx->EP3vm_state = VM_STOP;
+               goto error;
+       }
 
-               // 20060220 For recovering. check if operating in single USB mode
-               if (!HAL_USB_MODE_BURST(pHwData)) {
-                       SizeCheck = R00.R00_receive_byte_count;  //20060926 anson's endian
-                       if ((SizeCheck & 0x03) > 0)
-                               SizeCheck -= 4;
-                       SizeCheck = (SizeCheck + 3) & ~0x03;
-                       SizeCheck += 12; // 8 + 4 badbeef
-                       if ((BulkLength > 1600) ||
-                               (SizeCheck > 1600) ||
-                               (BulkLength != SizeCheck) ||
-                               (BulkLength == 0)) { // Add for fail Urb
-                               pWb35Rx->EP3vm_state = VM_STOP;
-                               pWb35Rx->Ep3ErrorCount2++;
-                       }
+       // 20060220 For recovering. check if operating in single USB mode
+       if (!HAL_USB_MODE_BURST(pHwData)) {
+               SizeCheck = R00.R00_receive_byte_count;  //20060926 anson's endian
+               if ((SizeCheck & 0x03) > 0)
+                       SizeCheck -= 4;
+               SizeCheck = (SizeCheck + 3) & ~0x03;
+               SizeCheck += 12; // 8 + 4 badbeef
+               if ((BulkLength > 1600) ||
+                       (SizeCheck > 1600) ||
+                       (BulkLength != SizeCheck) ||
+                       (BulkLength == 0)) { // Add for fail Urb
+                       pWb35Rx->EP3vm_state = VM_STOP;
+                       pWb35Rx->Ep3ErrorCount2++;
                }
+       }
 
-               // Indicating the receiving data
-               pWb35Rx->ByteReceived += BulkLength;
-               pWb35Rx->RxBufferSize[ RxBufferId ] = BulkLength;
-
-               if (!pWb35Rx->RxOwner[ RxBufferId ])
-                       Wb35Rx_indicate(pHwData);
+       // Indicating the receiving data
+       pWb35Rx->ByteReceived += BulkLength;
+       pWb35Rx->RxBufferSize[ RxBufferId ] = BulkLength;
 
-               kfree(pWb35Rx->pDRx);
-               // Do the next receive
-               Wb35Rx(pHwData);
-               return;
+       if (!pWb35Rx->RxOwner[ RxBufferId ])
+               Wb35Rx_indicate(pHwData);
 
-       } while(FALSE);
+       kfree(pWb35Rx->pDRx);
+       // Do the next receive
+       Wb35Rx(pHwData);
+       return;
 
+error:
        pWb35Rx->RxOwner[ RxBufferId ] = 1; // Set the owner to hardware
        OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Rx->RxFireCounter );
        pWb35Rx->EP3vm_state = VM_STOP;
@@ -223,7 +220,7 @@ void Wb35Rx_reset_descriptor(  phw_data_t pHwData )
 
 void Wb35Rx_adjust(PDESCRIPTOR pRxDes)
 {
-       PULONG  pRxBufferAddress;
+       u32 *   pRxBufferAddress;
        u32     DecryptionMethod;
        u32     i;
        u16     BufferSize;
@@ -264,7 +261,7 @@ u16 Wb35Rx_indicate(phw_data_t pHwData)
 {
        DESCRIPTOR      RxDes;
        PWB35RX pWb35Rx = &pHwData->Wb35Rx;
-       PUCHAR          pRxBufferAddress;
+       u8 *            pRxBufferAddress;
        u16             PacketSize;
        u16             stmp, BufferSize, stmp2 = 0;
        u32             RxBufferId;
@@ -283,13 +280,13 @@ u16 Wb35Rx_indicate(phw_data_t pHwData)
 
                // Parse the bulkin buffer
                while (BufferSize >= 4) {
-                       if ((cpu_to_le32(*(PULONG)pRxBufferAddress) & 0x0fffffff) == RX_END_TAG) //Is ending? 921002.9.a
+                       if ((cpu_to_le32(*(u32 *)pRxBufferAddress) & 0x0fffffff) == RX_END_TAG) //Is ending? 921002.9.a
                                break;
 
                        // Get the R00 R01 first
-                       RxDes.R00.value = le32_to_cpu(*(PULONG)pRxBufferAddress);
+                       RxDes.R00.value = le32_to_cpu(*(u32 *)pRxBufferAddress);
                        PacketSize = (u16)RxDes.R00.R00_receive_byte_count;
-                       RxDes.R01.value = le32_to_cpu(*((PULONG)(pRxBufferAddress+4)));
+                       RxDes.R01.value = le32_to_cpu(*((u32 *)(pRxBufferAddress+4)));
                        // For new DMA 4k
                        if ((PacketSize & 0x03) > 0)
                                PacketSize -= 4;
index 53b831fdeb78f590ca0b68ae877dc33f58d56f53..b90c269e6adb5bff6698f4f188a401d0d72fa300 100644 (file)
@@ -41,7 +41,7 @@ typedef struct _WB35RX
        u32             Ep3ErrorCount2; // 20060625.1 Usbd for Rx DMA error count
 
        int             EP3VM_status;
-       PUCHAR  pDRx;
+       u8 *    pDRx;
 
 } WB35RX, *PWB35RX;
 
index cf19c3bc524a7b72c7d6e1c2cec4c837b8ed463c..ba9d51244e29797c30570a0da72e3083e006cd54 100644 (file)
@@ -12,7 +12,7 @@
 
 
 unsigned char
-Wb35Tx_get_tx_buffer(phw_data_t pHwData, PUCHAR *pBuffer )
+Wb35Tx_get_tx_buffer(phw_data_t pHwData, u8 **pBuffer)
 {
        PWB35TX pWb35Tx = &pHwData->Wb35Tx;
 
@@ -37,7 +37,7 @@ void Wb35Tx(phw_data_t pHwData)
 {
        PWB35TX         pWb35Tx = &pHwData->Wb35Tx;
        PADAPTER        Adapter = pHwData->Adapter;
-       PUCHAR          pTxBufferAddress;
+       u8              *pTxBufferAddress;
        PMDS            pMds = &Adapter->Mds;
        struct urb *    pUrb = (struct urb *)pWb35Tx->Tx4Urb;
        int             retv;
@@ -100,25 +100,24 @@ void Wb35Tx_complete(struct urb * pUrb)
        pWb35Tx->TxSendIndex++;
        pWb35Tx->TxSendIndex %= MAX_USB_TX_BUFFER_NUMBER;
 
-       do {
-               if (pHwData->SurpriseRemove || pHwData->HwStop) // Let WbWlanHalt to handle surprise remove
-                       break;
+       if (pHwData->SurpriseRemove || pHwData->HwStop) // Let WbWlanHalt to handle surprise remove
+               goto error;
 
-               if (pWb35Tx->tx_halt)
-                       break;
+       if (pWb35Tx->tx_halt)
+               goto error;
 
-               // The URB is completed, check the result
-               if (pWb35Tx->EP4VM_status != 0) {
-                       printk("URB submission failed\n");
-                       pWb35Tx->EP4vm_state = VM_STOP;
-                       break; // Exit while(FALSE);
-               }
+       // The URB is completed, check the result
+       if (pWb35Tx->EP4VM_status != 0) {
+               printk("URB submission failed\n");
+               pWb35Tx->EP4vm_state = VM_STOP;
+               goto error;
+       }
 
-               Mds_Tx(Adapter);
-               Wb35Tx(pHwData);
-               return;
-       } while(FALSE);
+       Mds_Tx(Adapter);
+       Wb35Tx(pHwData);
+       return;
 
+error:
        OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxFireCounter );
        pWb35Tx->EP4vm_state = VM_STOP;
 }
@@ -225,36 +224,33 @@ void Wb35Tx_EP2VM(phw_data_t pHwData)
 {
        PWB35TX pWb35Tx = &pHwData->Wb35Tx;
        struct urb *    pUrb = (struct urb *)pWb35Tx->Tx2Urb;
-       PULONG  pltmp = (PULONG)pWb35Tx->EP2_buf;
+       u32 *   pltmp = (u32 *)pWb35Tx->EP2_buf;
        int             retv;
 
-       do {
-               if (pHwData->SurpriseRemove || pHwData->HwStop)
-                       break;
-
-               if (pWb35Tx->tx_halt)
-                       break;
-
-               //
-               // Issuing URB
-               //
-               usb_fill_int_urb( pUrb, pHwData->WbUsb.udev, usb_rcvintpipe(pHwData->WbUsb.udev,2),
-                                 pltmp, MAX_INTERRUPT_LENGTH, Wb35Tx_EP2VM_complete, pHwData, 32);
+       if (pHwData->SurpriseRemove || pHwData->HwStop)
+               goto error;
 
-               pWb35Tx->EP2vm_state = VM_RUNNING;
-               retv = wb_usb_submit_urb( pUrb );
+       if (pWb35Tx->tx_halt)
+               goto error;
 
-               if(retv < 0) {
-                       #ifdef _PE_TX_DUMP_
-                       WBDEBUG(("EP2 Tx Irp sending error\n"));
-                       #endif
-                       break;
-               }
+       //
+       // Issuing URB
+       //
+       usb_fill_int_urb( pUrb, pHwData->WbUsb.udev, usb_rcvintpipe(pHwData->WbUsb.udev,2),
+                         pltmp, MAX_INTERRUPT_LENGTH, Wb35Tx_EP2VM_complete, pHwData, 32);
 
-               return;
+       pWb35Tx->EP2vm_state = VM_RUNNING;
+       retv = wb_usb_submit_urb( pUrb );
 
-       } while(FALSE);
+       if (retv < 0) {
+               #ifdef _PE_TX_DUMP_
+               WBDEBUG(("EP2 Tx Irp sending error\n"));
+               #endif
+               goto error;
+       }
 
+       return;
+error:
        pWb35Tx->EP2vm_state = VM_STOP;
        OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxResultCount );
 }
@@ -266,7 +262,7 @@ void Wb35Tx_EP2VM_complete(struct urb * pUrb)
        T02_DESCRIPTOR  T02, TSTATUS;
        PADAPTER        Adapter = (PADAPTER)pHwData->Adapter;
        PWB35TX         pWb35Tx = &pHwData->Wb35Tx;
-       PULONG          pltmp = (PULONG)pWb35Tx->EP2_buf;
+       u32 *           pltmp = (u32 *)pWb35Tx->EP2_buf;
        u32             i;
        u16             InterruptInLength;
 
@@ -275,38 +271,36 @@ void Wb35Tx_EP2VM_complete(struct urb * pUrb)
        pWb35Tx->EP2vm_state = VM_COMPLETED;
        pWb35Tx->EP2VM_status = pUrb->status;
 
-       do {
-               // For Linux 2.4. Interrupt will always trigger
-               if( pHwData->SurpriseRemove || pHwData->HwStop ) // Let WbWlanHalt to handle surprise remove
-                       break;
-
-               if( pWb35Tx->tx_halt )
-                       break;
-
-               //The Urb is completed, check the result
-               if (pWb35Tx->EP2VM_status != 0) {
-                       WBDEBUG(("EP2 IoCompleteRoutine return error\n"));
-                       pWb35Tx->EP2vm_state= VM_STOP;
-                       break; // Exit while(FALSE);
-               }
-
-               // Update the Tx result
-               InterruptInLength = pUrb->actual_length;
-               // Modify for minimum memory access and DWORD alignment.
-               T02.value = cpu_to_le32(pltmp[0]) >> 8; // [31:8] -> [24:0]
-               InterruptInLength -= 1;// 20051221.1.c Modify the follow for more stable
-               InterruptInLength >>= 2; // InterruptInLength/4
-               for (i=1; i<=InterruptInLength; i++) {
-                       T02.value |= ((cpu_to_le32(pltmp[i]) & 0xff) << 24);
-
-                       TSTATUS.value = T02.value;  //20061009 anson's endian
-                       Mds_SendComplete( Adapter, &TSTATUS );
-                       T02.value = cpu_to_le32(pltmp[i]) >> 8;
-               }
-
-               return;
-       } while(FALSE);
+       // For Linux 2.4. Interrupt will always trigger
+       if (pHwData->SurpriseRemove || pHwData->HwStop) // Let WbWlanHalt to handle surprise remove
+               goto error;
+
+       if (pWb35Tx->tx_halt)
+               goto error;
+
+       //The Urb is completed, check the result
+       if (pWb35Tx->EP2VM_status != 0) {
+               WBDEBUG(("EP2 IoCompleteRoutine return error\n"));
+               pWb35Tx->EP2vm_state= VM_STOP;
+               goto error;
+       }
 
+       // Update the Tx result
+       InterruptInLength = pUrb->actual_length;
+       // Modify for minimum memory access and DWORD alignment.
+       T02.value = cpu_to_le32(pltmp[0]) >> 8; // [31:8] -> [24:0]
+       InterruptInLength -= 1;// 20051221.1.c Modify the follow for more stable
+       InterruptInLength >>= 2; // InterruptInLength/4
+       for (i = 1; i <= InterruptInLength; i++) {
+               T02.value |= ((cpu_to_le32(pltmp[i]) & 0xff) << 24);
+
+               TSTATUS.value = T02.value;  //20061009 anson's endian
+               Mds_SendComplete( Adapter, &TSTATUS );
+               T02.value = cpu_to_le32(pltmp[i]) >> 8;
+       }
+
+       return;
+error:
        OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxResultCount );
        pWb35Tx->EP2vm_state = VM_STOP;
 }
index 7705a8454dcbbc2db79b67ef957b0cc7cefc3e19..107b12918137ad726e99be9ea06bab91d771aa3e 100644 (file)
@@ -3,7 +3,7 @@
 //====================================
 unsigned char Wb35Tx_initial(   phw_data_t pHwData );
 void Wb35Tx_destroy(  phw_data_t pHwData );
-unsigned char Wb35Tx_get_tx_buffer(  phw_data_t pHwData,  PUCHAR *pBuffer );
+unsigned char Wb35Tx_get_tx_buffer(  phw_data_t pHwData,  u8 **pBuffer );
 
 void Wb35Tx_EP2VM(  phw_data_t pHwData );
 void Wb35Tx_EP2VM_start(  phw_data_t pHwData );
index cbad5fb0595980081eabd4407cbe70408421eb6e..f4a7875f2389673d146c7d840be4383156eb6a9c 100644 (file)
@@ -6,42 +6,29 @@
 #include "sysdef.h"
 #include <net/mac80211.h>
 
-
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 MODULE_VERSION("0.1");
 
-
-//============================================================
-// vendor ID and product ID can into here for others
-//============================================================
-static struct usb_device_id Id_Table[] =
-{
-  {USB_DEVICE( 0x0416, 0x0035 )},
-  {USB_DEVICE( 0x18E8, 0x6201 )},
-  {USB_DEVICE( 0x18E8, 0x6206 )},
-  {USB_DEVICE( 0x18E8, 0x6217 )},
-  {USB_DEVICE( 0x18E8, 0x6230 )},
-  {USB_DEVICE( 0x18E8, 0x6233 )},
-  {USB_DEVICE( 0x1131, 0x2035 )},
-  {  }
+static struct usb_device_id wb35_table[] __devinitdata = {
+       {USB_DEVICE(0x0416, 0x0035)},
+       {USB_DEVICE(0x18E8, 0x6201)},
+       {USB_DEVICE(0x18E8, 0x6206)},
+       {USB_DEVICE(0x18E8, 0x6217)},
+       {USB_DEVICE(0x18E8, 0x6230)},
+       {USB_DEVICE(0x18E8, 0x6233)},
+       {USB_DEVICE(0x1131, 0x2035)},
+       { 0, }
 };
 
-MODULE_DEVICE_TABLE(usb, Id_Table);
+MODULE_DEVICE_TABLE(usb, wb35_table);
 
-static struct usb_driver wb35_driver = {
-       .name =         "w35und",
-       .probe =        wb35_probe,
-       .disconnect = wb35_disconnect,
-       .id_table = Id_Table,
-};
-
-static const struct ieee80211_rate wbsoft_rates[] = {
+static struct ieee80211_rate wbsoft_rates[] = {
        { .bitrate = 10, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
 };
 
-static const struct ieee80211_channel wbsoft_channels[] = {
+static struct ieee80211_channel wbsoft_channels[] = {
        { .center_freq = 2412},
 };
 
@@ -62,9 +49,22 @@ static void wbsoft_remove_interface(struct ieee80211_hw *dev,
        printk("wbsoft_remove interface called\n");
 }
 
-static int wbsoft_nop(void)
+static void wbsoft_stop(struct ieee80211_hw *hw)
+{
+       printk(KERN_INFO "%s called\n", __func__);
+}
+
+static int wbsoft_get_stats(struct ieee80211_hw *hw,
+                           struct ieee80211_low_level_stats *stats)
 {
-       printk("wbsoft_nop called\n");
+       printk(KERN_INFO "%s called\n", __func__);
+       return 0;
+}
+
+static int wbsoft_get_tx_stats(struct ieee80211_hw *hw,
+                              struct ieee80211_tx_queue_stats *stats)
+{
+       printk(KERN_INFO "%s called\n", __func__);
        return 0;
 }
 
@@ -105,8 +105,7 @@ static void wbsoft_configure_filter(struct ieee80211_hw *dev,
        *total_flags = new_flags;
 }
 
-static int wbsoft_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
-                     struct ieee80211_tx_control *control)
+static int wbsoft_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
        char *buffer = kmalloc(skb->len, GFP_ATOMIC);
        printk("Sending frame %d bytes\n", skb->len);
@@ -136,7 +135,7 @@ static int wbsoft_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
        hal_set_current_channel(&my_adapter->sHwData, ch);
        hal_set_beacon_period(&my_adapter->sHwData, conf->beacon_int);
 //     hal_set_cap_info(&my_adapter->sHwData, ?? );
-// hal_set_ssid(phw_data_t pHwData,  PUCHAR pssid,  u8 ssid_len); ??
+// hal_set_ssid(phw_data_t pHwData,  u8 * pssid,  u8 ssid_len); ??
        hal_set_accept_broadcast(&my_adapter->sHwData, 1);
        hal_set_accept_promiscuous(&my_adapter->sHwData,  1);
        hal_set_accept_multicast(&my_adapter->sHwData,  1);
@@ -148,7 +147,7 @@ static int wbsoft_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
 
 //     hal_start_bss(&my_adapter->sHwData, WLAN_BSSTYPE_INFRASTRUCTURE);       ??
 
-//void hal_set_rates(phw_data_t pHwData, PUCHAR pbss_rates,
+//void hal_set_rates(phw_data_t pHwData, u8 * pbss_rates,
 //                u8 length, unsigned char basic_rate_set)
 
        return 0;
@@ -171,14 +170,14 @@ static u64 wbsoft_get_tsf(struct ieee80211_hw *dev)
 static const struct ieee80211_ops wbsoft_ops = {
        .tx                     = wbsoft_tx,
        .start                  = wbsoft_start,         /* Start can be pretty much empty as we do WbWLanInitialize() during probe? */
-       .stop                   = wbsoft_nop,
+       .stop                   = wbsoft_stop,
        .add_interface          = wbsoft_add_interface,
        .remove_interface       = wbsoft_remove_interface,
        .config                 = wbsoft_config,
        .config_interface       = wbsoft_config_interface,
        .configure_filter       = wbsoft_configure_filter,
-       .get_stats              = wbsoft_nop,
-       .get_tx_stats           = wbsoft_nop,
+       .get_stats              = wbsoft_get_stats,
+       .get_tx_stats           = wbsoft_get_tx_stats,
        .get_tsf                = wbsoft_get_tsf,
 // conf_tx: hal_set_cwmin()/hal_set_cwmax;
 };
@@ -187,21 +186,6 @@ struct wbsoft_priv {
 };
 
 
-int __init wb35_init(void)
-{
-       printk("[w35und]driver init\n");
-       return usb_register(&wb35_driver);
-}
-
-void __exit wb35_exit(void)
-{
-       printk("[w35und]driver exit\n");
-       usb_deregister( &wb35_driver );
-}
-
-module_init(wb35_init);
-module_exit(wb35_exit);
-
 // Usb kernel subsystem will call this function when a new device is plugged into.
 int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id_table)
 {
@@ -210,7 +194,7 @@ int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id_table)
        PWBUSB          pWbUsb;
         struct usb_host_interface *interface;
        struct usb_endpoint_descriptor *endpoint;
-       int     i, ret = -1;
+       int     ret = -1;
        u32     ltmp;
        struct usb_device *udev = interface_to_usbdev(intf);
 
@@ -218,114 +202,95 @@ int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id_table)
 
        printk("[w35und]wb35_probe ->\n");
 
-       do {
-               for (i=0; i<(sizeof(Id_Table)/sizeof(struct usb_device_id)); i++ ) {
-                       if ((udev->descriptor.idVendor == Id_Table[i].idVendor) &&
-                               (udev->descriptor.idProduct == Id_Table[i].idProduct)) {
-                               printk("[w35und]Found supported hardware\n");
-                               break;
-                       }
-               }
-               if ((i == (sizeof(Id_Table)/sizeof(struct usb_device_id)))) {
-                       #ifdef _PE_USB_INI_DUMP_
-                       WBDEBUG(("[w35und] This is not the one we are interested about\n"));
-                       #endif
-                       return -ENODEV;
-               }
-
-               // 20060630.2 Check the device if it already be opened
-               ret = usb_control_msg(udev, usb_rcvctrlpipe( udev, 0 ),
-                                     0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN,
-                                     0x0, 0x400, &ltmp, 4, HZ*100 );
-               if( ret < 0 )
-                       break;
+       // 20060630.2 Check the device if it already be opened
+       ret = usb_control_msg(udev, usb_rcvctrlpipe( udev, 0 ),
+                             0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN,
+                             0x0, 0x400, &ltmp, 4, HZ*100 );
+       if (ret < 0)
+               goto error;
 
-               ltmp = cpu_to_le32(ltmp);
-               if (ltmp)  // Is already initialized?
-                       break;
+       ltmp = cpu_to_le32(ltmp);
+       if (ltmp)  // Is already initialized?
+               goto error;
 
+       Adapter = kzalloc(sizeof(ADAPTER), GFP_KERNEL);
 
-               Adapter = kzalloc(sizeof(ADAPTER), GFP_KERNEL);
+       my_adapter = Adapter;
+       pWbLinux = &Adapter->WbLinux;
+       pWbUsb = &Adapter->sHwData.WbUsb;
+       pWbUsb->udev = udev;
 
-               my_adapter = Adapter;
-               pWbLinux = &Adapter->WbLinux;
-               pWbUsb = &Adapter->sHwData.WbUsb;
-               pWbUsb->udev = udev;
+        interface = intf->cur_altsetting;
+        endpoint = &interface->endpoint[0].desc;
 
-               interface = intf->cur_altsetting;
-               endpoint = &interface->endpoint[0].desc;
-
-               if (endpoint[2].wMaxPacketSize == 512) {
-                       printk("[w35und] Working on USB 2.0\n");
-                       pWbUsb->IsUsb20 = 1;
-               }
-
-               if (!WbWLanInitialize(Adapter)) {
-                       printk("[w35und]WbWLanInitialize fail\n");
-                       break;
-               }
+       if (endpoint[2].wMaxPacketSize == 512) {
+               printk("[w35und] Working on USB 2.0\n");
+               pWbUsb->IsUsb20 = 1;
+       }
 
-               {
-                       struct wbsoft_priv *priv;
-                       struct ieee80211_hw *dev;
-                       int res;
+       if (!WbWLanInitialize(Adapter)) {
+               printk("[w35und]WbWLanInitialize fail\n");
+               goto error;
+       }
 
-                       dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops);
+       {
+               struct wbsoft_priv *priv;
+               struct ieee80211_hw *dev;
+               static struct ieee80211_supported_band band;
+               int res;
 
-                       if (!dev) {
-                               printk("w35und: ieee80211 alloc failed\n" );
-                               BUG();
-                       }
+               dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops);
 
-                       my_dev = dev;
+               if (!dev) {
+                       printk("w35und: ieee80211 alloc failed\n" );
+                       BUG();
+               }
 
-                       SET_IEEE80211_DEV(dev, &udev->dev);
-                       {
-                               phw_data_t pHwData = &Adapter->sHwData;
-                               unsigned char           dev_addr[MAX_ADDR_LEN];
-                               hal_get_permanent_address(pHwData, dev_addr);
-                               SET_IEEE80211_PERM_ADDR(dev, dev_addr);
-                       }
+               my_dev = dev;
 
+               SET_IEEE80211_DEV(dev, &udev->dev);
+               {
+                       phw_data_t pHwData = &Adapter->sHwData;
+                       unsigned char           dev_addr[MAX_ADDR_LEN];
+                       hal_get_permanent_address(pHwData, dev_addr);
+                       SET_IEEE80211_PERM_ADDR(dev, dev_addr);
+               }
 
-                       dev->extra_tx_headroom = 12;    /* FIXME */
-                       dev->flags = 0;
 
-                       dev->channel_change_time = 1000;
-//                     dev->max_rssi = 100;
+               dev->extra_tx_headroom = 12;    /* FIXME */
+               dev->flags = 0;
 
-                       dev->queues = 1;
+               dev->channel_change_time = 1000;
+//             dev->max_rssi = 100;
 
-                       static struct ieee80211_supported_band band;
+               dev->queues = 1;
 
-                       band.channels = wbsoft_channels;
-                       band.n_channels = ARRAY_SIZE(wbsoft_channels);
-                       band.bitrates = wbsoft_rates;
-                       band.n_bitrates = ARRAY_SIZE(wbsoft_rates);
+               band.channels = wbsoft_channels;
+               band.n_channels = ARRAY_SIZE(wbsoft_channels);
+               band.bitrates = wbsoft_rates;
+               band.n_bitrates = ARRAY_SIZE(wbsoft_rates);
 
-                       dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band;
+               dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band;
 #if 0
-                       wbsoft_modes[0].num_channels = 1;
-                       wbsoft_modes[0].channels = wbsoft_channels;
-                       wbsoft_modes[0].mode = MODE_IEEE80211B;
-                       wbsoft_modes[0].num_rates = ARRAY_SIZE(wbsoft_rates);
-                       wbsoft_modes[0].rates = wbsoft_rates;
-
-                       res = ieee80211_register_hwmode(dev, &wbsoft_modes[0]);
-                       BUG_ON(res);
+               wbsoft_modes[0].num_channels = 1;
+               wbsoft_modes[0].channels = wbsoft_channels;
+               wbsoft_modes[0].mode = MODE_IEEE80211B;
+               wbsoft_modes[0].num_rates = ARRAY_SIZE(wbsoft_rates);
+               wbsoft_modes[0].rates = wbsoft_rates;
+
+               res = ieee80211_register_hwmode(dev, &wbsoft_modes[0]);
+               BUG_ON(res);
 #endif
 
-                       res = ieee80211_register_hw(dev);
-                       BUG_ON(res);
-               }
-
-               usb_set_intfdata( intf, Adapter );
-
-               printk("[w35und] _probe OK\n");
-               return 0;
+               res = ieee80211_register_hw(dev);
+               BUG_ON(res);
+       }
 
-       } while(FALSE);
+       usb_set_intfdata( intf, Adapter );
 
+       printk("[w35und] _probe OK\n");
+       return 0;
+error:
        return -ENOMEM;
 }
 
@@ -401,4 +366,22 @@ void wb35_disconnect(struct usb_interface *intf)
 
 }
 
+static struct usb_driver wb35_driver = {
+       .name           = "w35und",
+       .id_table       = wb35_table,
+       .probe          = wb35_probe,
+       .disconnect     = wb35_disconnect,
+};
 
+static int __init wb35_init(void)
+{
+       return usb_register(&wb35_driver);
+}
+
+static void __exit wb35_exit(void)
+{
+       usb_deregister(&wb35_driver);
+}
+
+module_init(wb35_init);
+module_exit(wb35_exit);
index 8ce6389c41359d860d025699903657f220322c2b..f1de813f9c76d567a53f4d04a01480149e373223 100644 (file)
@@ -40,7 +40,7 @@ Mds_Tx(PADAPTER Adapter)
        PMDS            pMds = &Adapter->Mds;
        DESCRIPTOR      TxDes;
        PDESCRIPTOR     pTxDes = &TxDes;
-       PUCHAR          XmitBufAddress;
+       u8              *XmitBufAddress;
        u16             XmitBufSize, PacketSize, stmp, CurrentSize, FragmentThreshold;
        u8              FillIndex, TxDesIndex, FragmentCount, FillCount;
        unsigned char   BufferFilled = FALSE, MICAdd = 0;
@@ -90,7 +90,7 @@ Mds_Tx(PADAPTER Adapter)
                        BufferFilled = TRUE;
 
                        /* Leaves first u8 intact */
-                       memset((PUCHAR)pTxDes + 1, 0, sizeof(DESCRIPTOR) - 1);
+                       memset((u8 *)pTxDes + 1, 0, sizeof(DESCRIPTOR) - 1);
 
                        TxDesIndex = pMds->TxDesIndex;//Get the current ID
                        pTxDes->Descriptor_ID = TxDesIndex;
@@ -229,10 +229,10 @@ Mds_SendComplete(PADAPTER Adapter, PT02_DESCRIPTOR pT02)
 }
 
 void
-Mds_HeaderCopy(PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer)
+Mds_HeaderCopy(PADAPTER Adapter, PDESCRIPTOR pDes, u8 *TargetBuffer)
 {
        PMDS    pMds = &Adapter->Mds;
-       PUCHAR  src_buffer = pDes->buffer_address[0];//931130.5.g
+       u8      *src_buffer = pDes->buffer_address[0];//931130.5.g
        PT00_DESCRIPTOR pT00;
        PT01_DESCRIPTOR pT01;
        u16     stmp;
@@ -276,7 +276,7 @@ Mds_HeaderCopy(PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer)
        //
        // Set tx rate
        //
-       stmp = *(PUSHORT)(TargetBuffer+30); // 2n alignment address
+       stmp = *(u16 *)(TargetBuffer+30); // 2n alignment address
 
        //Use basic rate
        ctmp1 = ctmpf = CURRENT_TX_RATE_FOR_MNG;
@@ -326,11 +326,13 @@ Mds_HeaderCopy(PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer)
 
 // The function return the 4n size of usb pk
 u16
-Mds_BodyCopy(PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer)
+Mds_BodyCopy(PADAPTER Adapter, PDESCRIPTOR pDes, u8 *TargetBuffer)
 {
        PT00_DESCRIPTOR pT00;
        PMDS    pMds = &Adapter->Mds;
-       PUCHAR  buffer, src_buffer, pctmp;
+       u8      *buffer;
+       u8      *src_buffer;
+       u8      *pctmp;
        u16     Size = 0;
        u16     SizeLeft, CopySize, CopyLeft, stmp;
        u8      buf_index, FragmentCount = 0;
@@ -354,7 +356,7 @@ Mds_BodyCopy(PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer)
                SizeLeft -= CopySize;
 
                // 1 Byte operation
-               pctmp = (PUCHAR)( buffer + 8 + DOT_11_SEQUENCE_OFFSET );
+               pctmp = (u8 *)( buffer + 8 + DOT_11_SEQUENCE_OFFSET );
                *pctmp &= 0xf0;
                *pctmp |= FragmentCount;//931130.5.m
                if( !FragmentCount )
@@ -379,7 +381,7 @@ Mds_BodyCopy(PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer)
                                buf_index++;
                                buf_index %= MAX_DESCRIPTOR_BUFFER_INDEX;
                        } else {
-                               PUCHAR  pctmp = pDes->buffer_address[buf_index];
+                               u8      *pctmp = pDes->buffer_address[buf_index];
                                pctmp += CopySize;
                                pDes->buffer_address[buf_index] = pctmp;
                                pDes->buffer_size[buf_index] -= CopySize;
@@ -419,7 +421,7 @@ Mds_BodyCopy(PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer)
 
        pT00->T00_last_mpdu = 1;
        pT00->T00_IsLastMpdu = 1;
-       buffer = (PUCHAR)pT00 + 8; // +8 for USB hdr
+       buffer = (u8 *)pT00 + 8; // +8 for USB hdr
        buffer[1] &= ~0x04; // Clear more frag bit of 802.11 frame control
        pDes->FragmentCount = FragmentCount; // Update the correct fragment number
        return Size;
@@ -427,7 +429,7 @@ Mds_BodyCopy(PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer)
 
 
 void
-Mds_DurationSet(  PADAPTER Adapter,  PDESCRIPTOR pDes,  PUCHAR buffer )
+Mds_DurationSet(  PADAPTER Adapter,  PDESCRIPTOR pDes,  u8 *buffer )
 {
        PT00_DESCRIPTOR pT00;
        PT01_DESCRIPTOR pT01;
@@ -435,7 +437,7 @@ Mds_DurationSet(  PADAPTER Adapter,  PDESCRIPTOR pDes,  PUCHAR buffer )
        u8      Rate, i;
        unsigned char   CTS_on = FALSE, RTS_on = FALSE;
        PT00_DESCRIPTOR pNextT00;
-       u16 BodyLen;
+       u16 BodyLen = 0;
        unsigned char boGroupAddr = FALSE;
 
 
@@ -574,7 +576,7 @@ Mds_DurationSet(  PADAPTER Adapter,  PDESCRIPTOR pDes,  PUCHAR buffer )
                                                        DEFAULT_SIFSTIME*3 );
                        }
 
-                       ((PUSHORT)buffer)[5] = cpu_to_le16(Duration);// 4 USHOR for skip 8B USB, 2USHORT=FC + Duration
+                       ((u16 *)buffer)[5] = cpu_to_le16(Duration);// 4 USHOR for skip 8B USB, 2USHORT=FC + Duration
 
                        //----20061009 add by anson's endian
                        pNextT00->value = cpu_to_le32(pNextT00->value);
@@ -615,7 +617,7 @@ Mds_DurationSet(  PADAPTER Adapter,  PDESCRIPTOR pDes,  PUCHAR buffer )
                }
        }
 
-       ((PUSHORT)buffer)[5] = cpu_to_le16(Duration);// 4 USHOR for skip 8B USB, 2USHORT=FC + Duration
+       ((u16 *)buffer)[5] = cpu_to_le16(Duration);// 4 USHOR for skip 8B USB, 2USHORT=FC + Duration
        pT00->value = cpu_to_le32(pT00->value);
        pT01->value = cpu_to_le32(pT01->value);
        //--end 20061009 add
index 651188be106510799b7e64d6f363e12ba3116d80..7a682d4cfbdc5af76dcee01aef0e96c81418aadb 100644 (file)
@@ -1,9 +1,9 @@
 unsigned char Mds_initial(  PADAPTER Adapter );
 void Mds_Destroy(  PADAPTER Adapter );
 void Mds_Tx(  PADAPTER Adapter );
-void Mds_HeaderCopy(  PADAPTER Adapter,  PDESCRIPTOR pDes,  PUCHAR TargetBuffer );
-u16 Mds_BodyCopy(  PADAPTER Adapter,  PDESCRIPTOR pDes,  PUCHAR TargetBuffer );
-void Mds_DurationSet(  PADAPTER Adapter,  PDESCRIPTOR pDes,  PUCHAR TargetBuffer );
+void Mds_HeaderCopy(  PADAPTER Adapter,  PDESCRIPTOR pDes,  u8 *TargetBuffer );
+u16 Mds_BodyCopy(  PADAPTER Adapter,  PDESCRIPTOR pDes,  u8 *TargetBuffer );
+void Mds_DurationSet(  PADAPTER Adapter,  PDESCRIPTOR pDes,  u8 *TargetBuffer );
 void Mds_SendComplete(  PADAPTER Adapter,  PT02_DESCRIPTOR pT02 );
 void Mds_MpduProcess(  PADAPTER Adapter,  PDESCRIPTOR pRxDes );
 void Mds_reset_descriptor(  PADAPTER Adapter );
index 4738279d5f39b32645c155dbc6d98ae54721d440..9df2e0936bf822843c155de817838a9b89e27b28 100644 (file)
@@ -86,7 +86,7 @@ typedef struct _MDS
 {
        // For Tx usage
        u8      TxOwner[ ((MAX_USB_TX_BUFFER_NUMBER + 3) & ~0x03) ];
-       PUCHAR  pTxBuffer;
+       u8      *pTxBuffer;
        u16     TxBufferSize[ ((MAX_USB_TX_BUFFER_NUMBER + 1) & ~0x01) ];
        u8      TxDesFrom[ ((MAX_USB_TX_DESCRIPTOR + 3) & ~0x03) ];//931130.4.u // 1: MLME 2: NDIS control 3: NDIS data
        u8      TxCountInBuffer[ ((MAX_USB_TX_DESCRIPTOR + 3) & ~0x03) ]; // 20060928
@@ -103,7 +103,7 @@ typedef struct _MDS
        u16     TxResult[ ((MAX_USB_TX_DESCRIPTOR + 1) & ~0x01) ];//Collect the sending result of Mpdu
 
        u8      MicRedundant[8]; // For tmp use
-       PUCHAR  MicWriteAddress[2]; //The start address to fill the Mic, use 2 point due to Mic maybe fragment
+       u8      *MicWriteAddress[2]; //The start address to fill the Mic, use 2 point due to Mic maybe fragment
 
        u16     MicWriteSize[2]; //931130.4.x
 
@@ -144,7 +144,7 @@ typedef struct _MDS
 
 typedef struct _RxBuffer
 {
-    PUCHAR  pBufferAddress;     // Pointer the received data buffer.
+    u8 * pBufferAddress;     // Pointer the received data buffer.
        u16     BufferSize;
        u8      RESERVED;
        u8      BufferIndex;// Only 1 byte
@@ -176,7 +176,7 @@ typedef struct _RXLAYER1
        /////////////////////////////////////////////////////////////////////////////////////////////
        // For brand-new Rx system
        u8      ReservedBuffer[ 2400 ];//If Buffer ID is reserved one, it must copy the data into this area
-       PUCHAR  ReservedBufferPoint;// Point to the next availabe address of reserved buffer
+       u8      *ReservedBufferPoint;// Point to the next availabe address of reserved buffer
 
 }RXLAYER1, * PRXLAYER1;
 
index 58094f61c032dfa17b0ec4eac1a529b6785835cf..039fd408ba62c7ae6680412910d04f5b72aba1d6 100644 (file)
 typedef struct _MLME_FRAME
 {
        //NDIS_PACKET           MLME_Packet;
-       PCHAR                   pMMPDU;
+       s8 *                    pMMPDU;
        u16                     len;
        u8                      DataType;
        u8                      IsInUsed;
 
-       OS_SPIN_LOCK    MLMESpinLock;
+       spinlock_t      MLMESpinLock;
 
     u8         TxMMPDU[MAX_NUM_TX_MMPDU][MAX_MMPDU_SIZE];
        u8              TxMMPDUInUse[ (MAX_NUM_TX_MMPDU+3) & ~0x03 ];
index 46b091e96794af332f6d1abea6f14856171116af..e8533b8d1976a99c80863dd499661462066878fd 100644 (file)
@@ -113,13 +113,13 @@ MLME_GetNextPacket(PADAPTER Adapter, PDESCRIPTOR pDes)
        pDes->Type = Adapter->sMlmeFrame.DataType;
 }
 
-void MLMEfreeMMPDUBuffer(PWB32_ADAPTER Adapter, PCHAR pData)
+void MLMEfreeMMPDUBuffer(PWB32_ADAPTER Adapter, s8 *pData)
 {
        int i;
 
        // Reclaim the data buffer
        for (i = 0; i < MAX_NUM_TX_MMPDU; i++) {
-               if (pData == (PCHAR)&(Adapter->sMlmeFrame.TxMMPDU[i]))
+               if (pData == (s8 *)&(Adapter->sMlmeFrame.TxMMPDU[i]))
                        break;
        }
        if (Adapter->sMlmeFrame.TxMMPDUInUse[i])
index d74e225be215362436ef70de1a77d0f310148a68..24cd5f308d9f8e45d62b9ffdac04676b81dea19e 100644 (file)
@@ -20,7 +20,7 @@ MLMEGetMMPDUBuffer(
      PWB32_ADAPTER    Adapter
    );
 
-void MLMEfreeMMPDUBuffer( PWB32_ADAPTER Adapter,  PCHAR pData);
+void MLMEfreeMMPDUBuffer( PWB32_ADAPTER Adapter,  s8 * pData);
 
 void MLME_GetNextPacket(  PADAPTER Adapter,  PDESCRIPTOR pDes );
 u8 MLMESendFrame( PWB32_ADAPTER Adapter,
@@ -42,7 +42,7 @@ MLMERcvFrame(
 void
 MLMEReturnPacket(
      PWB32_ADAPTER    Adapter,
-     PUCHAR           pRxBufer
+     u8 *          pRxBufer
    );
 #ifdef _IBSS_BEACON_SEQ_STICK_
 s8 SendBCNullData(PWB32_ADAPTER Adapter, u16 wIdx);
index b475c7a7c42412cd3f8ea2f7553ea9081085ee8a..57af5b831509054491d15ca8ab73d728404378b6 100644 (file)
@@ -922,16 +922,16 @@ Uxx_ReadEthernetAddress(  phw_data_t pHwData )
        // Only unplug and plug again can make hardware read EEPROM again. 20060727
        Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08000000 ); // Start EEPROM access + Read + address(0x0d)
        Wb35Reg_ReadSync( pHwData, 0x03b4, &ltmp );
-       *(PUSHORT)pHwData->PermanentMacAddress = cpu_to_le16((u16)ltmp); //20060926 anson's endian
+       *(u16 *)pHwData->PermanentMacAddress = cpu_to_le16((u16)ltmp); //20060926 anson's endian
        Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08010000 ); // Start EEPROM access + Read + address(0x0d)
        Wb35Reg_ReadSync( pHwData, 0x03b4, &ltmp );
-       *(PUSHORT)(pHwData->PermanentMacAddress + 2) = cpu_to_le16((u16)ltmp); //20060926 anson's endian
+       *(u16 *)(pHwData->PermanentMacAddress + 2) = cpu_to_le16((u16)ltmp); //20060926 anson's endian
        Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08020000 ); // Start EEPROM access + Read + address(0x0d)
        Wb35Reg_ReadSync( pHwData, 0x03b4, &ltmp );
-       *(PUSHORT)(pHwData->PermanentMacAddress + 4) = cpu_to_le16((u16)ltmp); //20060926 anson's endian
-       *(PUSHORT)(pHwData->PermanentMacAddress + 6) = 0;
-       Wb35Reg_WriteSync( pHwData, 0x03e8, cpu_to_le32(*(PULONG)pHwData->PermanentMacAddress) ); //20060926 anson's endian
-       Wb35Reg_WriteSync( pHwData, 0x03ec, cpu_to_le32(*(PULONG)(pHwData->PermanentMacAddress+4)) ); //20060926 anson's endian
+       *(u16 *)(pHwData->PermanentMacAddress + 4) = cpu_to_le16((u16)ltmp); //20060926 anson's endian
+       *(u16 *)(pHwData->PermanentMacAddress + 6) = 0;
+       Wb35Reg_WriteSync( pHwData, 0x03e8, cpu_to_le32(*(u32 *)pHwData->PermanentMacAddress) ); //20060926 anson's endian
+       Wb35Reg_WriteSync( pHwData, 0x03ec, cpu_to_le32(*(u32 *)(pHwData->PermanentMacAddress+4)) ); //20060926 anson's endian
 }
 
 
@@ -1038,7 +1038,7 @@ void
 RFSynthesizer_initial(phw_data_t pHwData)
 {
        u32     altmp[32];
-       PULONG  pltmp = altmp;
+       u32 *   pltmp = altmp;
        u32     ltmp;
        u8      number=0x00; // The number of register vale
        u8      i;
@@ -2358,11 +2358,11 @@ void Mxx_initial(  phw_data_t pHwData )
        pltmp[2] = pWb35Reg->M2C_MacControl;
 
        // M30 BSSID
-       pltmp[3] = *(PULONG)pHwData->bssid;
+       pltmp[3] = *(u32 *)pHwData->bssid;
 
        // M34
        pHwData->AID = DEFAULT_AID;
-       tmp = *(PUSHORT)(pHwData->bssid+4);
+       tmp = *(u16 *)(pHwData->bssid+4);
        tmp |= DEFAULT_AID << 16;
        pltmp[4] = tmp;
 
@@ -2428,7 +2428,7 @@ void GetTxVgaFromEEPROM(  phw_data_t pHwData )
 {
        u32             i, j, ltmp;
        u16             Value[MAX_TXVGA_EEPROM];
-       PUCHAR          pctmp;
+       u8              *pctmp;
        u8              ctmp=0;
 
        // Get the entire TxVga setting in EEPROM
@@ -2441,7 +2441,7 @@ void GetTxVgaFromEEPROM(  phw_data_t pHwData )
        }
 
        // Adjust the filed which fills with reserved value.
-       pctmp = (PUCHAR)Value;
+       pctmp = (u8 *)Value;
        for( i=0; i<(MAX_TXVGA_EEPROM*2); i++ )
        {
                if( pctmp[i] != 0xff )
@@ -2480,7 +2480,7 @@ void GetTxVgaFromEEPROM(  phw_data_t pHwData )
 // This function will use default TxVgaSettingInEEPROM data to calculate new TxVga.
 void EEPROMTxVgaAdjust(  phw_data_t pHwData ) // 20060619.5 Add
 {
-       PUCHAR          pTxVga = pHwData->TxVgaSettingInEEPROM;
+       u8      *       pTxVga = pHwData->TxVgaSettingInEEPROM;
        s16             i, stmp;
 
        //-- 2.4G -- 20060704.2 Request from Tiger
index 40e93b7600ebad5ec3edd093c89dd6c8a8bbf5c8..31c9673ea86534da5df804519c35be88d957e85c 100644 (file)
@@ -10,4 +10,5 @@
 s8 sme_get_rssi(void *pcore_data, s32 *prssi)
 {
        BUG();
+       return 0;
 }
index 016b225ca4a4c2e4e9b9335079dc20eb12939ea1..745eb376bc70dfc31d7a067999901a437d00b543 100644 (file)
@@ -208,7 +208,7 @@ s8 sme_set_tx_antenna(void *pcore_data, u32 TxAntenna);
 s8 sme_set_IBSS_chan(void *pcore_data, ChanInfo chan);
 
 //20061108 WPS
-s8 sme_set_IE_append(void *pcore_data, PUCHAR buffer, u16 buf_len);
+s8 sme_set_IE_append(void *pcore_data, u8 *buffer, u16 buf_len);
 
 
 
index daf44224755881f2d594168a43a456bf970d0880..5d68ecec34c77004c741bb23fa8d8ce88f381cd2 100644 (file)
@@ -1,13 +1,13 @@
 #include "os_common.h"
 
-void hal_get_ethernet_address( phw_data_t pHwData, PUCHAR current_address )
+void hal_get_ethernet_address( phw_data_t pHwData, u8 *current_address )
 {
        if( pHwData->SurpriseRemove ) return;
 
        memcpy( current_address, pHwData->CurrentMacAddress, ETH_LENGTH_OF_ADDRESS );
 }
 
-void hal_set_ethernet_address( phw_data_t pHwData, PUCHAR current_address )
+void hal_set_ethernet_address( phw_data_t pHwData, u8 *current_address )
 {
        u32 ltmp[2];
 
@@ -15,13 +15,13 @@ void hal_set_ethernet_address( phw_data_t pHwData, PUCHAR current_address )
 
        memcpy( pHwData->CurrentMacAddress, current_address, ETH_LENGTH_OF_ADDRESS );
 
-       ltmp[0]= cpu_to_le32( *(PULONG)pHwData->CurrentMacAddress );
-       ltmp[1]= cpu_to_le32( *(PULONG)(pHwData->CurrentMacAddress + 4) ) & 0xffff;
+       ltmp[0]= cpu_to_le32( *(u32 *)pHwData->CurrentMacAddress );
+       ltmp[1]= cpu_to_le32( *(u32 *)(pHwData->CurrentMacAddress + 4) ) & 0xffff;
 
        Wb35Reg_BurstWrite( pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT );
 }
 
-void hal_get_permanent_address( phw_data_t pHwData, PUCHAR pethernet_address )
+void hal_get_permanent_address( phw_data_t pHwData, u8 *pethernet_address )
 {
        if( pHwData->SurpriseRemove ) return;
 
@@ -89,7 +89,7 @@ void hal_halt(phw_data_t pHwData, void *ppa_data)
 }
 
 //---------------------------------------------------------------------------------------------------
-void hal_set_rates(phw_data_t pHwData, PUCHAR pbss_rates,
+void hal_set_rates(phw_data_t pHwData, u8 *pbss_rates,
                   u8 length, unsigned char basic_rate_set)
 {
        PWB35REG        pWb35Reg = &pHwData->Wb35Reg;
@@ -158,13 +158,13 @@ void hal_set_rates(phw_data_t pHwData, PUCHAR pbss_rates,
        // Fill data into support rate until buffer full
        //---20060926 add by anson's endian
        for (i=0; i<4; i++)
-               *(PULONG)(SupportedRate+(i<<2)) = cpu_to_le32( *(PULONG)(SupportedRate+(i<<2)) );
+               *(u32 *)(SupportedRate+(i<<2)) = cpu_to_le32( *(u32 *)(SupportedRate+(i<<2)) );
        //--- end 20060926 add by anson's endian
-       Wb35Reg_BurstWrite( pHwData,0x087c, (PULONG)SupportedRate, 4, AUTO_INCREMENT );
-       pWb35Reg->M7C_MacControl = ((PULONG)SupportedRate)[0];
-       pWb35Reg->M80_MacControl = ((PULONG)SupportedRate)[1];
-       pWb35Reg->M84_MacControl = ((PULONG)SupportedRate)[2];
-       pWb35Reg->M88_MacControl = ((PULONG)SupportedRate)[3];
+       Wb35Reg_BurstWrite( pHwData,0x087c, (u32 *)SupportedRate, 4, AUTO_INCREMENT );
+       pWb35Reg->M7C_MacControl = ((u32 *)SupportedRate)[0];
+       pWb35Reg->M80_MacControl = ((u32 *)SupportedRate)[1];
+       pWb35Reg->M84_MacControl = ((u32 *)SupportedRate)[2];
+       pWb35Reg->M88_MacControl = ((u32 *)SupportedRate)[3];
 
        // Fill length
        tmp = Count1<<28 | Count2<<24;
@@ -206,7 +206,7 @@ void hal_set_current_channel_ex(  phw_data_t pHwData,  ChanInfo channel )
        pWb35Reg->M28_MacControl &= ~0xff; // Clean channel information field
        pWb35Reg->M28_MacControl |= channel.ChanNo;
        Wb35Reg_WriteWithCallbackValue( pHwData, 0x0828, pWb35Reg->M28_MacControl,
-                                       (PCHAR)&channel, sizeof(ChanInfo));
+                                       (s8 *)&channel, sizeof(ChanInfo));
 }
 //---------------------------------------------------------------------------------------------------
 void hal_set_current_channel(  phw_data_t pHwData,  ChanInfo channel )
@@ -277,7 +277,7 @@ void hal_set_accept_beacon(  phw_data_t pHwData,  u8 enable )
        Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl );
 }
 //---------------------------------------------------------------------------------------------------
-void hal_set_multicast_address( phw_data_t pHwData, PUCHAR address, u8 number )
+void hal_set_multicast_address( phw_data_t pHwData, u8 *address, u8 number )
 {
        PWB35REG        pWb35Reg = &pHwData->Wb35Reg;
        u8              Byte, Bit;
@@ -297,7 +297,7 @@ void hal_set_multicast_address( phw_data_t pHwData, PUCHAR address, u8 number )
        }
 
        // Updating register
-       Wb35Reg_BurstWrite( pHwData, 0x0804, (PULONG)pWb35Reg->Multicast, 2, AUTO_INCREMENT );
+       Wb35Reg_BurstWrite( pHwData, 0x0804, (u32 *)pWb35Reg->Multicast, 2, AUTO_INCREMENT );
 }
 //---------------------------------------------------------------------------------------------------
 u8 hal_get_accept_beacon(  phw_data_t pHwData )
@@ -806,7 +806,7 @@ u8 hal_get_hw_radio_off(  phw_data_t pHwData )
        }
 }
 
-unsigned char hal_get_dxx_reg(  phw_data_t pHwData,  u16 number,  PULONG pValue )
+unsigned char hal_get_dxx_reg(  phw_data_t pHwData,  u16 number,  u32 * pValue )
 {
        if( number < 0x1000 )
                number += 0x1000;
index fe25f97af7242ade9717874c6698422593b4a730..ea9531ac8474c27a1260eb0c4a4165376bea6433 100644 (file)
 //====================================================================================
 // Function declaration
 //====================================================================================
-void hal_remove_mapping_key(  phw_data_t pHwData,  PUCHAR pmac_addr );
+void hal_remove_mapping_key(  phw_data_t pHwData,  u8 *pmac_addr );
 void hal_remove_default_key(  phw_data_t pHwData,  u32 index );
-unsigned char hal_set_mapping_key(  phw_data_t Adapter,  PUCHAR pmac_addr,  u8 null_key,  u8 wep_on,  PUCHAR ptx_tsc,  PUCHAR prx_tsc,  u8 key_type,  u8 key_len,  PUCHAR pkey_data );
-unsigned char hal_set_default_key(  phw_data_t Adapter,  u8 index,  u8 null_key,  u8 wep_on,  PUCHAR ptx_tsc,  PUCHAR prx_tsc,  u8 key_type,  u8 key_len,  PUCHAR pkey_data );
+unsigned char hal_set_mapping_key(  phw_data_t Adapter,  u8 *pmac_addr,  u8 null_key,  u8 wep_on,  u8 *ptx_tsc,  u8 *prx_tsc,  u8 key_type,  u8 key_len,  u8 *pkey_data );
+unsigned char hal_set_default_key(  phw_data_t Adapter,  u8 index,  u8 null_key,  u8 wep_on,  u8 *ptx_tsc,  u8 *prx_tsc,  u8 key_type,  u8 key_len,  u8 *pkey_data );
 void hal_clear_all_default_key(  phw_data_t pHwData );
 void hal_clear_all_group_key(  phw_data_t pHwData );
 void hal_clear_all_mapping_key(  phw_data_t pHwData );
 void hal_clear_all_key(  phw_data_t pHwData );
-void hal_get_ethernet_address(  phw_data_t pHwData,  PUCHAR current_address );
-void hal_set_ethernet_address(  phw_data_t pHwData,  PUCHAR current_address );
-void hal_get_permanent_address(  phw_data_t pHwData,  PUCHAR pethernet_address );
+void hal_get_ethernet_address(  phw_data_t pHwData,  u8 *current_address );
+void hal_set_ethernet_address(  phw_data_t pHwData,  u8 *current_address );
+void hal_get_permanent_address(  phw_data_t pHwData,  u8 *pethernet_address );
 unsigned char hal_init_hardware(  phw_data_t pHwData,  PADAPTER Adapter );
 void hal_set_power_save_mode(  phw_data_t pHwData,  unsigned char power_save,  unsigned char wakeup,  unsigned char dtim );
-void hal_get_power_save_mode(  phw_data_t pHwData,   PBOOLEAN pin_pwr_save );
+void hal_get_power_save_mode(  phw_data_t pHwData,   u8 *pin_pwr_save );
 void hal_set_slot_time(  phw_data_t pHwData,  u8 type );
 #define hal_set_atim_window( _A, _ATM )
-void hal_set_rates(  phw_data_t pHwData,  PUCHAR pbss_rates,  u8 length,  unsigned char basic_rate_set );
+void hal_set_rates(  phw_data_t pHwData,  u8 *pbss_rates,  u8 length,  unsigned char basic_rate_set );
 #define hal_set_basic_rates( _A, _R, _L ) hal_set_rates( _A, _R, _L, TRUE )
 #define hal_set_op_rates( _A, _R, _L ) hal_set_rates( _A, _R, _L, FALSE )
 void hal_start_bss(  phw_data_t pHwData,  u8 mac_op_mode );
@@ -40,19 +40,19 @@ void hal_join_request(  phw_data_t pHwData,  u8 bss_type ); // 0:BSS STA 1:IBSS
 void hal_stop_sync_bss(  phw_data_t pHwData );
 void hal_resume_sync_bss(  phw_data_t pHwData);
 void hal_set_aid(  phw_data_t pHwData,  u16 aid );
-void hal_set_bssid(  phw_data_t pHwData,  PUCHAR pbssid );
-void hal_get_bssid(  phw_data_t pHwData,  PUCHAR pbssid );
+void hal_set_bssid(  phw_data_t pHwData,  u8 *pbssid );
+void hal_get_bssid(  phw_data_t pHwData,  u8 *pbssid );
 void hal_set_beacon_period(  phw_data_t pHwData,  u16 beacon_period );
 void hal_set_listen_interval(  phw_data_t pHwData,  u16 listen_interval );
 void hal_set_cap_info(  phw_data_t pHwData,  u16 capability_info );
-void hal_set_ssid(  phw_data_t pHwData,  PUCHAR pssid,  u8 ssid_len );
+void hal_set_ssid(  phw_data_t pHwData,  u8 *pssid,  u8 ssid_len );
 void hal_set_current_channel(  phw_data_t pHwData,  ChanInfo channel );
 void hal_set_current_channel_ex(  phw_data_t pHwData,  ChanInfo channel );
 void hal_get_current_channel(  phw_data_t pHwData,  ChanInfo *channel );
 void hal_set_accept_broadcast(  phw_data_t pHwData,  u8 enable );
 void hal_set_accept_multicast(  phw_data_t pHwData,  u8 enable );
 void hal_set_accept_beacon(  phw_data_t pHwData,  u8 enable );
-void hal_set_multicast_address(  phw_data_t pHwData,  PUCHAR address,  u8 number );
+void hal_set_multicast_address(  phw_data_t pHwData,  u8 *address,  u8 number );
 u8 hal_get_accept_beacon(  phw_data_t pHwData );
 void hal_stop(  phw_data_t pHwData );
 void hal_halt(  phw_data_t pHwData, void *ppa_data );
@@ -97,7 +97,7 @@ void hal_surprise_remove(  phw_data_t pHwData );
 
 
 void hal_rate_change(  phw_data_t pHwData ); // Notify the HAL rate is changing 20060613.1
-unsigned char hal_get_dxx_reg(  phw_data_t pHwData,  u16 number,  PULONG pValue );
+unsigned char hal_get_dxx_reg(  phw_data_t pHwData,  u16 number,  u32 * pValue );
 unsigned char hal_set_dxx_reg(  phw_data_t pHwData,  u16 number,  u32 value );
 #define hal_get_time_count( _P )       (_P->time_count/10)     // return 100ms count
 #define hal_detect_error( _P )         (_P->WbUsb.DetectCount)
@@ -116,7 +116,7 @@ unsigned char       hal_idle(  phw_data_t pHwData );
 #define pa_stall_execution( _A )       //OS_SLEEP( 1 )
 #define hw_get_cxx_reg( _A, _B, _C )
 #define hw_set_cxx_reg( _A, _B, _C )
-#define hw_get_dxx_reg( _A, _B, _C )   hal_get_dxx_reg( _A, _B, (PULONG)_C )
+#define hw_get_dxx_reg( _A, _B, _C )   hal_get_dxx_reg( _A, _B, (u32 *)_C )
 #define hw_set_dxx_reg( _A, _B, _C )   hal_set_dxx_reg( _A, _B, (u32)_C )
 
 
index 5b862ff357bdbcf4144943621acdf278edb647ea..2ee3f0fc1ad84cfc756945ff28b1bdf93252ea11 100644 (file)
@@ -461,7 +461,7 @@ typedef struct _HW_DATA_T
        //=====================================================================
        // Definition for 802.11
        //=====================================================================
-       PUCHAR  bssid_pointer; // Used by hal_get_bssid for return value
+       u8      *bssid_pointer; // Used by hal_get_bssid for return value
        u8      bssid[8];// Only 6 byte will be used. 8 byte is required for read buffer
        u8      ssid[32];// maximum ssid length is 32 byte
 
@@ -486,7 +486,7 @@ typedef struct _HW_DATA_T
        u32     CurrentRadioSw; // 20060320.2 0:On 1:Off
        u32     CurrentRadioHw; // 20060825 0:On 1:Off
 
-       PUCHAR  power_save_point;  // Used by hal_get_power_save_mode for return value
+       u8      *power_save_point;  // Used by hal_get_power_save_mode for return value
        u8      cwmin;
        u8      desired_power_save;
        u8      dtim;// Is running dtim
index 2eade5a47b198aa61e671b1085b7fde258f5e4c4..4ed45e48831871c494eea1dfac594143fa230794 100644 (file)
@@ -25,11 +25,11 @@ EncapAtomicInc(PADAPTER Adapter, void* pAtomic)
 {
        PWBLINUX pWbLinux = &Adapter->WbLinux;
        u32     ltmp;
-       PULONG  pltmp = (PULONG)pAtomic;
-       OS_SPIN_LOCK_ACQUIRED( &pWbLinux->AtomicSpinLock );
+       u32 *   pltmp = (u32 *)pAtomic;
+       spin_lock_irq( &pWbLinux->AtomicSpinLock );
        (*pltmp)++;
        ltmp = (*pltmp);
-       OS_SPIN_LOCK_RELEASED( &pWbLinux->AtomicSpinLock );
+       spin_unlock_irq( &pWbLinux->AtomicSpinLock );
        return ltmp;
 }
 
@@ -38,11 +38,11 @@ EncapAtomicDec(PADAPTER Adapter, void* pAtomic)
 {
        PWBLINUX pWbLinux = &Adapter->WbLinux;
        u32     ltmp;
-       PULONG  pltmp = (PULONG)pAtomic;
-       OS_SPIN_LOCK_ACQUIRED( &pWbLinux->AtomicSpinLock );
+       u32 *   pltmp = (u32 *)pAtomic;
+       spin_lock_irq( &pWbLinux->AtomicSpinLock );
        (*pltmp)--;
        ltmp = (*pltmp);
-       OS_SPIN_LOCK_RELEASED( &pWbLinux->AtomicSpinLock );
+       spin_unlock_irq( &pWbLinux->AtomicSpinLock );
        return ltmp;
 }
 
@@ -51,8 +51,8 @@ WBLINUX_Initial(PADAPTER Adapter)
 {
        PWBLINUX pWbLinux = &Adapter->WbLinux;
 
-       OS_SPIN_LOCK_ALLOCATE( &pWbLinux->SpinLock );
-       OS_SPIN_LOCK_ALLOCATE( &pWbLinux->AtomicSpinLock );
+       spin_lock_init( &pWbLinux->SpinLock );
+       spin_lock_init( &pWbLinux->AtomicSpinLock );
        return TRUE;
 }
 
@@ -79,7 +79,6 @@ void
 WBLINUX_Destroy(PADAPTER Adapter)
 {
        WBLINUX_stop( Adapter );
-       OS_SPIN_LOCK_FREE( &pWbNdis->SpinLock );
 #ifdef _PE_USB_INI_DUMP_
        WBDEBUG(("[w35und] unregister_netdev!\n"));
 #endif
@@ -142,119 +141,118 @@ unsigned char
 WbWLanInitialize(PADAPTER Adapter)
 {
        phw_data_t      pHwData;
-       PUCHAR          pMacAddr, pMacAddr2;
+       u8              *pMacAddr;
+       u8              *pMacAddr2;
        u32             InitStep = 0;
        u8              EEPROM_region;
        u8              HwRadioOff;
 
-       do {
-               //
-               // Setting default value for Linux
-               //
-               Adapter->sLocalPara.region_INF = REGION_AUTO;
-               Adapter->sLocalPara.TxRateMode = RATE_AUTO;
-               psLOCAL->bMacOperationMode = MODE_802_11_BG;    // B/G mode
-               Adapter->Mds.TxRTSThreshold = DEFAULT_RTSThreshold;
-               Adapter->Mds.TxFragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
-               hal_set_phy_type( &Adapter->sHwData, RF_WB_242_1 );
-               Adapter->sLocalPara.MTUsize = MAX_ETHERNET_PACKET_SIZE;
-               psLOCAL->bPreambleMode = AUTO_MODE;
-               Adapter->sLocalPara.RadioOffStatus.boSwRadioOff = FALSE;
-               pHwData = &Adapter->sHwData;
-               hal_set_phy_type( pHwData, RF_DECIDE_BY_INF );
-
-               //
-               // Initial each module and variable
-               //
-               if (!WBLINUX_Initial(Adapter)) {
+       //
+       // Setting default value for Linux
+       //
+       Adapter->sLocalPara.region_INF = REGION_AUTO;
+       Adapter->sLocalPara.TxRateMode = RATE_AUTO;
+       psLOCAL->bMacOperationMode = MODE_802_11_BG;    // B/G mode
+       Adapter->Mds.TxRTSThreshold = DEFAULT_RTSThreshold;
+       Adapter->Mds.TxFragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
+       hal_set_phy_type( &Adapter->sHwData, RF_WB_242_1 );
+       Adapter->sLocalPara.MTUsize = MAX_ETHERNET_PACKET_SIZE;
+       psLOCAL->bPreambleMode = AUTO_MODE;
+       Adapter->sLocalPara.RadioOffStatus.boSwRadioOff = FALSE;
+       pHwData = &Adapter->sHwData;
+       hal_set_phy_type( pHwData, RF_DECIDE_BY_INF );
+
+       //
+       // Initial each module and variable
+       //
+       if (!WBLINUX_Initial(Adapter)) {
 #ifdef _PE_USB_INI_DUMP_
-                       WBDEBUG(("[w35und]WBNDIS initialization failed\n"));
+               WBDEBUG(("[w35und]WBNDIS initialization failed\n"));
 #endif
-                       break;
-               }
+               goto error;
+       }
 
-               // Initial Software variable
-               Adapter->sLocalPara.ShutDowned = FALSE;
-
-               //added by ws for wep key error detection
-               Adapter->sLocalPara.bWepKeyError= FALSE;
-               Adapter->sLocalPara.bToSelfPacketReceived = FALSE;
-               Adapter->sLocalPara.WepKeyDetectTimerCount= 2 * 100; /// 2 seconds
-
-               // Initial USB hal
-               InitStep = 1;
-               pHwData = &Adapter->sHwData;
-               if (!hal_init_hardware(pHwData, Adapter))
-                       break;
-
-               EEPROM_region = hal_get_region_from_EEPROM( pHwData );
-               if (EEPROM_region != REGION_AUTO)
-                       psLOCAL->region = EEPROM_region;
-               else {
-                       if (psLOCAL->region_INF != REGION_AUTO)
-                               psLOCAL->region = psLOCAL->region_INF;
-                       else
-                               psLOCAL->region = REGION_USA;   //default setting
-               }
+       // Initial Software variable
+       Adapter->sLocalPara.ShutDowned = FALSE;
+
+       //added by ws for wep key error detection
+       Adapter->sLocalPara.bWepKeyError= FALSE;
+       Adapter->sLocalPara.bToSelfPacketReceived = FALSE;
+       Adapter->sLocalPara.WepKeyDetectTimerCount= 2 * 100; /// 2 seconds
+
+       // Initial USB hal
+       InitStep = 1;
+       pHwData = &Adapter->sHwData;
+       if (!hal_init_hardware(pHwData, Adapter))
+               goto error;
+
+       EEPROM_region = hal_get_region_from_EEPROM( pHwData );
+       if (EEPROM_region != REGION_AUTO)
+               psLOCAL->region = EEPROM_region;
+       else {
+               if (psLOCAL->region_INF != REGION_AUTO)
+                       psLOCAL->region = psLOCAL->region_INF;
+               else
+                       psLOCAL->region = REGION_USA;   //default setting
+       }
 
-               // Get Software setting flag from hal
-               Adapter->sLocalPara.boAntennaDiversity = FALSE;
-               if (hal_software_set(pHwData) & 0x00000001)
-                       Adapter->sLocalPara.boAntennaDiversity = TRUE;
-
-               //
-               // For TS module
-               //
-               InitStep = 2;
-
-               // For MDS module
-               InitStep = 3;
-               Mds_initial(Adapter);
-
-               //=======================================
-               // Initialize the SME, SCAN, MLME, ROAM
-               //=======================================
-               InitStep = 4;
-               InitStep = 5;
-               InitStep = 6;
-
-               // If no user-defined address in the registry, use the addresss "burned" on the NIC instead.
-               pMacAddr = Adapter->sLocalPara.ThisMacAddress;
-               pMacAddr2 = Adapter->sLocalPara.PermanentAddress;
-               hal_get_permanent_address( pHwData, Adapter->sLocalPara.PermanentAddress );// Reading ethernet address from EEPROM
-               if (OS_MEMORY_COMPARE(pMacAddr, "\x00\x00\x00\x00\x00\x00", MAC_ADDR_LENGTH )) // Is equal
-               {
-                       memcpy( pMacAddr, pMacAddr2, MAC_ADDR_LENGTH );
-               } else {
-                       // Set the user define MAC address
-                       hal_set_ethernet_address( pHwData, Adapter->sLocalPara.ThisMacAddress );
-               }
+       // Get Software setting flag from hal
+       Adapter->sLocalPara.boAntennaDiversity = FALSE;
+       if (hal_software_set(pHwData) & 0x00000001)
+               Adapter->sLocalPara.boAntennaDiversity = TRUE;
+
+       //
+       // For TS module
+       //
+       InitStep = 2;
+
+       // For MDS module
+       InitStep = 3;
+       Mds_initial(Adapter);
+
+       //=======================================
+       // Initialize the SME, SCAN, MLME, ROAM
+       //=======================================
+       InitStep = 4;
+       InitStep = 5;
+       InitStep = 6;
+
+       // If no user-defined address in the registry, use the addresss "burned" on the NIC instead.
+       pMacAddr = Adapter->sLocalPara.ThisMacAddress;
+       pMacAddr2 = Adapter->sLocalPara.PermanentAddress;
+       hal_get_permanent_address( pHwData, Adapter->sLocalPara.PermanentAddress );// Reading ethernet address from EEPROM
+       if (OS_MEMORY_COMPARE(pMacAddr, "\x00\x00\x00\x00\x00\x00", MAC_ADDR_LENGTH )) // Is equal
+       {
+               memcpy( pMacAddr, pMacAddr2, MAC_ADDR_LENGTH );
+       } else {
+               // Set the user define MAC address
+               hal_set_ethernet_address( pHwData, Adapter->sLocalPara.ThisMacAddress );
+       }
 
-               //get current antenna
-               psLOCAL->bAntennaNo = hal_get_antenna_number(pHwData);
+       //get current antenna
+       psLOCAL->bAntennaNo = hal_get_antenna_number(pHwData);
 #ifdef _PE_STATE_DUMP_
-               WBDEBUG(("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo));
+       WBDEBUG(("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo));
 #endif
-               hal_get_hw_radio_off( pHwData );
+       hal_get_hw_radio_off( pHwData );
 
-               // Waiting for HAL setting OK
-               while (!hal_idle(pHwData))
-                       OS_SLEEP(10000);
+       // Waiting for HAL setting OK
+       while (!hal_idle(pHwData))
+               OS_SLEEP(10000);
 
-               MTO_Init(Adapter);
+       MTO_Init(Adapter);
 
-               HwRadioOff = hal_get_hw_radio_off( pHwData );
-               psLOCAL->RadioOffStatus.boHwRadioOff = !!HwRadioOff;
+       HwRadioOff = hal_get_hw_radio_off( pHwData );
+       psLOCAL->RadioOffStatus.boHwRadioOff = !!HwRadioOff;
 
-               hal_set_radio_mode( pHwData, (unsigned char)(psLOCAL->RadioOffStatus.boSwRadioOff || psLOCAL->RadioOffStatus.boHwRadioOff) );
+       hal_set_radio_mode( pHwData, (unsigned char)(psLOCAL->RadioOffStatus.boSwRadioOff || psLOCAL->RadioOffStatus.boHwRadioOff) );
 
-               hal_driver_init_OK(pHwData) = 1; // Notify hal that the driver is ready now.
-               //set a tx power for reference.....
-//             sme_set_tx_power_level(Adapter, 12);    FIXME?
-               return TRUE;
-       }
-       while(FALSE);
+       hal_driver_init_OK(pHwData) = 1; // Notify hal that the driver is ready now.
+       //set a tx power for reference.....
+//     sme_set_tx_power_level(Adapter, 12);    FIXME?
+       return TRUE;
 
+error:
        switch (InitStep) {
        case 5:
        case 4:
index 97e9167ab839b65cb095d330b015c9ed96d65990..fd2bb43bf3cf75a4bf41f8e9f69a20ed534b408f 100644 (file)
@@ -24,8 +24,8 @@
 
 typedef struct _WBLINUX
 {
-       OS_SPIN_LOCK    AtomicSpinLock;
-       OS_SPIN_LOCK    SpinLock;
+       spinlock_t      AtomicSpinLock;
+       spinlock_t      SpinLock;
        u32     shutdown;
 
        OS_ATOMIC       ThreadCount;
index 10b1f0f634d374b06742149863e9e7c20956e902..2425d860dcaf674357626d9e2d408437e9f24281 100644 (file)
@@ -1,6 +1,6 @@
 config PRISM2_USB
        tristate "Prism2.5 USB driver"
-       depends on USB
+       depends on WLAN_80211 && USB
        default n
        ---help---
          This is the wlan-ng prism 2.5 USB driver for a wide range of
index a2054639d24bcc2855da75e0293dd3607561a85e..0dfb8ce9aae78afe13f4e534c7101b75e391cd08 100644 (file)
@@ -824,7 +824,7 @@ PD Record codes
 #define                HFA384x_CMD_MACPORT_SET(value)          ((UINT16)HFA384x_CMD_AINFO_SET(value))
 #define                HFA384x_CMD_ISRECL(value)               ((UINT16)(HFA384x_CMD_AINFO_GET((UINT16)(value) & HFA384x_CMD_RECL)))
 #define                HFA384x_CMD_RECL_SET(value)             ((UINT16)HFA384x_CMD_AINFO_SET(value))
-#define                HFA384x_CMD_QOS_GET(value)              ((UINT16((((UINT16)(value))&((UINT16)0x3000)) >> 12))
+#define                HFA384x_CMD_QOS_GET(value)              ((UINT16)((((UINT16)(value))&((UINT16)0x3000)) >> 12))
 #define                HFA384x_CMD_QOS_SET(value)              ((UINT16)((((UINT16)(value)) << 12) & 0x3000))
 #define                HFA384x_CMD_ISWRITE(value)              ((UINT16)(HFA384x_CMD_AINFO_GET((UINT16)(value) & HFA384x_CMD_WRITE)))
 #define                HFA384x_CMD_WRITE_SET(value)            ((UINT16)HFA384x_CMD_AINFO_SET((UINT16)value))
index 53fe2985971f1dbba9090a9052d905f430aee865..11a50c7fbfc8c470e11dd35eeebfb5bacdd855f2 100644 (file)
@@ -64,7 +64,6 @@
 /*================================================================*/
 /* Project Includes */
 
-#include "version.h"
 #include "p80211hdr.h"
 #include "p80211types.h"
 #include "p80211msg.h"
index 268fd9bba1efb0fb3d92888c3c7f296ec7cc1de9..eac06f793d815b39b9c1d47c57afa018721b7f43 100644 (file)
@@ -90,8 +90,6 @@
 #include <linux/usb.h>
 //#endif
 
-#include "wlan_compat.h"
-
 /*================================================================*/
 /* Project Includes */
 
index 17026570708fda05f9f0e1fdff17000fad3d41ed..59dfa8f84cbea1f971be9ee453a3b3536a27c402 100644 (file)
@@ -245,11 +245,11 @@ typedef int64_t           INT64;
 #  define preempt_count() (0UL)
 #endif
 
-#define WLAN_LOG_ERROR(x,args...) printk(KERN_ERR "%s: " x , __FUNCTION__ , ##args);
+#define WLAN_LOG_ERROR(x,args...) printk(KERN_ERR "%s: " x , __func__ , ##args);
 
-#define WLAN_LOG_WARNING(x,args...) printk(KERN_WARNING "%s: " x , __FUNCTION__ , ##args);
+#define WLAN_LOG_WARNING(x,args...) printk(KERN_WARNING "%s: " x , __func__ , ##args);
 
-#define WLAN_LOG_NOTICE(x,args...) printk(KERN_NOTICE "%s: " x , __FUNCTION__ , ##args);
+#define WLAN_LOG_NOTICE(x,args...) printk(KERN_NOTICE "%s: " x , __func__ , ##args);
 
 #define WLAN_LOG_INFO(args... ) printk(KERN_INFO args)
 
@@ -265,7 +265,7 @@ typedef int64_t             INT64;
        #define DBFENTER { if ( WLAN_DBVAR >= 5 ){ WLAN_LOG_DEBUG(3,"---->\n"); } }
        #define DBFEXIT  { if ( WLAN_DBVAR >= 5 ){ WLAN_LOG_DEBUG(3,"<----\n"); } }
 
-       #define WLAN_LOG_DEBUG(l,x,args...) if ( WLAN_DBVAR >= (l)) printk(KERN_DEBUG "%s(%lu): " x ,  __FUNCTION__, (preempt_count() & PREEMPT_MASK), ##args );
+       #define WLAN_LOG_DEBUG(l,x,args...) if ( WLAN_DBVAR >= (l)) printk(KERN_DEBUG "%s(%lu): " x ,  __func__, (preempt_count() & PREEMPT_MASK), ##args );
 #else
        #define WLAN_ASSERT(c)
        #define WLAN_HEX_DUMP( l, s, p, n)
index 5dccf057a7dd41a5f31f69ec4d5d7982615655ec..f9b4647255aa041fa816612bdcd618bc4ecbabcc 100644 (file)
@@ -47,6 +47,9 @@ static struct uio_class {
        struct class *class;
 } *uio_class;
 
+/* Protect idr accesses */
+static DEFINE_MUTEX(minor_lock);
+
 /*
  * attributes
  */
@@ -239,7 +242,6 @@ static void uio_dev_del_attributes(struct uio_device *idev)
 
 static int uio_get_minor(struct uio_device *idev)
 {
-       static DEFINE_MUTEX(minor_lock);
        int retval = -ENOMEM;
        int id;
 
@@ -261,7 +263,9 @@ exit:
 
 static void uio_free_minor(struct uio_device *idev)
 {
+       mutex_lock(&minor_lock);
        idr_remove(&uio_idr, idev->minor);
+       mutex_unlock(&minor_lock);
 }
 
 /**
@@ -305,8 +309,9 @@ static int uio_open(struct inode *inode, struct file *filep)
        struct uio_listener *listener;
        int ret = 0;
 
-       lock_kernel();
+       mutex_lock(&minor_lock);
        idev = idr_find(&uio_idr, iminor(inode));
+       mutex_unlock(&minor_lock);
        if (!idev) {
                ret = -ENODEV;
                goto out;
@@ -332,18 +337,15 @@ static int uio_open(struct inode *inode, struct file *filep)
                if (ret)
                        goto err_infoopen;
        }
-       unlock_kernel();
        return 0;
 
 err_infoopen:
-
        kfree(listener);
-err_alloc_listener:
 
+err_alloc_listener:
        module_put(idev->owner);
 
 out:
-       unlock_kernel();
        return ret;
 }
 
index bcefbddeba5099877981a1717cfd22edfd35e159..289d81adfb9c7eae11bbbc5bec1a2b2c218bb901 100644 (file)
@@ -36,7 +36,8 @@ config USB_ARCH_HAS_OHCI
        default y if PXA3xx
        default y if ARCH_EP93XX
        default y if ARCH_AT91
-       default y if ARCH_PNX4008
+       default y if ARCH_PNX4008 && I2C
+       default y if MFD_TC6393XB
        # PPC:
        default y if STB03xxx
        default y if PPC_MPC52xx
@@ -97,6 +98,8 @@ source "drivers/usb/core/Kconfig"
 
 source "drivers/usb/mon/Kconfig"
 
+source "drivers/usb/wusbcore/Kconfig"
+
 source "drivers/usb/host/Kconfig"
 
 source "drivers/usb/musb/Kconfig"
index a419c42e880e208f5eec222fff067a7bbe7424c3..8b7c419b876e228439a597fccfc8a2233eafdc03 100644 (file)
@@ -16,9 +16,12 @@ obj-$(CONFIG_USB_UHCI_HCD)   += host/
 obj-$(CONFIG_USB_SL811_HCD)    += host/
 obj-$(CONFIG_USB_U132_HCD)     += host/
 obj-$(CONFIG_USB_R8A66597_HCD) += host/
+obj-$(CONFIG_USB_HWA_HCD)      += host/
 
 obj-$(CONFIG_USB_C67X00_HCD)   += c67x00/
 
+obj-$(CONFIG_USB_WUSB)         += wusbcore/
+
 obj-$(CONFIG_USB_ACM)          += class/
 obj-$(CONFIG_USB_PRINTER)      += class/
 
index 76fce44c2f9ace8a573da9fae2e289cc904c8dc9..3e862401a638e15141460190208270a03aa0a756 100644 (file)
@@ -722,6 +722,16 @@ static void speedtch_atm_stop(struct usbatm_data *usbatm, struct atm_dev *atm_de
        flush_scheduled_work();
 }
 
+static int speedtch_pre_reset(struct usb_interface *intf)
+{
+       return 0;
+}
+
+static int speedtch_post_reset(struct usb_interface *intf)
+{
+       return 0;
+}
+
 
 /**********
 **  USB  **
@@ -740,6 +750,8 @@ static struct usb_driver speedtch_usb_driver = {
        .name           = speedtch_driver_name,
        .probe          = speedtch_usb_probe,
        .disconnect     = usbatm_usb_disconnect,
+       .pre_reset      = speedtch_pre_reset,
+       .post_reset     = speedtch_post_reset,
        .id_table       = speedtch_usb_ids
 };
 
index fab23ee8702b0a813ef4da6ba9a63dc3c7271d28..20104443081ad1fc260d4ba74f17a0c9828eca69 100644 (file)
@@ -849,9 +849,10 @@ static void acm_write_buffers_free(struct acm *acm)
 {
        int i;
        struct acm_wb *wb;
+       struct usb_device *usb_dev = interface_to_usbdev(acm->control);
 
        for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++) {
-               usb_buffer_free(acm->dev, acm->writesize, wb->buf, wb->dmah);
+               usb_buffer_free(usb_dev, acm->writesize, wb->buf, wb->dmah);
        }
 }
 
index 7429f70b9d0643295a3ff86a5584bfe6614d9e29..5a8ecc045e3facb1ae6abee89867d68cf63eabb4 100644 (file)
@@ -42,6 +42,8 @@ static struct usb_device_id wdm_ids[] = {
        { }
 };
 
+MODULE_DEVICE_TABLE (usb, wdm_ids);
+
 #define WDM_MINOR_BASE 176
 
 
index e935be7eb468b7b70b08bbb4a16f9a7b5fb6546d..3d7793d93031525400d3ed746a60639ebed1d52f 100644 (file)
@@ -1610,7 +1610,8 @@ int usb_external_resume_device(struct usb_device *udev)
        status = usb_resume_both(udev);
        udev->last_busy = jiffies;
        usb_pm_unlock(udev);
-       do_unbind_rebind(udev, DO_REBIND);
+       if (status == 0)
+               do_unbind_rebind(udev, DO_REBIND);
 
        /* Now that the device is awake, we can start trying to autosuspend
         * it again. */
index d73ce262c3651446582b251c887b5f9af787f7ce..9b3f16bd12cb4508a51a63d936a527b02b152475 100644 (file)
@@ -3504,7 +3504,7 @@ int usb_reset_device(struct usb_device *udev)
                                                USB_INTERFACE_BOUND)
                                        rebind = 1;
                        }
-                       if (rebind)
+                       if (ret == 0 && rebind)
                                usb_rebind_intf(cintf);
                }
        }
index 1ca1c326392a9051c4609d84ad4b9ec2284432ec..e1191b9a316a6b3751c90c23e263849e5a5d6c51 100644 (file)
@@ -168,7 +168,7 @@ usb_copy_descriptors(struct usb_descriptor_header **src)
  * usb_find_endpoint - find a copy of an endpoint descriptor
  * @src: original vector of descriptors
  * @copy: copy of @src
- * @ep: endpoint descriptor found in @src
+ * @match: endpoint descriptor found in @src
  *
  * This returns the copy of the @match descriptor made for @copy.  Its
  * intended use is to help remembering the endpoint descriptor to use
index bcf375ca3d7279d43d66dae544211d5a70edde52..caa37c95802c925ad9f9caff5f71071e69e22383 100644 (file)
@@ -650,7 +650,7 @@ pxa_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
        struct pxa27x_request *req;
 
        req = kzalloc(sizeof *req, gfp_flags);
-       if (!req || !_ep)
+       if (!req)
                return NULL;
 
        INIT_LIST_HEAD(&req->queue);
index 48f51b12d2e21010140448a23b554cc5ee31a145..00ba06b4475204012498cfdd5028ce03556be948 100644 (file)
@@ -1894,11 +1894,8 @@ static int s3c2410_udc_probe(struct platform_device *pdev)
                udc->regs_info = debugfs_create_file("registers", S_IRUGO,
                                s3c2410_udc_debugfs_root,
                                udc, &s3c2410_udc_debugfs_fops);
-               if (IS_ERR(udc->regs_info)) {
-                       dev_warn(dev, "debugfs file creation failed %ld\n",
-                                PTR_ERR(udc->regs_info));
-                       udc->regs_info = NULL;
-               }
+               if (!udc->regs_info)
+                       dev_warn(dev, "debugfs file creation failed\n");
        }
 
        dev_dbg(dev, "probe ok\n");
index 228797e54f9cc009f4ed293da9ccc7f6626ea97a..56f592dc0b3626139f4e9b34dd191af967f30bf0 100644 (file)
@@ -138,7 +138,6 @@ config USB_OHCI_HCD
        tristate "OHCI HCD support"
        depends on USB && USB_ARCH_HAS_OHCI
        select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3
-       select I2C if ARCH_PNX4008
        ---help---
          The Open Host Controller Interface (OHCI) is a standard for accessing
          USB 1.1 host controller hardware.  It does more in hardware than Intel's
@@ -305,3 +304,31 @@ config SUPERH_ON_CHIP_R8A66597
        help
           This driver enables support for the on-chip R8A66597 in the
           SH7366 and SH7723 processors.
+
+config USB_WHCI_HCD
+       tristate "Wireless USB Host Controller Interface (WHCI) driver (EXPERIMENTAL)"
+       depends on EXPERIMENTAL
+       depends on PCI && USB
+       select USB_WUSB
+       select UWB_WHCI
+       help
+         A driver for PCI-based Wireless USB Host Controllers that are
+         compliant with the WHCI specification.
+
+         To compile this driver a module, choose M here: the module
+         will be called "whci-hcd".
+
+config USB_HWA_HCD
+       tristate "Host Wire Adapter (HWA) driver (EXPERIMENTAL)"
+       depends on EXPERIMENTAL
+       depends on USB
+       select USB_WUSB
+       select UWB_HWA
+       help
+         This driver enables you to connect Wireless USB devices to
+         your system using a Host Wire Adaptor USB dongle. This is an
+         UWB Radio Controller and WUSB Host Controller connected to
+         your machine via USB (specified in WUSB1.0).
+
+         To compile this driver a module, choose M here: the module
+         will be called "hwa-hc".
index f1edda2dcfdecdaf49f91f775ad8d11a981d110a..23be222240447bbc60c902617e77a6cc5b4476a4 100644 (file)
@@ -8,6 +8,8 @@ endif
 
 isp1760-objs := isp1760-hcd.o isp1760-if.o
 
+obj-$(CONFIG_USB_WHCI_HCD)     += whci/
+
 obj-$(CONFIG_PCI)              += pci-quirks.o
 
 obj-$(CONFIG_USB_EHCI_HCD)     += ehci-hcd.o
@@ -19,3 +21,4 @@ obj-$(CONFIG_USB_SL811_CS)    += sl811_cs.o
 obj-$(CONFIG_USB_U132_HCD)     += u132-hcd.o
 obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o
 obj-$(CONFIG_USB_ISP1760_HCD)  += isp1760.o
+obj-$(CONFIG_USB_HWA_HCD)      += hwa-hc.o
index d343afacb0b03215822d5d1b0043fb1bfbb234ba..15a803b206b8ea72c4774ba6edb504a0fd5e964c 100644 (file)
@@ -1111,8 +1111,8 @@ clean0:
 #ifdef DEBUG
        debugfs_remove(ehci_debug_root);
        ehci_debug_root = NULL;
-#endif
 err_debug:
+#endif
        clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
        return retval;
 }
diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c
new file mode 100644 (file)
index 0000000..64be4d8
--- /dev/null
@@ -0,0 +1,925 @@
+/*
+ * Host Wire Adapter:
+ * Driver glue, HWA-specific functions, bridges to WAHC and WUSBHC
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * The HWA driver is a simple layer that forwards requests to the WAHC
+ * (Wire Adater Host Controller) or WUSBHC (Wireless USB Host
+ * Controller) layers.
+ *
+ * Host Wire Adapter is the 'WUSB 1.0 standard' name for Wireless-USB
+ * Host Controller that is connected to your system via USB (a USB
+ * dongle that implements a USB host...). There is also a Device Wired
+ * Adaptor, DWA (Wireless USB hub) that uses the same mechanism for
+ * transferring data (it is after all a USB host connected via
+ * Wireless USB), we have a common layer called Wire Adapter Host
+ * Controller that does all the hard work. The WUSBHC (Wireless USB
+ * Host Controller) is the part common to WUSB Host Controllers, the
+ * HWA and the PCI-based one, that is implemented following the WHCI
+ * spec. All these layers are implemented in ../wusbcore.
+ *
+ * The main functions are hwahc_op_urb_{en,de}queue(), that pass the
+ * job of converting a URB to a Wire Adapter
+ *
+ * Entry points:
+ *
+ *   hwahc_driver_*()   Driver initialization, registration and
+ *                      teardown.
+ *
+ *   hwahc_probe()     New device came up, create an instance for
+ *                      it [from device enumeration].
+ *
+ *   hwahc_disconnect()        Remove device instance [from device
+ *                      enumeration].
+ *
+ *   [__]hwahc_op_*()   Host-Wire-Adaptor specific functions for
+ *                      starting/stopping/etc (some might be made also
+ *                      DWA).
+ */
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/workqueue.h>
+#include <linux/wait.h>
+#include <linux/completion.h>
+#include "../wusbcore/wa-hc.h"
+#include "../wusbcore/wusbhc.h"
+
+#define D_LOCAL 0
+#include <linux/uwb/debug.h>
+
+struct hwahc {
+       struct wusbhc wusbhc;   /* has to be 1st */
+       struct wahc wa;
+       u8 buffer[16];          /* for misc usb transactions */
+};
+
+/**
+ * FIXME should be wusbhc
+ *
+ * NOTE: we need to cache the Cluster ID because later...there is no
+ *       way to get it :)
+ */
+static int __hwahc_set_cluster_id(struct hwahc *hwahc, u8 cluster_id)
+{
+       int result;
+       struct wusbhc *wusbhc = &hwahc->wusbhc;
+       struct wahc *wa = &hwahc->wa;
+       struct device *dev = &wa->usb_iface->dev;
+
+       result = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
+                       WUSB_REQ_SET_CLUSTER_ID,
+                       USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+                       cluster_id,
+                       wa->usb_iface->cur_altsetting->desc.bInterfaceNumber,
+                       NULL, 0, 1000 /* FIXME: arbitrary */);
+       if (result < 0)
+               dev_err(dev, "Cannot set WUSB Cluster ID to 0x%02x: %d\n",
+                       cluster_id, result);
+       else
+               wusbhc->cluster_id = cluster_id;
+       dev_info(dev, "Wireless USB Cluster ID set to 0x%02x\n", cluster_id);
+       return result;
+}
+
+static int __hwahc_op_set_num_dnts(struct wusbhc *wusbhc, u8 interval, u8 slots)
+{
+       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+       struct wahc *wa = &hwahc->wa;
+
+       return usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
+                       WUSB_REQ_SET_NUM_DNTS,
+                       USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+                       interval << 8 | slots,
+                       wa->usb_iface->cur_altsetting->desc.bInterfaceNumber,
+                       NULL, 0, 1000 /* FIXME: arbitrary */);
+}
+
+/*
+ * Reset a WUSB host controller and wait for it to complete doing it.
+ *
+ * @usb_hcd:   Pointer to WUSB Host Controller instance.
+ *
+ */
+static int hwahc_op_reset(struct usb_hcd *usb_hcd)
+{
+       int result;
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+       struct device *dev = &hwahc->wa.usb_iface->dev;
+
+       d_fnstart(4, dev, "(hwahc %p)\n", hwahc);
+       mutex_lock(&wusbhc->mutex);
+       wa_nep_disarm(&hwahc->wa);
+       result = __wa_set_feature(&hwahc->wa, WA_RESET);
+       if (result < 0) {
+               dev_err(dev, "error commanding HC to reset: %d\n", result);
+               goto error_unlock;
+       }
+       d_printf(3, dev, "reset: waiting for device to change state\n");
+       result = __wa_wait_status(&hwahc->wa, WA_STATUS_RESETTING, 0);
+       if (result < 0) {
+               dev_err(dev, "error waiting for HC to reset: %d\n", result);
+               goto error_unlock;
+       }
+error_unlock:
+       mutex_unlock(&wusbhc->mutex);
+       d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
+       return result;
+}
+
+/*
+ * FIXME: break this function up
+ */
+static int hwahc_op_start(struct usb_hcd *usb_hcd)
+{
+       u8 addr;
+       int result;
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+       struct device *dev = &hwahc->wa.usb_iface->dev;
+
+       /* Set up a Host Info WUSB Information Element */
+       d_fnstart(4, dev, "(hwahc %p)\n", hwahc);
+       result = -ENOSPC;
+       mutex_lock(&wusbhc->mutex);
+       /* Start the numbering from the top so that the bottom
+        * range of the unauth addr space is used for devices,
+        * the top for HCs; use 0xfe - RC# */
+       addr = wusb_cluster_id_get();
+       if (addr == 0)
+               goto error_cluster_id_get;
+       result = __hwahc_set_cluster_id(hwahc, addr);
+       if (result < 0)
+               goto error_set_cluster_id;
+
+       result = wa_nep_arm(&hwahc->wa, GFP_KERNEL);
+       if (result < 0) {
+               dev_err(dev, "cannot listen to notifications: %d\n", result);
+               goto error_stop;
+       }
+       usb_hcd->uses_new_polling = 1;
+       usb_hcd->poll_rh = 1;
+       usb_hcd->state = HC_STATE_RUNNING;
+       result = 0;
+out:
+       mutex_unlock(&wusbhc->mutex);
+       d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
+       return result;
+
+error_stop:
+       __wa_stop(&hwahc->wa);
+error_set_cluster_id:
+       wusb_cluster_id_put(wusbhc->cluster_id);
+error_cluster_id_get:
+       goto out;
+
+}
+
+/*
+ * FIXME: break this function up
+ */
+static int __hwahc_op_wusbhc_start(struct wusbhc *wusbhc)
+{
+       int result;
+       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+       struct device *dev = &hwahc->wa.usb_iface->dev;
+
+       /* Set up a Host Info WUSB Information Element */
+       d_fnstart(4, dev, "(hwahc %p)\n", hwahc);
+       result = -ENOSPC;
+
+       result = __wa_set_feature(&hwahc->wa, WA_ENABLE);
+       if (result < 0) {
+               dev_err(dev, "error commanding HC to start: %d\n", result);
+               goto error_stop;
+       }
+       result = __wa_wait_status(&hwahc->wa, WA_ENABLE, WA_ENABLE);
+       if (result < 0) {
+               dev_err(dev, "error waiting for HC to start: %d\n", result);
+               goto error_stop;
+       }
+       result = 0;
+out:
+       d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
+       return result;
+
+error_stop:
+       result = __wa_clear_feature(&hwahc->wa, WA_ENABLE);
+       goto out;
+}
+
+static int hwahc_op_suspend(struct usb_hcd *usb_hcd, pm_message_t msg)
+{
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+       dev_err(wusbhc->dev, "%s (%p [%p], 0x%lx) UNIMPLEMENTED\n", __func__,
+               usb_hcd, hwahc, *(unsigned long *) &msg);
+       return -ENOSYS;
+}
+
+static int hwahc_op_resume(struct usb_hcd *usb_hcd)
+{
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+
+       dev_err(wusbhc->dev, "%s (%p [%p]) UNIMPLEMENTED\n", __func__,
+               usb_hcd, hwahc);
+       return -ENOSYS;
+}
+
+static void __hwahc_op_wusbhc_stop(struct wusbhc *wusbhc)
+{
+       int result;
+       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+       struct device *dev = &hwahc->wa.usb_iface->dev;
+
+       d_fnstart(4, dev, "(hwahc %p)\n", hwahc);
+       /* Nothing for now */
+       d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
+       return;
+}
+
+/*
+ * No need to abort pipes, as when this is called, all the children
+ * has been disconnected and that has done it [through
+ * usb_disable_interface() -> usb_disable_endpoint() ->
+ * hwahc_op_ep_disable() - >rpipe_ep_disable()].
+ */
+static void hwahc_op_stop(struct usb_hcd *usb_hcd)
+{
+       int result;
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+       struct wahc *wa = &hwahc->wa;
+       struct device *dev = &wa->usb_iface->dev;
+
+       d_fnstart(4, dev, "(hwahc %p)\n", hwahc);
+       mutex_lock(&wusbhc->mutex);
+       wusbhc_stop(wusbhc);
+       wa_nep_disarm(&hwahc->wa);
+       result = __wa_stop(&hwahc->wa);
+       wusb_cluster_id_put(wusbhc->cluster_id);
+       mutex_unlock(&wusbhc->mutex);
+       d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
+       return;
+}
+
+static int hwahc_op_get_frame_number(struct usb_hcd *usb_hcd)
+{
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+
+       dev_err(wusbhc->dev, "%s (%p [%p]) UNIMPLEMENTED\n", __func__,
+               usb_hcd, hwahc);
+       return -ENOSYS;
+}
+
+static int hwahc_op_urb_enqueue(struct usb_hcd *usb_hcd, struct urb *urb,
+                               gfp_t gfp)
+{
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+
+       return wa_urb_enqueue(&hwahc->wa, urb->ep, urb, gfp);
+}
+
+static int hwahc_op_urb_dequeue(struct usb_hcd *usb_hcd, struct urb *urb,
+                               int status)
+{
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+
+       return wa_urb_dequeue(&hwahc->wa, urb);
+}
+
+/*
+ * Release resources allocated for an endpoint
+ *
+ * If there is an associated rpipe to this endpoint, go ahead and put it.
+ */
+static void hwahc_op_endpoint_disable(struct usb_hcd *usb_hcd,
+                                     struct usb_host_endpoint *ep)
+{
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+
+       rpipe_ep_disable(&hwahc->wa, ep);
+}
+
+/*
+ * Set the UWB MAS allocation for the WUSB cluster
+ *
+ * @stream_index: stream to use (-1 for cancelling the allocation)
+ * @mas: mas bitmap to use
+ */
+static int __hwahc_op_bwa_set(struct wusbhc *wusbhc, s8 stream_index,
+                             const struct uwb_mas_bm *mas)
+{
+       int result;
+       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+       struct wahc *wa = &hwahc->wa;
+       struct device *dev = &wa->usb_iface->dev;
+       u8 mas_le[UWB_NUM_MAS/8];
+
+       /* Set the stream index */
+       result = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
+                       WUSB_REQ_SET_STREAM_IDX,
+                       USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+                       stream_index,
+                       wa->usb_iface->cur_altsetting->desc.bInterfaceNumber,
+                       NULL, 0, 1000 /* FIXME: arbitrary */);
+       if (result < 0) {
+               dev_err(dev, "Cannot set WUSB stream index: %d\n", result);
+               goto out;
+       }
+       uwb_mas_bm_copy_le(mas_le, mas);
+       /* Set the MAS allocation */
+       result = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
+                       WUSB_REQ_SET_WUSB_MAS,
+                       USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+                       0, wa->usb_iface->cur_altsetting->desc.bInterfaceNumber,
+                       mas_le, 32, 1000 /* FIXME: arbitrary */);
+       if (result < 0)
+               dev_err(dev, "Cannot set WUSB MAS allocation: %d\n", result);
+out:
+       return result;
+}
+
+/*
+ * Add an IE to the host's MMC
+ *
+ * @interval:    See WUSB1.0[8.5.3.1]
+ * @repeat_cnt:  See WUSB1.0[8.5.3.1]
+ * @handle:      See WUSB1.0[8.5.3.1]
+ * @wuie:        Pointer to the header of the WUSB IE data to add.
+ *               MUST BE allocated in a kmalloc buffer (no stack or
+ *               vmalloc).
+ *
+ * NOTE: the format of the WUSB IEs for MMCs are different to the
+ *       normal MBOA MAC IEs (IE Id + Length in MBOA MAC vs. Length +
+ *       Id in WUSB IEs). Standards...you gotta love'em.
+ */
+static int __hwahc_op_mmcie_add(struct wusbhc *wusbhc, u8 interval,
+                               u8 repeat_cnt, u8 handle,
+                               struct wuie_hdr *wuie)
+{
+       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+       struct wahc *wa = &hwahc->wa;
+       u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber;
+
+       return usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
+                       WUSB_REQ_ADD_MMC_IE,
+                       USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+                       interval << 8 | repeat_cnt,
+                       handle << 8 | iface_no,
+                       wuie, wuie->bLength, 1000 /* FIXME: arbitrary */);
+}
+
+/*
+ * Remove an IE to the host's MMC
+ *
+ * @handle:      See WUSB1.0[8.5.3.1]
+ */
+static int __hwahc_op_mmcie_rm(struct wusbhc *wusbhc, u8 handle)
+{
+       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+       struct wahc *wa = &hwahc->wa;
+       u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber;
+       return usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
+                       WUSB_REQ_REMOVE_MMC_IE,
+                       USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+                       0, handle << 8 | iface_no,
+                       NULL, 0, 1000 /* FIXME: arbitrary */);
+}
+
+/*
+ * Update device information for a given fake port
+ *
+ * @port_idx: Fake port to which device is connected (wusbhc index, not
+ *            USB port number).
+ */
+static int __hwahc_op_dev_info_set(struct wusbhc *wusbhc,
+                                  struct wusb_dev *wusb_dev)
+{
+       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+       struct wahc *wa = &hwahc->wa;
+       u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber;
+       struct hwa_dev_info *dev_info;
+       int ret;
+
+       /* fill out the Device Info buffer and send it */
+       dev_info = kzalloc(sizeof(struct hwa_dev_info), GFP_KERNEL);
+       if (!dev_info)
+               return -ENOMEM;
+       uwb_mas_bm_copy_le(dev_info->bmDeviceAvailability,
+                          &wusb_dev->availability);
+       dev_info->bDeviceAddress = wusb_dev->addr;
+
+       /*
+        * If the descriptors haven't been read yet, use a default PHY
+        * rate of 53.3 Mbit/s only.  The correct value will be used
+        * when this will be called again as part of the
+        * authentication process (which occurs after the descriptors
+        * have been read).
+        */
+       if (wusb_dev->wusb_cap_descr)
+               dev_info->wPHYRates = wusb_dev->wusb_cap_descr->wPHYRates;
+       else
+               dev_info->wPHYRates = cpu_to_le16(USB_WIRELESS_PHY_53);
+
+       ret = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
+                       WUSB_REQ_SET_DEV_INFO,
+                       USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+                       0, wusb_dev->port_idx << 8 | iface_no,
+                       dev_info, sizeof(struct hwa_dev_info),
+                       1000 /* FIXME: arbitrary */);
+       kfree(dev_info);
+       return ret;
+}
+
+/*
+ * Set host's idea of which encryption (and key) method to use when
+ * talking to ad evice on a given port.
+ *
+ * If key is NULL, it means disable encryption for that "virtual port"
+ * (used when we disconnect).
+ */
+static int __hwahc_dev_set_key(struct wusbhc *wusbhc, u8 port_idx, u32 tkid,
+                              const void *key, size_t key_size,
+                              u8 key_idx)
+{
+       int result = -ENOMEM;
+       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+       struct wahc *wa = &hwahc->wa;
+       u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber;
+       struct usb_key_descriptor *keyd;
+       size_t keyd_len;
+
+       keyd_len = sizeof(*keyd) + key_size;
+       keyd = kzalloc(keyd_len, GFP_KERNEL);
+       if (keyd == NULL)
+               return -ENOMEM;
+
+       keyd->bLength = keyd_len;
+       keyd->bDescriptorType = USB_DT_KEY;
+       keyd->tTKID[0] = (tkid >>  0) & 0xff;
+       keyd->tTKID[1] = (tkid >>  8) & 0xff;
+       keyd->tTKID[2] = (tkid >> 16) & 0xff;
+       memcpy(keyd->bKeyData, key, key_size);
+
+       result = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
+                       USB_REQ_SET_DESCRIPTOR,
+                       USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+                       USB_DT_KEY << 8 | key_idx,
+                       port_idx << 8 | iface_no,
+                       keyd, keyd_len, 1000 /* FIXME: arbitrary */);
+
+       memset(keyd, 0, sizeof(*keyd)); /* clear keys etc. */
+       kfree(keyd);
+       return result;
+}
+
+/*
+ * Set host's idea of which encryption (and key) method to use when
+ * talking to ad evice on a given port.
+ *
+ * If key is NULL, it means disable encryption for that "virtual port"
+ * (used when we disconnect).
+ */
+static int __hwahc_op_set_ptk(struct wusbhc *wusbhc, u8 port_idx, u32 tkid,
+                             const void *key, size_t key_size)
+{
+       int result = -ENOMEM;
+       struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+       struct wahc *wa = &hwahc->wa;
+       u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber;
+       u8 encryption_value;
+
+       /* Tell the host which key to use to talk to the device */
+       if (key) {
+               u8 key_idx = wusb_key_index(0, WUSB_KEY_INDEX_TYPE_PTK,
+                                           WUSB_KEY_INDEX_ORIGINATOR_HOST);
+
+               result = __hwahc_dev_set_key(wusbhc, port_idx, tkid,
+                                            key, key_size, key_idx);
+               if (result < 0)
+                       goto error_set_key;
+               encryption_value = wusbhc->ccm1_etd->bEncryptionValue;
+       } else {
+               /* FIXME: this should come from wusbhc->etd[UNSECURE].value */
+               encryption_value = 0;
+       }
+
+       /* Set the encryption type for commmunicating with the device */
+       result = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
+                       USB_REQ_SET_ENCRYPTION,
+                       USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+                       encryption_value, port_idx << 8 | iface_no,
+                       NULL, 0, 1000 /* FIXME: arbitrary */);
+       if (result < 0)
+               dev_err(wusbhc->dev, "Can't set host's WUSB encryption for "
+                       "port index %u to %s (value %d): %d\n", port_idx,
+                       wusb_et_name(wusbhc->ccm1_etd->bEncryptionType),
+                       wusbhc->ccm1_etd->bEncryptionValue, result);
+error_set_key:
+       return result;
+}
+
+/*
+ * Set host's GTK key
+ */
+static int __hwahc_op_set_gtk(struct wusbhc *wusbhc, u32 tkid,
+                             const void *key, size_t key_size)
+{
+       u8 key_idx = wusb_key_index(0, WUSB_KEY_INDEX_TYPE_GTK,
+                                   WUSB_KEY_INDEX_ORIGINATOR_HOST);
+
+       return __hwahc_dev_set_key(wusbhc, 0, tkid, key, key_size, key_idx);
+}
+
+/*
+ * Get the Wire Adapter class-specific descriptor
+ *
+ * NOTE: this descriptor comes with the big bundled configuration
+ *       descriptor that includes the interfaces' and endpoints', so
+ *       we just look for it in the cached copy kept by the USB stack.
+ *
+ * NOTE2: We convert LE fields to CPU order.
+ */
+static int wa_fill_descr(struct wahc *wa)
+{
+       int result;
+       struct device *dev = &wa->usb_iface->dev;
+       char *itr;
+       struct usb_device *usb_dev = wa->usb_dev;
+       struct usb_descriptor_header *hdr;
+       struct usb_wa_descriptor *wa_descr;
+       size_t itr_size, actconfig_idx;
+
+       actconfig_idx = (usb_dev->actconfig - usb_dev->config) /
+                       sizeof(usb_dev->config[0]);
+       itr = usb_dev->rawdescriptors[actconfig_idx];
+       itr_size = le16_to_cpu(usb_dev->actconfig->desc.wTotalLength);
+       while (itr_size >= sizeof(*hdr)) {
+               hdr = (struct usb_descriptor_header *) itr;
+               d_printf(3, dev, "Extra device descriptor: "
+                        "type %02x/%u bytes @ %zu (%zu left)\n",
+                        hdr->bDescriptorType, hdr->bLength,
+                        (itr - usb_dev->rawdescriptors[actconfig_idx]),
+                        itr_size);
+               if (hdr->bDescriptorType == USB_DT_WIRE_ADAPTER)
+                       goto found;
+               itr += hdr->bLength;
+               itr_size -= hdr->bLength;
+       }
+       dev_err(dev, "cannot find Wire Adapter Class descriptor\n");
+       return -ENODEV;
+
+found:
+       result = -EINVAL;
+       if (hdr->bLength > itr_size) {  /* is it available? */
+               dev_err(dev, "incomplete Wire Adapter Class descriptor "
+                       "(%zu bytes left, %u needed)\n",
+                       itr_size, hdr->bLength);
+               goto error;
+       }
+       if (hdr->bLength < sizeof(*wa->wa_descr)) {
+               dev_err(dev, "short Wire Adapter Class descriptor\n");
+               goto error;
+       }
+       wa->wa_descr = wa_descr = (struct usb_wa_descriptor *) hdr;
+       /* Make LE fields CPU order */
+       wa_descr->bcdWAVersion = le16_to_cpu(wa_descr->bcdWAVersion);
+       wa_descr->wNumRPipes = le16_to_cpu(wa_descr->wNumRPipes);
+       wa_descr->wRPipeMaxBlock = le16_to_cpu(wa_descr->wRPipeMaxBlock);
+       if (wa_descr->bcdWAVersion > 0x0100)
+               dev_warn(dev, "Wire Adapter v%d.%d newer than groked v1.0\n",
+                        wa_descr->bcdWAVersion & 0xff00 >> 8,
+                        wa_descr->bcdWAVersion & 0x00ff);
+       result = 0;
+error:
+       return result;
+}
+
+static struct hc_driver hwahc_hc_driver = {
+       .description = "hwa-hcd",
+       .product_desc = "Wireless USB HWA host controller",
+       .hcd_priv_size = sizeof(struct hwahc) - sizeof(struct usb_hcd),
+       .irq = NULL,                    /* FIXME */
+       .flags = HCD_USB2,              /* FIXME */
+       .reset = hwahc_op_reset,
+       .start = hwahc_op_start,
+       .pci_suspend = hwahc_op_suspend,
+       .pci_resume = hwahc_op_resume,
+       .stop = hwahc_op_stop,
+       .get_frame_number = hwahc_op_get_frame_number,
+       .urb_enqueue = hwahc_op_urb_enqueue,
+       .urb_dequeue = hwahc_op_urb_dequeue,
+       .endpoint_disable = hwahc_op_endpoint_disable,
+
+       .hub_status_data = wusbhc_rh_status_data,
+       .hub_control = wusbhc_rh_control,
+       .bus_suspend = wusbhc_rh_suspend,
+       .bus_resume = wusbhc_rh_resume,
+       .start_port_reset = wusbhc_rh_start_port_reset,
+};
+
+static int hwahc_security_create(struct hwahc *hwahc)
+{
+       int result;
+       struct wusbhc *wusbhc = &hwahc->wusbhc;
+       struct usb_device *usb_dev = hwahc->wa.usb_dev;
+       struct device *dev = &usb_dev->dev;
+       struct usb_security_descriptor *secd;
+       struct usb_encryption_descriptor *etd;
+       void *itr, *top;
+       size_t itr_size, needed, bytes;
+       u8 index;
+       char buf[64];
+
+       /* Find the host's security descriptors in the config descr bundle */
+       index = (usb_dev->actconfig - usb_dev->config) /
+               sizeof(usb_dev->config[0]);
+       itr = usb_dev->rawdescriptors[index];
+       itr_size = le16_to_cpu(usb_dev->actconfig->desc.wTotalLength);
+       top = itr + itr_size;
+       result = __usb_get_extra_descriptor(usb_dev->rawdescriptors[index],
+                       le16_to_cpu(usb_dev->actconfig->desc.wTotalLength),
+                       USB_DT_SECURITY, (void **) &secd);
+       if (result == -1) {
+               dev_warn(dev, "BUG? WUSB host has no security descriptors\n");
+               return 0;
+       }
+       needed = sizeof(*secd);
+       if (top - (void *)secd < needed) {
+               dev_err(dev, "BUG? Not enough data to process security "
+                       "descriptor header (%zu bytes left vs %zu needed)\n",
+                       top - (void *) secd, needed);
+               return 0;
+       }
+       needed = le16_to_cpu(secd->wTotalLength);
+       if (top - (void *)secd < needed) {
+               dev_err(dev, "BUG? Not enough data to process security "
+                       "descriptors (%zu bytes left vs %zu needed)\n",
+                       top - (void *) secd, needed);
+               return 0;
+       }
+       /* Walk over the sec descriptors and store CCM1's on wusbhc */
+       itr = (void *) secd + sizeof(*secd);
+       top = (void *) secd + le16_to_cpu(secd->wTotalLength);
+       index = 0;
+       bytes = 0;
+       while (itr < top) {
+               etd = itr;
+               if (top - itr < sizeof(*etd)) {
+                       dev_err(dev, "BUG: bad host security descriptor; "
+                               "not enough data (%zu vs %zu left)\n",
+                               top - itr, sizeof(*etd));
+                       break;
+               }
+               if (etd->bLength < sizeof(*etd)) {
+                       dev_err(dev, "BUG: bad host encryption descriptor; "
+                               "descriptor is too short "
+                               "(%zu vs %zu needed)\n",
+                               (size_t)etd->bLength, sizeof(*etd));
+                       break;
+               }
+               itr += etd->bLength;
+               bytes += snprintf(buf + bytes, sizeof(buf) - bytes,
+                                 "%s (0x%02x) ",
+                                 wusb_et_name(etd->bEncryptionType),
+                                 etd->bEncryptionValue);
+               wusbhc->ccm1_etd = etd;
+       }
+       dev_info(dev, "supported encryption types: %s\n", buf);
+       if (wusbhc->ccm1_etd == NULL) {
+               dev_err(dev, "E: host doesn't support CCM-1 crypto\n");
+               return 0;
+       }
+       /* Pretty print what we support */
+       return 0;
+}
+
+static void hwahc_security_release(struct hwahc *hwahc)
+{
+       /* nothing to do here so far... */
+}
+
+static int hwahc_create(struct hwahc *hwahc, struct usb_interface *iface)
+{
+       int result;
+       struct device *dev = &iface->dev;
+       struct wusbhc *wusbhc = &hwahc->wusbhc;
+       struct wahc *wa = &hwahc->wa;
+       struct usb_device *usb_dev = interface_to_usbdev(iface);
+
+       wa->usb_dev = usb_get_dev(usb_dev);     /* bind the USB device */
+       wa->usb_iface = usb_get_intf(iface);
+       wusbhc->dev = dev;
+       wusbhc->uwb_rc = uwb_rc_get_by_grandpa(iface->dev.parent);
+       if (wusbhc->uwb_rc == NULL) {
+               result = -ENODEV;
+               dev_err(dev, "Cannot get associated UWB Host Controller\n");
+               goto error_rc_get;
+       }
+       result = wa_fill_descr(wa);     /* Get the device descriptor */
+       if (result < 0)
+               goto error_fill_descriptor;
+       if (wa->wa_descr->bNumPorts > USB_MAXCHILDREN) {
+               dev_err(dev, "FIXME: USB_MAXCHILDREN too low for WUSB "
+                       "adapter (%u ports)\n", wa->wa_descr->bNumPorts);
+               wusbhc->ports_max = USB_MAXCHILDREN;
+       } else {
+               wusbhc->ports_max = wa->wa_descr->bNumPorts;
+       }
+       wusbhc->mmcies_max = wa->wa_descr->bNumMMCIEs;
+       wusbhc->start = __hwahc_op_wusbhc_start;
+       wusbhc->stop = __hwahc_op_wusbhc_stop;
+       wusbhc->mmcie_add = __hwahc_op_mmcie_add;
+       wusbhc->mmcie_rm = __hwahc_op_mmcie_rm;
+       wusbhc->dev_info_set = __hwahc_op_dev_info_set;
+       wusbhc->bwa_set = __hwahc_op_bwa_set;
+       wusbhc->set_num_dnts = __hwahc_op_set_num_dnts;
+       wusbhc->set_ptk = __hwahc_op_set_ptk;
+       wusbhc->set_gtk = __hwahc_op_set_gtk;
+       result = hwahc_security_create(hwahc);
+       if (result < 0) {
+               dev_err(dev, "Can't initialize security: %d\n", result);
+               goto error_security_create;
+       }
+       wa->wusb = wusbhc;      /* FIXME: ugly, need to fix */
+       result = wusbhc_create(&hwahc->wusbhc);
+       if (result < 0) {
+               dev_err(dev, "Can't create WUSB HC structures: %d\n", result);
+               goto error_wusbhc_create;
+       }
+       result = wa_create(&hwahc->wa, iface);
+       if (result < 0)
+               goto error_wa_create;
+       return 0;
+
+error_wa_create:
+       wusbhc_destroy(&hwahc->wusbhc);
+error_wusbhc_create:
+       /* WA Descr fill allocs no resources */
+error_security_create:
+error_fill_descriptor:
+       uwb_rc_put(wusbhc->uwb_rc);
+error_rc_get:
+       usb_put_intf(iface);
+       usb_put_dev(usb_dev);
+       return result;
+}
+
+static void hwahc_destroy(struct hwahc *hwahc)
+{
+       struct wusbhc *wusbhc = &hwahc->wusbhc;
+
+       d_fnstart(1, NULL, "(hwahc %p)\n", hwahc);
+       mutex_lock(&wusbhc->mutex);
+       __wa_destroy(&hwahc->wa);
+       wusbhc_destroy(&hwahc->wusbhc);
+       hwahc_security_release(hwahc);
+       hwahc->wusbhc.dev = NULL;
+       uwb_rc_put(wusbhc->uwb_rc);
+       usb_put_intf(hwahc->wa.usb_iface);
+       usb_put_dev(hwahc->wa.usb_dev);
+       mutex_unlock(&wusbhc->mutex);
+       d_fnend(1, NULL, "(hwahc %p) = void\n", hwahc);
+}
+
+static void hwahc_init(struct hwahc *hwahc)
+{
+       wa_init(&hwahc->wa);
+}
+
+static int hwahc_probe(struct usb_interface *usb_iface,
+                      const struct usb_device_id *id)
+{
+       int result;
+       struct usb_hcd *usb_hcd;
+       struct wusbhc *wusbhc;
+       struct hwahc *hwahc;
+       struct device *dev = &usb_iface->dev;
+
+       d_fnstart(4, dev, "(%p, %p)\n", usb_iface, id);
+       result = -ENOMEM;
+       usb_hcd = usb_create_hcd(&hwahc_hc_driver, &usb_iface->dev, "wusb-hwa");
+       if (usb_hcd == NULL) {
+               dev_err(dev, "unable to allocate instance\n");
+               goto error_alloc;
+       }
+       usb_hcd->wireless = 1;
+       usb_hcd->flags |= HCD_FLAG_SAW_IRQ;
+       wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+       hwahc_init(hwahc);
+       result = hwahc_create(hwahc, usb_iface);
+       if (result < 0) {
+               dev_err(dev, "Cannot initialize internals: %d\n", result);
+               goto error_hwahc_create;
+       }
+       result = usb_add_hcd(usb_hcd, 0, 0);
+       if (result < 0) {
+               dev_err(dev, "Cannot add HCD: %d\n", result);
+               goto error_add_hcd;
+       }
+       result = wusbhc_b_create(&hwahc->wusbhc);
+       if (result < 0) {
+               dev_err(dev, "Cannot setup phase B of WUSBHC: %d\n", result);
+               goto error_wusbhc_b_create;
+       }
+       d_fnend(4, dev, "(%p, %p) = 0\n", usb_iface, id);
+       return 0;
+
+error_wusbhc_b_create:
+       usb_remove_hcd(usb_hcd);
+error_add_hcd:
+       hwahc_destroy(hwahc);
+error_hwahc_create:
+       usb_put_hcd(usb_hcd);
+error_alloc:
+       d_fnend(4, dev, "(%p, %p) = %d\n", usb_iface, id, result);
+       return result;
+}
+
+static void hwahc_disconnect(struct usb_interface *usb_iface)
+{
+       struct usb_hcd *usb_hcd;
+       struct wusbhc *wusbhc;
+       struct hwahc *hwahc;
+
+       usb_hcd = usb_get_intfdata(usb_iface);
+       wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       hwahc = container_of(wusbhc, struct hwahc, wusbhc);
+
+       d_fnstart(1, NULL, "(hwahc %p [usb_iface %p])\n", hwahc, usb_iface);
+       wusbhc_b_destroy(&hwahc->wusbhc);
+       usb_remove_hcd(usb_hcd);
+       hwahc_destroy(hwahc);
+       usb_put_hcd(usb_hcd);
+       d_fnend(1, NULL, "(hwahc %p [usb_iface %p]) = void\n", hwahc,
+               usb_iface);
+}
+
+/** USB device ID's that we handle */
+static struct usb_device_id hwahc_id_table[] = {
+       /* FIXME: use class labels for this */
+       { USB_INTERFACE_INFO(0xe0, 0x02, 0x01), },
+       {},
+};
+MODULE_DEVICE_TABLE(usb, hwahc_id_table);
+
+static struct usb_driver hwahc_driver = {
+       .name =         "hwa-hc",
+       .probe =        hwahc_probe,
+       .disconnect =   hwahc_disconnect,
+       .id_table =     hwahc_id_table,
+};
+
+static int __init hwahc_driver_init(void)
+{
+       int result;
+       result = usb_register(&hwahc_driver);
+       if (result < 0) {
+               printk(KERN_ERR "WA-CDS: Cannot register USB driver: %d\n",
+                      result);
+               goto error_usb_register;
+       }
+       return 0;
+
+error_usb_register:
+       return result;
+
+}
+module_init(hwahc_driver_init);
+
+static void __exit hwahc_driver_exit(void)
+{
+       usb_deregister(&hwahc_driver);
+}
+module_exit(hwahc_driver_exit);
+
+
+MODULE_AUTHOR("Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>");
+MODULE_DESCRIPTION("Host Wired Adapter USB Host Control Driver");
+MODULE_LICENSE("GPL");
index 8647dab0d7f900d2e3dc3da53159068903418178..8aa3f4556a32fb91b1f2878aded3d9f918dee260 100644 (file)
@@ -1075,12 +1075,18 @@ MODULE_LICENSE ("GPL");
 #define SM501_OHCI_DRIVER      ohci_hcd_sm501_driver
 #endif
 
+#ifdef CONFIG_MFD_TC6393XB
+#include "ohci-tmio.c"
+#define TMIO_OHCI_DRIVER       ohci_hcd_tmio_driver
+#endif
+
 #if    !defined(PCI_DRIVER) &&         \
        !defined(PLATFORM_DRIVER) &&    \
        !defined(OF_PLATFORM_DRIVER) && \
        !defined(SA1111_DRIVER) &&      \
        !defined(PS3_SYSTEM_BUS_DRIVER) && \
        !defined(SM501_OHCI_DRIVER) && \
+       !defined(TMIO_OHCI_DRIVER) && \
        !defined(SSB_OHCI_DRIVER)
 #error "missing bus glue for ohci-hcd"
 #endif
@@ -1147,13 +1153,25 @@ static int __init ohci_hcd_mod_init(void)
                goto error_sm501;
 #endif
 
+#ifdef TMIO_OHCI_DRIVER
+       retval = platform_driver_register(&TMIO_OHCI_DRIVER);
+       if (retval < 0)
+               goto error_tmio;
+#endif
+
        return retval;
 
        /* Error path */
+#ifdef TMIO_OHCI_DRIVER
+       platform_driver_unregister(&TMIO_OHCI_DRIVER);
+ error_tmio:
+#endif
 #ifdef SM501_OHCI_DRIVER
+       platform_driver_unregister(&SM501_OHCI_DRIVER);
  error_sm501:
 #endif
 #ifdef SSB_OHCI_DRIVER
+       ssb_driver_unregister(&SSB_OHCI_DRIVER);
  error_ssb:
 #endif
 #ifdef PCI_DRIVER
@@ -1189,6 +1207,9 @@ module_init(ohci_hcd_mod_init);
 
 static void __exit ohci_hcd_mod_exit(void)
 {
+#ifdef TMIO_OHCI_DRIVER
+       platform_driver_unregister(&TMIO_OHCI_DRIVER);
+#endif
 #ifdef SM501_OHCI_DRIVER
        platform_driver_unregister(&SM501_OHCI_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c
new file mode 100644 (file)
index 0000000..f9f134a
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+ * OHCI HCD(Host Controller Driver) for USB.
+ *
+ *(C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
+ *(C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
+ *(C) Copyright 2002 Hewlett-Packard Company
+ *
+ * Bus glue for Toshiba Mobile IO(TMIO) Controller's OHCI core
+ * (C) Copyright 2005 Chris Humbert <mahadri-usb@drigon.com>
+ * (C) Copyright 2007, 2008 Dmitry Baryshkov <dbaryshkov@gmail.com>
+ *
+ * This is known to work with the following variants:
+ *     TC6393XB revision 3     (32kB SRAM)
+ *
+ * The TMIO's OHCI core DMAs through a small internal buffer that
+ * is directly addressable by the CPU.
+ *
+ * Written from sparse documentation from Toshiba and Sharp's driver
+ * for the 2.4 kernel,
+ *     usb-ohci-tc6393.c(C) Copyright 2004 Lineo Solutions, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/init.h>
+#include <linux/namei.h>
+#include <linux/sched.h>*/
+#include <linux/platform_device.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/tmio.h>
+#include <linux/dma-mapping.h>
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * USB Host Controller Configuration Register
+ */
+#define CCR_REVID      0x08    /* b Revision ID                                */
+#define CCR_BASE       0x10    /* l USB Control Register Base Address Low      */
+#define CCR_ILME       0x40    /* b Internal Local Memory Enable               */
+#define CCR_PM         0x4c    /* w Power Management                   */
+#define CCR_INTC       0x50    /* b INT Control                                */
+#define CCR_LMW1L      0x54    /* w Local Memory Window 1 LMADRS Low   */
+#define CCR_LMW1H      0x56    /* w Local Memory Window 1 LMADRS High  */
+#define CCR_LMW1BL     0x58    /* w Local Memory Window 1 Base Address Low     */
+#define CCR_LMW1BH     0x5A    /* w Local Memory Window 1 Base Address High    */
+#define CCR_LMW2L      0x5C    /* w Local Memory Window 2 LMADRS Low   */
+#define CCR_LMW2H      0x5E    /* w Local Memory Window 2 LMADRS High  */
+#define CCR_LMW2BL     0x60    /* w Local Memory Window 2 Base Address Low     */
+#define CCR_LMW2BH     0x62    /* w Local Memory Window 2 Base Address High    */
+#define CCR_MISC       0xFC    /* b MISC                                       */
+
+#define CCR_PM_GKEN      0x0001
+#define CCR_PM_CKRNEN    0x0002
+#define CCR_PM_USBPW1    0x0004
+#define CCR_PM_USBPW2    0x0008
+#define CCR_PM_USBPW3    0x0008
+#define CCR_PM_PMEE      0x0100
+#define CCR_PM_PMES      0x8000
+
+/*-------------------------------------------------------------------------*/
+
+struct tmio_hcd {
+       void __iomem            *ccr;
+       spinlock_t              lock; /* protects RMW cycles */
+};
+
+#define hcd_to_tmio(hcd)       ((struct tmio_hcd *)(hcd_to_ohci(hcd) + 1))
+
+/*-------------------------------------------------------------------------*/
+
+static void tmio_write_pm(struct platform_device *dev)
+{
+       struct usb_hcd *hcd = platform_get_drvdata(dev);
+       struct tmio_hcd *tmio = hcd_to_tmio(hcd);
+       u16 pm;
+       unsigned long flags;
+
+       spin_lock_irqsave(&tmio->lock, flags);
+
+       pm = CCR_PM_GKEN | CCR_PM_CKRNEN |
+            CCR_PM_PMEE | CCR_PM_PMES;
+
+       tmio_iowrite16(pm, tmio->ccr + CCR_PM);
+       spin_unlock_irqrestore(&tmio->lock, flags);
+}
+
+static void tmio_stop_hc(struct platform_device *dev)
+{
+       struct usb_hcd *hcd = platform_get_drvdata(dev);
+       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+       struct tmio_hcd *tmio = hcd_to_tmio(hcd);
+       u16 pm;
+
+       pm = CCR_PM_GKEN | CCR_PM_CKRNEN;
+       switch (ohci->num_ports) {
+               default:
+                       dev_err(&dev->dev, "Unsupported amount of ports: %d\n", ohci->num_ports);
+               case 3:
+                       pm |= CCR_PM_USBPW3;
+               case 2:
+                       pm |= CCR_PM_USBPW2;
+               case 1:
+                       pm |= CCR_PM_USBPW1;
+       }
+       tmio_iowrite8(0, tmio->ccr + CCR_INTC);
+       tmio_iowrite8(0, tmio->ccr + CCR_ILME);
+       tmio_iowrite16(0, tmio->ccr + CCR_BASE);
+       tmio_iowrite16(0, tmio->ccr + CCR_BASE + 2);
+       tmio_iowrite16(pm, tmio->ccr + CCR_PM);
+}
+
+static void tmio_start_hc(struct platform_device *dev)
+{
+       struct usb_hcd *hcd = platform_get_drvdata(dev);
+       struct tmio_hcd *tmio = hcd_to_tmio(hcd);
+       unsigned long base = hcd->rsrc_start;
+
+       tmio_write_pm(dev);
+       tmio_iowrite16(base, tmio->ccr + CCR_BASE);
+       tmio_iowrite16(base >> 16, tmio->ccr + CCR_BASE + 2);
+       tmio_iowrite8(1, tmio->ccr + CCR_ILME);
+       tmio_iowrite8(2, tmio->ccr + CCR_INTC);
+
+       dev_info(&dev->dev, "revision %d @ 0x%08llx, irq %d\n",
+                       tmio_ioread8(tmio->ccr + CCR_REVID), hcd->rsrc_start, hcd->irq);
+}
+
+static int ohci_tmio_start(struct usb_hcd *hcd)
+{
+       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+       int ret;
+
+       if ((ret = ohci_init(ohci)) < 0)
+               return ret;
+
+       if ((ret = ohci_run(ohci)) < 0) {
+               err("can't start %s", hcd->self.bus_name);
+               ohci_stop(hcd);
+               return ret;
+       }
+
+       return 0;
+}
+
+static const struct hc_driver ohci_tmio_hc_driver = {
+       .description =          hcd_name,
+       .product_desc =         "TMIO OHCI USB Host Controller",
+       .hcd_priv_size =        sizeof(struct ohci_hcd) + sizeof (struct tmio_hcd),
+
+       /* generic hardware linkage */
+       .irq =                  ohci_irq,
+       .flags =                HCD_USB11 | HCD_MEMORY | HCD_LOCAL_MEM,
+
+       /* basic lifecycle operations */
+       .start =                ohci_tmio_start,
+       .stop =                 ohci_stop,
+       .shutdown =             ohci_shutdown,
+
+       /* managing i/o requests and associated device resources */
+       .urb_enqueue =          ohci_urb_enqueue,
+       .urb_dequeue =          ohci_urb_dequeue,
+       .endpoint_disable =     ohci_endpoint_disable,
+
+       /* scheduling support */
+       .get_frame_number =     ohci_get_frame,
+
+       /* root hub support */
+       .hub_status_data =      ohci_hub_status_data,
+       .hub_control =          ohci_hub_control,
+#ifdef CONFIG_PM
+       .bus_suspend =          ohci_bus_suspend,
+       .bus_resume =           ohci_bus_resume,
+#endif
+       .start_port_reset =     ohci_start_port_reset,
+};
+
+/*-------------------------------------------------------------------------*/
+static struct platform_driver ohci_hcd_tmio_driver;
+
+static int __devinit ohci_hcd_tmio_drv_probe(struct platform_device *dev)
+{
+       struct mfd_cell *cell = dev->dev.platform_data;
+       struct resource *regs = platform_get_resource(dev, IORESOURCE_MEM, 0);
+       struct resource *config = platform_get_resource(dev, IORESOURCE_MEM, 1);
+       struct resource *sram = platform_get_resource(dev, IORESOURCE_MEM, 2);
+       int irq = platform_get_irq(dev, 0);
+       struct tmio_hcd *tmio;
+       struct ohci_hcd *ohci;
+       struct usb_hcd *hcd;
+       int ret;
+
+       if (usb_disabled())
+               return -ENODEV;
+
+       if (!cell)
+               return -EINVAL;
+
+       hcd = usb_create_hcd(&ohci_tmio_hc_driver, &dev->dev, dev->dev.bus_id);
+       if (!hcd) {
+               ret = -ENOMEM;
+               goto err_usb_create_hcd;
+       }
+
+       hcd->rsrc_start = regs->start;
+       hcd->rsrc_len = regs->end - regs->start + 1;
+
+       tmio = hcd_to_tmio(hcd);
+
+       spin_lock_init(&tmio->lock);
+
+       tmio->ccr = ioremap(config->start, config->end - config->start + 1);
+       if (!tmio->ccr) {
+               ret = -ENOMEM;
+               goto err_ioremap_ccr;
+       }
+
+       hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+       if (!hcd->regs) {
+               ret = -ENOMEM;
+               goto err_ioremap_regs;
+       }
+
+       if (!dma_declare_coherent_memory(&dev->dev, sram->start,
+                               sram->start,
+                               sram->end - sram->start + 1,
+                               DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE)) {
+               ret = -EBUSY;
+               goto err_dma_declare;
+       }
+
+       if (cell->enable) {
+               ret = cell->enable(dev);
+               if (ret)
+                       goto err_enable;
+       }
+
+       tmio_start_hc(dev);
+       ohci = hcd_to_ohci(hcd);
+       ohci_hcd_init(ohci);
+
+       ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
+       if (ret)
+               goto err_add_hcd;
+
+       if (ret == 0)
+               return ret;
+
+       usb_remove_hcd(hcd);
+
+err_add_hcd:
+       tmio_stop_hc(dev);
+       if (cell->disable)
+               cell->disable(dev);
+err_enable:
+       dma_release_declared_memory(&dev->dev);
+err_dma_declare:
+       iounmap(hcd->regs);
+err_ioremap_regs:
+       iounmap(tmio->ccr);
+err_ioremap_ccr:
+       usb_put_hcd(hcd);
+err_usb_create_hcd:
+
+       return ret;
+}
+
+static int __devexit ohci_hcd_tmio_drv_remove(struct platform_device *dev)
+{
+       struct usb_hcd *hcd = platform_get_drvdata(dev);
+       struct tmio_hcd *tmio = hcd_to_tmio(hcd);
+       struct mfd_cell *cell = dev->dev.platform_data;
+
+       usb_remove_hcd(hcd);
+       tmio_stop_hc(dev);
+       if (cell->disable)
+               cell->disable(dev);
+       dma_release_declared_memory(&dev->dev);
+       iounmap(hcd->regs);
+       iounmap(tmio->ccr);
+       usb_put_hcd(hcd);
+
+       platform_set_drvdata(dev, NULL);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t state)
+{
+       struct mfd_cell *cell = dev->dev.platform_data;
+       struct usb_hcd *hcd = platform_get_drvdata(dev);
+       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+       struct tmio_hcd *tmio = hcd_to_tmio(hcd);
+       unsigned long flags;
+       u8 misc;
+       int ret;
+
+       if (time_before(jiffies, ohci->next_statechange))
+               msleep(5);
+       ohci->next_statechange = jiffies;
+
+       spin_lock_irqsave(&tmio->lock, flags);
+
+       misc = tmio_ioread8(tmio->ccr + CCR_MISC);
+       misc |= 1 << 3; /* USSUSP */
+       tmio_iowrite8(misc, tmio->ccr + CCR_MISC);
+
+       spin_unlock_irqrestore(&tmio->lock, flags);
+
+       if (cell->suspend) {
+               ret = cell->suspend(dev);
+               if (ret)
+                       return ret;
+       }
+
+       hcd->state = HC_STATE_SUSPENDED;
+
+       return 0;
+}
+
+static int ohci_hcd_tmio_drv_resume(struct platform_device *dev)
+{
+       struct mfd_cell *cell = dev->dev.platform_data;
+       struct usb_hcd *hcd = platform_get_drvdata(dev);
+       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+       struct tmio_hcd *tmio = hcd_to_tmio(hcd);
+       unsigned long flags;
+       u8 misc;
+       int ret;
+
+       if (time_before(jiffies, ohci->next_statechange))
+               msleep(5);
+       ohci->next_statechange = jiffies;
+
+       if (cell->resume) {
+               ret = cell->resume(dev);
+               if (ret)
+                       return ret;
+       }
+
+       tmio_start_hc(dev);
+
+       spin_lock_irqsave(&tmio->lock, flags);
+
+       misc = tmio_ioread8(tmio->ccr + CCR_MISC);
+       misc &= ~(1 << 3); /* USSUSP */
+       tmio_iowrite8(misc, tmio->ccr + CCR_MISC);
+
+       spin_unlock_irqrestore(&tmio->lock, flags);
+
+       ohci_finish_controller_resume(hcd);
+
+       return 0;
+}
+#else
+#define ohci_hcd_tmio_drv_suspend NULL
+#define ohci_hcd_tmio_drv_resume NULL
+#endif
+
+static struct platform_driver ohci_hcd_tmio_driver = {
+       .probe          = ohci_hcd_tmio_drv_probe,
+       .remove         = __devexit_p(ohci_hcd_tmio_drv_remove),
+       .shutdown       = usb_hcd_platform_shutdown,
+       .suspend        = ohci_hcd_tmio_drv_suspend,
+       .resume         = ohci_hcd_tmio_drv_resume,
+       .driver         = {
+               .name   = "tmio-ohci",
+               .owner  = THIS_MODULE,
+       },
+};
diff --git a/drivers/usb/host/whci/Kbuild b/drivers/usb/host/whci/Kbuild
new file mode 100644 (file)
index 0000000..26a3871
--- /dev/null
@@ -0,0 +1,11 @@
+obj-$(CONFIG_USB_WHCI_HCD) += whci-hcd.o
+
+whci-hcd-y := \
+       asl.o   \
+       hcd.o   \
+       hw.o    \
+       init.o  \
+       int.o   \
+       pzl.o   \
+       qset.o  \
+       wusb.o
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c
new file mode 100644 (file)
index 0000000..4d7078e
--- /dev/null
@@ -0,0 +1,367 @@
+/*
+ * Wireless Host Controller (WHC) asynchronous schedule management.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/uwb/umc.h>
+#include <linux/usb.h>
+#define D_LOCAL 0
+#include <linux/uwb/debug.h>
+
+#include "../../wusbcore/wusbhc.h"
+
+#include "whcd.h"
+
+#if D_LOCAL >= 4
+static void dump_asl(struct whc *whc, const char *tag)
+{
+       struct device *dev = &whc->umc->dev;
+       struct whc_qset *qset;
+
+       d_printf(4, dev, "ASL %s\n", tag);
+
+       list_for_each_entry(qset, &whc->async_list, list_node) {
+               dump_qset(qset, dev);
+       }
+}
+#else
+static inline void dump_asl(struct whc *whc, const char *tag)
+{
+}
+#endif
+
+
+static void qset_get_next_prev(struct whc *whc, struct whc_qset *qset,
+                              struct whc_qset **next, struct whc_qset **prev)
+{
+       struct list_head *n, *p;
+
+       BUG_ON(list_empty(&whc->async_list));
+
+       n = qset->list_node.next;
+       if (n == &whc->async_list)
+               n = n->next;
+       p = qset->list_node.prev;
+       if (p == &whc->async_list)
+               p = p->prev;
+
+       *next = container_of(n, struct whc_qset, list_node);
+       *prev = container_of(p, struct whc_qset, list_node);
+
+}
+
+static void asl_qset_insert_begin(struct whc *whc, struct whc_qset *qset)
+{
+       list_move(&qset->list_node, &whc->async_list);
+       qset->in_sw_list = true;
+}
+
+static void asl_qset_insert(struct whc *whc, struct whc_qset *qset)
+{
+       struct whc_qset *next, *prev;
+
+       qset_clear(whc, qset);
+
+       /* Link into ASL. */
+       qset_get_next_prev(whc, qset, &next, &prev);
+       whc_qset_set_link_ptr(&qset->qh.link, next->qset_dma);
+       whc_qset_set_link_ptr(&prev->qh.link, qset->qset_dma);
+       qset->in_hw_list = true;
+}
+
+static void asl_qset_remove(struct whc *whc, struct whc_qset *qset)
+{
+       struct whc_qset *prev, *next;
+
+       qset_get_next_prev(whc, qset, &next, &prev);
+
+       list_move(&qset->list_node, &whc->async_removed_list);
+       qset->in_sw_list = false;
+
+       /*
+        * No more qsets in the ASL?  The caller must stop the ASL as
+        * it's no longer valid.
+        */
+       if (list_empty(&whc->async_list))
+               return;
+
+       /* Remove from ASL. */
+       whc_qset_set_link_ptr(&prev->qh.link, next->qset_dma);
+       qset->in_hw_list = false;
+}
+
+/**
+ * process_qset - process any recently inactivated or halted qTDs in a
+ * qset.
+ *
+ * After inactive qTDs are removed, new qTDs can be added if the
+ * urb queue still contains URBs.
+ *
+ * Returns any additional WUSBCMD bits for the ASL sync command (i.e.,
+ * WUSBCMD_ASYNC_QSET_RM if a halted qset was removed).
+ */
+static uint32_t process_qset(struct whc *whc, struct whc_qset *qset)
+{
+       enum whc_update update = 0;
+       uint32_t status = 0;
+
+       while (qset->ntds) {
+               struct whc_qtd *td;
+               int t;
+
+               t = qset->td_start;
+               td = &qset->qtd[qset->td_start];
+               status = le32_to_cpu(td->status);
+
+               /*
+                * Nothing to do with a still active qTD.
+                */
+               if (status & QTD_STS_ACTIVE)
+                       break;
+
+               if (status & QTD_STS_HALTED) {
+                       /* Ug, an error. */
+                       process_halted_qtd(whc, qset, td);
+                       goto done;
+               }
+
+               /* Mmm, a completed qTD. */
+               process_inactive_qtd(whc, qset, td);
+       }
+
+       update |= qset_add_qtds(whc, qset);
+
+done:
+       /*
+        * Remove this qset from the ASL if requested, but only if has
+        * no qTDs.
+        */
+       if (qset->remove && qset->ntds == 0) {
+               asl_qset_remove(whc, qset);
+               update |= WHC_UPDATE_REMOVED;
+       }
+       return update;
+}
+
+void asl_start(struct whc *whc)
+{
+       struct whc_qset *qset;
+
+       qset = list_first_entry(&whc->async_list, struct whc_qset, list_node);
+
+       le_writeq(qset->qset_dma | QH_LINK_NTDS(8), whc->base + WUSBASYNCLISTADDR);
+
+       whc_write_wusbcmd(whc, WUSBCMD_ASYNC_EN, WUSBCMD_ASYNC_EN);
+       whci_wait_for(&whc->umc->dev, whc->base + WUSBSTS,
+                     WUSBSTS_ASYNC_SCHED, WUSBSTS_ASYNC_SCHED,
+                     1000, "start ASL");
+}
+
+void asl_stop(struct whc *whc)
+{
+       whc_write_wusbcmd(whc, WUSBCMD_ASYNC_EN, 0);
+       whci_wait_for(&whc->umc->dev, whc->base + WUSBSTS,
+                     WUSBSTS_ASYNC_SCHED, 0,
+                     1000, "stop ASL");
+}
+
+void asl_update(struct whc *whc, uint32_t wusbcmd)
+{
+       whc_write_wusbcmd(whc, wusbcmd, wusbcmd);
+       wait_event(whc->async_list_wq,
+                  (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0);
+}
+
+/**
+ * scan_async_work - scan the ASL for qsets to process.
+ *
+ * Process each qset in the ASL in turn and then signal the WHC that
+ * the ASL has been updated.
+ *
+ * Then start, stop or update the asynchronous schedule as required.
+ */
+void scan_async_work(struct work_struct *work)
+{
+       struct whc *whc = container_of(work, struct whc, async_work);
+       struct whc_qset *qset, *t;
+       enum whc_update update = 0;
+
+       spin_lock_irq(&whc->lock);
+
+       dump_asl(whc, "before processing");
+
+       /*
+        * Transerve the software list backwards so new qsets can be
+        * safely inserted into the ASL without making it non-circular.
+        */
+       list_for_each_entry_safe_reverse(qset, t, &whc->async_list, list_node) {
+               if (!qset->in_hw_list) {
+                       asl_qset_insert(whc, qset);
+                       update |= WHC_UPDATE_ADDED;
+               }
+
+               update |= process_qset(whc, qset);
+       }
+
+       dump_asl(whc, "after processing");
+
+       spin_unlock_irq(&whc->lock);
+
+       if (update) {
+               uint32_t wusbcmd = WUSBCMD_ASYNC_UPDATED | WUSBCMD_ASYNC_SYNCED_DB;
+               if (update & WHC_UPDATE_REMOVED)
+                       wusbcmd |= WUSBCMD_ASYNC_QSET_RM;
+               asl_update(whc, wusbcmd);
+       }
+
+       /*
+        * Now that the ASL is updated, complete the removal of any
+        * removed qsets.
+        */
+       spin_lock(&whc->lock);
+
+       list_for_each_entry_safe(qset, t, &whc->async_removed_list, list_node) {
+               qset_remove_complete(whc, qset);
+       }
+
+       spin_unlock(&whc->lock);
+}
+
+/**
+ * asl_urb_enqueue - queue an URB onto the asynchronous list (ASL).
+ * @whc: the WHCI host controller
+ * @urb: the URB to enqueue
+ * @mem_flags: flags for any memory allocations
+ *
+ * The qset for the endpoint is obtained and the urb queued on to it.
+ *
+ * Work is scheduled to update the hardware's view of the ASL.
+ */
+int asl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags)
+{
+       struct whc_qset *qset;
+       int err;
+       unsigned long flags;
+
+       spin_lock_irqsave(&whc->lock, flags);
+
+       qset = get_qset(whc, urb, GFP_ATOMIC);
+       if (qset == NULL)
+               err = -ENOMEM;
+       else
+               err = qset_add_urb(whc, qset, urb, GFP_ATOMIC);
+       if (!err) {
+               usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
+               if (!qset->in_sw_list)
+                       asl_qset_insert_begin(whc, qset);
+       }
+
+       spin_unlock_irqrestore(&whc->lock, flags);
+
+       if (!err)
+               queue_work(whc->workqueue, &whc->async_work);
+
+       return 0;
+}
+
+/**
+ * asl_urb_dequeue - remove an URB (qset) from the async list.
+ * @whc: the WHCI host controller
+ * @urb: the URB to dequeue
+ * @status: the current status of the URB
+ *
+ * URBs that do yet have qTDs can simply be removed from the software
+ * queue, otherwise the qset must be removed from the ASL so the qTDs
+ * can be removed.
+ */
+int asl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
+{
+       struct whc_urb *wurb = urb->hcpriv;
+       struct whc_qset *qset = wurb->qset;
+       struct whc_std *std, *t;
+       int ret;
+       unsigned long flags;
+
+       spin_lock_irqsave(&whc->lock, flags);
+
+       ret = usb_hcd_check_unlink_urb(&whc->wusbhc.usb_hcd, urb, status);
+       if (ret < 0)
+               goto out;
+
+       list_for_each_entry_safe(std, t, &qset->stds, list_node) {
+               if (std->urb == urb)
+                       qset_free_std(whc, std);
+               else
+                       std->qtd = NULL; /* so this std is re-added when the qset is */
+       }
+
+       asl_qset_remove(whc, qset);
+       wurb->status = status;
+       wurb->is_async = true;
+       queue_work(whc->workqueue, &wurb->dequeue_work);
+
+out:
+       spin_unlock_irqrestore(&whc->lock, flags);
+
+       return ret;
+}
+
+/**
+ * asl_qset_delete - delete a qset from the ASL
+ */
+void asl_qset_delete(struct whc *whc, struct whc_qset *qset)
+{
+       qset->remove = 1;
+       queue_work(whc->workqueue, &whc->async_work);
+       qset_delete(whc, qset);
+}
+
+/**
+ * asl_init - initialize the asynchronous schedule list
+ *
+ * A dummy qset with no qTDs is added to the ASL to simplify removing
+ * qsets (no need to stop the ASL when the last qset is removed).
+ */
+int asl_init(struct whc *whc)
+{
+       struct whc_qset *qset;
+
+       qset = qset_alloc(whc, GFP_KERNEL);
+       if (qset == NULL)
+               return -ENOMEM;
+
+       asl_qset_insert_begin(whc, qset);
+       asl_qset_insert(whc, qset);
+
+       return 0;
+}
+
+/**
+ * asl_clean_up - free ASL resources
+ *
+ * The ASL is stopped and empty except for the dummy qset.
+ */
+void asl_clean_up(struct whc *whc)
+{
+       struct whc_qset *qset;
+
+       if (!list_empty(&whc->async_list)) {
+               qset = list_first_entry(&whc->async_list, struct whc_qset, list_node);
+               list_del(&qset->list_node);
+               qset_free(whc, qset);
+       }
+}
diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c
new file mode 100644 (file)
index 0000000..ef3ad4d
--- /dev/null
@@ -0,0 +1,339 @@
+/*
+ * Wireless Host Controller (WHC) driver.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/uwb/umc.h>
+
+#include "../../wusbcore/wusbhc.h"
+
+#include "whcd.h"
+
+/*
+ * One time initialization.
+ *
+ * Nothing to do here.
+ */
+static int whc_reset(struct usb_hcd *usb_hcd)
+{
+       return 0;
+}
+
+/*
+ * Start the wireless host controller.
+ *
+ * Start device notification.
+ *
+ * Put hc into run state, set DNTS parameters.
+ */
+static int whc_start(struct usb_hcd *usb_hcd)
+{
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       struct whc *whc = wusbhc_to_whc(wusbhc);
+       u8 bcid;
+       int ret;
+
+       mutex_lock(&wusbhc->mutex);
+
+       le_writel(WUSBINTR_GEN_CMD_DONE
+                 | WUSBINTR_HOST_ERR
+                 | WUSBINTR_ASYNC_SCHED_SYNCED
+                 | WUSBINTR_DNTS_INT
+                 | WUSBINTR_ERR_INT
+                 | WUSBINTR_INT,
+                 whc->base + WUSBINTR);
+
+       /* set cluster ID */
+       bcid = wusb_cluster_id_get();
+       ret = whc_set_cluster_id(whc, bcid);
+       if (ret < 0)
+               goto out;
+       wusbhc->cluster_id = bcid;
+
+       /* start HC */
+       whc_write_wusbcmd(whc, WUSBCMD_RUN, WUSBCMD_RUN);
+
+       usb_hcd->uses_new_polling = 1;
+       usb_hcd->poll_rh = 1;
+       usb_hcd->state = HC_STATE_RUNNING;
+
+out:
+       mutex_unlock(&wusbhc->mutex);
+       return ret;
+}
+
+
+/*
+ * Stop the wireless host controller.
+ *
+ * Stop device notification.
+ *
+ * Wait for pending transfer to stop? Put hc into stop state?
+ */
+static void whc_stop(struct usb_hcd *usb_hcd)
+{
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       struct whc *whc = wusbhc_to_whc(wusbhc);
+
+       mutex_lock(&wusbhc->mutex);
+
+       wusbhc_stop(wusbhc);
+
+       /* stop HC */
+       le_writel(0, whc->base + WUSBINTR);
+       whc_write_wusbcmd(whc, WUSBCMD_RUN, 0);
+       whci_wait_for(&whc->umc->dev, whc->base + WUSBSTS,
+                     WUSBSTS_HCHALTED, WUSBSTS_HCHALTED,
+                     100, "HC to halt");
+
+       wusb_cluster_id_put(wusbhc->cluster_id);
+
+       mutex_unlock(&wusbhc->mutex);
+}
+
+static int whc_get_frame_number(struct usb_hcd *usb_hcd)
+{
+       /* Frame numbers are not applicable to WUSB. */
+       return -ENOSYS;
+}
+
+
+/*
+ * Queue an URB to the ASL or PZL
+ */
+static int whc_urb_enqueue(struct usb_hcd *usb_hcd, struct urb *urb,
+                          gfp_t mem_flags)
+{
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       struct whc *whc = wusbhc_to_whc(wusbhc);
+       int ret;
+
+       switch (usb_pipetype(urb->pipe)) {
+       case PIPE_INTERRUPT:
+               ret = pzl_urb_enqueue(whc, urb, mem_flags);
+               break;
+       case PIPE_ISOCHRONOUS:
+               dev_err(&whc->umc->dev, "isochronous transfers unsupported\n");
+               ret = -ENOTSUPP;
+               break;
+       case PIPE_CONTROL:
+       case PIPE_BULK:
+       default:
+               ret = asl_urb_enqueue(whc, urb, mem_flags);
+               break;
+       };
+
+       return ret;
+}
+
+/*
+ * Remove a queued URB from the ASL or PZL.
+ */
+static int whc_urb_dequeue(struct usb_hcd *usb_hcd, struct urb *urb, int status)
+{
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       struct whc *whc = wusbhc_to_whc(wusbhc);
+       int ret;
+
+       switch (usb_pipetype(urb->pipe)) {
+       case PIPE_INTERRUPT:
+               ret = pzl_urb_dequeue(whc, urb, status);
+               break;
+       case PIPE_ISOCHRONOUS:
+               ret = -ENOTSUPP;
+               break;
+       case PIPE_CONTROL:
+       case PIPE_BULK:
+       default:
+               ret = asl_urb_dequeue(whc, urb, status);
+               break;
+       };
+
+       return ret;
+}
+
+/*
+ * Wait for all URBs to the endpoint to be completed, then delete the
+ * qset.
+ */
+static void whc_endpoint_disable(struct usb_hcd *usb_hcd,
+                                struct usb_host_endpoint *ep)
+{
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       struct whc *whc = wusbhc_to_whc(wusbhc);
+       struct whc_qset *qset;
+
+       qset = ep->hcpriv;
+       if (qset) {
+               ep->hcpriv = NULL;
+               if (usb_endpoint_xfer_bulk(&ep->desc)
+                   || usb_endpoint_xfer_control(&ep->desc))
+                       asl_qset_delete(whc, qset);
+               else
+                       pzl_qset_delete(whc, qset);
+       }
+}
+
+static struct hc_driver whc_hc_driver = {
+       .description = "whci-hcd",
+       .product_desc = "Wireless host controller",
+       .hcd_priv_size = sizeof(struct whc) - sizeof(struct usb_hcd),
+       .irq = whc_int_handler,
+       .flags = HCD_USB2,
+
+       .reset = whc_reset,
+       .start = whc_start,
+       .stop = whc_stop,
+       .get_frame_number = whc_get_frame_number,
+       .urb_enqueue = whc_urb_enqueue,
+       .urb_dequeue = whc_urb_dequeue,
+       .endpoint_disable = whc_endpoint_disable,
+
+       .hub_status_data = wusbhc_rh_status_data,
+       .hub_control = wusbhc_rh_control,
+       .bus_suspend = wusbhc_rh_suspend,
+       .bus_resume = wusbhc_rh_resume,
+       .start_port_reset = wusbhc_rh_start_port_reset,
+};
+
+static int whc_probe(struct umc_dev *umc)
+{
+       int ret = -ENOMEM;
+       struct usb_hcd *usb_hcd;
+       struct wusbhc *wusbhc = NULL;
+       struct whc *whc = NULL;
+       struct device *dev = &umc->dev;
+
+       usb_hcd = usb_create_hcd(&whc_hc_driver, dev, "whci");
+       if (usb_hcd == NULL) {
+               dev_err(dev, "unable to create hcd\n");
+               goto error;
+       }
+
+       usb_hcd->wireless = 1;
+
+       wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       whc = wusbhc_to_whc(wusbhc);
+       whc->umc = umc;
+
+       ret = whc_init(whc);
+       if (ret)
+               goto error;
+
+       wusbhc->dev = dev;
+       wusbhc->uwb_rc = uwb_rc_get_by_grandpa(umc->dev.parent);
+       if (!wusbhc->uwb_rc) {
+               ret = -ENODEV;
+               dev_err(dev, "cannot get radio controller\n");
+               goto error;
+       }
+
+       if (whc->n_devices > USB_MAXCHILDREN) {
+               dev_warn(dev, "USB_MAXCHILDREN too low for WUSB adapter (%u ports)\n",
+                        whc->n_devices);
+               wusbhc->ports_max = USB_MAXCHILDREN;
+       } else
+               wusbhc->ports_max = whc->n_devices;
+       wusbhc->mmcies_max      = whc->n_mmc_ies;
+       wusbhc->start           = whc_wusbhc_start;
+       wusbhc->stop            = whc_wusbhc_stop;
+       wusbhc->mmcie_add       = whc_mmcie_add;
+       wusbhc->mmcie_rm        = whc_mmcie_rm;
+       wusbhc->dev_info_set    = whc_dev_info_set;
+       wusbhc->bwa_set         = whc_bwa_set;
+       wusbhc->set_num_dnts    = whc_set_num_dnts;
+       wusbhc->set_ptk         = whc_set_ptk;
+       wusbhc->set_gtk         = whc_set_gtk;
+
+       ret = wusbhc_create(wusbhc);
+       if (ret)
+               goto error_wusbhc_create;
+
+       ret = usb_add_hcd(usb_hcd, whc->umc->irq, IRQF_SHARED);
+       if (ret) {
+               dev_err(dev, "cannot add HCD: %d\n", ret);
+               goto error_usb_add_hcd;
+       }
+
+       ret = wusbhc_b_create(wusbhc);
+       if (ret) {
+               dev_err(dev, "WUSBHC phase B setup failed: %d\n", ret);
+               goto error_wusbhc_b_create;
+       }
+
+       return 0;
+
+error_wusbhc_b_create:
+       usb_remove_hcd(usb_hcd);
+error_usb_add_hcd:
+       wusbhc_destroy(wusbhc);
+error_wusbhc_create:
+       uwb_rc_put(wusbhc->uwb_rc);
+error:
+       whc_clean_up(whc);
+       if (usb_hcd)
+               usb_put_hcd(usb_hcd);
+       return ret;
+}
+
+
+static void whc_remove(struct umc_dev *umc)
+{
+       struct usb_hcd *usb_hcd = dev_get_drvdata(&umc->dev);
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       struct whc *whc = wusbhc_to_whc(wusbhc);
+
+       if (usb_hcd) {
+               wusbhc_b_destroy(wusbhc);
+               usb_remove_hcd(usb_hcd);
+               wusbhc_destroy(wusbhc);
+               uwb_rc_put(wusbhc->uwb_rc);
+               whc_clean_up(whc);
+               usb_put_hcd(usb_hcd);
+       }
+}
+
+static struct umc_driver whci_hc_driver = {
+       .name =         "whci-hcd",
+       .cap_id =       UMC_CAP_ID_WHCI_WUSB_HC,
+       .probe =        whc_probe,
+       .remove =       whc_remove,
+};
+
+static int __init whci_hc_driver_init(void)
+{
+       return umc_driver_register(&whci_hc_driver);
+}
+module_init(whci_hc_driver_init);
+
+static void __exit whci_hc_driver_exit(void)
+{
+       umc_driver_unregister(&whci_hc_driver);
+}
+module_exit(whci_hc_driver_exit);
+
+/* PCI device ID's that we handle (so it gets loaded) */
+static struct pci_device_id whci_hcd_id_table[] = {
+       { PCI_DEVICE_CLASS(PCI_CLASS_WIRELESS_WHCI, ~0) },
+       { /* empty last entry */ }
+};
+MODULE_DEVICE_TABLE(pci, whci_hcd_id_table);
+
+MODULE_DESCRIPTION("WHCI Wireless USB host controller driver");
+MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/host/whci/hw.c b/drivers/usb/host/whci/hw.c
new file mode 100644 (file)
index 0000000..ac86e59
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Wireless Host Controller (WHC) hardware access helpers.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/uwb/umc.h>
+
+#include "../../wusbcore/wusbhc.h"
+
+#include "whcd.h"
+
+void whc_write_wusbcmd(struct whc *whc, u32 mask, u32 val)
+{
+       unsigned long flags;
+       u32 cmd;
+
+       spin_lock_irqsave(&whc->lock, flags);
+
+       cmd = le_readl(whc->base + WUSBCMD);
+       cmd = (cmd & ~mask) | val;
+       le_writel(cmd, whc->base + WUSBCMD);
+
+       spin_unlock_irqrestore(&whc->lock, flags);
+}
+
+/**
+ * whc_do_gencmd - start a generic command via the WUSBGENCMDSTS register
+ * @whc:    the WHCI HC
+ * @cmd:    command to start.
+ * @params: parameters for the command (the WUSBGENCMDPARAMS register value).
+ * @addr:   pointer to any data for the command (may be NULL).
+ * @len:    length of the data (if any).
+ */
+int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len)
+{
+       unsigned long flags;
+       dma_addr_t dma_addr;
+       int t;
+
+       mutex_lock(&whc->mutex);
+
+       /* Wait for previous command to complete. */
+       t = wait_event_timeout(whc->cmd_wq,
+                              (le_readl(whc->base + WUSBGENCMDSTS) & WUSBGENCMDSTS_ACTIVE) == 0,
+                              WHC_GENCMD_TIMEOUT_MS);
+       if (t == 0) {
+               dev_err(&whc->umc->dev, "generic command timeout (%04x/%04x)\n",
+                       le_readl(whc->base + WUSBGENCMDSTS),
+                       le_readl(whc->base + WUSBGENCMDPARAMS));
+               return -ETIMEDOUT;
+       }
+
+       if (addr) {
+               memcpy(whc->gen_cmd_buf, addr, len);
+               dma_addr = whc->gen_cmd_buf_dma;
+       } else
+               dma_addr = 0;
+
+       /* Poke registers to start cmd. */
+       spin_lock_irqsave(&whc->lock, flags);
+
+       le_writel(params, whc->base + WUSBGENCMDPARAMS);
+       le_writeq(dma_addr, whc->base + WUSBGENADDR);
+
+       le_writel(WUSBGENCMDSTS_ACTIVE | WUSBGENCMDSTS_IOC | cmd,
+                 whc->base + WUSBGENCMDSTS);
+
+       spin_unlock_irqrestore(&whc->lock, flags);
+
+       mutex_unlock(&whc->mutex);
+
+       return 0;
+}
diff --git a/drivers/usb/host/whci/init.c b/drivers/usb/host/whci/init.c
new file mode 100644 (file)
index 0000000..34a783c
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Wireless Host Controller (WHC) initialization.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/uwb/umc.h>
+
+#include "../../wusbcore/wusbhc.h"
+
+#include "whcd.h"
+
+/*
+ * Reset the host controller.
+ */
+static void whc_hw_reset(struct whc *whc)
+{
+       le_writel(WUSBCMD_WHCRESET, whc->base + WUSBCMD);
+       whci_wait_for(&whc->umc->dev, whc->base + WUSBCMD, WUSBCMD_WHCRESET, 0,
+                     100, "reset");
+}
+
+static void whc_hw_init_di_buf(struct whc *whc)
+{
+       int d;
+
+       /* Disable all entries in the Device Information buffer. */
+       for (d = 0; d < whc->n_devices; d++)
+               whc->di_buf[d].addr_sec_info = WHC_DI_DISABLE;
+
+       le_writeq(whc->di_buf_dma, whc->base + WUSBDEVICEINFOADDR);
+}
+
+static void whc_hw_init_dn_buf(struct whc *whc)
+{
+       /* Clear the Device Notification buffer to ensure the V (valid)
+        * bits are clear.  */
+       memset(whc->dn_buf, 0, 4096);
+
+       le_writeq(whc->dn_buf_dma, whc->base + WUSBDNTSBUFADDR);
+}
+
+int whc_init(struct whc *whc)
+{
+       u32 whcsparams;
+       int ret, i;
+       resource_size_t start, len;
+
+       spin_lock_init(&whc->lock);
+       mutex_init(&whc->mutex);
+       init_waitqueue_head(&whc->cmd_wq);
+       init_waitqueue_head(&whc->async_list_wq);
+       init_waitqueue_head(&whc->periodic_list_wq);
+       whc->workqueue = create_singlethread_workqueue(dev_name(&whc->umc->dev));
+       if (whc->workqueue == NULL) {
+               ret = -ENOMEM;
+               goto error;
+       }
+       INIT_WORK(&whc->dn_work, whc_dn_work);
+
+       INIT_WORK(&whc->async_work, scan_async_work);
+       INIT_LIST_HEAD(&whc->async_list);
+       INIT_LIST_HEAD(&whc->async_removed_list);
+
+       INIT_WORK(&whc->periodic_work, scan_periodic_work);
+       for (i = 0; i < 5; i++)
+               INIT_LIST_HEAD(&whc->periodic_list[i]);
+       INIT_LIST_HEAD(&whc->periodic_removed_list);
+
+       /* Map HC registers. */
+       start = whc->umc->resource.start;
+       len   = whc->umc->resource.end - start + 1;
+       if (!request_mem_region(start, len, "whci-hc")) {
+               dev_err(&whc->umc->dev, "can't request HC region\n");
+               ret = -EBUSY;
+               goto error;
+       }
+       whc->base_phys = start;
+       whc->base = ioremap(start, len);
+       if (!whc->base) {
+               dev_err(&whc->umc->dev, "ioremap\n");
+               ret = -ENOMEM;
+               goto error;
+       }
+
+       whc_hw_reset(whc);
+
+       /* Read maximum number of devices, keys and MMC IEs. */
+       whcsparams = le_readl(whc->base + WHCSPARAMS);
+       whc->n_devices = WHCSPARAMS_TO_N_DEVICES(whcsparams);
+       whc->n_keys    = WHCSPARAMS_TO_N_KEYS(whcsparams);
+       whc->n_mmc_ies = WHCSPARAMS_TO_N_MMC_IES(whcsparams);
+
+       dev_dbg(&whc->umc->dev, "N_DEVICES = %d, N_KEYS = %d, N_MMC_IES = %d\n",
+               whc->n_devices, whc->n_keys, whc->n_mmc_ies);
+
+       whc->qset_pool = dma_pool_create("qset", &whc->umc->dev,
+                                        sizeof(struct whc_qset), 64, 0);
+       if (whc->qset_pool == NULL) {
+               ret = -ENOMEM;
+               goto error;
+       }
+
+       ret = asl_init(whc);
+       if (ret < 0)
+               goto error;
+       ret = pzl_init(whc);
+       if (ret < 0)
+               goto error;
+
+       /* Allocate and initialize a buffer for generic commands, the
+          Device Information buffer, and the Device Notification
+          buffer. */
+
+       whc->gen_cmd_buf = dma_alloc_coherent(&whc->umc->dev, WHC_GEN_CMD_DATA_LEN,
+                                             &whc->gen_cmd_buf_dma, GFP_KERNEL);
+       if (whc->gen_cmd_buf == NULL) {
+               ret = -ENOMEM;
+               goto error;
+       }
+
+       whc->dn_buf = dma_alloc_coherent(&whc->umc->dev,
+                                        sizeof(struct dn_buf_entry) * WHC_N_DN_ENTRIES,
+                                        &whc->dn_buf_dma, GFP_KERNEL);
+       if (!whc->dn_buf) {
+               ret = -ENOMEM;
+               goto error;
+       }
+       whc_hw_init_dn_buf(whc);
+
+       whc->di_buf = dma_alloc_coherent(&whc->umc->dev,
+                                        sizeof(struct di_buf_entry) * whc->n_devices,
+                                        &whc->di_buf_dma, GFP_KERNEL);
+       if (!whc->di_buf) {
+               ret = -ENOMEM;
+               goto error;
+       }
+       whc_hw_init_di_buf(whc);
+
+       return 0;
+
+error:
+       whc_clean_up(whc);
+       return ret;
+}
+
+void whc_clean_up(struct whc *whc)
+{
+       resource_size_t len;
+
+       if (whc->di_buf)
+               dma_free_coherent(&whc->umc->dev, sizeof(struct di_buf_entry) * whc->n_devices,
+                                 whc->di_buf, whc->di_buf_dma);
+       if (whc->dn_buf)
+               dma_free_coherent(&whc->umc->dev, sizeof(struct dn_buf_entry) * WHC_N_DN_ENTRIES,
+                                 whc->dn_buf, whc->dn_buf_dma);
+       if (whc->gen_cmd_buf)
+               dma_free_coherent(&whc->umc->dev, WHC_GEN_CMD_DATA_LEN,
+                                 whc->gen_cmd_buf, whc->gen_cmd_buf_dma);
+
+       pzl_clean_up(whc);
+       asl_clean_up(whc);
+
+       if (whc->qset_pool)
+               dma_pool_destroy(whc->qset_pool);
+
+       len   = whc->umc->resource.end - whc->umc->resource.start + 1;
+       if (whc->base)
+               iounmap(whc->base);
+       if (whc->base_phys)
+               release_mem_region(whc->base_phys, len);
+
+       if (whc->workqueue)
+               destroy_workqueue(whc->workqueue);
+}
diff --git a/drivers/usb/host/whci/int.c b/drivers/usb/host/whci/int.c
new file mode 100644 (file)
index 0000000..fce0117
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Wireless Host Controller (WHC) interrupt handling.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/uwb/umc.h>
+
+#include "../../wusbcore/wusbhc.h"
+
+#include "whcd.h"
+
+static void transfer_done(struct whc *whc)
+{
+       queue_work(whc->workqueue, &whc->async_work);
+       queue_work(whc->workqueue, &whc->periodic_work);
+}
+
+irqreturn_t whc_int_handler(struct usb_hcd *hcd)
+{
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(hcd);
+       struct whc *whc = wusbhc_to_whc(wusbhc);
+       u32 sts;
+
+       sts = le_readl(whc->base + WUSBSTS);
+       if (!(sts & WUSBSTS_INT_MASK))
+               return IRQ_NONE;
+       le_writel(sts & WUSBSTS_INT_MASK, whc->base + WUSBSTS);
+
+       if (sts & WUSBSTS_GEN_CMD_DONE)
+               wake_up(&whc->cmd_wq);
+
+       if (sts & WUSBSTS_HOST_ERR)
+               dev_err(&whc->umc->dev, "FIXME: host system error\n");
+
+       if (sts & WUSBSTS_ASYNC_SCHED_SYNCED)
+               wake_up(&whc->async_list_wq);
+
+       if (sts & WUSBSTS_PERIODIC_SCHED_SYNCED)
+               wake_up(&whc->periodic_list_wq);
+
+       if (sts & WUSBSTS_DNTS_INT)
+               queue_work(whc->workqueue, &whc->dn_work);
+
+       /*
+        * A transfer completed (see [WHCI] section 4.7.1.2 for when
+        * this occurs).
+        */
+       if (sts & (WUSBSTS_INT | WUSBSTS_ERR_INT))
+               transfer_done(whc);
+
+       return IRQ_HANDLED;
+}
+
+static int process_dn_buf(struct whc *whc)
+{
+       struct wusbhc *wusbhc = &whc->wusbhc;
+       struct dn_buf_entry *dn;
+       int processed = 0;
+
+       for (dn = whc->dn_buf; dn < whc->dn_buf + WHC_N_DN_ENTRIES; dn++) {
+               if (dn->status & WHC_DN_STATUS_VALID) {
+                       wusbhc_handle_dn(wusbhc, dn->src_addr,
+                                        (struct wusb_dn_hdr *)dn->dn_data,
+                                        dn->msg_size);
+                       dn->status &= ~WHC_DN_STATUS_VALID;
+                       processed++;
+               }
+       }
+       return processed;
+}
+
+void whc_dn_work(struct work_struct *work)
+{
+       struct whc *whc = container_of(work, struct whc, dn_work);
+       int processed;
+
+       do {
+               processed = process_dn_buf(whc);
+       } while (processed);
+}
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c
new file mode 100644 (file)
index 0000000..8d62df0
--- /dev/null
@@ -0,0 +1,398 @@
+/*
+ * Wireless Host Controller (WHC) periodic schedule management.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/uwb/umc.h>
+#include <linux/usb.h>
+#define D_LOCAL 0
+#include <linux/uwb/debug.h>
+
+#include "../../wusbcore/wusbhc.h"
+
+#include "whcd.h"
+
+#if D_LOCAL >= 4
+static void dump_pzl(struct whc *whc, const char *tag)
+{
+       struct device *dev = &whc->umc->dev;
+       struct whc_qset *qset;
+       int period = 0;
+
+       d_printf(4, dev, "PZL %s\n", tag);
+
+       for (period = 0; period < 5; period++) {
+               d_printf(4, dev, "Period %d\n", period);
+               list_for_each_entry(qset, &whc->periodic_list[period], list_node) {
+                       dump_qset(qset, dev);
+               }
+       }
+}
+#else
+static inline void dump_pzl(struct whc *whc, const char *tag)
+{
+}
+#endif
+
+static void update_pzl_pointers(struct whc *whc, int period, u64 addr)
+{
+       switch (period) {
+       case 0:
+               whc_qset_set_link_ptr(&whc->pz_list[0], addr);
+               whc_qset_set_link_ptr(&whc->pz_list[2], addr);
+               whc_qset_set_link_ptr(&whc->pz_list[4], addr);
+               whc_qset_set_link_ptr(&whc->pz_list[6], addr);
+               whc_qset_set_link_ptr(&whc->pz_list[8], addr);
+               whc_qset_set_link_ptr(&whc->pz_list[10], addr);
+               whc_qset_set_link_ptr(&whc->pz_list[12], addr);
+               whc_qset_set_link_ptr(&whc->pz_list[14], addr);
+               break;
+       case 1:
+               whc_qset_set_link_ptr(&whc->pz_list[1], addr);
+               whc_qset_set_link_ptr(&whc->pz_list[5], addr);
+               whc_qset_set_link_ptr(&whc->pz_list[9], addr);
+               whc_qset_set_link_ptr(&whc->pz_list[13], addr);
+               break;
+       case 2:
+               whc_qset_set_link_ptr(&whc->pz_list[3], addr);
+               whc_qset_set_link_ptr(&whc->pz_list[11], addr);
+               break;
+       case 3:
+               whc_qset_set_link_ptr(&whc->pz_list[7], addr);
+               break;
+       case 4:
+               whc_qset_set_link_ptr(&whc->pz_list[15], addr);
+               break;
+       }
+}
+
+/*
+ * Return the 'period' to use for this qset.  The minimum interval for
+ * the endpoint is used so whatever urbs are submitted the device is
+ * polled often enough.
+ */
+static int qset_get_period(struct whc *whc, struct whc_qset *qset)
+{
+       uint8_t bInterval = qset->ep->desc.bInterval;
+
+       if (bInterval < 6)
+               bInterval = 6;
+       if (bInterval > 10)
+               bInterval = 10;
+       return bInterval - 6;
+}
+
+static void qset_insert_in_sw_list(struct whc *whc, struct whc_qset *qset)
+{
+       int period;
+
+       period = qset_get_period(whc, qset);
+
+       qset_clear(whc, qset);
+       list_move(&qset->list_node, &whc->periodic_list[period]);
+       qset->in_sw_list = true;
+}
+
+static void pzl_qset_remove(struct whc *whc, struct whc_qset *qset)
+{
+       list_move(&qset->list_node, &whc->periodic_removed_list);
+       qset->in_hw_list = false;
+       qset->in_sw_list = false;
+}
+
+/**
+ * pzl_process_qset - process any recently inactivated or halted qTDs
+ * in a qset.
+ *
+ * After inactive qTDs are removed, new qTDs can be added if the
+ * urb queue still contains URBs.
+ *
+ * Returns the schedule updates required.
+ */
+static enum whc_update pzl_process_qset(struct whc *whc, struct whc_qset *qset)
+{
+       enum whc_update update = 0;
+       uint32_t status = 0;
+
+       while (qset->ntds) {
+               struct whc_qtd *td;
+               int t;
+
+               t = qset->td_start;
+               td = &qset->qtd[qset->td_start];
+               status = le32_to_cpu(td->status);
+
+               /*
+                * Nothing to do with a still active qTD.
+                */
+               if (status & QTD_STS_ACTIVE)
+                       break;
+
+               if (status & QTD_STS_HALTED) {
+                       /* Ug, an error. */
+                       process_halted_qtd(whc, qset, td);
+                       goto done;
+               }
+
+               /* Mmm, a completed qTD. */
+               process_inactive_qtd(whc, qset, td);
+       }
+
+       update |= qset_add_qtds(whc, qset);
+
+done:
+       /*
+        * If there are no qTDs in this qset, remove it from the PZL.
+        */
+       if (qset->remove && qset->ntds == 0) {
+               pzl_qset_remove(whc, qset);
+               update |= WHC_UPDATE_REMOVED;
+       }
+
+       return update;
+}
+
+/**
+ * pzl_start - start the periodic schedule
+ * @whc: the WHCI host controller
+ *
+ * The PZL must be valid (e.g., all entries in the list should have
+ * the T bit set).
+ */
+void pzl_start(struct whc *whc)
+{
+       le_writeq(whc->pz_list_dma, whc->base + WUSBPERIODICLISTBASE);
+
+       whc_write_wusbcmd(whc, WUSBCMD_PERIODIC_EN, WUSBCMD_PERIODIC_EN);
+       whci_wait_for(&whc->umc->dev, whc->base + WUSBSTS,
+                     WUSBSTS_PERIODIC_SCHED, WUSBSTS_PERIODIC_SCHED,
+                     1000, "start PZL");
+}
+
+/**
+ * pzl_stop - stop the periodic schedule
+ * @whc: the WHCI host controller
+ */
+void pzl_stop(struct whc *whc)
+{
+       whc_write_wusbcmd(whc, WUSBCMD_PERIODIC_EN, 0);
+       whci_wait_for(&whc->umc->dev, whc->base + WUSBSTS,
+                     WUSBSTS_PERIODIC_SCHED, 0,
+                     1000, "stop PZL");
+}
+
+void pzl_update(struct whc *whc, uint32_t wusbcmd)
+{
+       whc_write_wusbcmd(whc, wusbcmd, wusbcmd);
+       wait_event(whc->periodic_list_wq,
+                  (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0);
+}
+
+static void update_pzl_hw_view(struct whc *whc)
+{
+       struct whc_qset *qset, *t;
+       int period;
+       u64 tmp_qh = 0;
+
+       for (period = 0; period < 5; period++) {
+               list_for_each_entry_safe(qset, t, &whc->periodic_list[period], list_node) {
+                       whc_qset_set_link_ptr(&qset->qh.link, tmp_qh);
+                       tmp_qh = qset->qset_dma;
+                       qset->in_hw_list = true;
+               }
+               update_pzl_pointers(whc, period, tmp_qh);
+       }
+}
+
+/**
+ * scan_periodic_work - scan the PZL for qsets to process.
+ *
+ * Process each qset in the PZL in turn and then signal the WHC that
+ * the PZL has been updated.
+ *
+ * Then start, stop or update the periodic schedule as required.
+ */
+void scan_periodic_work(struct work_struct *work)
+{
+       struct whc *whc = container_of(work, struct whc, periodic_work);
+       struct whc_qset *qset, *t;
+       enum whc_update update = 0;
+       int period;
+
+       spin_lock_irq(&whc->lock);
+
+       dump_pzl(whc, "before processing");
+
+       for (period = 4; period >= 0; period--) {
+               list_for_each_entry_safe(qset, t, &whc->periodic_list[period], list_node) {
+                       if (!qset->in_hw_list)
+                               update |= WHC_UPDATE_ADDED;
+                       update |= pzl_process_qset(whc, qset);
+               }
+       }
+
+       if (update & (WHC_UPDATE_ADDED | WHC_UPDATE_REMOVED))
+               update_pzl_hw_view(whc);
+
+       dump_pzl(whc, "after processing");
+
+       spin_unlock_irq(&whc->lock);
+
+       if (update) {
+               uint32_t wusbcmd = WUSBCMD_PERIODIC_UPDATED | WUSBCMD_PERIODIC_SYNCED_DB;
+               if (update & WHC_UPDATE_REMOVED)
+                       wusbcmd |= WUSBCMD_PERIODIC_QSET_RM;
+               pzl_update(whc, wusbcmd);
+       }
+
+       /*
+        * Now that the PZL is updated, complete the removal of any
+        * removed qsets.
+        */
+       spin_lock(&whc->lock);
+
+       list_for_each_entry_safe(qset, t, &whc->periodic_removed_list, list_node) {
+               qset_remove_complete(whc, qset);
+       }
+
+       spin_unlock(&whc->lock);
+}
+
+/**
+ * pzl_urb_enqueue - queue an URB onto the periodic list (PZL)
+ * @whc: the WHCI host controller
+ * @urb: the URB to enqueue
+ * @mem_flags: flags for any memory allocations
+ *
+ * The qset for the endpoint is obtained and the urb queued on to it.
+ *
+ * Work is scheduled to update the hardware's view of the PZL.
+ */
+int pzl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags)
+{
+       struct whc_qset *qset;
+       int err;
+       unsigned long flags;
+
+       spin_lock_irqsave(&whc->lock, flags);
+
+       qset = get_qset(whc, urb, GFP_ATOMIC);
+       if (qset == NULL)
+               err = -ENOMEM;
+       else
+               err = qset_add_urb(whc, qset, urb, GFP_ATOMIC);
+       if (!err) {
+               usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
+               if (!qset->in_sw_list)
+                       qset_insert_in_sw_list(whc, qset);
+       }
+
+       spin_unlock_irqrestore(&whc->lock, flags);
+
+       if (!err)
+               queue_work(whc->workqueue, &whc->periodic_work);
+
+       return 0;
+}
+
+/**
+ * pzl_urb_dequeue - remove an URB (qset) from the periodic list
+ * @whc: the WHCI host controller
+ * @urb: the URB to dequeue
+ * @status: the current status of the URB
+ *
+ * URBs that do yet have qTDs can simply be removed from the software
+ * queue, otherwise the qset must be removed so the qTDs can be safely
+ * removed.
+ */
+int pzl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
+{
+       struct whc_urb *wurb = urb->hcpriv;
+       struct whc_qset *qset = wurb->qset;
+       struct whc_std *std, *t;
+       int ret;
+       unsigned long flags;
+
+       spin_lock_irqsave(&whc->lock, flags);
+
+       ret = usb_hcd_check_unlink_urb(&whc->wusbhc.usb_hcd, urb, status);
+       if (ret < 0)
+               goto out;
+
+       list_for_each_entry_safe(std, t, &qset->stds, list_node) {
+               if (std->urb == urb)
+                       qset_free_std(whc, std);
+               else
+                       std->qtd = NULL; /* so this std is re-added when the qset is */
+       }
+
+       pzl_qset_remove(whc, qset);
+       wurb->status = status;
+       wurb->is_async = false;
+       queue_work(whc->workqueue, &wurb->dequeue_work);
+
+out:
+       spin_unlock_irqrestore(&whc->lock, flags);
+
+       return ret;
+}
+
+/**
+ * pzl_qset_delete - delete a qset from the PZL
+ */
+void pzl_qset_delete(struct whc *whc, struct whc_qset *qset)
+{
+       qset->remove = 1;
+       queue_work(whc->workqueue, &whc->periodic_work);
+       qset_delete(whc, qset);
+}
+
+
+/**
+ * pzl_init - initialize the periodic zone list
+ * @whc: the WHCI host controller
+ */
+int pzl_init(struct whc *whc)
+{
+       int i;
+
+       whc->pz_list = dma_alloc_coherent(&whc->umc->dev, sizeof(u64) * 16,
+                                         &whc->pz_list_dma, GFP_KERNEL);
+       if (whc->pz_list == NULL)
+               return -ENOMEM;
+
+       /* Set T bit on all elements in PZL. */
+       for (i = 0; i < 16; i++)
+               whc->pz_list[i] = cpu_to_le64(QH_LINK_NTDS(8) | QH_LINK_T);
+
+       le_writeq(whc->pz_list_dma, whc->base + WUSBPERIODICLISTBASE);
+
+       return 0;
+}
+
+/**
+ * pzl_clean_up - free PZL resources
+ * @whc: the WHCI host controller
+ *
+ * The PZL is stopped and empty.
+ */
+void pzl_clean_up(struct whc *whc)
+{
+       if (whc->pz_list)
+               dma_free_coherent(&whc->umc->dev,  sizeof(u64) * 16, whc->pz_list,
+                                 whc->pz_list_dma);
+}
diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c
new file mode 100644 (file)
index 0000000..0420037
--- /dev/null
@@ -0,0 +1,567 @@
+/*
+ * Wireless Host Controller (WHC) qset management.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/uwb/umc.h>
+#include <linux/usb.h>
+
+#include "../../wusbcore/wusbhc.h"
+
+#include "whcd.h"
+
+void dump_qset(struct whc_qset *qset, struct device *dev)
+{
+       struct whc_std *std;
+       struct urb *urb = NULL;
+       int i;
+
+       dev_dbg(dev, "qset %08x\n", (u32)qset->qset_dma);
+       dev_dbg(dev, "  -> %08x\n", (u32)qset->qh.link);
+       dev_dbg(dev, "  info: %08x %08x %08x\n",
+               qset->qh.info1, qset->qh.info2,  qset->qh.info3);
+       dev_dbg(dev, "  sts: %04x errs: %d\n", qset->qh.status, qset->qh.err_count);
+       dev_dbg(dev, "  TD: sts: %08x opts: %08x\n",
+               qset->qh.overlay.qtd.status, qset->qh.overlay.qtd.options);
+
+       for (i = 0; i < WHCI_QSET_TD_MAX; i++) {
+               dev_dbg(dev, "  %c%c TD[%d]: sts: %08x opts: %08x ptr: %08x\n",
+                       i == qset->td_start ? 'S' : ' ',
+                       i == qset->td_end ? 'E' : ' ',
+                       i, qset->qtd[i].status, qset->qtd[i].options,
+                       (u32)qset->qtd[i].page_list_ptr);
+       }
+       dev_dbg(dev, "  ntds: %d\n", qset->ntds);
+       list_for_each_entry(std, &qset->stds, list_node) {
+               if (urb != std->urb) {
+                       urb = std->urb;
+                       dev_dbg(dev, "  urb %p transferred: %d bytes\n", urb,
+                               urb->actual_length);
+               }
+               if (std->qtd)
+                       dev_dbg(dev, "    sTD[%td]: %zu bytes @ %08x\n",
+                               std->qtd - &qset->qtd[0],
+                               std->len, std->num_pointers ?
+                               (u32)(std->pl_virt[0].buf_ptr) : (u32)std->dma_addr);
+               else
+                       dev_dbg(dev, "    sTD[-]: %zd bytes @ %08x\n",
+                               std->len, std->num_pointers ?
+                               (u32)(std->pl_virt[0].buf_ptr) : (u32)std->dma_addr);
+       }
+}
+
+struct whc_qset *qset_alloc(struct whc *whc, gfp_t mem_flags)
+{
+       struct whc_qset *qset;
+       dma_addr_t dma;
+
+       qset = dma_pool_alloc(whc->qset_pool, mem_flags, &dma);
+       if (qset == NULL)
+               return NULL;
+       memset(qset, 0, sizeof(struct whc_qset));
+
+       qset->qset_dma = dma;
+       qset->whc = whc;
+
+       INIT_LIST_HEAD(&qset->list_node);
+       INIT_LIST_HEAD(&qset->stds);
+
+       return qset;
+}
+
+/**
+ * qset_fill_qh - fill the static endpoint state in a qset's QHead
+ * @qset: the qset whose QH needs initializing with static endpoint
+ *        state
+ * @urb:  an urb for a transfer to this endpoint
+ */
+static void qset_fill_qh(struct whc_qset *qset, struct urb *urb)
+{
+       struct usb_device *usb_dev = urb->dev;
+       struct usb_wireless_ep_comp_descriptor *epcd;
+       bool is_out;
+
+       is_out = usb_pipeout(urb->pipe);
+
+       epcd = (struct usb_wireless_ep_comp_descriptor *)qset->ep->extra;
+
+       if (epcd) {
+               qset->max_seq = epcd->bMaxSequence;
+               qset->max_burst = epcd->bMaxBurst;
+       } else {
+               qset->max_seq = 2;
+               qset->max_burst = 1;
+       }
+
+       qset->qh.info1 = cpu_to_le32(
+               QH_INFO1_EP(usb_pipeendpoint(urb->pipe))
+               | (is_out ? QH_INFO1_DIR_OUT : QH_INFO1_DIR_IN)
+               | usb_pipe_to_qh_type(urb->pipe)
+               | QH_INFO1_DEV_INFO_IDX(wusb_port_no_to_idx(usb_dev->portnum))
+               | QH_INFO1_MAX_PKT_LEN(usb_maxpacket(urb->dev, urb->pipe, is_out))
+               );
+       qset->qh.info2 = cpu_to_le32(
+               QH_INFO2_BURST(qset->max_burst)
+               | QH_INFO2_DBP(0)
+               | QH_INFO2_MAX_COUNT(3)
+               | QH_INFO2_MAX_RETRY(3)
+               | QH_INFO2_MAX_SEQ(qset->max_seq - 1)
+               );
+       /* FIXME: where can we obtain these Tx parameters from?  Why
+        * doesn't the chip know what Tx power to use? It knows the Rx
+        * strength and can presumably guess the Tx power required
+        * from that? */
+       qset->qh.info3 = cpu_to_le32(
+               QH_INFO3_TX_RATE_53_3
+               | QH_INFO3_TX_PWR(0) /* 0 == max power */
+               );
+}
+
+/**
+ * qset_clear - clear fields in a qset so it may be reinserted into a
+ * schedule
+ */
+void qset_clear(struct whc *whc, struct whc_qset *qset)
+{
+       qset->td_start = qset->td_end = qset->ntds = 0;
+       qset->remove = 0;
+
+       qset->qh.link = cpu_to_le32(QH_LINK_NTDS(8) | QH_LINK_T);
+       qset->qh.status = cpu_to_le16(QH_STATUS_ICUR(qset->td_start));
+       qset->qh.err_count = 0;
+       qset->qh.cur_window = cpu_to_le32((1 << qset->max_burst) - 1);
+       qset->qh.scratch[0] = 0;
+       qset->qh.scratch[1] = 0;
+       qset->qh.scratch[2] = 0;
+
+       memset(&qset->qh.overlay, 0, sizeof(qset->qh.overlay));
+
+       init_completion(&qset->remove_complete);
+}
+
+/**
+ * get_qset - get the qset for an async endpoint
+ *
+ * A new qset is created if one does not already exist.
+ */
+struct whc_qset *get_qset(struct whc *whc, struct urb *urb,
+                                gfp_t mem_flags)
+{
+       struct whc_qset *qset;
+
+       qset = urb->ep->hcpriv;
+       if (qset == NULL) {
+               qset = qset_alloc(whc, mem_flags);
+               if (qset == NULL)
+                       return NULL;
+
+               qset->ep = urb->ep;
+               urb->ep->hcpriv = qset;
+               qset_fill_qh(qset, urb);
+       }
+       return qset;
+}
+
+void qset_remove_complete(struct whc *whc, struct whc_qset *qset)
+{
+       list_del_init(&qset->list_node);
+       complete(&qset->remove_complete);
+}
+
+/**
+ * qset_add_qtds - add qTDs for an URB to a qset
+ *
+ * Returns true if the list (ASL/PZL) must be updated because (for a
+ * WHCI 0.95 controller) an activated qTD was pointed to be iCur.
+ */
+enum whc_update qset_add_qtds(struct whc *whc, struct whc_qset *qset)
+{
+       struct whc_std *std;
+       enum whc_update update = 0;
+
+       list_for_each_entry(std, &qset->stds, list_node) {
+               struct whc_qtd *qtd;
+               uint32_t status;
+
+               if (qset->ntds >= WHCI_QSET_TD_MAX
+                   || (qset->pause_after_urb && std->urb != qset->pause_after_urb))
+                       break;
+
+               if (std->qtd)
+                       continue; /* already has a qTD */
+
+               qtd = std->qtd = &qset->qtd[qset->td_end];
+
+               /* Fill in setup bytes for control transfers. */
+               if (usb_pipecontrol(std->urb->pipe))
+                       memcpy(qtd->setup, std->urb->setup_packet, 8);
+
+               status = QTD_STS_ACTIVE | QTD_STS_LEN(std->len);
+
+               if (whc_std_last(std) && usb_pipeout(std->urb->pipe))
+                       status |= QTD_STS_LAST_PKT;
+
+               /*
+                * For an IN transfer the iAlt field should be set so
+                * the h/w will automatically advance to the next
+                * transfer. However, if there are 8 or more TDs
+                * remaining in this transfer then iAlt cannot be set
+                * as it could point to somewhere in this transfer.
+                */
+               if (std->ntds_remaining < WHCI_QSET_TD_MAX) {
+                       int ialt;
+                       ialt = (qset->td_end + std->ntds_remaining) % WHCI_QSET_TD_MAX;
+                       status |= QTD_STS_IALT(ialt);
+               } else if (usb_pipein(std->urb->pipe))
+                       qset->pause_after_urb = std->urb;
+
+               if (std->num_pointers)
+                       qtd->options = cpu_to_le32(QTD_OPT_IOC);
+               else
+                       qtd->options = cpu_to_le32(QTD_OPT_IOC | QTD_OPT_SMALL);
+               qtd->page_list_ptr = cpu_to_le64(std->dma_addr);
+
+               qtd->status = cpu_to_le32(status);
+
+               if (QH_STATUS_TO_ICUR(qset->qh.status) == qset->td_end)
+                       update = WHC_UPDATE_UPDATED;
+
+               if (++qset->td_end >= WHCI_QSET_TD_MAX)
+                       qset->td_end = 0;
+               qset->ntds++;
+       }
+
+       return update;
+}
+
+/**
+ * qset_remove_qtd - remove the first qTD from a qset.
+ *
+ * The qTD might be still active (if it's part of a IN URB that
+ * resulted in a short read) so ensure it's deactivated.
+ */
+static void qset_remove_qtd(struct whc *whc, struct whc_qset *qset)
+{
+       qset->qtd[qset->td_start].status = 0;
+
+       if (++qset->td_start >= WHCI_QSET_TD_MAX)
+               qset->td_start = 0;
+       qset->ntds--;
+}
+
+/**
+ * qset_free_std - remove an sTD and free it.
+ * @whc: the WHCI host controller
+ * @std: the sTD to remove and free.
+ */
+void qset_free_std(struct whc *whc, struct whc_std *std)
+{
+       list_del(&std->list_node);
+       if (std->num_pointers) {
+               dma_unmap_single(whc->wusbhc.dev, std->dma_addr,
+                                std->num_pointers * sizeof(struct whc_page_list_entry),
+                                DMA_TO_DEVICE);
+               kfree(std->pl_virt);
+       }
+
+       kfree(std);
+}
+
+/**
+ * qset_remove_qtds - remove an URB's qTDs (and sTDs).
+ */
+static void qset_remove_qtds(struct whc *whc, struct whc_qset *qset,
+                            struct urb *urb)
+{
+       struct whc_std *std, *t;
+
+       list_for_each_entry_safe(std, t, &qset->stds, list_node) {
+               if (std->urb != urb)
+                       break;
+               if (std->qtd != NULL)
+                       qset_remove_qtd(whc, qset);
+               qset_free_std(whc, std);
+       }
+}
+
+/**
+ * qset_free_stds - free any remaining sTDs for an URB.
+ */
+static void qset_free_stds(struct whc_qset *qset, struct urb *urb)
+{
+       struct whc_std *std, *t;
+
+       list_for_each_entry_safe(std, t, &qset->stds, list_node) {
+               if (std->urb == urb)
+                       qset_free_std(qset->whc, std);
+       }
+}
+
+static int qset_fill_page_list(struct whc *whc, struct whc_std *std, gfp_t mem_flags)
+{
+       dma_addr_t dma_addr = std->dma_addr;
+       dma_addr_t sp, ep;
+       size_t std_len = std->len;
+       size_t pl_len;
+       int p;
+
+       sp = ALIGN(dma_addr, WHCI_PAGE_SIZE);
+       ep = dma_addr + std_len;
+       std->num_pointers = DIV_ROUND_UP(ep - sp, WHCI_PAGE_SIZE);
+
+       pl_len = std->num_pointers * sizeof(struct whc_page_list_entry);
+       std->pl_virt = kmalloc(pl_len, mem_flags);
+       if (std->pl_virt == NULL)
+               return -ENOMEM;
+       std->dma_addr = dma_map_single(whc->wusbhc.dev, std->pl_virt, pl_len, DMA_TO_DEVICE);
+
+       for (p = 0; p < std->num_pointers; p++) {
+               std->pl_virt[p].buf_ptr = cpu_to_le64(dma_addr);
+               dma_addr = ALIGN(dma_addr + WHCI_PAGE_SIZE, WHCI_PAGE_SIZE);
+       }
+
+       return 0;
+}
+
+/**
+ * urb_dequeue_work - executes asl/pzl update and gives back the urb to the system.
+ */
+static void urb_dequeue_work(struct work_struct *work)
+{
+       struct whc_urb *wurb = container_of(work, struct whc_urb, dequeue_work);
+       struct whc_qset *qset = wurb->qset;
+       struct whc *whc = qset->whc;
+       unsigned long flags;
+
+       if (wurb->is_async == true)
+               asl_update(whc, WUSBCMD_ASYNC_UPDATED
+                          | WUSBCMD_ASYNC_SYNCED_DB
+                          | WUSBCMD_ASYNC_QSET_RM);
+       else
+               pzl_update(whc, WUSBCMD_PERIODIC_UPDATED
+                          | WUSBCMD_PERIODIC_SYNCED_DB
+                          | WUSBCMD_PERIODIC_QSET_RM);
+
+       spin_lock_irqsave(&whc->lock, flags);
+       qset_remove_urb(whc, qset, wurb->urb, wurb->status);
+       spin_unlock_irqrestore(&whc->lock, flags);
+}
+
+/**
+ * qset_add_urb - add an urb to the qset's queue.
+ *
+ * The URB is chopped into sTDs, one for each qTD that will required.
+ * At least one qTD (and sTD) is required even if the transfer has no
+ * data (e.g., for some control transfers).
+ */
+int qset_add_urb(struct whc *whc, struct whc_qset *qset, struct urb *urb,
+       gfp_t mem_flags)
+{
+       struct whc_urb *wurb;
+       int remaining = urb->transfer_buffer_length;
+       u64 transfer_dma = urb->transfer_dma;
+       int ntds_remaining;
+
+       ntds_remaining = DIV_ROUND_UP(remaining, QTD_MAX_XFER_SIZE);
+       if (ntds_remaining == 0)
+               ntds_remaining = 1;
+
+       wurb = kzalloc(sizeof(struct whc_urb), mem_flags);
+       if (wurb == NULL)
+               goto err_no_mem;
+       urb->hcpriv = wurb;
+       wurb->qset = qset;
+       wurb->urb = urb;
+       INIT_WORK(&wurb->dequeue_work, urb_dequeue_work);
+
+       while (ntds_remaining) {
+               struct whc_std *std;
+               size_t std_len;
+
+               std = kmalloc(sizeof(struct whc_std), mem_flags);
+               if (std == NULL)
+                       goto err_no_mem;
+
+               std_len = remaining;
+               if (std_len > QTD_MAX_XFER_SIZE)
+                       std_len = QTD_MAX_XFER_SIZE;
+
+               std->urb = urb;
+               std->dma_addr = transfer_dma;
+               std->len = std_len;
+               std->ntds_remaining = ntds_remaining;
+               std->qtd = NULL;
+
+               INIT_LIST_HEAD(&std->list_node);
+               list_add_tail(&std->list_node, &qset->stds);
+
+               if (std_len > WHCI_PAGE_SIZE) {
+                       if (qset_fill_page_list(whc, std, mem_flags) < 0)
+                               goto err_no_mem;
+               } else
+                       std->num_pointers = 0;
+
+               ntds_remaining--;
+               remaining -= std_len;
+               transfer_dma += std_len;
+       }
+
+       return 0;
+
+err_no_mem:
+       qset_free_stds(qset, urb);
+       return -ENOMEM;
+}
+
+/**
+ * qset_remove_urb - remove an URB from the urb queue.
+ *
+ * The URB is returned to the USB subsystem.
+ */
+void qset_remove_urb(struct whc *whc, struct whc_qset *qset,
+                           struct urb *urb, int status)
+{
+       struct wusbhc *wusbhc = &whc->wusbhc;
+       struct whc_urb *wurb = urb->hcpriv;
+
+       usb_hcd_unlink_urb_from_ep(&wusbhc->usb_hcd, urb);
+       /* Drop the lock as urb->complete() may enqueue another urb. */
+       spin_unlock(&whc->lock);
+       wusbhc_giveback_urb(wusbhc, urb, status);
+       spin_lock(&whc->lock);
+
+       kfree(wurb);
+}
+
+/**
+ * get_urb_status_from_qtd - get the completed urb status from qTD status
+ * @urb:    completed urb
+ * @status: qTD status
+ */
+static int get_urb_status_from_qtd(struct urb *urb, u32 status)
+{
+       if (status & QTD_STS_HALTED) {
+               if (status & QTD_STS_DBE)
+                       return usb_pipein(urb->pipe) ? -ENOSR : -ECOMM;
+               else if (status & QTD_STS_BABBLE)
+                       return -EOVERFLOW;
+               else if (status & QTD_STS_RCE)
+                       return -ETIME;
+               return -EPIPE;
+       }
+       if (usb_pipein(urb->pipe)
+           && (urb->transfer_flags & URB_SHORT_NOT_OK)
+           && urb->actual_length < urb->transfer_buffer_length)
+               return -EREMOTEIO;
+       return 0;
+}
+
+/**
+ * process_inactive_qtd - process an inactive (but not halted) qTD.
+ *
+ * Update the urb with the transfer bytes from the qTD, if the urb is
+ * completely transfered or (in the case of an IN only) the LPF is
+ * set, then the transfer is complete and the urb should be returned
+ * to the system.
+ */
+void process_inactive_qtd(struct whc *whc, struct whc_qset *qset,
+                                struct whc_qtd *qtd)
+{
+       struct whc_std *std = list_first_entry(&qset->stds, struct whc_std, list_node);
+       struct urb *urb = std->urb;
+       uint32_t status;
+       bool complete;
+
+       status = le32_to_cpu(qtd->status);
+
+       urb->actual_length += std->len - QTD_STS_TO_LEN(status);
+
+       if (usb_pipein(urb->pipe) && (status & QTD_STS_LAST_PKT))
+               complete = true;
+       else
+               complete = whc_std_last(std);
+
+       qset_remove_qtd(whc, qset);
+       qset_free_std(whc, std);
+
+       /*
+        * Transfers for this URB are complete?  Then return it to the
+        * USB subsystem.
+        */
+       if (complete) {
+               qset_remove_qtds(whc, qset, urb);
+               qset_remove_urb(whc, qset, urb, get_urb_status_from_qtd(urb, status));
+
+               /*
+                * If iAlt isn't valid then the hardware didn't
+                * advance iCur. Adjust the start and end pointers to
+                * match iCur.
+                */
+               if (!(status & QTD_STS_IALT_VALID))
+                       qset->td_start = qset->td_end
+                               = QH_STATUS_TO_ICUR(le16_to_cpu(qset->qh.status));
+               qset->pause_after_urb = NULL;
+       }
+}
+
+/**
+ * process_halted_qtd - process a qset with a halted qtd
+ *
+ * Remove all the qTDs for the failed URB and return the failed URB to
+ * the USB subsystem.  Then remove all other qTDs so the qset can be
+ * removed.
+ *
+ * FIXME: this is the point where rate adaptation can be done.  If a
+ * transfer failed because it exceeded the maximum number of retries
+ * then it could be reactivated with a slower rate without having to
+ * remove the qset.
+ */
+void process_halted_qtd(struct whc *whc, struct whc_qset *qset,
+                              struct whc_qtd *qtd)
+{
+       struct whc_std *std = list_first_entry(&qset->stds, struct whc_std, list_node);
+       struct urb *urb = std->urb;
+       int urb_status;
+
+       urb_status = get_urb_status_from_qtd(urb, le32_to_cpu(qtd->status));
+
+       qset_remove_qtds(whc, qset, urb);
+       qset_remove_urb(whc, qset, urb, urb_status);
+
+       list_for_each_entry(std, &qset->stds, list_node) {
+               if (qset->ntds == 0)
+                       break;
+               qset_remove_qtd(whc, qset);
+               std->qtd = NULL;
+       }
+
+       qset->remove = 1;
+}
+
+void qset_free(struct whc *whc, struct whc_qset *qset)
+{
+       dma_pool_free(whc->qset_pool, qset, qset->qset_dma);
+}
+
+/**
+ * qset_delete - wait for a qset to be unused, then free it.
+ */
+void qset_delete(struct whc *whc, struct whc_qset *qset)
+{
+       wait_for_completion(&qset->remove_complete);
+       qset_free(whc, qset);
+}
diff --git a/drivers/usb/host/whci/whcd.h b/drivers/usb/host/whci/whcd.h
new file mode 100644 (file)
index 0000000..1d2a53b
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Wireless Host Controller (WHC) private header.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#ifndef __WHCD_H
+#define __WHCD_H
+
+#include <linux/uwb/whci.h>
+#include <linux/workqueue.h>
+
+#include "whci-hc.h"
+
+/* Generic command timeout. */
+#define WHC_GENCMD_TIMEOUT_MS 100
+
+
+struct whc {
+       struct wusbhc wusbhc;
+       struct umc_dev *umc;
+
+       resource_size_t base_phys;
+       void __iomem *base;
+       int irq;
+
+       u8 n_devices;
+       u8 n_keys;
+       u8 n_mmc_ies;
+
+       u64 *pz_list;
+       struct dn_buf_entry *dn_buf;
+       struct di_buf_entry *di_buf;
+       dma_addr_t pz_list_dma;
+       dma_addr_t dn_buf_dma;
+       dma_addr_t di_buf_dma;
+
+       spinlock_t   lock;
+       struct mutex mutex;
+
+       void *            gen_cmd_buf;
+       dma_addr_t        gen_cmd_buf_dma;
+       wait_queue_head_t cmd_wq;
+
+       struct workqueue_struct *workqueue;
+       struct work_struct       dn_work;
+
+       struct dma_pool *qset_pool;
+
+       struct list_head async_list;
+       struct list_head async_removed_list;
+       wait_queue_head_t async_list_wq;
+       struct work_struct async_work;
+
+       struct list_head periodic_list[5];
+       struct list_head periodic_removed_list;
+       wait_queue_head_t periodic_list_wq;
+       struct work_struct periodic_work;
+};
+
+#define wusbhc_to_whc(w) (container_of((w), struct whc, wusbhc))
+
+/**
+ * struct whc_std - a software TD.
+ * @urb: the URB this sTD is for.
+ * @offset: start of the URB's data for this TD.
+ * @len: the length of data in the associated TD.
+ * @ntds_remaining: number of TDs (starting from this one) in this transfer.
+ *
+ * Queued URBs may require more TDs than are available in a qset so we
+ * use a list of these "software TDs" (sTDs) to hold per-TD data.
+ */
+struct whc_std {
+       struct urb *urb;
+       size_t len;
+       int    ntds_remaining;
+       struct whc_qtd *qtd;
+
+       struct list_head list_node;
+       int num_pointers;
+       dma_addr_t dma_addr;
+       struct whc_page_list_entry *pl_virt;
+};
+
+/**
+ * struct whc_urb - per URB host controller structure.
+ * @urb: the URB this struct is for.
+ * @qset: the qset associated to the URB.
+ * @dequeue_work: the work to remove the URB when dequeued.
+ * @is_async: the URB belongs to async sheduler or not.
+ * @status: the status to be returned when calling wusbhc_giveback_urb.
+ */
+struct whc_urb {
+       struct urb *urb;
+       struct whc_qset *qset;
+       struct work_struct dequeue_work;
+       bool is_async;
+       int status;
+};
+
+/**
+ * whc_std_last - is this sTD the URB's last?
+ * @std: the sTD to check.
+ */
+static inline bool whc_std_last(struct whc_std *std)
+{
+       return std->ntds_remaining <= 1;
+}
+
+enum whc_update {
+       WHC_UPDATE_ADDED   = 0x01,
+       WHC_UPDATE_REMOVED = 0x02,
+       WHC_UPDATE_UPDATED = 0x04,
+};
+
+/* init.c */
+int whc_init(struct whc *whc);
+void whc_clean_up(struct whc *whc);
+
+/* hw.c */
+void whc_write_wusbcmd(struct whc *whc, u32 mask, u32 val);
+int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len);
+
+/* wusb.c */
+int whc_wusbhc_start(struct wusbhc *wusbhc);
+void whc_wusbhc_stop(struct wusbhc *wusbhc);
+int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt,
+                 u8 handle, struct wuie_hdr *wuie);
+int whc_mmcie_rm(struct wusbhc *wusbhc, u8 handle);
+int whc_bwa_set(struct wusbhc *wusbhc, s8 stream_index, const struct uwb_mas_bm *mas_bm);
+int whc_dev_info_set(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev);
+int whc_set_num_dnts(struct wusbhc *wusbhc, u8 interval, u8 slots);
+int whc_set_ptk(struct wusbhc *wusbhc, u8 port_idx, u32 tkid,
+               const void *ptk, size_t key_size);
+int whc_set_gtk(struct wusbhc *wusbhc, u32 tkid,
+               const void *gtk, size_t key_size);
+int whc_set_cluster_id(struct whc *whc, u8 bcid);
+
+/* int.c */
+irqreturn_t whc_int_handler(struct usb_hcd *hcd);
+void whc_dn_work(struct work_struct *work);
+
+/* asl.c */
+void asl_start(struct whc *whc);
+void asl_stop(struct whc *whc);
+int  asl_init(struct whc *whc);
+void asl_clean_up(struct whc *whc);
+int  asl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags);
+int  asl_urb_dequeue(struct whc *whc, struct urb *urb, int status);
+void asl_qset_delete(struct whc *whc, struct whc_qset *qset);
+void scan_async_work(struct work_struct *work);
+
+/* pzl.c */
+int  pzl_init(struct whc *whc);
+void pzl_clean_up(struct whc *whc);
+void pzl_start(struct whc *whc);
+void pzl_stop(struct whc *whc);
+int  pzl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags);
+int  pzl_urb_dequeue(struct whc *whc, struct urb *urb, int status);
+void pzl_qset_delete(struct whc *whc, struct whc_qset *qset);
+void scan_periodic_work(struct work_struct *work);
+
+/* qset.c */
+struct whc_qset *qset_alloc(struct whc *whc, gfp_t mem_flags);
+void qset_free(struct whc *whc, struct whc_qset *qset);
+struct whc_qset *get_qset(struct whc *whc, struct urb *urb, gfp_t mem_flags);
+void qset_delete(struct whc *whc, struct whc_qset *qset);
+void qset_clear(struct whc *whc, struct whc_qset *qset);
+int qset_add_urb(struct whc *whc, struct whc_qset *qset, struct urb *urb,
+                gfp_t mem_flags);
+void qset_free_std(struct whc *whc, struct whc_std *std);
+void qset_remove_urb(struct whc *whc, struct whc_qset *qset,
+                           struct urb *urb, int status);
+void process_halted_qtd(struct whc *whc, struct whc_qset *qset,
+                              struct whc_qtd *qtd);
+void process_inactive_qtd(struct whc *whc, struct whc_qset *qset,
+                                struct whc_qtd *qtd);
+enum whc_update qset_add_qtds(struct whc *whc, struct whc_qset *qset);
+void qset_remove_complete(struct whc *whc, struct whc_qset *qset);
+void dump_qset(struct whc_qset *qset, struct device *dev);
+void pzl_update(struct whc *whc, uint32_t wusbcmd);
+void asl_update(struct whc *whc, uint32_t wusbcmd);
+
+#endif /* #ifndef __WHCD_H */
diff --git a/drivers/usb/host/whci/whci-hc.h b/drivers/usb/host/whci/whci-hc.h
new file mode 100644 (file)
index 0000000..bff1eb7
--- /dev/null
@@ -0,0 +1,416 @@
+/*
+ * Wireless Host Controller (WHC) data structures.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#ifndef _WHCI_WHCI_HC_H
+#define _WHCI_WHCI_HC_H
+
+#include <linux/list.h>
+
+/**
+ * WHCI_PAGE_SIZE - page size use by WHCI
+ *
+ * WHCI assumes that host system uses pages of 4096 octets.
+ */
+#define WHCI_PAGE_SIZE 4096
+
+
+/**
+ * QTD_MAX_TXFER_SIZE - max number of bytes to transfer with a single
+ * qtd.
+ *
+ * This is 2^20 - 1.
+ */
+#define QTD_MAX_XFER_SIZE 1048575
+
+
+/**
+ * struct whc_qtd - Queue Element Transfer Descriptors (qTD)
+ *
+ * This describes the data for a bulk, control or interrupt transfer.
+ *
+ * [WHCI] section 3.2.4
+ */
+struct whc_qtd {
+       __le32 status; /*< remaining transfer len and transfer status */
+       __le32 options;
+       __le64 page_list_ptr; /*< physical pointer to data buffer page list*/
+       __u8   setup[8];      /*< setup data for control transfers */
+} __attribute__((packed));
+
+#define QTD_STS_ACTIVE     (1 << 31)  /* enable execution of transaction */
+#define QTD_STS_HALTED     (1 << 30)  /* transfer halted */
+#define QTD_STS_DBE        (1 << 29)  /* data buffer error */
+#define QTD_STS_BABBLE     (1 << 28)  /* babble detected */
+#define QTD_STS_RCE        (1 << 27)  /* retry count exceeded */
+#define QTD_STS_LAST_PKT   (1 << 26)  /* set Last Packet Flag in WUSB header */
+#define QTD_STS_INACTIVE   (1 << 25)  /* queue set is marked inactive */
+#define QTD_STS_IALT_VALID (1 << 23)                          /* iAlt field is valid */
+#define QTD_STS_IALT(i)    (QTD_STS_IALT_VALID | ((i) << 20)) /* iAlt field */
+#define QTD_STS_LEN(l)     ((l) << 0) /* transfer length */
+#define QTD_STS_TO_LEN(s)  ((s) & 0x000fffff)
+
+#define QTD_OPT_IOC      (1 << 1) /* page_list_ptr points to buffer directly */
+#define QTD_OPT_SMALL    (1 << 0) /* interrupt on complete */
+
+/**
+ * struct whc_itd - Isochronous Queue Element Transfer Descriptors (iTD)
+ *
+ * This describes the data and other parameters for an isochronous
+ * transfer.
+ *
+ * [WHCI] section 3.2.5
+ */
+struct whc_itd {
+       __le16 presentation_time;    /*< presentation time for OUT transfers */
+       __u8   num_segments;         /*< number of data segments in segment list */
+       __u8   status;               /*< command execution status */
+       __le32 options;              /*< misc transfer options */
+       __le64 page_list_ptr;        /*< physical pointer to data buffer page list */
+       __le64 seg_list_ptr;         /*< physical pointer to segment list */
+} __attribute__((packed));
+
+#define ITD_STS_ACTIVE   (1 << 7) /* enable execution of transaction */
+#define ITD_STS_DBE      (1 << 5) /* data buffer error */
+#define ITD_STS_BABBLE   (1 << 4) /* babble detected */
+#define ITD_STS_INACTIVE (1 << 1) /* queue set is marked inactive */
+
+#define ITD_OPT_IOC      (1 << 1) /* interrupt on complete */
+#define ITD_OPT_SMALL    (1 << 0) /* page_list_ptr points to buffer directly */
+
+/**
+ * Page list entry.
+ *
+ * A TD's page list must contain sufficient page list entries for the
+ * total data length in the TD.
+ *
+ * [WHCI] section 3.2.4.3
+ */
+struct whc_page_list_entry {
+       __le64 buf_ptr; /*< physical pointer to buffer */
+} __attribute__((packed));
+
+/**
+ * struct whc_seg_list_entry - Segment list entry.
+ *
+ * Describes a portion of the data buffer described in the containing
+ * qTD's page list.
+ *
+ * seg_ptr = qtd->page_list_ptr[qtd->seg_list_ptr[seg].idx].buf_ptr
+ *           + qtd->seg_list_ptr[seg].offset;
+ *
+ * Segments can't cross page boundries.
+ *
+ * [WHCI] section 3.2.5.5
+ */
+struct whc_seg_list_entry {
+       __le16 len;    /*< segment length */
+       __u8   idx;    /*< index into page list */
+       __u8   status; /*< segment status */
+       __le16 offset; /*< 12 bit offset into page */
+} __attribute__((packed));
+
+/**
+ * struct whc_qhead - endpoint and status information for a qset.
+ *
+ * [WHCI] section 3.2.6
+ */
+struct whc_qhead {
+       __le64 link; /*< next qset in list */
+       __le32 info1;
+       __le32 info2;
+       __le32 info3;
+       __le16 status;
+       __le16 err_count;  /*< transaction error count */
+       __le32 cur_window;
+       __le32 scratch[3]; /*< h/w scratch area */
+       union {
+               struct whc_qtd qtd;
+               struct whc_itd itd;
+       } overlay;
+} __attribute__((packed));
+
+#define QH_LINK_PTR_MASK (~0x03Full)
+#define QH_LINK_PTR(ptr) ((ptr) & QH_LINK_PTR_MASK)
+#define QH_LINK_IQS      (1 << 4) /* isochronous queue set */
+#define QH_LINK_NTDS(n)  (((n) - 1) << 1) /* number of TDs in queue set */
+#define QH_LINK_T        (1 << 0) /* last queue set in periodic schedule list */
+
+#define QH_INFO1_EP(e)           ((e) << 0)  /* endpoint number */
+#define QH_INFO1_DIR_IN          (1 << 4)    /* IN transfer */
+#define QH_INFO1_DIR_OUT         (0 << 4)    /* OUT transfer */
+#define QH_INFO1_TR_TYPE_CTRL    (0x0 << 5)  /* control transfer */
+#define QH_INFO1_TR_TYPE_ISOC    (0x1 << 5)  /* isochronous transfer */
+#define QH_INFO1_TR_TYPE_BULK    (0x2 << 5)  /* bulk transfer */
+#define QH_INFO1_TR_TYPE_INT     (0x3 << 5)  /* interrupt */
+#define QH_INFO1_TR_TYPE_LP_INT  (0x7 << 5)  /* low power interrupt */
+#define QH_INFO1_DEV_INFO_IDX(i) ((i) << 8)  /* index into device info buffer */
+#define QH_INFO1_SET_INACTIVE    (1 << 15)   /* set inactive after transfer */
+#define QH_INFO1_MAX_PKT_LEN(l)  ((l) << 16) /* maximum packet length */
+
+#define QH_INFO2_BURST(b)        ((b) << 0)  /* maximum burst length */
+#define QH_INFO2_DBP(p)          ((p) << 5)  /* data burst policy (see [WUSB] table 5-7) */
+#define QH_INFO2_MAX_COUNT(c)    ((c) << 8)  /* max isoc/int pkts per zone */
+#define QH_INFO2_RQS             (1 << 15)   /* reactivate queue set */
+#define QH_INFO2_MAX_RETRY(r)    ((r) << 16) /* maximum transaction retries */
+#define QH_INFO2_MAX_SEQ(s)      ((s) << 20) /* maximum sequence number */
+#define QH_INFO3_MAX_DELAY(d)    ((d) << 0)  /* maximum stream delay in 125 us units (isoc only) */
+#define QH_INFO3_INTERVAL(i)     ((i) << 16) /* segment interval in 125 us units (isoc only) */
+
+#define QH_INFO3_TX_RATE_53_3    (0 << 24)
+#define QH_INFO3_TX_RATE_80      (1 << 24)
+#define QH_INFO3_TX_RATE_106_7   (2 << 24)
+#define QH_INFO3_TX_RATE_160     (3 << 24)
+#define QH_INFO3_TX_RATE_200     (4 << 24)
+#define QH_INFO3_TX_RATE_320     (5 << 24)
+#define QH_INFO3_TX_RATE_400     (6 << 24)
+#define QH_INFO3_TX_RATE_480     (7 << 24)
+#define QH_INFO3_TX_PWR(p)       ((p) << 29) /* transmit power (see [WUSB] section 5.2.1.2) */
+
+#define QH_STATUS_FLOW_CTRL      (1 << 15)
+#define QH_STATUS_ICUR(i)        ((i) << 5)
+#define QH_STATUS_TO_ICUR(s)     (((s) >> 5) & 0x7)
+
+/**
+ * usb_pipe_to_qh_type - USB core pipe type to QH transfer type
+ *
+ * Returns the QH type field for a USB core pipe type.
+ */
+static inline unsigned usb_pipe_to_qh_type(unsigned pipe)
+{
+       static const unsigned type[] = {
+               [PIPE_ISOCHRONOUS] = QH_INFO1_TR_TYPE_ISOC,
+               [PIPE_INTERRUPT]   = QH_INFO1_TR_TYPE_INT,
+               [PIPE_CONTROL]     = QH_INFO1_TR_TYPE_CTRL,
+               [PIPE_BULK]        = QH_INFO1_TR_TYPE_BULK,
+       };
+       return type[usb_pipetype(pipe)];
+}
+
+/**
+ * Maxiumum number of TDs in a qset.
+ */
+#define WHCI_QSET_TD_MAX 8
+
+/**
+ * struct whc_qset - WUSB data transfers to a specific endpoint
+ * @qh: the QHead of this qset
+ * @qtd: up to 8 qTDs (for qsets for control, bulk and interrupt
+ * transfers)
+ * @itd: up to 8 iTDs (for qsets for isochronous transfers)
+ * @qset_dma: DMA address for this qset
+ * @whc: WHCI HC this qset is for
+ * @ep: endpoint
+ * @stds: list of sTDs queued to this qset
+ * @ntds: number of qTDs queued (not necessarily the same as nTDs
+ * field in the QH)
+ * @td_start: index of the first qTD in the list
+ * @td_end: index of next free qTD in the list (provided
+ *          ntds < WHCI_QSET_TD_MAX)
+ *
+ * Queue Sets (qsets) are added to the asynchronous schedule list
+ * (ASL) or the periodic zone list (PZL).
+ *
+ * qsets may contain up to 8 TDs (either qTDs or iTDs as appropriate).
+ * Each TD may refer to at most 1 MiB of data. If a single transfer
+ * has > 8MiB of data, TDs can be reused as they are completed since
+ * the TD list is used as a circular buffer.  Similarly, several
+ * (smaller) transfers may be queued in a qset.
+ *
+ * WHCI controllers may cache portions of the qsets in the ASL and
+ * PZL, requiring the WHCD to inform the WHC that the lists have been
+ * updated (fields changed or qsets inserted or removed).  For safe
+ * insertion and removal of qsets from the lists the schedule must be
+ * stopped to avoid races in updating the QH link pointers.
+ *
+ * Since the HC is free to execute qsets in any order, all transfers
+ * to an endpoint should use the same qset to ensure transfers are
+ * executed in the order they're submitted.
+ *
+ * [WHCI] section 3.2.3
+ */
+struct whc_qset {
+       struct whc_qhead qh;
+       union {
+               struct whc_qtd qtd[WHCI_QSET_TD_MAX];
+               struct whc_itd itd[WHCI_QSET_TD_MAX];
+       };
+
+       /* private data for WHCD */
+       dma_addr_t qset_dma;
+       struct whc *whc;
+       struct usb_host_endpoint *ep;
+       struct list_head stds;
+       int ntds;
+       int td_start;
+       int td_end;
+       struct list_head list_node;
+       unsigned in_sw_list:1;
+       unsigned in_hw_list:1;
+       unsigned remove:1;
+       struct urb *pause_after_urb;
+       struct completion remove_complete;
+       int max_burst;
+       int max_seq;
+};
+
+static inline void whc_qset_set_link_ptr(u64 *ptr, u64 target)
+{
+       if (target)
+               *ptr = (*ptr & ~(QH_LINK_PTR_MASK | QH_LINK_T)) | QH_LINK_PTR(target);
+       else
+               *ptr = QH_LINK_T;
+}
+
+/**
+ * struct di_buf_entry - Device Information (DI) buffer entry.
+ *
+ * There's one of these per connected device.
+ */
+struct di_buf_entry {
+       __le32 availability_info[8]; /*< MAS availability information, one MAS per bit */
+       __le32 addr_sec_info;        /*< addressing and security info */
+       __le32 reserved[7];
+} __attribute__((packed));
+
+#define WHC_DI_SECURE           (1 << 31)
+#define WHC_DI_DISABLE          (1 << 30)
+#define WHC_DI_KEY_IDX(k)       ((k) << 8)
+#define WHC_DI_KEY_IDX_MASK     0x0000ff00
+#define WHC_DI_DEV_ADDR(a)      ((a) << 0)
+#define WHC_DI_DEV_ADDR_MASK    0x000000ff
+
+/**
+ * struct dn_buf_entry - Device Notification (DN) buffer entry.
+ *
+ * [WHCI] section 3.2.8
+ */
+struct dn_buf_entry {
+       __u8   msg_size;    /*< number of octets of valid DN data */
+       __u8   reserved1;
+       __u8   src_addr;    /*< source address */
+       __u8   status;      /*< buffer entry status */
+       __le32 tkid;        /*< TKID for source device, valid if secure bit is set */
+       __u8   dn_data[56]; /*< up to 56 octets of DN data */
+} __attribute__((packed));
+
+#define WHC_DN_STATUS_VALID  (1 << 7) /* buffer entry is valid */
+#define WHC_DN_STATUS_SECURE (1 << 6) /* notification received using secure frame */
+
+#define WHC_N_DN_ENTRIES (4096 / sizeof(struct dn_buf_entry))
+
+/* The Add MMC IE WUSB Generic Command may take up to 256 bytes of
+   data. [WHCI] section 2.4.7. */
+#define WHC_GEN_CMD_DATA_LEN 256
+
+/*
+ * HC registers.
+ *
+ * [WHCI] section 2.4
+ */
+
+#define WHCIVERSION          0x00
+
+#define WHCSPARAMS           0x04
+#  define WHCSPARAMS_TO_N_MMC_IES(p) (((p) >> 16) & 0xff)
+#  define WHCSPARAMS_TO_N_KEYS(p)    (((p) >> 8) & 0xff)
+#  define WHCSPARAMS_TO_N_DEVICES(p) (((p) >> 0) & 0x7f)
+
+#define WUSBCMD              0x08
+#  define WUSBCMD_BCID(b)            ((b) << 16)
+#  define WUSBCMD_BCID_MASK          (0xff << 16)
+#  define WUSBCMD_ASYNC_QSET_RM      (1 << 12)
+#  define WUSBCMD_PERIODIC_QSET_RM   (1 << 11)
+#  define WUSBCMD_WUSBSI(s)          ((s) << 8)
+#  define WUSBCMD_WUSBSI_MASK        (0x7 << 8)
+#  define WUSBCMD_ASYNC_SYNCED_DB    (1 << 7)
+#  define WUSBCMD_PERIODIC_SYNCED_DB (1 << 6)
+#  define WUSBCMD_ASYNC_UPDATED      (1 << 5)
+#  define WUSBCMD_PERIODIC_UPDATED   (1 << 4)
+#  define WUSBCMD_ASYNC_EN           (1 << 3)
+#  define WUSBCMD_PERIODIC_EN        (1 << 2)
+#  define WUSBCMD_WHCRESET           (1 << 1)
+#  define WUSBCMD_RUN                (1 << 0)
+
+#define WUSBSTS              0x0c
+#  define WUSBSTS_ASYNC_SCHED             (1 << 15)
+#  define WUSBSTS_PERIODIC_SCHED          (1 << 14)
+#  define WUSBSTS_DNTS_SCHED              (1 << 13)
+#  define WUSBSTS_HCHALTED                (1 << 12)
+#  define WUSBSTS_GEN_CMD_DONE            (1 << 9)
+#  define WUSBSTS_CHAN_TIME_ROLLOVER      (1 << 8)
+#  define WUSBSTS_DNTS_OVERFLOW           (1 << 7)
+#  define WUSBSTS_BPST_ADJUSTMENT_CHANGED (1 << 6)
+#  define WUSBSTS_HOST_ERR                (1 << 5)
+#  define WUSBSTS_ASYNC_SCHED_SYNCED      (1 << 4)
+#  define WUSBSTS_PERIODIC_SCHED_SYNCED   (1 << 3)
+#  define WUSBSTS_DNTS_INT                (1 << 2)
+#  define WUSBSTS_ERR_INT                 (1 << 1)
+#  define WUSBSTS_INT                     (1 << 0)
+#  define WUSBSTS_INT_MASK                0x3ff
+
+#define WUSBINTR             0x10
+#  define WUSBINTR_GEN_CMD_DONE             (1 << 9)
+#  define WUSBINTR_CHAN_TIME_ROLLOVER       (1 << 8)
+#  define WUSBINTR_DNTS_OVERFLOW            (1 << 7)
+#  define WUSBINTR_BPST_ADJUSTMENT_CHANGED  (1 << 6)
+#  define WUSBINTR_HOST_ERR                 (1 << 5)
+#  define WUSBINTR_ASYNC_SCHED_SYNCED       (1 << 4)
+#  define WUSBINTR_PERIODIC_SCHED_SYNCED    (1 << 3)
+#  define WUSBINTR_DNTS_INT                 (1 << 2)
+#  define WUSBINTR_ERR_INT                  (1 << 1)
+#  define WUSBINTR_INT                      (1 << 0)
+#  define WUSBINTR_ALL 0x3ff
+
+#define WUSBGENCMDSTS        0x14
+#  define WUSBGENCMDSTS_ACTIVE (1 << 31)
+#  define WUSBGENCMDSTS_ERROR  (1 << 24)
+#  define WUSBGENCMDSTS_IOC    (1 << 23)
+#  define WUSBGENCMDSTS_MMCIE_ADD 0x01
+#  define WUSBGENCMDSTS_MMCIE_RM  0x02
+#  define WUSBGENCMDSTS_SET_MAS   0x03
+#  define WUSBGENCMDSTS_CHAN_STOP 0x04
+#  define WUSBGENCMDSTS_RWP_EN    0x05
+
+#define WUSBGENCMDPARAMS     0x18
+#define WUSBGENADDR          0x20
+#define WUSBASYNCLISTADDR    0x28
+#define WUSBDNTSBUFADDR      0x30
+#define WUSBDEVICEINFOADDR   0x38
+
+#define WUSBSETSECKEYCMD     0x40
+#  define WUSBSETSECKEYCMD_SET    (1 << 31)
+#  define WUSBSETSECKEYCMD_ERASE  (1 << 30)
+#  define WUSBSETSECKEYCMD_GTK    (1 << 8)
+#  define WUSBSETSECKEYCMD_IDX(i) ((i) << 0)
+
+#define WUSBTKID             0x44
+#define WUSBSECKEY           0x48
+#define WUSBPERIODICLISTBASE 0x58
+#define WUSBMASINDEX         0x60
+
+#define WUSBDNTSCTRL         0x64
+#  define WUSBDNTSCTRL_ACTIVE      (1 << 31)
+#  define WUSBDNTSCTRL_INTERVAL(i) ((i) << 8)
+#  define WUSBDNTSCTRL_SLOTS(s)    ((s) << 0)
+
+#define WUSBTIME             0x68
+#define WUSBBPST             0x6c
+#define WUSBDIBUPDATED       0x70
+
+#endif /* #ifndef _WHCI_WHCI_HC_H */
diff --git a/drivers/usb/host/whci/wusb.c b/drivers/usb/host/whci/wusb.c
new file mode 100644 (file)
index 0000000..66e4ddc
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * Wireless Host Controller (WHC) WUSB operations.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/uwb/umc.h>
+#define D_LOCAL 1
+#include <linux/uwb/debug.h>
+
+#include "../../wusbcore/wusbhc.h"
+
+#include "whcd.h"
+
+#if D_LOCAL >= 1
+static void dump_di(struct whc *whc, int idx)
+{
+       struct di_buf_entry *di = &whc->di_buf[idx];
+       struct device *dev = &whc->umc->dev;
+       char buf[128];
+
+       bitmap_scnprintf(buf, sizeof(buf), (unsigned long *)di->availability_info, UWB_NUM_MAS);
+
+       d_printf(1, dev, "DI[%d]\n", idx);
+       d_printf(1, dev, "  availability: %s\n", buf);
+       d_printf(1, dev, "  %c%c key idx: %d dev addr: %d\n",
+                (di->addr_sec_info & WHC_DI_SECURE) ? 'S' : ' ',
+                (di->addr_sec_info & WHC_DI_DISABLE) ? 'D' : ' ',
+                (di->addr_sec_info & WHC_DI_KEY_IDX_MASK) >> 8,
+                (di->addr_sec_info & WHC_DI_DEV_ADDR_MASK));
+}
+#else
+static inline void dump_di(struct whc *whc, int idx)
+{
+}
+#endif
+
+static int whc_update_di(struct whc *whc, int idx)
+{
+       int offset = idx / 32;
+       u32 bit = 1 << (idx % 32);
+
+       dump_di(whc, idx);
+
+       le_writel(bit, whc->base + WUSBDIBUPDATED + offset);
+
+       return whci_wait_for(&whc->umc->dev,
+                            whc->base + WUSBDIBUPDATED + offset, bit, 0,
+                            100, "DI update");
+}
+
+/*
+ * WHCI starts and stops MMCs based on there being a valid GTK so
+ * these need only start/stop the asynchronous and periodic schedules.
+ */
+
+int whc_wusbhc_start(struct wusbhc *wusbhc)
+{
+       struct whc *whc = wusbhc_to_whc(wusbhc);
+
+       asl_start(whc);
+       pzl_start(whc);
+
+       return 0;
+}
+
+void whc_wusbhc_stop(struct wusbhc *wusbhc)
+{
+       struct whc *whc = wusbhc_to_whc(wusbhc);
+
+       pzl_stop(whc);
+       asl_stop(whc);
+}
+
+int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt,
+                 u8 handle, struct wuie_hdr *wuie)
+{
+       struct whc *whc = wusbhc_to_whc(wusbhc);
+       u32 params;
+
+       params = (interval << 24)
+               | (repeat_cnt << 16)
+               | (wuie->bLength << 8)
+               | handle;
+
+       return whc_do_gencmd(whc, WUSBGENCMDSTS_MMCIE_ADD, params, wuie, wuie->bLength);
+}
+
+int whc_mmcie_rm(struct wusbhc *wusbhc, u8 handle)
+{
+       struct whc *whc = wusbhc_to_whc(wusbhc);
+       u32 params;
+
+       params = handle;
+
+       return whc_do_gencmd(whc, WUSBGENCMDSTS_MMCIE_RM, params, NULL, 0);
+}
+
+int whc_bwa_set(struct wusbhc *wusbhc, s8 stream_index, const struct uwb_mas_bm *mas_bm)
+{
+       struct whc *whc = wusbhc_to_whc(wusbhc);
+
+       if (stream_index >= 0)
+               whc_write_wusbcmd(whc, WUSBCMD_WUSBSI_MASK, WUSBCMD_WUSBSI(stream_index));
+
+       return whc_do_gencmd(whc, WUSBGENCMDSTS_SET_MAS, 0, (void *)mas_bm, sizeof(*mas_bm));
+}
+
+int whc_dev_info_set(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
+{
+       struct whc *whc = wusbhc_to_whc(wusbhc);
+       int idx = wusb_dev->port_idx;
+       struct di_buf_entry *di = &whc->di_buf[idx];
+       int ret;
+
+       mutex_lock(&whc->mutex);
+
+       uwb_mas_bm_copy_le(di->availability_info, &wusb_dev->availability);
+       di->addr_sec_info &= ~(WHC_DI_DISABLE | WHC_DI_DEV_ADDR_MASK);
+       di->addr_sec_info |= WHC_DI_DEV_ADDR(wusb_dev->addr);
+
+       ret = whc_update_di(whc, idx);
+
+       mutex_unlock(&whc->mutex);
+
+       return ret;
+}
+
+/*
+ * Set the number of Device Notification Time Slots (DNTS) and enable
+ * device notifications.
+ */
+int whc_set_num_dnts(struct wusbhc *wusbhc, u8 interval, u8 slots)
+{
+       struct whc *whc = wusbhc_to_whc(wusbhc);
+       u32 dntsctrl;
+
+       dntsctrl = WUSBDNTSCTRL_ACTIVE
+               | WUSBDNTSCTRL_INTERVAL(interval)
+               | WUSBDNTSCTRL_SLOTS(slots);
+
+       le_writel(dntsctrl, whc->base + WUSBDNTSCTRL);
+
+       return 0;
+}
+
+static int whc_set_key(struct whc *whc, u8 key_index, uint32_t tkid,
+                      const void *key, size_t key_size, bool is_gtk)
+{
+       uint32_t setkeycmd;
+       uint32_t seckey[4];
+       int i;
+       int ret;
+
+       memcpy(seckey, key, key_size);
+       setkeycmd = WUSBSETSECKEYCMD_SET | WUSBSETSECKEYCMD_IDX(key_index);
+       if (is_gtk)
+               setkeycmd |= WUSBSETSECKEYCMD_GTK;
+
+       le_writel(tkid, whc->base + WUSBTKID);
+       for (i = 0; i < 4; i++)
+               le_writel(seckey[i], whc->base + WUSBSECKEY + 4*i);
+       le_writel(setkeycmd, whc->base + WUSBSETSECKEYCMD);
+
+       ret = whci_wait_for(&whc->umc->dev, whc->base + WUSBSETSECKEYCMD,
+                           WUSBSETSECKEYCMD_SET, 0, 100, "set key");
+
+       return ret;
+}
+
+/**
+ * whc_set_ptk - set the PTK to use for a device.
+ *
+ * The index into the key table for this PTK is the same as the
+ * device's port index.
+ */
+int whc_set_ptk(struct wusbhc *wusbhc, u8 port_idx, u32 tkid,
+               const void *ptk, size_t key_size)
+{
+       struct whc *whc = wusbhc_to_whc(wusbhc);
+       struct di_buf_entry *di = &whc->di_buf[port_idx];
+       int ret;
+
+       mutex_lock(&whc->mutex);
+
+       if (ptk) {
+               ret = whc_set_key(whc, port_idx, tkid, ptk, key_size, false);
+               if (ret)
+                       goto out;
+
+               di->addr_sec_info &= ~WHC_DI_KEY_IDX_MASK;
+               di->addr_sec_info |= WHC_DI_SECURE | WHC_DI_KEY_IDX(port_idx);
+       } else
+               di->addr_sec_info &= ~WHC_DI_SECURE;
+
+       ret = whc_update_di(whc, port_idx);
+out:
+       mutex_unlock(&whc->mutex);
+       return ret;
+}
+
+/**
+ * whc_set_gtk - set the GTK for subsequent broadcast packets
+ *
+ * The GTK is stored in the last entry in the key table (the previous
+ * N_DEVICES entries are for the per-device PTKs).
+ */
+int whc_set_gtk(struct wusbhc *wusbhc, u32 tkid,
+               const void *gtk, size_t key_size)
+{
+       struct whc *whc = wusbhc_to_whc(wusbhc);
+       int ret;
+
+       mutex_lock(&whc->mutex);
+
+       ret = whc_set_key(whc, whc->n_devices, tkid, gtk, key_size, true);
+
+       mutex_unlock(&whc->mutex);
+
+       return ret;
+}
+
+int whc_set_cluster_id(struct whc *whc, u8 bcid)
+{
+       whc_write_wusbcmd(whc, WUSBCMD_BCID_MASK, WUSBCMD_BCID(bcid));
+       return 0;
+}
index b358c4e1cf212f114bbad89416f358c244311bc3..444c69c447bec115e4757446b6ad8a34ae42816c 100644 (file)
@@ -1561,8 +1561,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
        if (code != USBTEST_REQUEST)
                return -EOPNOTSUPP;
 
-       if (param->iterations <= 0 || param->length < 0
-                       || param->sglen < 0 || param->vary < 0)
+       if (param->iterations <= 0)
                return -EINVAL;
 
        if (mutex_lock_interruptible(&dev->lock))
index 3d87eabcd922a503eec45a5c70dea5a67b15a4ec..bd07eaa300b967f792ffd2923af3385b8784cf3b 100644 (file)
@@ -95,11 +95,20 @@ static int  option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
 #define HUAWEI_PRODUCT_E220                    0x1003
 #define HUAWEI_PRODUCT_E220BIS                 0x1004
 #define HUAWEI_PRODUCT_E1401                   0x1401
+#define HUAWEI_PRODUCT_E1402                   0x1402
 #define HUAWEI_PRODUCT_E1403                   0x1403
+#define HUAWEI_PRODUCT_E1404                   0x1404
 #define HUAWEI_PRODUCT_E1405                   0x1405
 #define HUAWEI_PRODUCT_E1406                   0x1406
+#define HUAWEI_PRODUCT_E1407                   0x1407
 #define HUAWEI_PRODUCT_E1408                   0x1408
 #define HUAWEI_PRODUCT_E1409                   0x1409
+#define HUAWEI_PRODUCT_E140A                   0x140A
+#define HUAWEI_PRODUCT_E140B                   0x140B
+#define HUAWEI_PRODUCT_E140C                   0x140C
+#define HUAWEI_PRODUCT_E140D                   0x140D
+#define HUAWEI_PRODUCT_E140E                   0x140E
+#define HUAWEI_PRODUCT_E140F                   0x140F
 #define HUAWEI_PRODUCT_E1410                   0x1410
 #define HUAWEI_PRODUCT_E1411                   0x1411
 #define HUAWEI_PRODUCT_E1412                   0x1412
@@ -110,6 +119,44 @@ static int  option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
 #define HUAWEI_PRODUCT_E1417                   0x1417
 #define HUAWEI_PRODUCT_E1418                   0x1418
 #define HUAWEI_PRODUCT_E1419                   0x1419
+#define HUAWEI_PRODUCT_E141A                   0x141A
+#define HUAWEI_PRODUCT_E141B                   0x141B
+#define HUAWEI_PRODUCT_E141C                   0x141C
+#define HUAWEI_PRODUCT_E141D                   0x141D
+#define HUAWEI_PRODUCT_E141E                   0x141E
+#define HUAWEI_PRODUCT_E141F                   0x141F
+#define HUAWEI_PRODUCT_E1420                   0x1420
+#define HUAWEI_PRODUCT_E1421                   0x1421
+#define HUAWEI_PRODUCT_E1422                   0x1422
+#define HUAWEI_PRODUCT_E1423                   0x1423
+#define HUAWEI_PRODUCT_E1424                   0x1424
+#define HUAWEI_PRODUCT_E1425                   0x1425
+#define HUAWEI_PRODUCT_E1426                   0x1426
+#define HUAWEI_PRODUCT_E1427                   0x1427
+#define HUAWEI_PRODUCT_E1428                   0x1428
+#define HUAWEI_PRODUCT_E1429                   0x1429
+#define HUAWEI_PRODUCT_E142A                   0x142A
+#define HUAWEI_PRODUCT_E142B                   0x142B
+#define HUAWEI_PRODUCT_E142C                   0x142C
+#define HUAWEI_PRODUCT_E142D                   0x142D
+#define HUAWEI_PRODUCT_E142E                   0x142E
+#define HUAWEI_PRODUCT_E142F                   0x142F
+#define HUAWEI_PRODUCT_E1430                   0x1430
+#define HUAWEI_PRODUCT_E1431                   0x1431
+#define HUAWEI_PRODUCT_E1432                   0x1432
+#define HUAWEI_PRODUCT_E1433                   0x1433
+#define HUAWEI_PRODUCT_E1434                   0x1434
+#define HUAWEI_PRODUCT_E1435                   0x1435
+#define HUAWEI_PRODUCT_E1436                   0x1436
+#define HUAWEI_PRODUCT_E1437                   0x1437
+#define HUAWEI_PRODUCT_E1438                   0x1438
+#define HUAWEI_PRODUCT_E1439                   0x1439
+#define HUAWEI_PRODUCT_E143A                   0x143A
+#define HUAWEI_PRODUCT_E143B                   0x143B
+#define HUAWEI_PRODUCT_E143C                   0x143C
+#define HUAWEI_PRODUCT_E143D                   0x143D
+#define HUAWEI_PRODUCT_E143E                   0x143E
+#define HUAWEI_PRODUCT_E143F                   0x143F
 
 #define NOVATELWIRELESS_VENDOR_ID              0x1410
 
@@ -207,6 +254,7 @@ static int  option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
 /* ZTE PRODUCTS */
 #define ZTE_VENDOR_ID                          0x19d2
 #define ZTE_PRODUCT_MF628                      0x0015
+#define ZTE_PRODUCT_MF626                      0x0031
 #define ZTE_PRODUCT_CDMA_TECH                  0xfffe
 
 /* Ericsson products */
@@ -248,11 +296,20 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1401, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1402, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1403, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1404, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1405, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1406, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1407, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1408, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1409, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140A, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140B, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140C, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140D, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140E, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140F, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1410, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1411, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1412, 0xff, 0xff, 0xff) },
@@ -263,6 +320,44 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1417, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1418, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1419, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141A, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141B, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141C, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141D, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141E, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141F, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1420, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1421, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1422, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1423, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1424, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1425, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1426, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1427, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1428, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1429, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142A, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142B, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142C, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142D, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142E, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142F, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1430, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1431, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1432, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1433, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1434, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1435, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1436, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1437, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1438, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1439, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143A, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143B, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143C, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) },
        { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_9508) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, /* Novatel Merlin V640/XV620 */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, /* Novatel Merlin V620/S620 */
@@ -336,6 +431,7 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
        { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
+       { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626) },
        { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) },
        { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) },
        { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G) },
index 4995bb595aef027367134f7043edab080128a52f..2dd9bd4bff56edceec8962d79ba17f72efad8854 100644 (file)
@@ -95,11 +95,10 @@ int usb_stor_huawei_e220_init(struct us_data *us)
 {
        int result;
 
-       us->iobuf[0] = 0x1;
        result = usb_stor_control_msg(us, us->send_ctrl_pipe,
                                      USB_REQ_SET_FEATURE,
                                      USB_TYPE_STANDARD | USB_RECIP_DEVICE,
-                                     0x01, 0x0, us->iobuf, 0x1, 1000);
+                                     0x01, 0x0, NULL, 0x0, 1000);
        US_DEBUGP("usb_control_msg performing result is %d\n", result);
        return (result ? 0 : -1);
 }
index cd155475cb6edf9a3af0cf115ffd2aa751fb0972..a2b9ebbef38e98142ff7c3f0666ac3eba101d169 100644 (file)
@@ -1628,97 +1628,332 @@ UNUSUAL_DEV(  0x1210, 0x0003, 0x0100, 0x0100,
 /* Reported by fangxiaozhi <huananhu@huawei.com>
  * This brings the HUAWEI data card devices into multi-port mode
  */
-UNUSUAL_DEV( 0x12d1, 0x1001, 0x0000, 0x0000,
+UNUSUAL_DEV(  0x12d1, 0x1001, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
-UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0x0000,
+UNUSUAL_DEV(  0x12d1, 0x1003, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
-UNUSUAL_DEV( 0x12d1, 0x1004, 0x0000, 0x0000,
+UNUSUAL_DEV(  0x12d1, 0x1004, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
-UNUSUAL_DEV( 0x12d1, 0x1401, 0x0000, 0x0000,
+UNUSUAL_DEV(  0x12d1, 0x1401, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
-UNUSUAL_DEV( 0x12d1, 0x1403, 0x0000, 0x0000,
+UNUSUAL_DEV(  0x12d1, 0x1402, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
-UNUSUAL_DEV( 0x12d1, 0x1405, 0x0000, 0x0000,
+UNUSUAL_DEV(  0x12d1, 0x1403, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
-UNUSUAL_DEV( 0x12d1, 0x1406, 0x0000, 0x0000,
+UNUSUAL_DEV(  0x12d1, 0x1404, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
-UNUSUAL_DEV( 0x12d1, 0x1408, 0x0000, 0x0000,
+UNUSUAL_DEV(  0x12d1, 0x1405, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
-UNUSUAL_DEV( 0x12d1, 0x1409, 0x0000, 0x0000,
+UNUSUAL_DEV(  0x12d1, 0x1406, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
-UNUSUAL_DEV( 0x12d1, 0x1410, 0x0000, 0x0000,
+UNUSUAL_DEV(  0x12d1, 0x1407, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
-UNUSUAL_DEV( 0x12d1, 0x1411, 0x0000, 0x0000,
+UNUSUAL_DEV(  0x12d1, 0x1408, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
-UNUSUAL_DEV( 0x12d1, 0x1412, 0x0000, 0x0000,
+UNUSUAL_DEV(  0x12d1, 0x1409, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
-UNUSUAL_DEV( 0x12d1, 0x1413, 0x0000, 0x0000,
+UNUSUAL_DEV(  0x12d1, 0x140A, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
-UNUSUAL_DEV( 0x12d1, 0x1414, 0x0000, 0x0000,
+UNUSUAL_DEV(  0x12d1, 0x140B, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
-UNUSUAL_DEV( 0x12d1, 0x1415, 0x0000, 0x0000,
+UNUSUAL_DEV(  0x12d1, 0x140C, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
-UNUSUAL_DEV( 0x12d1, 0x1416, 0x0000, 0x0000,
+UNUSUAL_DEV(  0x12d1, 0x140D, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
-UNUSUAL_DEV( 0x12d1, 0x1417, 0x0000, 0x0000,
+UNUSUAL_DEV(  0x12d1, 0x140E, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
-UNUSUAL_DEV( 0x12d1, 0x1418, 0x0000, 0x0000,
+UNUSUAL_DEV(  0x12d1, 0x140F, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
-UNUSUAL_DEV( 0x12d1, 0x1419, 0x0000, 0x0000,
+UNUSUAL_DEV(  0x12d1, 0x1410, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1411, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1412, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1413, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1414, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1415, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1416, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1417, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1418, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1419, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x141A, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x141B, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x141C, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x141D, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x141E, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x141F, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1420, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1421, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1422, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1423, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1424, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1425, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1426, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1427, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1428, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1429, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x142A, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x142B, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x142C, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x142D, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x142E, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x142F, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1430, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1431, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1432, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1433, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1434, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1435, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1436, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1437, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1438, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1439, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x143A, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x143B, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x143C, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x143D, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x143E, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x143F, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
@@ -1745,6 +1980,15 @@ UNUSUAL_DEV(  0x14cd, 0x6600, 0x0201, 0x0201,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_IGNORE_RESIDUE ),
 
+/* Reported by Alexandre Oliva <oliva@lsd.ic.unicamp.br>
+ * JMicron responds to USN and several other SCSI ioctls with a
+ * residue that causes subsequent I/O requests to fail.  */
+UNUSUAL_DEV(  0x152d, 0x2329, 0x0100, 0x0100,
+               "JMicron",
+               "USB to ATA/ATAPI Bridge",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_IGNORE_RESIDUE ),
+
 /* Reported by Robert Schedel <r.schedel@yahoo.de>
  * Note: this is a 'super top' device like the above 14cd/6600 device */
 UNUSUAL_DEV(  0x1652, 0x6600, 0x0201, 0x0201,
@@ -1818,6 +2062,15 @@ UNUSUAL_DEV(  0x2770, 0x915d, 0x0010, 0x0010,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_CAPACITY ),
 
+/* Reported by Frederic Marchal <frederic.marchal@wowcompany.com>
+ * Mio Moov 330
+ */
+UNUSUAL_DEV(  0x3340, 0xffff, 0x0000, 0x0000,
+               "Mitac",
+               "Mio DigiWalker USB Sync",
+               US_SC_DEVICE,US_PR_DEVICE,NULL,
+               US_FL_MAX_SECTORS_64 ),
+
 /* Reported by Andrey Rahmatullin <wrar@altlinux.org> */
 UNUSUAL_DEV(  0x4102, 0x1020, 0x0100,  0x0100,
                "iRiver",
diff --git a/drivers/usb/wusbcore/Kconfig b/drivers/usb/wusbcore/Kconfig
new file mode 100644 (file)
index 0000000..eb09a0a
--- /dev/null
@@ -0,0 +1,41 @@
+#
+# Wireless USB Core configuration
+#
+config USB_WUSB
+       tristate "Enable Wireless USB extensions (EXPERIMENTAL)"
+       depends on EXPERIMENTAL
+       depends on USB
+        select UWB
+        select CRYPTO
+        select CRYPTO_BLKCIPHER
+        select CRYPTO_CBC
+        select CRYPTO_MANAGER
+        select CRYPTO_AES
+       help
+         Enable the host-side support for Wireless USB.
+
+          To compile this support select Y (built in). It is safe to
+         select even if you don't have the hardware.
+
+config USB_WUSB_CBAF
+       tristate "Support WUSB Cable Based Association (CBA)"
+       depends on USB
+       help
+         Some WUSB devices support Cable Based Association. It's used to
+         enable the secure communication between the host and the
+         device.
+
+         Enable this option if your WUSB device must to be connected
+         via wired USB before establishing a wireless link.
+
+         It is safe to select even if you don't have a compatible
+         hardware.
+
+config USB_WUSB_CBAF_DEBUG
+       bool "Enable CBA debug messages"
+       depends on USB_WUSB_CBAF
+       help
+         Say Y here if you want the CBA to produce a bunch of debug messages
+         to the system log. Select this if you are having a problem with
+         CBA support and want to see more of what is going on.
+
diff --git a/drivers/usb/wusbcore/Makefile b/drivers/usb/wusbcore/Makefile
new file mode 100644 (file)
index 0000000..75f1ade
--- /dev/null
@@ -0,0 +1,26 @@
+obj-$(CONFIG_USB_WUSB)         += wusbcore.o
+obj-$(CONFIG_USB_HWA_HCD)      += wusb-wa.o
+obj-$(CONFIG_USB_WUSB_CBAF)    += wusb-cbaf.o
+
+
+wusbcore-objs :=       \
+       crypto.o        \
+       devconnect.o    \
+       dev-sysfs.o     \
+       mmc.o           \
+       pal.o           \
+       rh.o            \
+       reservation.o   \
+       security.o      \
+       wusbhc.o
+
+wusb-cbaf-objs := cbaf.o
+
+wusb-wa-objs :=        wa-hc.o         \
+               wa-nep.o        \
+               wa-rpipe.o      \
+               wa-xfer.o
+
+ifeq ($(CONFIG_USB_WUSB_CBAF_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
diff --git a/drivers/usb/wusbcore/cbaf.c b/drivers/usb/wusbcore/cbaf.c
new file mode 100644 (file)
index 0000000..ab4788d
--- /dev/null
@@ -0,0 +1,673 @@
+/*
+ * Wireless USB - Cable Based Association
+ *
+ *
+ * Copyright (C) 2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * WUSB devices have to be paired (associated in WUSB lingo) so
+ * that they can connect to the system.
+ *
+ * One way of pairing is using CBA-Cable Based Association. First
+ * time you plug the device with a cable, association is done between
+ * host and device and subsequent times, you can connect wirelessly
+ * without having to associate again. That's the idea.
+ *
+ * This driver does nothing Earth shattering. It just provides an
+ * interface to chat with the wire-connected device so we can get a
+ * CDID (device ID) that might have been previously associated to a
+ * CHID (host ID) and to set up a new <CHID,CDID,CK> triplet
+ * (connection context), with the CK being the secret, or connection
+ * key. This is the pairing data.
+ *
+ * When a device with the CBA capability connects, the probe routine
+ * just creates a bunch of sysfs files that a user space enumeration
+ * manager uses to allow it to connect wirelessly to the system or not.
+ *
+ * The process goes like this:
+ *
+ * 1. Device plugs, cbaf is loaded, notifications happen.
+ *
+ * 2. The connection manager (CM) sees a device with CBAF capability
+ *    (the wusb_chid etc. files in /sys/devices/blah/OURDEVICE).
+ *
+ * 3. The CM writes the host name, supported band groups, and the CHID
+ *    (host ID) into the wusb_host_name, wusb_host_band_groups and
+ *    wusb_chid files. These get sent to the device and the CDID (if
+ *    any) for this host is requested.
+ *
+ * 4. The CM can verify that the device's supported band groups
+ *    (wusb_device_band_groups) are compatible with the host.
+ *
+ * 5. The CM reads the wusb_cdid file.
+ *
+ * 6. The CM looks up its database
+ *
+ * 6.1 If it has a matching CHID,CDID entry, the device has been
+ *     authorized before (paired) and nothing further needs to be
+ *     done.
+ *
+ * 6.2 If the CDID is zero (or the CM doesn't find a matching CDID in
+ *     its database), the device is assumed to be not known.  The CM
+ *     may associate the host with device by: writing a randomly
+ *     generated CDID to wusb_cdid and then a random CK to wusb_ck
+ *     (this uploads the new CC to the device).
+ *
+ *     CMD may choose to prompt the user before associating with a new
+ *     device.
+ *
+ * 7. Device is unplugged.
+ *
+ * When the device tries to connect wirelessly, it will present its
+ * CDID to the WUSB host controller.  The CM will query the
+ * database. If the CHID/CDID pair found, it will (with a 4-way
+ * handshake) challenge the device to demonstrate it has the CK secret
+ * key (from our database) without actually exchanging it. Once
+ * satisfied, crypto keys are derived from the CK, the device is
+ * connected and all communication is encrypted.
+ *
+ * References:
+ *   [WUSB-AM] Association Models Supplement to the Certified Wireless
+ *             Universal Serial Bus Specification, version 1.0.
+ */
+#include <linux/module.h>
+#include <linux/ctype.h>
+#include <linux/version.h>
+#include <linux/usb.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/random.h>
+#include <linux/mutex.h>
+#include <linux/uwb.h>
+#include <linux/usb/wusb.h>
+#include <linux/usb/association.h>
+
+#define CBA_NAME_LEN 0x40 /* [WUSB-AM] table 4-7 */
+
+/* An instance of a Cable-Based-Association-Framework device */
+struct cbaf {
+       struct usb_device *usb_dev;
+       struct usb_interface *usb_iface;
+       void *buffer;
+       size_t buffer_size;
+
+       struct wusb_ckhdid chid;
+       char host_name[CBA_NAME_LEN];
+       u16 host_band_groups;
+
+       struct wusb_ckhdid cdid;
+       char device_name[CBA_NAME_LEN];
+       u16 device_band_groups;
+
+       struct wusb_ckhdid ck;
+};
+
+/*
+ * Verify that a CBAF USB-interface has what we need
+ *
+ * According to [WUSB-AM], CBA devices should provide at least two
+ * interfaces:
+ *  - RETRIEVE_HOST_INFO
+ *  - ASSOCIATE
+ *
+ * If the device doesn't provide these interfaces, we do not know how
+ * to deal with it.
+ */
+static int cbaf_check(struct cbaf *cbaf)
+{
+       int result;
+       struct device *dev = &cbaf->usb_iface->dev;
+       struct wusb_cbaf_assoc_info *assoc_info;
+       struct wusb_cbaf_assoc_request *assoc_request;
+       size_t assoc_size;
+       void *itr, *top;
+       int ar_rhi = 0, ar_assoc = 0;
+
+       result = usb_control_msg(
+               cbaf->usb_dev, usb_rcvctrlpipe(cbaf->usb_dev, 0),
+               CBAF_REQ_GET_ASSOCIATION_INFORMATION,
+               USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+               0, cbaf->usb_iface->cur_altsetting->desc.bInterfaceNumber,
+               cbaf->buffer, cbaf->buffer_size, 1000 /* FIXME: arbitrary */);
+       if (result < 0) {
+               dev_err(dev, "Cannot get available association types: %d\n",
+                       result);
+               return result;
+       }
+
+       assoc_info = cbaf->buffer;
+       if (result < sizeof(*assoc_info)) {
+               dev_err(dev, "Not enough data to decode association info "
+                       "header (%zu vs %zu bytes required)\n",
+                       (size_t)result, sizeof(*assoc_info));
+               return result;
+       }
+
+       assoc_size = le16_to_cpu(assoc_info->Length);
+       if (result < assoc_size) {
+               dev_err(dev, "Not enough data to decode association info "
+                       "(%zu vs %zu bytes required)\n",
+                       (size_t)assoc_size, sizeof(*assoc_info));
+               return result;
+       }
+       /*
+        * From now on, we just verify, but won't error out unless we
+        * don't find the AR_TYPE_WUSB_{RETRIEVE_HOST_INFO,ASSOCIATE}
+        * types.
+        */
+       itr = cbaf->buffer + sizeof(*assoc_info);
+       top = cbaf->buffer + assoc_size;
+       dev_dbg(dev, "Found %u association requests (%zu bytes)\n",
+                assoc_info->NumAssociationRequests, assoc_size);
+
+       while (itr < top) {
+               u16 ar_type, ar_subtype;
+               u32 ar_size;
+               const char *ar_name;
+
+               assoc_request = itr;
+
+               if (top - itr < sizeof(*assoc_request)) {
+                       dev_err(dev, "Not enough data to decode associaton "
+                               "request (%zu vs %zu bytes needed)\n",
+                               top - itr, sizeof(*assoc_request));
+                       break;
+               }
+
+               ar_type = le16_to_cpu(assoc_request->AssociationTypeId);
+               ar_subtype = le16_to_cpu(assoc_request->AssociationSubTypeId);
+               ar_size = le32_to_cpu(assoc_request->AssociationTypeInfoSize);
+               ar_name = "unknown";
+
+               switch (ar_type) {
+               case AR_TYPE_WUSB:
+                       /* Verify we have what is mandated by [WUSB-AM]. */
+                       switch (ar_subtype) {
+                       case AR_TYPE_WUSB_RETRIEVE_HOST_INFO:
+                               ar_name = "RETRIEVE_HOST_INFO";
+                               ar_rhi = 1;
+                               break;
+                       case AR_TYPE_WUSB_ASSOCIATE:
+                               /* send assoc data */
+                               ar_name = "ASSOCIATE";
+                               ar_assoc = 1;
+                               break;
+                       };
+                       break;
+               };
+
+               dev_dbg(dev, "Association request #%02u: 0x%04x/%04x "
+                        "(%zu bytes): %s\n",
+                        assoc_request->AssociationDataIndex, ar_type,
+                        ar_subtype, (size_t)ar_size, ar_name);
+
+               itr += sizeof(*assoc_request);
+       }
+
+       if (!ar_rhi) {
+               dev_err(dev, "Missing RETRIEVE_HOST_INFO association "
+                       "request\n");
+               return -EINVAL;
+       }
+       if (!ar_assoc) {
+               dev_err(dev, "Missing ASSOCIATE association request\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static const struct wusb_cbaf_host_info cbaf_host_info_defaults = {
+       .AssociationTypeId_hdr    = WUSB_AR_AssociationTypeId,
+       .AssociationTypeId        = cpu_to_le16(AR_TYPE_WUSB),
+       .AssociationSubTypeId_hdr = WUSB_AR_AssociationSubTypeId,
+       .AssociationSubTypeId = cpu_to_le16(AR_TYPE_WUSB_RETRIEVE_HOST_INFO),
+       .CHID_hdr                 = WUSB_AR_CHID,
+       .LangID_hdr               = WUSB_AR_LangID,
+       .HostFriendlyName_hdr     = WUSB_AR_HostFriendlyName,
+};
+
+/* Send WUSB host information (CHID and name) to a CBAF device */
+static int cbaf_send_host_info(struct cbaf *cbaf)
+{
+       struct wusb_cbaf_host_info *hi;
+       size_t name_len;
+       size_t hi_size;
+
+       hi = cbaf->buffer;
+       memset(hi, 0, sizeof(*hi));
+       *hi = cbaf_host_info_defaults;
+       hi->CHID = cbaf->chid;
+       hi->LangID = 0; /* FIXME: I guess... */
+       strlcpy(hi->HostFriendlyName, cbaf->host_name, CBA_NAME_LEN);
+       name_len = strlen(cbaf->host_name);
+       hi->HostFriendlyName_hdr.len = cpu_to_le16(name_len);
+       hi_size = sizeof(*hi) + name_len;
+
+       return usb_control_msg(cbaf->usb_dev, usb_sndctrlpipe(cbaf->usb_dev, 0),
+                       CBAF_REQ_SET_ASSOCIATION_RESPONSE,
+                       USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+                       0x0101,
+                       cbaf->usb_iface->cur_altsetting->desc.bInterfaceNumber,
+                       hi, hi_size, 1000 /* FIXME: arbitrary */);
+}
+
+/*
+ * Get device's information (CDID) associated to CHID
+ *
+ * The device will return it's information (CDID, name, bandgroups)
+ * associated to the CHID we have set before, or 0 CDID and default
+ * name and bandgroup if no CHID set or unknown.
+ */
+static int cbaf_cdid_get(struct cbaf *cbaf)
+{
+       int result;
+       struct device *dev = &cbaf->usb_iface->dev;
+       struct wusb_cbaf_device_info *di;
+       size_t needed;
+
+       di = cbaf->buffer;
+       result = usb_control_msg(
+               cbaf->usb_dev, usb_rcvctrlpipe(cbaf->usb_dev, 0),
+               CBAF_REQ_GET_ASSOCIATION_REQUEST,
+               USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+               0x0200, cbaf->usb_iface->cur_altsetting->desc.bInterfaceNumber,
+               di, cbaf->buffer_size, 1000 /* FIXME: arbitrary */);
+       if (result < 0) {
+               dev_err(dev, "Cannot request device information: %d\n", result);
+               return result;
+       }
+
+       needed = result < sizeof(*di) ? sizeof(*di) : le32_to_cpu(di->Length);
+       if (result < needed) {
+               dev_err(dev, "Not enough data in DEVICE_INFO reply (%zu vs "
+                       "%zu bytes needed)\n", (size_t)result, needed);
+               return result;
+       }
+
+       strlcpy(cbaf->device_name, di->DeviceFriendlyName, CBA_NAME_LEN);
+       cbaf->cdid = di->CDID;
+       cbaf->device_band_groups = le16_to_cpu(di->BandGroups);
+
+       return 0;
+}
+
+static ssize_t cbaf_wusb_chid_show(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
+{
+       struct usb_interface *iface = to_usb_interface(dev);
+       struct cbaf *cbaf = usb_get_intfdata(iface);
+       char pr_chid[WUSB_CKHDID_STRSIZE];
+
+       ckhdid_printf(pr_chid, sizeof(pr_chid), &cbaf->chid);
+       return scnprintf(buf, PAGE_SIZE, "%s\n", pr_chid);
+}
+
+static ssize_t cbaf_wusb_chid_store(struct device *dev,
+                                        struct device_attribute *attr,
+                                        const char *buf, size_t size)
+{
+       ssize_t result;
+       struct usb_interface *iface = to_usb_interface(dev);
+       struct cbaf *cbaf = usb_get_intfdata(iface);
+
+       result = sscanf(buf,
+                       "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx",
+                       &cbaf->chid.data[0] , &cbaf->chid.data[1],
+                       &cbaf->chid.data[2] , &cbaf->chid.data[3],
+                       &cbaf->chid.data[4] , &cbaf->chid.data[5],
+                       &cbaf->chid.data[6] , &cbaf->chid.data[7],
+                       &cbaf->chid.data[8] , &cbaf->chid.data[9],
+                       &cbaf->chid.data[10], &cbaf->chid.data[11],
+                       &cbaf->chid.data[12], &cbaf->chid.data[13],
+                       &cbaf->chid.data[14], &cbaf->chid.data[15]);
+
+       if (result != 16)
+               return -EINVAL;
+
+       result = cbaf_send_host_info(cbaf);
+       if (result < 0)
+               return result;
+       result = cbaf_cdid_get(cbaf);
+       if (result < 0)
+               return -result;
+       return size;
+}
+static DEVICE_ATTR(wusb_chid, 0600, cbaf_wusb_chid_show, cbaf_wusb_chid_store);
+
+static ssize_t cbaf_wusb_host_name_show(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
+{
+       struct usb_interface *iface = to_usb_interface(dev);
+       struct cbaf *cbaf = usb_get_intfdata(iface);
+
+       return scnprintf(buf, PAGE_SIZE, "%s\n", cbaf->host_name);
+}
+
+static ssize_t cbaf_wusb_host_name_store(struct device *dev,
+                                        struct device_attribute *attr,
+                                        const char *buf, size_t size)
+{
+       ssize_t result;
+       struct usb_interface *iface = to_usb_interface(dev);
+       struct cbaf *cbaf = usb_get_intfdata(iface);
+
+       result = sscanf(buf, "%63s", cbaf->host_name);
+       if (result != 1)
+               return -EINVAL;
+
+       return size;
+}
+static DEVICE_ATTR(wusb_host_name, 0600, cbaf_wusb_host_name_show,
+                                        cbaf_wusb_host_name_store);
+
+static ssize_t cbaf_wusb_host_band_groups_show(struct device *dev,
+                                              struct device_attribute *attr,
+                                              char *buf)
+{
+       struct usb_interface *iface = to_usb_interface(dev);
+       struct cbaf *cbaf = usb_get_intfdata(iface);
+
+       return scnprintf(buf, PAGE_SIZE, "0x%04x\n", cbaf->host_band_groups);
+}
+
+static ssize_t cbaf_wusb_host_band_groups_store(struct device *dev,
+                                               struct device_attribute *attr,
+                                               const char *buf, size_t size)
+{
+       ssize_t result;
+       struct usb_interface *iface = to_usb_interface(dev);
+       struct cbaf *cbaf = usb_get_intfdata(iface);
+       u16 band_groups = 0;
+
+       result = sscanf(buf, "%04hx", &band_groups);
+       if (result != 1)
+               return -EINVAL;
+
+       cbaf->host_band_groups = band_groups;
+
+       return size;
+}
+
+static DEVICE_ATTR(wusb_host_band_groups, 0600,
+                  cbaf_wusb_host_band_groups_show,
+                  cbaf_wusb_host_band_groups_store);
+
+static const struct wusb_cbaf_device_info cbaf_device_info_defaults = {
+       .Length_hdr               = WUSB_AR_Length,
+       .CDID_hdr                 = WUSB_AR_CDID,
+       .BandGroups_hdr           = WUSB_AR_BandGroups,
+       .LangID_hdr               = WUSB_AR_LangID,
+       .DeviceFriendlyName_hdr   = WUSB_AR_DeviceFriendlyName,
+};
+
+static ssize_t cbaf_wusb_cdid_show(struct device *dev,
+                                  struct device_attribute *attr, char *buf)
+{
+       struct usb_interface *iface = to_usb_interface(dev);
+       struct cbaf *cbaf = usb_get_intfdata(iface);
+       char pr_cdid[WUSB_CKHDID_STRSIZE];
+
+       ckhdid_printf(pr_cdid, sizeof(pr_cdid), &cbaf->cdid);
+       return scnprintf(buf, PAGE_SIZE, "%s\n", pr_cdid);
+}
+
+static ssize_t cbaf_wusb_cdid_store(struct device *dev,
+                               struct device_attribute *attr,
+                               const char *buf, size_t size)
+{
+       ssize_t result;
+       struct usb_interface *iface = to_usb_interface(dev);
+       struct cbaf *cbaf = usb_get_intfdata(iface);
+       struct wusb_ckhdid cdid;
+
+       result = sscanf(buf,
+                       "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx",
+                       &cdid.data[0] , &cdid.data[1],
+                       &cdid.data[2] , &cdid.data[3],
+                       &cdid.data[4] , &cdid.data[5],
+                       &cdid.data[6] , &cdid.data[7],
+                       &cdid.data[8] , &cdid.data[9],
+                       &cdid.data[10], &cdid.data[11],
+                       &cdid.data[12], &cdid.data[13],
+                       &cdid.data[14], &cdid.data[15]);
+       if (result != 16)
+               return -EINVAL;
+
+       cbaf->cdid = cdid;
+
+       return size;
+}
+static DEVICE_ATTR(wusb_cdid, 0600, cbaf_wusb_cdid_show, cbaf_wusb_cdid_store);
+
+static ssize_t cbaf_wusb_device_band_groups_show(struct device *dev,
+                                                struct device_attribute *attr,
+                                                char *buf)
+{
+       struct usb_interface *iface = to_usb_interface(dev);
+       struct cbaf *cbaf = usb_get_intfdata(iface);
+
+       return scnprintf(buf, PAGE_SIZE, "0x%04x\n", cbaf->device_band_groups);
+}
+
+static DEVICE_ATTR(wusb_device_band_groups, 0600,
+                  cbaf_wusb_device_band_groups_show,
+                  NULL);
+
+static ssize_t cbaf_wusb_device_name_show(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
+{
+       struct usb_interface *iface = to_usb_interface(dev);
+       struct cbaf *cbaf = usb_get_intfdata(iface);
+
+       return scnprintf(buf, PAGE_SIZE, "%s\n", cbaf->device_name);
+}
+static DEVICE_ATTR(wusb_device_name, 0600, cbaf_wusb_device_name_show, NULL);
+
+static const struct wusb_cbaf_cc_data cbaf_cc_data_defaults = {
+       .AssociationTypeId_hdr    = WUSB_AR_AssociationTypeId,
+       .AssociationTypeId        = cpu_to_le16(AR_TYPE_WUSB),
+       .AssociationSubTypeId_hdr = WUSB_AR_AssociationSubTypeId,
+       .AssociationSubTypeId     = cpu_to_le16(AR_TYPE_WUSB_ASSOCIATE),
+       .Length_hdr               = WUSB_AR_Length,
+       .Length                   = cpu_to_le32(sizeof(struct wusb_cbaf_cc_data)),
+       .ConnectionContext_hdr    = WUSB_AR_ConnectionContext,
+       .BandGroups_hdr           = WUSB_AR_BandGroups,
+};
+
+static const struct wusb_cbaf_cc_data_fail cbaf_cc_data_fail_defaults = {
+       .AssociationTypeId_hdr    = WUSB_AR_AssociationTypeId,
+       .AssociationSubTypeId_hdr = WUSB_AR_AssociationSubTypeId,
+       .Length_hdr               = WUSB_AR_Length,
+       .AssociationStatus_hdr    = WUSB_AR_AssociationStatus,
+};
+
+/*
+ * Send a new CC to the device.
+ */
+static int cbaf_cc_upload(struct cbaf *cbaf)
+{
+       int result;
+       struct device *dev = &cbaf->usb_iface->dev;
+       struct wusb_cbaf_cc_data *ccd;
+       char pr_cdid[WUSB_CKHDID_STRSIZE];
+
+       ccd =  cbaf->buffer;
+       *ccd = cbaf_cc_data_defaults;
+       ccd->CHID = cbaf->chid;
+       ccd->CDID = cbaf->cdid;
+       ccd->CK = cbaf->ck;
+       ccd->BandGroups = cpu_to_le16(cbaf->host_band_groups);
+
+       dev_dbg(dev, "Trying to upload CC:\n");
+       ckhdid_printf(pr_cdid, sizeof(pr_cdid), &ccd->CHID);
+       dev_dbg(dev, "  CHID       %s\n", pr_cdid);
+       ckhdid_printf(pr_cdid, sizeof(pr_cdid), &ccd->CDID);
+       dev_dbg(dev, "  CDID       %s\n", pr_cdid);
+       dev_dbg(dev, "  Bandgroups 0x%04x\n", cbaf->host_band_groups);
+
+       result = usb_control_msg(
+               cbaf->usb_dev, usb_sndctrlpipe(cbaf->usb_dev, 0),
+               CBAF_REQ_SET_ASSOCIATION_RESPONSE,
+               USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+               0x0201, cbaf->usb_iface->cur_altsetting->desc.bInterfaceNumber,
+               ccd, sizeof(*ccd), 1000 /* FIXME: arbitrary */);
+
+       return result;
+}
+
+static ssize_t cbaf_wusb_ck_store(struct device *dev,
+                                 struct device_attribute *attr,
+                                 const char *buf, size_t size)
+{
+       ssize_t result;
+       struct usb_interface *iface = to_usb_interface(dev);
+       struct cbaf *cbaf = usb_get_intfdata(iface);
+
+       result = sscanf(buf,
+                       "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx",
+                       &cbaf->ck.data[0] , &cbaf->ck.data[1],
+                       &cbaf->ck.data[2] , &cbaf->ck.data[3],
+                       &cbaf->ck.data[4] , &cbaf->ck.data[5],
+                       &cbaf->ck.data[6] , &cbaf->ck.data[7],
+                       &cbaf->ck.data[8] , &cbaf->ck.data[9],
+                       &cbaf->ck.data[10], &cbaf->ck.data[11],
+                       &cbaf->ck.data[12], &cbaf->ck.data[13],
+                       &cbaf->ck.data[14], &cbaf->ck.data[15]);
+       if (result != 16)
+               return -EINVAL;
+
+       result = cbaf_cc_upload(cbaf);
+       if (result < 0)
+               return result;
+
+       return size;
+}
+static DEVICE_ATTR(wusb_ck, 0600, NULL, cbaf_wusb_ck_store);
+
+static struct attribute *cbaf_dev_attrs[] = {
+       &dev_attr_wusb_host_name.attr,
+       &dev_attr_wusb_host_band_groups.attr,
+       &dev_attr_wusb_chid.attr,
+       &dev_attr_wusb_cdid.attr,
+       &dev_attr_wusb_device_name.attr,
+       &dev_attr_wusb_device_band_groups.attr,
+       &dev_attr_wusb_ck.attr,
+       NULL,
+};
+
+static struct attribute_group cbaf_dev_attr_group = {
+       .name = NULL,   /* we want them in the same directory */
+       .attrs = cbaf_dev_attrs,
+};
+
+static int cbaf_probe(struct usb_interface *iface,
+                     const struct usb_device_id *id)
+{
+       struct cbaf *cbaf;
+       struct device *dev = &iface->dev;
+       int result = -ENOMEM;
+
+       cbaf = kzalloc(sizeof(*cbaf), GFP_KERNEL);
+       if (cbaf == NULL)
+               goto error_kzalloc;
+       cbaf->buffer = kmalloc(512, GFP_KERNEL);
+       if (cbaf->buffer == NULL)
+               goto error_kmalloc_buffer;
+
+       cbaf->buffer_size = 512;
+       cbaf->usb_dev = usb_get_dev(interface_to_usbdev(iface));
+       cbaf->usb_iface = usb_get_intf(iface);
+       result = cbaf_check(cbaf);
+       if (result < 0) {
+               dev_err(dev, "This device is not WUSB-CBAF compliant"
+                       "and is not supported yet.\n");
+               goto error_check;
+       }
+
+       result = sysfs_create_group(&dev->kobj, &cbaf_dev_attr_group);
+       if (result < 0) {
+               dev_err(dev, "Can't register sysfs attr group: %d\n", result);
+               goto error_create_group;
+       }
+       usb_set_intfdata(iface, cbaf);
+       return 0;
+
+error_create_group:
+error_check:
+       kfree(cbaf->buffer);
+error_kmalloc_buffer:
+       kfree(cbaf);
+error_kzalloc:
+       return result;
+}
+
+static void cbaf_disconnect(struct usb_interface *iface)
+{
+       struct cbaf *cbaf = usb_get_intfdata(iface);
+       struct device *dev = &iface->dev;
+       sysfs_remove_group(&dev->kobj, &cbaf_dev_attr_group);
+       usb_set_intfdata(iface, NULL);
+       usb_put_intf(iface);
+       kfree(cbaf->buffer);
+       /* paranoia: clean up crypto keys */
+       memset(cbaf, 0, sizeof(*cbaf));
+       kfree(cbaf);
+}
+
+static struct usb_device_id cbaf_id_table[] = {
+       { USB_INTERFACE_INFO(0xef, 0x03, 0x01), },
+       { },
+};
+MODULE_DEVICE_TABLE(usb, cbaf_id_table);
+
+static struct usb_driver cbaf_driver = {
+       .name =         "wusb-cbaf",
+       .id_table =     cbaf_id_table,
+       .probe =        cbaf_probe,
+       .disconnect =   cbaf_disconnect,
+};
+
+static int __init cbaf_driver_init(void)
+{
+       return usb_register(&cbaf_driver);
+}
+module_init(cbaf_driver_init);
+
+static void __exit cbaf_driver_exit(void)
+{
+       usb_deregister(&cbaf_driver);
+}
+module_exit(cbaf_driver_exit);
+
+MODULE_AUTHOR("Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>");
+MODULE_DESCRIPTION("Wireless USB Cable Based Association");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/wusbcore/crypto.c b/drivers/usb/wusbcore/crypto.c
new file mode 100644 (file)
index 0000000..c36c438
--- /dev/null
@@ -0,0 +1,538 @@
+/*
+ * Ultra Wide Band
+ * AES-128 CCM Encryption
+ *
+ * Copyright (C) 2007 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * We don't do any encryption here; we use the Linux Kernel's AES-128
+ * crypto modules to construct keys and payload blocks in a way
+ * defined by WUSB1.0[6]. Check the erratas, as typos are are patched
+ * there.
+ *
+ * Thanks a zillion to John Keys for his help and clarifications over
+ * the designed-by-a-committee text.
+ *
+ * So the idea is that there is this basic Pseudo-Random-Function
+ * defined in WUSB1.0[6.5] which is the core of everything. It works
+ * by tweaking some blocks, AES crypting them and then xoring
+ * something else with them (this seems to be called CBC(AES) -- can
+ * you tell I know jack about crypto?). So we just funnel it into the
+ * Linux Crypto API.
+ *
+ * We leave a crypto test module so we can verify that vectors match,
+ * every now and then.
+ *
+ * Block size: 16 bytes -- AES seems to do things in 'block sizes'. I
+ *             am learning a lot...
+ *
+ *             Conveniently, some data structures that need to be
+ *             funneled through AES are...16 bytes in size!
+ */
+
+#include <linux/crypto.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/uwb.h>
+#include <linux/usb/wusb.h>
+#include <linux/scatterlist.h>
+#define D_LOCAL 0
+#include <linux/uwb/debug.h>
+
+
+/*
+ * Block of data, as understood by AES-CCM
+ *
+ * The code assumes this structure is nothing but a 16 byte array
+ * (packed in a struct to avoid common mess ups that I usually do with
+ * arrays and enforcing type checking).
+ */
+struct aes_ccm_block {
+       u8 data[16];
+} __attribute__((packed));
+
+/*
+ * Counter-mode Blocks (WUSB1.0[6.4])
+ *
+ * According to CCM (or so it seems), for the purpose of calculating
+ * the MIC, the message is broken in N counter-mode blocks, B0, B1,
+ * ... BN.
+ *
+ * B0 contains flags, the CCM nonce and l(m).
+ *
+ * B1 contains l(a), the MAC header, the encryption offset and padding.
+ *
+ * If EO is nonzero, additional blocks are built from payload bytes
+ * until EO is exahusted (FIXME: padding to 16 bytes, I guess). The
+ * padding is not xmitted.
+ */
+
+/* WUSB1.0[T6.4] */
+struct aes_ccm_b0 {
+       u8 flags;       /* 0x59, per CCM spec */
+       struct aes_ccm_nonce ccm_nonce;
+       __be16 lm;
+} __attribute__((packed));
+
+/* WUSB1.0[T6.5] */
+struct aes_ccm_b1 {
+       __be16 la;
+       u8 mac_header[10];
+       __le16 eo;
+       u8 security_reserved;   /* This is always zero */
+       u8 padding;             /* 0 */
+} __attribute__((packed));
+
+/*
+ * Encryption Blocks (WUSB1.0[6.4.4])
+ *
+ * CCM uses Ax blocks to generate a keystream with which the MIC and
+ * the message's payload are encoded. A0 always encrypts/decrypts the
+ * MIC. Ax (x>0) are used for the sucesive payload blocks.
+ *
+ * The x is the counter, and is increased for each block.
+ */
+struct aes_ccm_a {
+       u8 flags;       /* 0x01, per CCM spec */
+       struct aes_ccm_nonce ccm_nonce;
+       __be16 counter; /* Value of x */
+} __attribute__((packed));
+
+static void bytewise_xor(void *_bo, const void *_bi1, const void *_bi2,
+                        size_t size)
+{
+       u8 *bo = _bo;
+       const u8 *bi1 = _bi1, *bi2 = _bi2;
+       size_t itr;
+       for (itr = 0; itr < size; itr++)
+               bo[itr] = bi1[itr] ^ bi2[itr];
+}
+
+/*
+ * CC-MAC function WUSB1.0[6.5]
+ *
+ * Take a data string and produce the encrypted CBC Counter-mode MIC
+ *
+ * Note the names for most function arguments are made to (more or
+ * less) match those used in the pseudo-function definition given in
+ * WUSB1.0[6.5].
+ *
+ * @tfm_cbc: CBC(AES) blkcipher handle (initialized)
+ *
+ * @tfm_aes: AES cipher handle (initialized)
+ *
+ * @mic: buffer for placing the computed MIC (Message Integrity
+ *       Code). This is exactly 8 bytes, and we expect the buffer to
+ *       be at least eight bytes in length.
+ *
+ * @key: 128 bit symmetric key
+ *
+ * @n: CCM nonce
+ *
+ * @a: ASCII string, 14 bytes long (I guess zero padded if needed;
+ *     we use exactly 14 bytes).
+ *
+ * @b: data stream to be processed; cannot be a global or const local
+ *     (will confuse the scatterlists)
+ *
+ * @blen: size of b...
+ *
+ * Still not very clear how this is done, but looks like this: we
+ * create block B0 (as WUSB1.0[6.5] says), then we AES-crypt it with
+ * @key. We bytewise xor B0 with B1 (1) and AES-crypt that. Then we
+ * take the payload and divide it in blocks (16 bytes), xor them with
+ * the previous crypto result (16 bytes) and crypt it, repeat the next
+ * block with the output of the previous one, rinse wash (I guess this
+ * is what AES CBC mode means...but I truly have no idea). So we use
+ * the CBC(AES) blkcipher, that does precisely that. The IV (Initial
+ * Vector) is 16 bytes and is set to zero, so
+ *
+ * See rfc3610. Linux crypto has a CBC implementation, but the
+ * documentation is scarce, to say the least, and the example code is
+ * so intricated that is difficult to understand how things work. Most
+ * of this is guess work -- bite me.
+ *
+ * (1) Created as 6.5 says, again, using as l(a) 'Blen + 14', and
+ *     using the 14 bytes of @a to fill up
+ *     b1.{mac_header,e0,security_reserved,padding}.
+ *
+ * NOTE: The definiton of l(a) in WUSB1.0[6.5] vs the definition of
+ *       l(m) is orthogonal, they bear no relationship, so it is not
+ *       in conflict with the parameter's relation that
+ *       WUSB1.0[6.4.2]) defines.
+ *
+ * NOTE: WUSB1.0[A.1]: Host Nonce is missing a nibble? (1e); fixed in
+ *       first errata released on 2005/07.
+ *
+ * NOTE: we need to clean IV to zero at each invocation to make sure
+ *       we start with a fresh empty Initial Vector, so that the CBC
+ *       works ok.
+ *
+ * NOTE: blen is not aligned to a block size, we'll pad zeros, that's
+ *       what sg[4] is for. Maybe there is a smarter way to do this.
+ */
+static int wusb_ccm_mac(struct crypto_blkcipher *tfm_cbc,
+                       struct crypto_cipher *tfm_aes, void *mic,
+                       const struct aes_ccm_nonce *n,
+                       const struct aes_ccm_label *a, const void *b,
+                       size_t blen)
+{
+       int result = 0;
+       struct blkcipher_desc desc;
+       struct aes_ccm_b0 b0;
+       struct aes_ccm_b1 b1;
+       struct aes_ccm_a ax;
+       struct scatterlist sg[4], sg_dst;
+       void *iv, *dst_buf;
+       size_t ivsize, dst_size;
+       const u8 bzero[16] = { 0 };
+       size_t zero_padding;
+
+       d_fnstart(3, NULL, "(tfm_cbc %p, tfm_aes %p, mic %p, "
+                 "n %p, a %p, b %p, blen %zu)\n",
+                 tfm_cbc, tfm_aes, mic, n, a, b, blen);
+       /*
+        * These checks should be compile time optimized out
+        * ensure @a fills b1's mac_header and following fields
+        */
+       WARN_ON(sizeof(*a) != sizeof(b1) - sizeof(b1.la));
+       WARN_ON(sizeof(b0) != sizeof(struct aes_ccm_block));
+       WARN_ON(sizeof(b1) != sizeof(struct aes_ccm_block));
+       WARN_ON(sizeof(ax) != sizeof(struct aes_ccm_block));
+
+       result = -ENOMEM;
+       zero_padding = sizeof(struct aes_ccm_block)
+               - blen % sizeof(struct aes_ccm_block);
+       zero_padding = blen % sizeof(struct aes_ccm_block);
+       if (zero_padding)
+               zero_padding = sizeof(struct aes_ccm_block) - zero_padding;
+       dst_size = blen + sizeof(b0) + sizeof(b1) + zero_padding;
+       dst_buf = kzalloc(dst_size, GFP_KERNEL);
+       if (dst_buf == NULL) {
+               printk(KERN_ERR "E: can't alloc destination buffer\n");
+               goto error_dst_buf;
+       }
+
+       iv = crypto_blkcipher_crt(tfm_cbc)->iv;
+       ivsize = crypto_blkcipher_ivsize(tfm_cbc);
+       memset(iv, 0, ivsize);
+
+       /* Setup B0 */
+       b0.flags = 0x59;        /* Format B0 */
+       b0.ccm_nonce = *n;
+       b0.lm = cpu_to_be16(0); /* WUSB1.0[6.5] sez l(m) is 0 */
+
+       /* Setup B1
+        *
+        * The WUSB spec is anything but clear! WUSB1.0[6.5]
+        * says that to initialize B1 from A with 'l(a) = blen +
+        * 14'--after clarification, it means to use A's contents
+        * for MAC Header, EO, sec reserved and padding.
+        */
+       b1.la = cpu_to_be16(blen + 14);
+       memcpy(&b1.mac_header, a, sizeof(*a));
+
+       d_printf(4, NULL, "I: B0 (%zu bytes)\n", sizeof(b0));
+       d_dump(4, NULL, &b0, sizeof(b0));
+       d_printf(4, NULL, "I: B1 (%zu bytes)\n", sizeof(b1));
+       d_dump(4, NULL, &b1, sizeof(b1));
+       d_printf(4, NULL, "I: B (%zu bytes)\n", blen);
+       d_dump(4, NULL, b, blen);
+       d_printf(4, NULL, "I: B 0-padding (%zu bytes)\n", zero_padding);
+       d_printf(4, NULL, "D: IV before crypto (%zu)\n", ivsize);
+       d_dump(4, NULL, iv, ivsize);
+
+       sg_init_table(sg, ARRAY_SIZE(sg));
+       sg_set_buf(&sg[0], &b0, sizeof(b0));
+       sg_set_buf(&sg[1], &b1, sizeof(b1));
+       sg_set_buf(&sg[2], b, blen);
+       /* 0 if well behaved :) */
+       sg_set_buf(&sg[3], bzero, zero_padding);
+       sg_init_one(&sg_dst, dst_buf, dst_size);
+
+       desc.tfm = tfm_cbc;
+       desc.flags = 0;
+       result = crypto_blkcipher_encrypt(&desc, &sg_dst, sg, dst_size);
+       if (result < 0) {
+               printk(KERN_ERR "E: can't compute CBC-MAC tag (MIC): %d\n",
+                      result);
+               goto error_cbc_crypt;
+       }
+       d_printf(4, NULL, "D: MIC tag\n");
+       d_dump(4, NULL, iv, ivsize);
+
+       /* Now we crypt the MIC Tag (*iv) with Ax -- values per WUSB1.0[6.5]
+        * The procedure is to AES crypt the A0 block and XOR the MIC
+        * Tag agains it; we only do the first 8 bytes and place it
+        * directly in the destination buffer.
+        *
+        * POS Crypto API: size is assumed to be AES's block size.
+        * Thanks for documenting it -- tip taken from airo.c
+        */
+       ax.flags = 0x01;                /* as per WUSB 1.0 spec */
+       ax.ccm_nonce = *n;
+       ax.counter = 0;
+       crypto_cipher_encrypt_one(tfm_aes, (void *)&ax, (void *)&ax);
+       bytewise_xor(mic, &ax, iv, 8);
+       d_printf(4, NULL, "D: CTR[MIC]\n");
+       d_dump(4, NULL, &ax, 8);
+       d_printf(4, NULL, "D: CCM-MIC tag\n");
+       d_dump(4, NULL, mic, 8);
+       result = 8;
+error_cbc_crypt:
+       kfree(dst_buf);
+error_dst_buf:
+       d_fnend(3, NULL, "(tfm_cbc %p, tfm_aes %p, mic %p, "
+               "n %p, a %p, b %p, blen %zu)\n",
+               tfm_cbc, tfm_aes, mic, n, a, b, blen);
+       return result;
+}
+
+/*
+ * WUSB Pseudo Random Function (WUSB1.0[6.5])
+ *
+ * @b: buffer to the source data; cannot be a global or const local
+ *     (will confuse the scatterlists)
+ */
+ssize_t wusb_prf(void *out, size_t out_size,
+                const u8 key[16], const struct aes_ccm_nonce *_n,
+                const struct aes_ccm_label *a,
+                const void *b, size_t blen, size_t len)
+{
+       ssize_t result, bytes = 0, bitr;
+       struct aes_ccm_nonce n = *_n;
+       struct crypto_blkcipher *tfm_cbc;
+       struct crypto_cipher *tfm_aes;
+       u64 sfn = 0;
+       __le64 sfn_le;
+
+       d_fnstart(3, NULL, "(out %p, out_size %zu, key %p, _n %p, "
+                 "a %p, b %p, blen %zu, len %zu)\n", out, out_size,
+                 key, _n, a, b, blen, len);
+
+       tfm_cbc = crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
+       if (IS_ERR(tfm_cbc)) {
+               result = PTR_ERR(tfm_cbc);
+               printk(KERN_ERR "E: can't load CBC(AES): %d\n", (int)result);
+               goto error_alloc_cbc;
+       }
+       result = crypto_blkcipher_setkey(tfm_cbc, key, 16);
+       if (result < 0) {
+               printk(KERN_ERR "E: can't set CBC key: %d\n", (int)result);
+               goto error_setkey_cbc;
+       }
+
+       tfm_aes = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
+       if (IS_ERR(tfm_aes)) {
+               result = PTR_ERR(tfm_aes);
+               printk(KERN_ERR "E: can't load AES: %d\n", (int)result);
+               goto error_alloc_aes;
+       }
+       result = crypto_cipher_setkey(tfm_aes, key, 16);
+       if (result < 0) {
+               printk(KERN_ERR "E: can't set AES key: %d\n", (int)result);
+               goto error_setkey_aes;
+       }
+
+       for (bitr = 0; bitr < (len + 63) / 64; bitr++) {
+               sfn_le = cpu_to_le64(sfn++);
+               memcpy(&n.sfn, &sfn_le, sizeof(n.sfn)); /* n.sfn++... */
+               result = wusb_ccm_mac(tfm_cbc, tfm_aes, out + bytes,
+                                     &n, a, b, blen);
+               if (result < 0)
+                       goto error_ccm_mac;
+               bytes += result;
+       }
+       result = bytes;
+error_ccm_mac:
+error_setkey_aes:
+       crypto_free_cipher(tfm_aes);
+error_alloc_aes:
+error_setkey_cbc:
+       crypto_free_blkcipher(tfm_cbc);
+error_alloc_cbc:
+       d_fnend(3, NULL, "(out %p, out_size %zu, key %p, _n %p, "
+               "a %p, b %p, blen %zu, len %zu) = %d\n", out, out_size,
+               key, _n, a, b, blen, len, (int)bytes);
+       return result;
+}
+
+/* WUSB1.0[A.2] test vectors */
+static const u8 stv_hsmic_key[16] = {
+       0x4b, 0x79, 0xa3, 0xcf, 0xe5, 0x53, 0x23, 0x9d,
+       0xd7, 0xc1, 0x6d, 0x1c, 0x2d, 0xab, 0x6d, 0x3f
+};
+
+static const struct aes_ccm_nonce stv_hsmic_n = {
+       .sfn = { 0 },
+       .tkid = { 0x76, 0x98, 0x01,  },
+       .dest_addr = { .data = { 0xbe, 0x00 } },
+               .src_addr = { .data = { 0x76, 0x98 } },
+};
+
+/*
+ * Out-of-band MIC Generation verification code
+ *
+ */
+static int wusb_oob_mic_verify(void)
+{
+       int result;
+       u8 mic[8];
+       /* WUSB1.0[A.2] test vectors
+        *
+        * Need to keep it in the local stack as GCC 4.1.3something
+        * messes up and generates noise.
+        */
+       struct usb_handshake stv_hsmic_hs = {
+               .bMessageNumber = 2,
+               .bStatus        = 00,
+               .tTKID          = { 0x76, 0x98, 0x01 },
+               .bReserved      = 00,
+               .CDID           = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+                                   0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
+                                   0x3c, 0x3d, 0x3e, 0x3f },
+               .nonce          = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
+                                   0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
+                                   0x2c, 0x2d, 0x2e, 0x2f },
+               .MIC            = { 0x75, 0x6a, 0x97, 0x51, 0x0c, 0x8c,
+                                   0x14, 0x7b } ,
+       };
+       size_t hs_size;
+
+       result = wusb_oob_mic(mic, stv_hsmic_key, &stv_hsmic_n, &stv_hsmic_hs);
+       if (result < 0)
+               printk(KERN_ERR "E: WUSB OOB MIC test: failed: %d\n", result);
+       else if (memcmp(stv_hsmic_hs.MIC, mic, sizeof(mic))) {
+               printk(KERN_ERR "E: OOB MIC test: "
+                      "mismatch between MIC result and WUSB1.0[A2]\n");
+               hs_size = sizeof(stv_hsmic_hs) - sizeof(stv_hsmic_hs.MIC);
+               printk(KERN_ERR "E: Handshake2 in: (%zu bytes)\n", hs_size);
+               dump_bytes(NULL, &stv_hsmic_hs, hs_size);
+               printk(KERN_ERR "E: CCM Nonce in: (%zu bytes)\n",
+                      sizeof(stv_hsmic_n));
+               dump_bytes(NULL, &stv_hsmic_n, sizeof(stv_hsmic_n));
+               printk(KERN_ERR "E: MIC out:\n");
+               dump_bytes(NULL, mic, sizeof(mic));
+               printk(KERN_ERR "E: MIC out (from WUSB1.0[A.2]):\n");
+               dump_bytes(NULL, stv_hsmic_hs.MIC, sizeof(stv_hsmic_hs.MIC));
+               result = -EINVAL;
+       } else
+               result = 0;
+       return result;
+}
+
+/*
+ * Test vectors for Key derivation
+ *
+ * These come from WUSB1.0[6.5.1], the vectors in WUSB1.0[A.1]
+ * (errata corrected in 2005/07).
+ */
+static const u8 stv_key_a1[16] __attribute__ ((__aligned__(4))) = {
+       0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
+       0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f
+};
+
+static const struct aes_ccm_nonce stv_keydvt_n_a1 = {
+       .sfn = { 0 },
+       .tkid = { 0x76, 0x98, 0x01,  },
+       .dest_addr = { .data = { 0xbe, 0x00 } },
+       .src_addr = { .data = { 0x76, 0x98 } },
+};
+
+static const struct wusb_keydvt_out stv_keydvt_out_a1 = {
+       .kck = {
+               0x4b, 0x79, 0xa3, 0xcf, 0xe5, 0x53, 0x23, 0x9d,
+               0xd7, 0xc1, 0x6d, 0x1c, 0x2d, 0xab, 0x6d, 0x3f
+       },
+       .ptk = {
+               0xc8, 0x70, 0x62, 0x82, 0xb6, 0x7c, 0xe9, 0x06,
+               0x7b, 0xc5, 0x25, 0x69, 0xf2, 0x36, 0x61, 0x2d
+       }
+};
+
+/*
+ * Performa a test to make sure we match the vectors defined in
+ * WUSB1.0[A.1](Errata2006/12)
+ */
+static int wusb_key_derive_verify(void)
+{
+       int result = 0;
+       struct wusb_keydvt_out keydvt_out;
+       /* These come from WUSB1.0[A.1] + 2006/12 errata
+        * NOTE: can't make this const or global -- somehow it seems
+        *       the scatterlists for crypto get confused and we get
+        *       bad data. There is no doc on this... */
+       struct wusb_keydvt_in stv_keydvt_in_a1 = {
+               .hnonce = {
+                       0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+                       0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
+               },
+               .dnonce = {
+                       0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+                       0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f
+               }
+       };
+
+       result = wusb_key_derive(&keydvt_out, stv_key_a1, &stv_keydvt_n_a1,
+                                &stv_keydvt_in_a1);
+       if (result < 0)
+               printk(KERN_ERR "E: WUSB key derivation test: "
+                      "derivation failed: %d\n", result);
+       if (memcmp(&stv_keydvt_out_a1, &keydvt_out, sizeof(keydvt_out))) {
+               printk(KERN_ERR "E: WUSB key derivation test: "
+                      "mismatch between key derivation result "
+                      "and WUSB1.0[A1] Errata 2006/12\n");
+               printk(KERN_ERR "E: keydvt in: key (%zu bytes)\n",
+                      sizeof(stv_key_a1));
+               dump_bytes(NULL, stv_key_a1, sizeof(stv_key_a1));
+               printk(KERN_ERR "E: keydvt in: nonce (%zu bytes)\n",
+                      sizeof(stv_keydvt_n_a1));
+               dump_bytes(NULL, &stv_keydvt_n_a1, sizeof(stv_keydvt_n_a1));
+               printk(KERN_ERR "E: keydvt in: hnonce & dnonce (%zu bytes)\n",
+                      sizeof(stv_keydvt_in_a1));
+               dump_bytes(NULL, &stv_keydvt_in_a1, sizeof(stv_keydvt_in_a1));
+               printk(KERN_ERR "E: keydvt out: KCK\n");
+               dump_bytes(NULL, &keydvt_out.kck, sizeof(keydvt_out.kck));
+               printk(KERN_ERR "E: keydvt out: PTK\n");
+               dump_bytes(NULL, &keydvt_out.ptk, sizeof(keydvt_out.ptk));
+               result = -EINVAL;
+       } else
+               result = 0;
+       return result;
+}
+
+/*
+ * Initialize crypto system
+ *
+ * FIXME: we do nothing now, other than verifying. Later on we'll
+ * cache the encryption stuff, so that's why we have a separate init.
+ */
+int wusb_crypto_init(void)
+{
+       int result;
+
+       result = wusb_key_derive_verify();
+       if (result < 0)
+               return result;
+       return wusb_oob_mic_verify();
+}
+
+void wusb_crypto_exit(void)
+{
+       /* FIXME: free cached crypto transforms */
+}
diff --git a/drivers/usb/wusbcore/dev-sysfs.c b/drivers/usb/wusbcore/dev-sysfs.c
new file mode 100644 (file)
index 0000000..7897a19
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * WUSB devices
+ * sysfs bindings
+ *
+ * Copyright (C) 2007 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * Get them out of the way...
+ */
+
+#include <linux/jiffies.h>
+#include <linux/ctype.h>
+#include <linux/workqueue.h>
+#include "wusbhc.h"
+
+#undef D_LOCAL
+#define D_LOCAL 4
+#include <linux/uwb/debug.h>
+
+static ssize_t wusb_disconnect_store(struct device *dev,
+                                    struct device_attribute *attr,
+                                    const char *buf, size_t size)
+{
+       struct usb_device *usb_dev;
+       struct wusbhc *wusbhc;
+       unsigned command;
+       u8 port_idx;
+
+       if (sscanf(buf, "%u", &command) != 1)
+               return -EINVAL;
+       if (command == 0)
+               return size;
+       usb_dev = to_usb_device(dev);
+       wusbhc = wusbhc_get_by_usb_dev(usb_dev);
+       if (wusbhc == NULL)
+               return -ENODEV;
+
+       mutex_lock(&wusbhc->mutex);
+       port_idx = wusb_port_no_to_idx(usb_dev->portnum);
+       __wusbhc_dev_disable(wusbhc, port_idx);
+       mutex_unlock(&wusbhc->mutex);
+       wusbhc_put(wusbhc);
+       return size;
+}
+static DEVICE_ATTR(wusb_disconnect, 0200, NULL, wusb_disconnect_store);
+
+static ssize_t wusb_cdid_show(struct device *dev,
+                             struct device_attribute *attr, char *buf)
+{
+       ssize_t result;
+       struct wusb_dev *wusb_dev;
+
+       wusb_dev = wusb_dev_get_by_usb_dev(to_usb_device(dev));
+       if (wusb_dev == NULL)
+               return -ENODEV;
+       result = ckhdid_printf(buf, PAGE_SIZE, &wusb_dev->cdid);
+       strcat(buf, "\n");
+       wusb_dev_put(wusb_dev);
+       return result + 1;
+}
+static DEVICE_ATTR(wusb_cdid, 0444, wusb_cdid_show, NULL);
+
+static ssize_t wusb_ck_store(struct device *dev,
+                            struct device_attribute *attr,
+                            const char *buf, size_t size)
+{
+       int result;
+       struct usb_device *usb_dev;
+       struct wusbhc *wusbhc;
+       struct wusb_ckhdid ck;
+
+       result = sscanf(buf,
+                       "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx\n",
+                       &ck.data[0] , &ck.data[1],
+                       &ck.data[2] , &ck.data[3],
+                       &ck.data[4] , &ck.data[5],
+                       &ck.data[6] , &ck.data[7],
+                       &ck.data[8] , &ck.data[9],
+                       &ck.data[10], &ck.data[11],
+                       &ck.data[12], &ck.data[13],
+                       &ck.data[14], &ck.data[15]);
+       if (result != 16)
+               return -EINVAL;
+
+       usb_dev = to_usb_device(dev);
+       wusbhc = wusbhc_get_by_usb_dev(usb_dev);
+       if (wusbhc == NULL)
+               return -ENODEV;
+       result = wusb_dev_4way_handshake(wusbhc, usb_dev->wusb_dev, &ck);
+       memset(&ck, 0, sizeof(ck));
+       wusbhc_put(wusbhc);
+       return result < 0 ? result : size;
+}
+static DEVICE_ATTR(wusb_ck, 0200, NULL, wusb_ck_store);
+
+static struct attribute *wusb_dev_attrs[] = {
+               &dev_attr_wusb_disconnect.attr,
+               &dev_attr_wusb_cdid.attr,
+               &dev_attr_wusb_ck.attr,
+               NULL,
+};
+
+static struct attribute_group wusb_dev_attr_group = {
+       .name = NULL,   /* we want them in the same directory */
+       .attrs = wusb_dev_attrs,
+};
+
+int wusb_dev_sysfs_add(struct wusbhc *wusbhc, struct usb_device *usb_dev,
+                      struct wusb_dev *wusb_dev)
+{
+       int result = sysfs_create_group(&usb_dev->dev.kobj,
+                                       &wusb_dev_attr_group);
+       struct device *dev = &usb_dev->dev;
+       if (result < 0)
+               dev_err(dev, "Cannot register WUSB-dev attributes: %d\n",
+                       result);
+       return result;
+}
+
+void wusb_dev_sysfs_rm(struct wusb_dev *wusb_dev)
+{
+       struct usb_device *usb_dev = wusb_dev->usb_dev;
+       if (usb_dev)
+               sysfs_remove_group(&usb_dev->dev.kobj, &wusb_dev_attr_group);
+}
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c
new file mode 100644 (file)
index 0000000..f45d777
--- /dev/null
@@ -0,0 +1,1297 @@
+/*
+ * WUSB Wire Adapter: Control/Data Streaming Interface (WUSB[8])
+ * Device Connect handling
+ *
+ * Copyright (C) 2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ * FIXME: this file needs to be broken up, it's grown too big
+ *
+ *
+ * WUSB1.0[7.1, 7.5.1, ]
+ *
+ * WUSB device connection is kind of messy. Some background:
+ *
+ *     When a device wants to connect it scans the UWB radio channels
+ *     looking for a WUSB Channel; a WUSB channel is defined by MMCs
+ *     (Micro Managed Commands or something like that) [see
+ *     Design-overview for more on this] .
+ *
+ * So, device scans the radio, finds MMCs and thus a host and checks
+ * when the next DNTS is. It sends a Device Notification Connect
+ * (DN_Connect); the host picks it up (through nep.c and notif.c, ends
+ * up in wusb_devconnect_ack(), which creates a wusb_dev structure in
+ * wusbhc->port[port_number].wusb_dev), assigns an unauth address
+ * to the device (this means from 0x80 to 0xfe) and sends, in the MMC
+ * a Connect Ack Information Element (ConnAck IE).
+ *
+ * So now the device now has a WUSB address. From now on, we use
+ * that to talk to it in the RPipes.
+ *
+ * ASSUMPTIONS:
+ *
+ *  - We use the the as device address the port number where it is
+ *    connected (port 0 doesn't exist). For unauth, it is 128 + that.
+ *
+ * ROADMAP:
+ *
+ *   This file contains the logic for doing that--entry points:
+ *
+ *   wusb_devconnect_ack()      Ack a device until _acked() called.
+ *                              Called by notif.c:wusb_handle_dn_connect()
+ *                              when a DN_Connect is received.
+ *
+ *   wusbhc_devconnect_auth()   Called by rh.c:wusbhc_rh_port_reset() when
+ *                              doing the device connect sequence.
+ *
+ *     wusb_devconnect_acked()  Ack done, release resources.
+ *
+ *   wusb_handle_dn_alive()     Called by notif.c:wusb_handle_dn()
+ *                              for processing a DN_Alive pong from a device.
+ *
+ *   wusb_handle_dn_disconnect()Called by notif.c:wusb_handle_dn() to
+ *                              process a disconenct request from a
+ *                              device.
+ *
+ *   wusb_dev_reset()           Called by rh.c:wusbhc_rh_port_reset() when
+ *                              resetting a device.
+ *
+ *   __wusb_dev_disable()       Called by rh.c:wusbhc_rh_clear_port_feat() when
+ *                              disabling a port.
+ *
+ *   wusb_devconnect_create()   Called when creating the host by
+ *                              lc.c:wusbhc_create().
+ *
+ *   wusb_devconnect_destroy()  Cleanup called removing the host. Called
+ *                              by lc.c:wusbhc_destroy().
+ *
+ *   Each Wireless USB host maintains a list of DN_Connect requests
+ *   (actually we maintain a list of pending Connect Acks, the
+ *   wusbhc->ca_list).
+ *
+ * LIFE CYCLE OF port->wusb_dev
+ *
+ *   Before the @wusbhc structure put()s the reference it owns for
+ *   port->wusb_dev [and clean the wusb_dev pointer], it needs to
+ *   lock @wusbhc->mutex.
+ */
+
+#include <linux/jiffies.h>
+#include <linux/ctype.h>
+#include <linux/workqueue.h>
+#include "wusbhc.h"
+
+#undef D_LOCAL
+#define D_LOCAL 1
+#include <linux/uwb/debug.h>
+
+static void wusbhc_devconnect_acked_work(struct work_struct *work);
+
+static void wusb_dev_free(struct wusb_dev *wusb_dev)
+{
+       if (wusb_dev) {
+               kfree(wusb_dev->set_gtk_req);
+               usb_free_urb(wusb_dev->set_gtk_urb);
+               kfree(wusb_dev);
+       }
+}
+
+static struct wusb_dev *wusb_dev_alloc(struct wusbhc *wusbhc)
+{
+       struct wusb_dev *wusb_dev;
+       struct urb *urb;
+       struct usb_ctrlrequest *req;
+
+       wusb_dev = kzalloc(sizeof(*wusb_dev), GFP_KERNEL);
+       if (wusb_dev == NULL)
+               goto err;
+
+       wusb_dev->wusbhc = wusbhc;
+
+       INIT_WORK(&wusb_dev->devconnect_acked_work, wusbhc_devconnect_acked_work);
+
+       urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (urb == NULL)
+               goto err;
+
+       req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
+       if (req == NULL)
+               goto err;
+
+       req->bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
+       req->bRequest = USB_REQ_SET_DESCRIPTOR;
+       req->wValue = cpu_to_le16(USB_DT_KEY << 8 | wusbhc->gtk_index);
+       req->wIndex = 0;
+       req->wLength = cpu_to_le16(wusbhc->gtk.descr.bLength);
+
+       wusb_dev->set_gtk_urb = urb;
+       wusb_dev->set_gtk_req = req;
+
+       return wusb_dev;
+err:
+       wusb_dev_free(wusb_dev);
+       return NULL;
+}
+
+
+/*
+ * Using the Connect-Ack list, fill out the @wusbhc Connect-Ack WUSB IE
+ * properly so that it can be added to the MMC.
+ *
+ * We just get the @wusbhc->ca_list and fill out the first four ones or
+ * less (per-spec WUSB1.0[7.5, before T7-38). If the ConnectAck WUSB
+ * IE is not allocated, we alloc it.
+ *
+ * @wusbhc->mutex must be taken
+ */
+static void wusbhc_fill_cack_ie(struct wusbhc *wusbhc)
+{
+       unsigned cnt;
+       struct wusb_dev *dev_itr;
+       struct wuie_connect_ack *cack_ie;
+
+       cack_ie = &wusbhc->cack_ie;
+       cnt = 0;
+       list_for_each_entry(dev_itr, &wusbhc->cack_list, cack_node) {
+               cack_ie->blk[cnt].CDID = dev_itr->cdid;
+               cack_ie->blk[cnt].bDeviceAddress = dev_itr->addr;
+               if (++cnt >= WUIE_ELT_MAX)
+                       break;
+       }
+       cack_ie->hdr.bLength = sizeof(cack_ie->hdr)
+               + cnt * sizeof(cack_ie->blk[0]);
+}
+
+/*
+ * Register a new device that wants to connect
+ *
+ * A new device wants to connect, so we add it to the Connect-Ack
+ * list. We give it an address in the unauthorized range (bit 8 set);
+ * user space will have to drive authorization further on.
+ *
+ * @dev_addr: address to use for the device (which is also the port
+ *            number).
+ *
+ * @wusbhc->mutex must be taken
+ */
+static struct wusb_dev *wusbhc_cack_add(struct wusbhc *wusbhc,
+                                       struct wusb_dn_connect *dnc,
+                                       const char *pr_cdid, u8 port_idx)
+{
+       struct device *dev = wusbhc->dev;
+       struct wusb_dev *wusb_dev;
+       int new_connection = wusb_dn_connect_new_connection(dnc);
+       u8 dev_addr;
+       int result;
+
+       /* Is it registered already? */
+       list_for_each_entry(wusb_dev, &wusbhc->cack_list, cack_node)
+               if (!memcmp(&wusb_dev->cdid, &dnc->CDID,
+                           sizeof(wusb_dev->cdid)))
+                       return wusb_dev;
+       /* We don't have it, create an entry, register it */
+       wusb_dev = wusb_dev_alloc(wusbhc);
+       if (wusb_dev == NULL)
+               return NULL;
+       wusb_dev_init(wusb_dev);
+       wusb_dev->cdid = dnc->CDID;
+       wusb_dev->port_idx = port_idx;
+
+       /*
+        * Devices are always available within the cluster reservation
+        * and since the hardware will take the intersection of the
+        * per-device availability and the cluster reservation, the
+        * per-device availability can simply be set to always
+        * available.
+        */
+       bitmap_fill(wusb_dev->availability.bm, UWB_NUM_MAS);
+
+       /* FIXME: handle reconnects instead of assuming connects are
+          always new. */
+       if (1 && new_connection == 0)
+               new_connection = 1;
+       if (new_connection) {
+               dev_addr = (port_idx + 2) | WUSB_DEV_ADDR_UNAUTH;
+
+               dev_info(dev, "Connecting new WUSB device to address %u, "
+                       "port %u\n", dev_addr, port_idx);
+
+               result = wusb_set_dev_addr(wusbhc, wusb_dev, dev_addr);
+               if (result < 0)
+                       return NULL;
+       }
+       wusb_dev->entry_ts = jiffies;
+       list_add_tail(&wusb_dev->cack_node, &wusbhc->cack_list);
+       wusbhc->cack_count++;
+       wusbhc_fill_cack_ie(wusbhc);
+       return wusb_dev;
+}
+
+/*
+ * Remove a Connect-Ack context entry from the HCs view
+ *
+ * @wusbhc->mutex must be taken
+ */
+static void wusbhc_cack_rm(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
+{
+       struct device *dev = wusbhc->dev;
+       d_fnstart(3, dev, "(wusbhc %p wusb_dev %p)\n", wusbhc, wusb_dev);
+       list_del_init(&wusb_dev->cack_node);
+       wusbhc->cack_count--;
+       wusbhc_fill_cack_ie(wusbhc);
+       d_fnend(3, dev, "(wusbhc %p wusb_dev %p) = void\n", wusbhc, wusb_dev);
+}
+
+/*
+ * @wusbhc->mutex must be taken */
+static
+void wusbhc_devconnect_acked(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
+{
+       struct device *dev = wusbhc->dev;
+       d_fnstart(3, dev, "(wusbhc %p wusb_dev %p)\n", wusbhc, wusb_dev);
+       wusbhc_cack_rm(wusbhc, wusb_dev);
+       if (wusbhc->cack_count)
+               wusbhc_mmcie_set(wusbhc, 0, 0, &wusbhc->cack_ie.hdr);
+       else
+               wusbhc_mmcie_rm(wusbhc, &wusbhc->cack_ie.hdr);
+       d_fnend(3, dev, "(wusbhc %p wusb_dev %p) = void\n", wusbhc, wusb_dev);
+}
+
+static void wusbhc_devconnect_acked_work(struct work_struct *work)
+{
+       struct wusb_dev *wusb_dev = container_of(work, struct wusb_dev,
+                                                devconnect_acked_work);
+       struct wusbhc *wusbhc = wusb_dev->wusbhc;
+
+       mutex_lock(&wusbhc->mutex);
+       wusbhc_devconnect_acked(wusbhc, wusb_dev);
+       mutex_unlock(&wusbhc->mutex);
+}
+
+/*
+ * Ack a device for connection
+ *
+ * FIXME: docs
+ *
+ * @pr_cdid:   Printable CDID...hex Use @dnc->cdid for the real deal.
+ *
+ * So we get the connect ack IE (may have been allocated already),
+ * find an empty connect block, an empty virtual port, create an
+ * address with it (see below), make it an unauth addr [bit 7 set] and
+ * set the MMC.
+ *
+ * Addresses: because WUSB hosts have no downstream hubs, we can do a
+ *            1:1 mapping between 'port number' and device
+ *            address. This simplifies many things, as during this
+ *            initial connect phase the USB stack has no knoledge of
+ *            the device and hasn't assigned an address yet--we know
+ *            USB's choose_address() will use the same euristics we
+ *            use here, so we can assume which address will be assigned.
+ *
+ *            USB stack always assigns address 1 to the root hub, so
+ *            to the port number we add 2 (thus virtual port #0 is
+ *            addr #2).
+ *
+ * @wusbhc shall be referenced
+ */
+static
+void wusbhc_devconnect_ack(struct wusbhc *wusbhc, struct wusb_dn_connect *dnc,
+                          const char *pr_cdid)
+{
+       int result;
+       struct device *dev = wusbhc->dev;
+       struct wusb_dev *wusb_dev;
+       struct wusb_port *port;
+       unsigned idx, devnum;
+
+       d_fnstart(3, dev, "(%p, %p, %s)\n", wusbhc, dnc, pr_cdid);
+       mutex_lock(&wusbhc->mutex);
+
+       /* Check we are not handling it already */
+       for (idx = 0; idx < wusbhc->ports_max; idx++) {
+               port = wusb_port_by_idx(wusbhc, idx);
+               if (port->wusb_dev
+                   && memcmp(&dnc->CDID, &port->wusb_dev->cdid, sizeof(dnc->CDID)) == 0)
+                       goto error_unlock;
+       }
+       /* Look up those fake ports we have for a free one */
+       for (idx = 0; idx < wusbhc->ports_max; idx++) {
+               port = wusb_port_by_idx(wusbhc, idx);
+               if ((port->status & USB_PORT_STAT_POWER)
+                   && !(port->status & USB_PORT_STAT_CONNECTION))
+                       break;
+       }
+       if (idx >= wusbhc->ports_max) {
+               dev_err(dev, "Host controller can't connect more devices "
+                       "(%u already connected); device %s rejected\n",
+                       wusbhc->ports_max, pr_cdid);
+               /* NOTE: we could send a WUIE_Disconnect here, but we haven't
+                *       event acked, so the device will eventually timeout the
+                *       connection, right? */
+               goto error_unlock;
+       }
+
+       devnum = idx + 2;
+
+       /* Make sure we are using no crypto on that "virtual port" */
+       wusbhc->set_ptk(wusbhc, idx, 0, NULL, 0);
+
+       /* Grab a filled in Connect-Ack context, fill out the
+        * Connect-Ack Wireless USB IE, set the MMC */
+       wusb_dev = wusbhc_cack_add(wusbhc, dnc, pr_cdid, idx);
+       if (wusb_dev == NULL)
+               goto error_unlock;
+       result = wusbhc_mmcie_set(wusbhc, 0, 0, &wusbhc->cack_ie.hdr);
+       if (result < 0)
+               goto error_unlock;
+       /* Give the device at least 2ms (WUSB1.0[7.5.1p3]), let's do
+        * three for a good measure */
+       msleep(3);
+       port->wusb_dev = wusb_dev;
+       port->status |= USB_PORT_STAT_CONNECTION;
+       port->change |= USB_PORT_STAT_C_CONNECTION;
+       port->reset_count = 0;
+       /* Now the port status changed to connected; khubd will
+        * pick the change up and try to reset the port to bring it to
+        * the enabled state--so this process returns up to the stack
+        * and it calls back into wusbhc_rh_port_reset() who will call
+        * devconnect_auth().
+        */
+error_unlock:
+       mutex_unlock(&wusbhc->mutex);
+       d_fnend(3, dev, "(%p, %p, %s) = void\n", wusbhc, dnc, pr_cdid);
+       return;
+
+}
+
+/*
+ * Disconnect a Wireless USB device from its fake port
+ *
+ * Marks the port as disconnected so that khubd can pick up the change
+ * and drops our knowledge about the device.
+ *
+ * Assumes there is a device connected
+ *
+ * @port_index: zero based port number
+ *
+ * NOTE: @wusbhc->mutex is locked
+ *
+ * WARNING: From here it is not very safe to access anything hanging off
+ *         wusb_dev
+ */
+static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc,
+                                   struct wusb_port *port)
+{
+       struct device *dev = wusbhc->dev;
+       struct wusb_dev *wusb_dev = port->wusb_dev;
+
+       d_fnstart(3, dev, "(wusbhc %p, port %p)\n", wusbhc, port);
+       port->status &= ~(USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE
+                         | USB_PORT_STAT_SUSPEND | USB_PORT_STAT_RESET
+                         | USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED);
+       port->change |= USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE;
+       if (wusb_dev) {
+               if (!list_empty(&wusb_dev->cack_node))
+                       list_del_init(&wusb_dev->cack_node);
+               /* For the one in cack_add() */
+               wusb_dev_put(wusb_dev);
+       }
+       port->wusb_dev = NULL;
+       /* don't reset the reset_count to zero or wusbhc_rh_port_reset will get
+        * confused! We only reset to zero when we connect a new device.
+        */
+
+       /* After a device disconnects, change the GTK (see [WUSB]
+        * section 6.2.11.2). */
+       wusbhc_gtk_rekey(wusbhc);
+
+       d_fnend(3, dev, "(wusbhc %p, port %p) = void\n", wusbhc, port);
+       /* The Wireless USB part has forgotten about the device already; now
+        * khubd's timer will pick up the disconnection and remove the USB
+        * device from the system
+        */
+}
+
+/*
+ * Authenticate a device into the WUSB Cluster
+ *
+ * Called from the Root Hub code (rh.c:wusbhc_rh_port_reset()) when
+ * asking for a reset on a port that is not enabled (ie: first connect
+ * on the port).
+ *
+ * Performs the 4way handshake to allow the device to comunicate w/ the
+ * WUSB Cluster securely; once done, issue a request to the device for
+ * it to change to address 0.
+ *
+ * This mimics the reset step of Wired USB that once resetting a
+ * device, leaves the port in enabled state and the dev with the
+ * default address (0).
+ *
+ * WUSB1.0[7.1.2]
+ *
+ * @port_idx: port where the change happened--This is the index into
+ *            the wusbhc port array, not the USB port number.
+ */
+int wusbhc_devconnect_auth(struct wusbhc *wusbhc, u8 port_idx)
+{
+       struct device *dev = wusbhc->dev;
+       struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx);
+
+       d_fnstart(3, dev, "(%p, %u)\n", wusbhc, port_idx);
+       port->status &= ~USB_PORT_STAT_RESET;
+       port->status |= USB_PORT_STAT_ENABLE;
+       port->change |= USB_PORT_STAT_C_RESET | USB_PORT_STAT_C_ENABLE;
+       d_fnend(3, dev, "(%p, %u) = 0\n", wusbhc, port_idx);
+       return 0;
+}
+
+/*
+ * Refresh the list of keep alives to emit in the MMC
+ *
+ * Some devices don't respond to keep alives unless they've been
+ * authenticated, so skip unauthenticated devices.
+ *
+ * We only publish the first four devices that have a coming timeout
+ * condition. Then when we are done processing those, we go for the
+ * next ones. We ignore the ones that have timed out already (they'll
+ * be purged).
+ *
+ * This might cause the first devices to timeout the last devices in
+ * the port array...FIXME: come up with a better algorithm?
+ *
+ * Note we can't do much about MMC's ops errors; we hope next refresh
+ * will kind of handle it.
+ *
+ * NOTE: @wusbhc->mutex is locked
+ */
+static void __wusbhc_keep_alive(struct wusbhc *wusbhc)
+{
+       struct device *dev = wusbhc->dev;
+       unsigned cnt;
+       struct wusb_dev *wusb_dev;
+       struct wusb_port *wusb_port;
+       struct wuie_keep_alive *ie = &wusbhc->keep_alive_ie;
+       unsigned keep_alives, old_keep_alives;
+
+       old_keep_alives = ie->hdr.bLength - sizeof(ie->hdr);
+       keep_alives = 0;
+       for (cnt = 0;
+            keep_alives <= WUIE_ELT_MAX && cnt < wusbhc->ports_max;
+            cnt++) {
+               unsigned tt = msecs_to_jiffies(wusbhc->trust_timeout);
+
+               wusb_port = wusb_port_by_idx(wusbhc, cnt);
+               wusb_dev = wusb_port->wusb_dev;
+
+               if (wusb_dev == NULL)
+                       continue;
+               if (wusb_dev->usb_dev == NULL || !wusb_dev->usb_dev->authenticated)
+                       continue;
+
+               if (time_after(jiffies, wusb_dev->entry_ts + tt)) {
+                       dev_err(dev, "KEEPALIVE: device %u timed out\n",
+                               wusb_dev->addr);
+                       __wusbhc_dev_disconnect(wusbhc, wusb_port);
+               } else if (time_after(jiffies, wusb_dev->entry_ts + tt/2)) {
+                       /* Approaching timeout cut out, need to refresh */
+                       ie->bDeviceAddress[keep_alives++] = wusb_dev->addr;
+               }
+       }
+       if (keep_alives & 0x1)  /* pad to even number ([WUSB] section 7.5.9) */
+               ie->bDeviceAddress[keep_alives++] = 0x7f;
+       ie->hdr.bLength = sizeof(ie->hdr) +
+               keep_alives*sizeof(ie->bDeviceAddress[0]);
+       if (keep_alives > 0)
+               wusbhc_mmcie_set(wusbhc, 10, 5, &ie->hdr);
+       else if (old_keep_alives != 0)
+               wusbhc_mmcie_rm(wusbhc, &ie->hdr);
+}
+
+/*
+ * Do a run through all devices checking for timeouts
+ */
+static void wusbhc_keep_alive_run(struct work_struct *ws)
+{
+       struct delayed_work *dw =
+               container_of(ws, struct delayed_work, work);
+       struct wusbhc *wusbhc =
+               container_of(dw, struct wusbhc, keep_alive_timer);
+
+       d_fnstart(5, wusbhc->dev, "(wusbhc %p)\n", wusbhc);
+       if (wusbhc->active) {
+               mutex_lock(&wusbhc->mutex);
+               __wusbhc_keep_alive(wusbhc);
+               mutex_unlock(&wusbhc->mutex);
+               queue_delayed_work(wusbd, &wusbhc->keep_alive_timer,
+                                  (wusbhc->trust_timeout * CONFIG_HZ)/1000/2);
+       }
+       d_fnend(5, wusbhc->dev, "(wusbhc %p) = void\n", wusbhc);
+       return;
+}
+
+/*
+ * Find the wusb_dev from its device address.
+ *
+ * The device can be found directly from the address (see
+ * wusb_cack_add() for where the device address is set to port_idx
+ * +2), except when the address is zero.
+ */
+static struct wusb_dev *wusbhc_find_dev_by_addr(struct wusbhc *wusbhc, u8 addr)
+{
+       int p;
+
+       if (addr == 0xff) /* unconnected */
+               return NULL;
+
+       if (addr > 0) {
+               int port = (addr & ~0x80) - 2;
+               if (port < 0 || port >= wusbhc->ports_max)
+                       return NULL;
+               return wusb_port_by_idx(wusbhc, port)->wusb_dev;
+       }
+
+       /* Look for the device with address 0. */
+       for (p = 0; p < wusbhc->ports_max; p++) {
+               struct wusb_dev *wusb_dev = wusb_port_by_idx(wusbhc, p)->wusb_dev;
+               if (wusb_dev && wusb_dev->addr == addr)
+                       return wusb_dev;
+       }
+       return NULL;
+}
+
+/*
+ * Handle a DN_Alive notification (WUSB1.0[7.6.1])
+ *
+ * This just updates the device activity timestamp and then refreshes
+ * the keep alive IE.
+ *
+ * @wusbhc shall be referenced and unlocked
+ */
+static void wusbhc_handle_dn_alive(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
+{
+       struct device *dev = wusbhc->dev;
+
+       d_printf(2, dev, "DN ALIVE: device 0x%02x pong\n", wusb_dev->addr);
+
+       mutex_lock(&wusbhc->mutex);
+       wusb_dev->entry_ts = jiffies;
+       __wusbhc_keep_alive(wusbhc);
+       mutex_unlock(&wusbhc->mutex);
+}
+
+/*
+ * Handle a DN_Connect notification (WUSB1.0[7.6.1])
+ *
+ * @wusbhc
+ * @pkt_hdr
+ * @size:    Size of the buffer where the notification resides; if the
+ *           notification data suggests there should be more data than
+ *           available, an error will be signaled and the whole buffer
+ *           consumed.
+ *
+ * @wusbhc->mutex shall be held
+ */
+static void wusbhc_handle_dn_connect(struct wusbhc *wusbhc,
+                                    struct wusb_dn_hdr *dn_hdr,
+                                    size_t size)
+{
+       struct device *dev = wusbhc->dev;
+       struct wusb_dn_connect *dnc;
+       char pr_cdid[WUSB_CKHDID_STRSIZE];
+       static const char *beacon_behaviour[] = {
+               "reserved",
+               "self-beacon",
+               "directed-beacon",
+               "no-beacon"
+       };
+
+       d_fnstart(3, dev, "(%p, %p, %zu)\n", wusbhc, dn_hdr, size);
+       if (size < sizeof(*dnc)) {
+               dev_err(dev, "DN CONNECT: short notification (%zu < %zu)\n",
+                       size, sizeof(*dnc));
+               goto out;
+       }
+
+       dnc = container_of(dn_hdr, struct wusb_dn_connect, hdr);
+       ckhdid_printf(pr_cdid, sizeof(pr_cdid), &dnc->CDID);
+       dev_info(dev, "DN CONNECT: device %s @ %x (%s) wants to %s\n",
+                pr_cdid,
+                wusb_dn_connect_prev_dev_addr(dnc),
+                beacon_behaviour[wusb_dn_connect_beacon_behavior(dnc)],
+                wusb_dn_connect_new_connection(dnc) ? "connect" : "reconnect");
+       /* ACK the connect */
+       wusbhc_devconnect_ack(wusbhc, dnc, pr_cdid);
+out:
+       d_fnend(3, dev, "(%p, %p, %zu) = void\n",
+               wusbhc, dn_hdr, size);
+       return;
+}
+
+/*
+ * Handle a DN_Disconnect notification (WUSB1.0[7.6.1])
+ *
+ * Device is going down -- do the disconnect.
+ *
+ * @wusbhc shall be referenced and unlocked
+ */
+static void wusbhc_handle_dn_disconnect(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
+{
+       struct device *dev = wusbhc->dev;
+
+       dev_info(dev, "DN DISCONNECT: device 0x%02x going down\n", wusb_dev->addr);
+
+       mutex_lock(&wusbhc->mutex);
+       __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, wusb_dev->port_idx));
+       mutex_unlock(&wusbhc->mutex);
+}
+
+/*
+ * Reset a WUSB device on a HWA
+ *
+ * @wusbhc
+ * @port_idx   Index of the port where the device is
+ *
+ * In Wireless USB, a reset is more or less equivalent to a full
+ * disconnect; so we just do a full disconnect and send the device a
+ * Device Reset IE (WUSB1.0[7.5.11]) giving it a few millisecs (6 MMCs).
+ *
+ * @wusbhc should be refcounted and unlocked
+ */
+int wusbhc_dev_reset(struct wusbhc *wusbhc, u8 port_idx)
+{
+       int result;
+       struct device *dev = wusbhc->dev;
+       struct wusb_dev *wusb_dev;
+       struct wuie_reset *ie;
+
+       d_fnstart(3, dev, "(%p, %u)\n", wusbhc, port_idx);
+       mutex_lock(&wusbhc->mutex);
+       result = 0;
+       wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev;
+       if (wusb_dev == NULL) {
+               /* reset no device? ignore */
+               dev_dbg(dev, "RESET: no device at port %u, ignoring\n",
+                       port_idx);
+               goto error_unlock;
+       }
+       result = -ENOMEM;
+       ie = kzalloc(sizeof(*ie), GFP_KERNEL);
+       if (ie == NULL)
+               goto error_unlock;
+       ie->hdr.bLength = sizeof(ie->hdr) + sizeof(ie->CDID);
+       ie->hdr.bIEIdentifier = WUIE_ID_RESET_DEVICE;
+       ie->CDID = wusb_dev->cdid;
+       result = wusbhc_mmcie_set(wusbhc, 0xff, 6, &ie->hdr);
+       if (result < 0) {
+               dev_err(dev, "RESET: cant's set MMC: %d\n", result);
+               goto error_kfree;
+       }
+       __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx));
+
+       /* 120ms, hopefully 6 MMCs (FIXME) */
+       msleep(120);
+       wusbhc_mmcie_rm(wusbhc, &ie->hdr);
+error_kfree:
+       kfree(ie);
+error_unlock:
+       mutex_unlock(&wusbhc->mutex);
+       d_fnend(3, dev, "(%p, %u) = %d\n", wusbhc, port_idx, result);
+       return result;
+}
+
+/*
+ * Handle a Device Notification coming a host
+ *
+ * The Device Notification comes from a host (HWA, DWA or WHCI)
+ * wrapped in a set of headers. Somebody else has peeled off those
+ * headers for us and we just get one Device Notifications.
+ *
+ * Invalid DNs (e.g., too short) are discarded.
+ *
+ * @wusbhc shall be referenced
+ *
+ * FIXMES:
+ *  - implement priorities as in WUSB1.0[Table 7-55]?
+ */
+void wusbhc_handle_dn(struct wusbhc *wusbhc, u8 srcaddr,
+                     struct wusb_dn_hdr *dn_hdr, size_t size)
+{
+       struct device *dev = wusbhc->dev;
+       struct wusb_dev *wusb_dev;
+
+       d_fnstart(3, dev, "(%p, %p)\n", wusbhc, dn_hdr);
+
+       if (size < sizeof(struct wusb_dn_hdr)) {
+               dev_err(dev, "DN data shorter than DN header (%d < %d)\n",
+                       (int)size, (int)sizeof(struct wusb_dn_hdr));
+               goto out;
+       }
+
+       wusb_dev = wusbhc_find_dev_by_addr(wusbhc, srcaddr);
+       if (wusb_dev == NULL && dn_hdr->bType != WUSB_DN_CONNECT) {
+               dev_dbg(dev, "ignoring DN %d from unconnected device %02x\n",
+                       dn_hdr->bType, srcaddr);
+               goto out;
+       }
+
+       switch (dn_hdr->bType) {
+       case WUSB_DN_CONNECT:
+               wusbhc_handle_dn_connect(wusbhc, dn_hdr, size);
+               break;
+       case WUSB_DN_ALIVE:
+               wusbhc_handle_dn_alive(wusbhc, wusb_dev);
+               break;
+       case WUSB_DN_DISCONNECT:
+               wusbhc_handle_dn_disconnect(wusbhc, wusb_dev);
+               break;
+       case WUSB_DN_MASAVAILCHANGED:
+       case WUSB_DN_RWAKE:
+       case WUSB_DN_SLEEP:
+               /* FIXME: handle these DNs. */
+               break;
+       case WUSB_DN_EPRDY:
+               /* The hardware handles these. */
+               break;
+       default:
+               dev_warn(dev, "unknown DN %u (%d octets) from %u\n",
+                        dn_hdr->bType, (int)size, srcaddr);
+       }
+out:
+       d_fnend(3, dev, "(%p, %p) = void\n", wusbhc, dn_hdr);
+       return;
+}
+EXPORT_SYMBOL_GPL(wusbhc_handle_dn);
+
+/*
+ * Disconnect a WUSB device from a the cluster
+ *
+ * @wusbhc
+ * @port     Fake port where the device is (wusbhc index, not USB port number).
+ *
+ * In Wireless USB, a disconnect is basically telling the device he is
+ * being disconnected and forgetting about him.
+ *
+ * We send the device a Device Disconnect IE (WUSB1.0[7.5.11]) for 100
+ * ms and then keep going.
+ *
+ * We don't do much in case of error; we always pretend we disabled
+ * the port and disconnected the device. If physically the request
+ * didn't get there (many things can fail in the way there), the stack
+ * will reject the device's communication attempts.
+ *
+ * @wusbhc should be refcounted and locked
+ */
+void __wusbhc_dev_disable(struct wusbhc *wusbhc, u8 port_idx)
+{
+       int result;
+       struct device *dev = wusbhc->dev;
+       struct wusb_dev *wusb_dev;
+       struct wuie_disconnect *ie;
+
+       d_fnstart(3, dev, "(%p, %u)\n", wusbhc, port_idx);
+       result = 0;
+       wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev;
+       if (wusb_dev == NULL) {
+               /* reset no device? ignore */
+               dev_dbg(dev, "DISCONNECT: no device at port %u, ignoring\n",
+                       port_idx);
+               goto error;
+       }
+       __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx));
+
+       result = -ENOMEM;
+       ie = kzalloc(sizeof(*ie), GFP_KERNEL);
+       if (ie == NULL)
+               goto error;
+       ie->hdr.bLength = sizeof(*ie);
+       ie->hdr.bIEIdentifier = WUIE_ID_DEVICE_DISCONNECT;
+       ie->bDeviceAddress = wusb_dev->addr;
+       result = wusbhc_mmcie_set(wusbhc, 0, 0, &ie->hdr);
+       if (result < 0) {
+               dev_err(dev, "DISCONNECT: can't set MMC: %d\n", result);
+               goto error_kfree;
+       }
+
+       /* 120ms, hopefully 6 MMCs */
+       msleep(100);
+       wusbhc_mmcie_rm(wusbhc, &ie->hdr);
+error_kfree:
+       kfree(ie);
+error:
+       d_fnend(3, dev, "(%p, %u) = %d\n", wusbhc, port_idx, result);
+       return;
+}
+
+static void wusb_cap_descr_printf(const unsigned level, struct device *dev,
+                                 const struct usb_wireless_cap_descriptor *wcd)
+{
+       d_printf(level, dev,
+                "WUSB Capability Descriptor\n"
+                "  bDevCapabilityType          0x%02x\n"
+                "  bmAttributes                0x%02x\n"
+                "  wPhyRates                   0x%04x\n"
+                "  bmTFITXPowerInfo            0x%02x\n"
+                "  bmFFITXPowerInfo            0x%02x\n"
+                "  bmBandGroup                 0x%04x\n"
+                "  bReserved                   0x%02x\n",
+                wcd->bDevCapabilityType,
+                wcd->bmAttributes,
+                le16_to_cpu(wcd->wPHYRates),
+                wcd->bmTFITXPowerInfo,
+                wcd->bmFFITXPowerInfo,
+                wcd->bmBandGroup,
+                wcd->bReserved);
+}
+
+/*
+ * Walk over the BOS descriptor, verify and grok it
+ *
+ * @usb_dev: referenced
+ * @wusb_dev: referenced and unlocked
+ *
+ * The BOS descriptor is defined at WUSB1.0[7.4.1], and it defines a
+ * "flexible" way to wrap all kinds of descriptors inside an standard
+ * descriptor (wonder why they didn't use normal descriptors,
+ * btw). Not like they lack code.
+ *
+ * At the end we go to look for the WUSB Device Capabilities
+ * (WUSB1.0[7.4.1.1]) that is wrapped in a device capability descriptor
+ * that is part of the BOS descriptor set. That tells us what does the
+ * device support (dual role, beacon type, UWB PHY rates).
+ */
+static int wusb_dev_bos_grok(struct usb_device *usb_dev,
+                            struct wusb_dev *wusb_dev,
+                            struct usb_bos_descriptor *bos, size_t desc_size)
+{
+       ssize_t result;
+       struct device *dev = &usb_dev->dev;
+       void *itr, *top;
+
+       /* Walk over BOS capabilities, verify them */
+       itr = (void *)bos + sizeof(*bos);
+       top = itr + desc_size - sizeof(*bos);
+       while (itr < top) {
+               struct usb_dev_cap_header *cap_hdr = itr;
+               size_t cap_size;
+               u8 cap_type;
+               if (top - itr < sizeof(*cap_hdr)) {
+                       dev_err(dev, "Device BUG? premature end of BOS header "
+                               "data [offset 0x%02x]: only %zu bytes left\n",
+                               (int)(itr - (void *)bos), top - itr);
+                       result = -ENOSPC;
+                       goto error_bad_cap;
+               }
+               cap_size = cap_hdr->bLength;
+               cap_type = cap_hdr->bDevCapabilityType;
+               d_printf(4, dev, "BOS Capability: 0x%02x (%zu bytes)\n",
+                        cap_type, cap_size);
+               if (cap_size == 0)
+                       break;
+               if (cap_size > top - itr) {
+                       dev_err(dev, "Device BUG? premature end of BOS data "
+                               "[offset 0x%02x cap %02x %zu bytes]: "
+                               "only %zu bytes left\n",
+                               (int)(itr - (void *)bos),
+                               cap_type, cap_size, top - itr);
+                       result = -EBADF;
+                       goto error_bad_cap;
+               }
+               d_dump(3, dev, itr, cap_size);
+               switch (cap_type) {
+               case USB_CAP_TYPE_WIRELESS_USB:
+                       if (cap_size != sizeof(*wusb_dev->wusb_cap_descr))
+                               dev_err(dev, "Device BUG? WUSB Capability "
+                                       "descriptor is %zu bytes vs %zu "
+                                       "needed\n", cap_size,
+                                       sizeof(*wusb_dev->wusb_cap_descr));
+                       else {
+                               wusb_dev->wusb_cap_descr = itr;
+                               wusb_cap_descr_printf(3, dev, itr);
+                       }
+                       break;
+               default:
+                       dev_err(dev, "BUG? Unknown BOS capability 0x%02x "
+                               "(%zu bytes) at offset 0x%02x\n", cap_type,
+                               cap_size, (int)(itr - (void *)bos));
+               }
+               itr += cap_size;
+       }
+       result = 0;
+error_bad_cap:
+       return result;
+}
+
+/*
+ * Add information from the BOS descriptors to the device
+ *
+ * @usb_dev: referenced
+ * @wusb_dev: referenced and unlocked
+ *
+ * So what we do is we alloc a space for the BOS descriptor of 64
+ * bytes; read the first four bytes which include the wTotalLength
+ * field (WUSB1.0[T7-26]) and if it fits in those 64 bytes, read the
+ * whole thing. If not we realloc to that size.
+ *
+ * Then we call the groking function, that will fill up
+ * wusb_dev->wusb_cap_descr, which is what we'll need later on.
+ */
+static int wusb_dev_bos_add(struct usb_device *usb_dev,
+                           struct wusb_dev *wusb_dev)
+{
+       ssize_t result;
+       struct device *dev = &usb_dev->dev;
+       struct usb_bos_descriptor *bos;
+       size_t alloc_size = 32, desc_size = 4;
+
+       bos = kmalloc(alloc_size, GFP_KERNEL);
+       if (bos == NULL)
+               return -ENOMEM;
+       result = usb_get_descriptor(usb_dev, USB_DT_BOS, 0, bos, desc_size);
+       if (result < 4) {
+               dev_err(dev, "Can't get BOS descriptor or too short: %zd\n",
+                       result);
+               goto error_get_descriptor;
+       }
+       desc_size = le16_to_cpu(bos->wTotalLength);
+       if (desc_size >= alloc_size) {
+               kfree(bos);
+               alloc_size = desc_size;
+               bos = kmalloc(alloc_size, GFP_KERNEL);
+               if (bos == NULL)
+                       return -ENOMEM;
+       }
+       result = usb_get_descriptor(usb_dev, USB_DT_BOS, 0, bos, desc_size);
+       if (result < 0 || result != desc_size) {
+               dev_err(dev, "Can't get  BOS descriptor or too short (need "
+                       "%zu bytes): %zd\n", desc_size, result);
+               goto error_get_descriptor;
+       }
+       if (result < sizeof(*bos)
+           || le16_to_cpu(bos->wTotalLength) != desc_size) {
+               dev_err(dev, "Can't get  BOS descriptor or too short (need "
+                       "%zu bytes): %zd\n", desc_size, result);
+               goto error_get_descriptor;
+       }
+       d_printf(2, dev, "Got BOS descriptor %zd bytes, %u capabilities\n",
+                result, bos->bNumDeviceCaps);
+       d_dump(2, dev, bos, result);
+       result = wusb_dev_bos_grok(usb_dev, wusb_dev, bos, result);
+       if (result < 0)
+               goto error_bad_bos;
+       wusb_dev->bos = bos;
+       return 0;
+
+error_bad_bos:
+error_get_descriptor:
+       kfree(bos);
+       wusb_dev->wusb_cap_descr = NULL;
+       return result;
+}
+
+static void wusb_dev_bos_rm(struct wusb_dev *wusb_dev)
+{
+       kfree(wusb_dev->bos);
+       wusb_dev->wusb_cap_descr = NULL;
+};
+
+static struct usb_wireless_cap_descriptor wusb_cap_descr_default = {
+       .bLength = sizeof(wusb_cap_descr_default),
+       .bDescriptorType = USB_DT_DEVICE_CAPABILITY,
+       .bDevCapabilityType = USB_CAP_TYPE_WIRELESS_USB,
+
+       .bmAttributes = USB_WIRELESS_BEACON_NONE,
+       .wPHYRates = cpu_to_le16(USB_WIRELESS_PHY_53),
+       .bmTFITXPowerInfo = 0,
+       .bmFFITXPowerInfo = 0,
+       .bmBandGroup = cpu_to_le16(0x0001),     /* WUSB1.0[7.4.1] bottom */
+       .bReserved = 0
+};
+
+/*
+ * USB stack's device addition Notifier Callback
+ *
+ * Called from drivers/usb/core/hub.c when a new device is added; we
+ * use this hook to perform certain WUSB specific setup work on the
+ * new device. As well, it is the first time we can connect the
+ * wusb_dev and the usb_dev. So we note it down in wusb_dev and take a
+ * reference that we'll drop.
+ *
+ * First we need to determine if the device is a WUSB device (else we
+ * ignore it). For that we use the speed setting (USB_SPEED_VARIABLE)
+ * [FIXME: maybe we'd need something more definitive]. If so, we track
+ * it's usb_busd and from there, the WUSB HC.
+ *
+ * Because all WUSB HCs are contained in a 'struct wusbhc', voila, we
+ * get the wusbhc for the device.
+ *
+ * We have a reference on @usb_dev (as we are called at the end of its
+ * enumeration).
+ *
+ * NOTE: @usb_dev locked
+ */
+static void wusb_dev_add_ncb(struct usb_device *usb_dev)
+{
+       int result = 0;
+       struct wusb_dev *wusb_dev;
+       struct wusbhc *wusbhc;
+       struct device *dev = &usb_dev->dev;
+       u8 port_idx;
+
+       if (usb_dev->wusb == 0 || usb_dev->devnum == 1)
+               return;         /* skip non wusb and wusb RHs */
+
+       d_fnstart(3, dev, "(usb_dev %p)\n", usb_dev);
+
+       wusbhc = wusbhc_get_by_usb_dev(usb_dev);
+       if (wusbhc == NULL)
+               goto error_nodev;
+       mutex_lock(&wusbhc->mutex);
+       wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, usb_dev);
+       port_idx = wusb_port_no_to_idx(usb_dev->portnum);
+       mutex_unlock(&wusbhc->mutex);
+       if (wusb_dev == NULL)
+               goto error_nodev;
+       wusb_dev->usb_dev = usb_get_dev(usb_dev);
+       usb_dev->wusb_dev = wusb_dev_get(wusb_dev);
+       result = wusb_dev_sec_add(wusbhc, usb_dev, wusb_dev);
+       if (result < 0) {
+               dev_err(dev, "Cannot enable security: %d\n", result);
+               goto error_sec_add;
+       }
+       /* Now query the device for it's BOS and attach it to wusb_dev */
+       result = wusb_dev_bos_add(usb_dev, wusb_dev);
+       if (result < 0) {
+               dev_err(dev, "Cannot get BOS descriptors: %d\n", result);
+               goto error_bos_add;
+       }
+       result = wusb_dev_sysfs_add(wusbhc, usb_dev, wusb_dev);
+       if (result < 0)
+               goto error_add_sysfs;
+out:
+       wusb_dev_put(wusb_dev);
+       wusbhc_put(wusbhc);
+error_nodev:
+       d_fnend(3, dev, "(usb_dev %p) = void\n", usb_dev);
+       return;
+
+       wusb_dev_sysfs_rm(wusb_dev);
+error_add_sysfs:
+       wusb_dev_bos_rm(wusb_dev);
+error_bos_add:
+       wusb_dev_sec_rm(wusb_dev);
+error_sec_add:
+       mutex_lock(&wusbhc->mutex);
+       __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx));
+       mutex_unlock(&wusbhc->mutex);
+       goto out;
+}
+
+/*
+ * Undo all the steps done at connection by the notifier callback
+ *
+ * NOTE: @usb_dev locked
+ */
+static void wusb_dev_rm_ncb(struct usb_device *usb_dev)
+{
+       struct wusb_dev *wusb_dev = usb_dev->wusb_dev;
+
+       if (usb_dev->wusb == 0 || usb_dev->devnum == 1)
+               return;         /* skip non wusb and wusb RHs */
+
+       wusb_dev_sysfs_rm(wusb_dev);
+       wusb_dev_bos_rm(wusb_dev);
+       wusb_dev_sec_rm(wusb_dev);
+       wusb_dev->usb_dev = NULL;
+       usb_dev->wusb_dev = NULL;
+       wusb_dev_put(wusb_dev);
+       usb_put_dev(usb_dev);
+}
+
+/*
+ * Handle notifications from the USB stack (notifier call back)
+ *
+ * This is called when the USB stack does a
+ * usb_{bus,device}_{add,remove}() so we can do WUSB specific
+ * handling. It is called with [for the case of
+ * USB_DEVICE_{ADD,REMOVE} with the usb_dev locked.
+ */
+int wusb_usb_ncb(struct notifier_block *nb, unsigned long val,
+                void *priv)
+{
+       int result = NOTIFY_OK;
+
+       switch (val) {
+       case USB_DEVICE_ADD:
+               wusb_dev_add_ncb(priv);
+               break;
+       case USB_DEVICE_REMOVE:
+               wusb_dev_rm_ncb(priv);
+               break;
+       case USB_BUS_ADD:
+               /* ignore (for now) */
+       case USB_BUS_REMOVE:
+               break;
+       default:
+               WARN_ON(1);
+               result = NOTIFY_BAD;
+       };
+       return result;
+}
+
+/*
+ * Return a referenced wusb_dev given a @wusbhc and @usb_dev
+ */
+struct wusb_dev *__wusb_dev_get_by_usb_dev(struct wusbhc *wusbhc,
+                                          struct usb_device *usb_dev)
+{
+       struct wusb_dev *wusb_dev;
+       u8 port_idx;
+
+       port_idx = wusb_port_no_to_idx(usb_dev->portnum);
+       BUG_ON(port_idx > wusbhc->ports_max);
+       wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev;
+       if (wusb_dev != NULL)           /* ops, device is gone */
+               wusb_dev_get(wusb_dev);
+       return wusb_dev;
+}
+EXPORT_SYMBOL_GPL(__wusb_dev_get_by_usb_dev);
+
+void wusb_dev_destroy(struct kref *_wusb_dev)
+{
+       struct wusb_dev *wusb_dev
+               = container_of(_wusb_dev, struct wusb_dev, refcnt);
+       list_del_init(&wusb_dev->cack_node);
+       wusb_dev_free(wusb_dev);
+       d_fnend(1, NULL, "%s (wusb_dev %p) = void\n", __func__, wusb_dev);
+}
+EXPORT_SYMBOL_GPL(wusb_dev_destroy);
+
+/*
+ * Create all the device connect handling infrastructure
+ *
+ * This is basically the device info array, Connect Acknowledgement
+ * (cack) lists, keep-alive timers (and delayed work thread).
+ */
+int wusbhc_devconnect_create(struct wusbhc *wusbhc)
+{
+       d_fnstart(3, wusbhc->dev, "(wusbhc %p)\n", wusbhc);
+
+       wusbhc->keep_alive_ie.hdr.bIEIdentifier = WUIE_ID_KEEP_ALIVE;
+       wusbhc->keep_alive_ie.hdr.bLength = sizeof(wusbhc->keep_alive_ie.hdr);
+       INIT_DELAYED_WORK(&wusbhc->keep_alive_timer, wusbhc_keep_alive_run);
+
+       wusbhc->cack_ie.hdr.bIEIdentifier = WUIE_ID_CONNECTACK;
+       wusbhc->cack_ie.hdr.bLength = sizeof(wusbhc->cack_ie.hdr);
+       INIT_LIST_HEAD(&wusbhc->cack_list);
+
+       d_fnend(3, wusbhc->dev, "(wusbhc %p) = void\n", wusbhc);
+       return 0;
+}
+
+/*
+ * Release all resources taken by the devconnect stuff
+ */
+void wusbhc_devconnect_destroy(struct wusbhc *wusbhc)
+{
+       d_fnstart(3, wusbhc->dev, "(wusbhc %p)\n", wusbhc);
+       d_fnend(3, wusbhc->dev, "(wusbhc %p) = void\n", wusbhc);
+}
+
+/*
+ * wusbhc_devconnect_start - start accepting device connections
+ * @wusbhc: the WUSB HC
+ *
+ * Sets the Host Info IE to accept all new connections.
+ *
+ * FIXME: This also enables the keep alives but this is not necessary
+ * until there are connected and authenticated devices.
+ */
+int wusbhc_devconnect_start(struct wusbhc *wusbhc,
+                           const struct wusb_ckhdid *chid)
+{
+       struct device *dev = wusbhc->dev;
+       struct wuie_host_info *hi;
+       int result;
+
+       hi = kzalloc(sizeof(*hi), GFP_KERNEL);
+       if (hi == NULL)
+               return -ENOMEM;
+
+       hi->hdr.bLength       = sizeof(*hi);
+       hi->hdr.bIEIdentifier = WUIE_ID_HOST_INFO;
+       hi->attributes        = cpu_to_le16((wusbhc->rsv->stream << 3) | WUIE_HI_CAP_ALL);
+       hi->CHID              = *chid;
+       result = wusbhc_mmcie_set(wusbhc, 0, 0, &hi->hdr);
+       if (result < 0) {
+               dev_err(dev, "Cannot add Host Info MMCIE: %d\n", result);
+               goto error_mmcie_set;
+       }
+       wusbhc->wuie_host_info = hi;
+
+       queue_delayed_work(wusbd, &wusbhc->keep_alive_timer,
+                          (wusbhc->trust_timeout*CONFIG_HZ)/1000/2);
+
+       return 0;
+
+error_mmcie_set:
+       kfree(hi);
+       return result;
+}
+
+/*
+ * wusbhc_devconnect_stop - stop managing connected devices
+ * @wusbhc: the WUSB HC
+ *
+ * Removes the Host Info IE and stops the keep alives.
+ *
+ * FIXME: should this disconnect all devices?
+ */
+void wusbhc_devconnect_stop(struct wusbhc *wusbhc)
+{
+       cancel_delayed_work_sync(&wusbhc->keep_alive_timer);
+       WARN_ON(!list_empty(&wusbhc->cack_list));
+
+       wusbhc_mmcie_rm(wusbhc, &wusbhc->wuie_host_info->hdr);
+       kfree(wusbhc->wuie_host_info);
+       wusbhc->wuie_host_info = NULL;
+}
+
+/*
+ * wusb_set_dev_addr - set the WUSB device address used by the host
+ * @wusbhc: the WUSB HC the device is connect to
+ * @wusb_dev: the WUSB device
+ * @addr: new device address
+ */
+int wusb_set_dev_addr(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev, u8 addr)
+{
+       int result;
+
+       wusb_dev->addr = addr;
+       result = wusbhc->dev_info_set(wusbhc, wusb_dev);
+       if (result < 0)
+               dev_err(wusbhc->dev, "device %d: failed to set device "
+                       "address\n", wusb_dev->port_idx);
+       else
+               dev_info(wusbhc->dev, "device %d: %s addr %u\n",
+                        wusb_dev->port_idx,
+                        (addr & WUSB_DEV_ADDR_UNAUTH) ? "unauth" : "auth",
+                        wusb_dev->addr);
+
+       return result;
+}
diff --git a/drivers/usb/wusbcore/mmc.c b/drivers/usb/wusbcore/mmc.c
new file mode 100644 (file)
index 0000000..cfa77a0
--- /dev/null
@@ -0,0 +1,321 @@
+/*
+ * WUSB Wire Adapter: Control/Data Streaming Interface (WUSB[8])
+ * MMC (Microscheduled Management Command) handling
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * WUIEs and MMC IEs...well, they are almost the same at the end. MMC
+ * IEs are Wireless USB IEs that go into the MMC period...[what is
+ * that? look in Design-overview.txt].
+ *
+ *
+ * This is a simple subsystem to keep track of which IEs are being
+ * sent by the host in the MMC period.
+ *
+ * For each WUIE we ask to send, we keep it in an array, so we can
+ * request its removal later, or replace the content. They are tracked
+ * by pointer, so be sure to use the same pointer if you want to
+ * remove it or update the contents.
+ *
+ * FIXME:
+ *  - add timers that autoremove intervalled IEs?
+ */
+#include <linux/usb/wusb.h>
+#include "wusbhc.h"
+
+/* Initialize the MMCIEs handling mechanism */
+int wusbhc_mmcie_create(struct wusbhc *wusbhc)
+{
+       u8 mmcies = wusbhc->mmcies_max;
+       wusbhc->mmcie = kcalloc(mmcies, sizeof(wusbhc->mmcie[0]), GFP_KERNEL);
+       if (wusbhc->mmcie == NULL)
+               return -ENOMEM;
+       mutex_init(&wusbhc->mmcie_mutex);
+       return 0;
+}
+
+/* Release resources used by the MMCIEs handling mechanism */
+void wusbhc_mmcie_destroy(struct wusbhc *wusbhc)
+{
+       kfree(wusbhc->mmcie);
+}
+
+/*
+ * Add or replace an MMC Wireless USB IE.
+ *
+ * @interval:    See WUSB1.0[8.5.3.1]
+ * @repeat_cnt:  See WUSB1.0[8.5.3.1]
+ * @handle:      See WUSB1.0[8.5.3.1]
+ * @wuie:        Pointer to the header of the WUSB IE data to add.
+ *               MUST BE allocated in a kmalloc buffer (no stack or
+ *               vmalloc).
+ *               THE CALLER ALWAYS OWNS THE POINTER (we don't free it
+ *               on remove, we just forget about it).
+ * @returns:     0 if ok, < 0 errno code on error.
+ *
+ * Goes over the *whole* @wusbhc->mmcie array looking for (a) the
+ * first free spot and (b) if @wuie is already in the array (aka:
+ * transmitted in the MMCs) the spot were it is.
+ *
+ * If present, we "overwrite it" (update).
+ *
+ *
+ * NOTE: Need special ordering rules -- see below WUSB1.0 Table 7-38.
+ *       The host uses the handle as the 'sort' index. We
+ *       allocate the last one always for the WUIE_ID_HOST_INFO, and
+ *       the rest, first come first serve in inverse order.
+ *
+ *       Host software must make sure that it adds the other IEs in
+ *       the right order... the host hardware is responsible for
+ *       placing the WCTA IEs in the right place with the other IEs
+ *       set by host software.
+ *
+ * NOTE: we can access wusbhc->wa_descr without locking because it is
+ *       read only.
+ */
+int wusbhc_mmcie_set(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt,
+                    struct wuie_hdr *wuie)
+{
+       int result = -ENOBUFS;
+       unsigned handle, itr;
+
+       /* Search a handle, taking into account the ordering */
+       mutex_lock(&wusbhc->mmcie_mutex);
+       switch (wuie->bIEIdentifier) {
+       case WUIE_ID_HOST_INFO:
+               /* Always last */
+               handle = wusbhc->mmcies_max - 1;
+               break;
+       case WUIE_ID_ISOCH_DISCARD:
+               dev_err(wusbhc->dev, "Special ordering case for WUIE ID 0x%x "
+                       "unimplemented\n", wuie->bIEIdentifier);
+               result = -ENOSYS;
+               goto error_unlock;
+       default:
+               /* search for it or find the last empty slot */
+               handle = ~0;
+               for (itr = 0; itr < wusbhc->mmcies_max - 1; itr++) {
+                       if (wusbhc->mmcie[itr] == wuie) {
+                               handle = itr;
+                               break;
+                       }
+                       if (wusbhc->mmcie[itr] == NULL)
+                               handle = itr;
+               }
+               if (handle == ~0)
+                       goto error_unlock;
+       }
+       result = (wusbhc->mmcie_add)(wusbhc, interval, repeat_cnt, handle,
+                                    wuie);
+       if (result >= 0)
+               wusbhc->mmcie[handle] = wuie;
+error_unlock:
+       mutex_unlock(&wusbhc->mmcie_mutex);
+       return result;
+}
+EXPORT_SYMBOL_GPL(wusbhc_mmcie_set);
+
+/*
+ * Remove an MMC IE previously added with wusbhc_mmcie_set()
+ *
+ * @wuie       Pointer used to add the WUIE
+ */
+void wusbhc_mmcie_rm(struct wusbhc *wusbhc, struct wuie_hdr *wuie)
+{
+       int result;
+       unsigned handle, itr;
+
+       mutex_lock(&wusbhc->mmcie_mutex);
+       for (itr = 0; itr < wusbhc->mmcies_max; itr++) {
+               if (wusbhc->mmcie[itr] == wuie) {
+                       handle = itr;
+                       goto found;
+               }
+       }
+       mutex_unlock(&wusbhc->mmcie_mutex);
+       return;
+
+found:
+       result = (wusbhc->mmcie_rm)(wusbhc, handle);
+       if (result == 0)
+               wusbhc->mmcie[itr] = NULL;
+       mutex_unlock(&wusbhc->mmcie_mutex);
+}
+EXPORT_SYMBOL_GPL(wusbhc_mmcie_rm);
+
+/*
+ * wusbhc_start - start transmitting MMCs and accepting connections
+ * @wusbhc: the HC to start
+ * @chid: the CHID to use for this host
+ *
+ * Establishes a cluster reservation, enables device connections, and
+ * starts MMCs with appropriate DNTS parameters.
+ */
+int wusbhc_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid)
+{
+       int result;
+       struct device *dev = wusbhc->dev;
+
+       WARN_ON(wusbhc->wuie_host_info != NULL);
+
+       result = wusbhc_rsv_establish(wusbhc);
+       if (result < 0) {
+               dev_err(dev, "cannot establish cluster reservation: %d\n",
+                       result);
+               goto error_rsv_establish;
+       }
+
+       result = wusbhc_devconnect_start(wusbhc, chid);
+       if (result < 0) {
+               dev_err(dev, "error enabling device connections: %d\n", result);
+               goto error_devconnect_start;
+       }
+
+       result = wusbhc_sec_start(wusbhc);
+       if (result < 0) {
+               dev_err(dev, "error starting security in the HC: %d\n", result);
+               goto error_sec_start;
+       }
+       /* FIXME: the choice of the DNTS parameters is somewhat
+        * arbitrary */
+       result = wusbhc->set_num_dnts(wusbhc, 0, 15);
+       if (result < 0) {
+               dev_err(dev, "Cannot set DNTS parameters: %d\n", result);
+               goto error_set_num_dnts;
+       }
+       result = wusbhc->start(wusbhc);
+       if (result < 0) {
+               dev_err(dev, "error starting wusbch: %d\n", result);
+               goto error_wusbhc_start;
+       }
+       wusbhc->active = 1;
+       return 0;
+
+error_wusbhc_start:
+       wusbhc_sec_stop(wusbhc);
+error_set_num_dnts:
+error_sec_start:
+       wusbhc_devconnect_stop(wusbhc);
+error_devconnect_start:
+       wusbhc_rsv_terminate(wusbhc);
+error_rsv_establish:
+       return result;
+}
+
+/*
+ * Disconnect all from the WUSB Channel
+ *
+ * Send a Host Disconnect IE in the MMC, wait, don't send it any more
+ */
+static int __wusbhc_host_disconnect_ie(struct wusbhc *wusbhc)
+{
+       int result = -ENOMEM;
+       struct wuie_host_disconnect *host_disconnect_ie;
+       might_sleep();
+       host_disconnect_ie = kmalloc(sizeof(*host_disconnect_ie), GFP_KERNEL);
+       if (host_disconnect_ie == NULL)
+               goto error_alloc;
+       host_disconnect_ie->hdr.bLength       = sizeof(*host_disconnect_ie);
+       host_disconnect_ie->hdr.bIEIdentifier = WUIE_ID_HOST_DISCONNECT;
+       result = wusbhc_mmcie_set(wusbhc, 0, 0, &host_disconnect_ie->hdr);
+       if (result < 0)
+               goto error_mmcie_set;
+
+       /* WUSB1.0[8.5.3.1 & 7.5.2] */
+       msleep(100);
+       wusbhc_mmcie_rm(wusbhc, &host_disconnect_ie->hdr);
+error_mmcie_set:
+       kfree(host_disconnect_ie);
+error_alloc:
+       return result;
+}
+
+/*
+ * wusbhc_stop - stop transmitting MMCs
+ * @wusbhc: the HC to stop
+ *
+ * Send a Host Disconnect IE, wait, remove all the MMCs (stop sending MMCs).
+ *
+ * If we can't allocate a Host Stop IE, screw it, we don't notify the
+ * devices we are disconnecting...
+ */
+void wusbhc_stop(struct wusbhc *wusbhc)
+{
+       if (wusbhc->active) {
+               wusbhc->active = 0;
+               wusbhc->stop(wusbhc);
+               wusbhc_sec_stop(wusbhc);
+               __wusbhc_host_disconnect_ie(wusbhc);
+               wusbhc_devconnect_stop(wusbhc);
+               wusbhc_rsv_terminate(wusbhc);
+       }
+}
+EXPORT_SYMBOL_GPL(wusbhc_stop);
+
+/*
+ * Change the CHID in a WUSB Channel
+ *
+ * If it is just a new CHID, send a Host Disconnect IE and then change
+ * the CHID IE.
+ */
+static int __wusbhc_chid_change(struct wusbhc *wusbhc,
+                               const struct wusb_ckhdid *chid)
+{
+       int result = -ENOSYS;
+       struct device *dev = wusbhc->dev;
+       dev_err(dev, "%s() not implemented yet\n", __func__);
+       return result;
+
+       BUG_ON(wusbhc->wuie_host_info == NULL);
+       __wusbhc_host_disconnect_ie(wusbhc);
+       wusbhc->wuie_host_info->CHID = *chid;
+       result = wusbhc_mmcie_set(wusbhc, 0, 0, &wusbhc->wuie_host_info->hdr);
+       if (result < 0)
+               dev_err(dev, "Can't update Host Info WUSB IE: %d\n", result);
+       return result;
+}
+
+/*
+ * Set/reset/update a new CHID
+ *
+ * Depending on the previous state of the MMCs, start, stop or change
+ * the sent MMC. This effectively switches the host controller on and
+ * off (radio wise).
+ */
+int wusbhc_chid_set(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid)
+{
+       int result = 0;
+
+       if (memcmp(chid, &wusb_ckhdid_zero, sizeof(chid)) == 0)
+               chid = NULL;
+
+       mutex_lock(&wusbhc->mutex);
+       if (wusbhc->active) {
+               if (chid)
+                       result = __wusbhc_chid_change(wusbhc, chid);
+               else
+                       wusbhc_stop(wusbhc);
+       } else {
+               if (chid)
+                       wusbhc_start(wusbhc, chid);
+       }
+       mutex_unlock(&wusbhc->mutex);
+       return result;
+}
+EXPORT_SYMBOL_GPL(wusbhc_chid_set);
diff --git a/drivers/usb/wusbcore/pal.c b/drivers/usb/wusbcore/pal.c
new file mode 100644 (file)
index 0000000..7cc51e9
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Wireless USB Host Controller
+ * UWB Protocol Adaptation Layer (PAL) glue.
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include "wusbhc.h"
+
+/**
+ * wusbhc_pal_register - register the WUSB HC as a UWB PAL
+ * @wusbhc: the WUSB HC
+ */
+int wusbhc_pal_register(struct wusbhc *wusbhc)
+{
+       uwb_pal_init(&wusbhc->pal);
+
+       wusbhc->pal.name   = "wusbhc";
+       wusbhc->pal.device = wusbhc->usb_hcd.self.controller;
+
+       return uwb_pal_register(wusbhc->uwb_rc, &wusbhc->pal);
+}
+
+/**
+ * wusbhc_pal_register - unregister the WUSB HC as a UWB PAL
+ * @wusbhc: the WUSB HC
+ */
+void wusbhc_pal_unregister(struct wusbhc *wusbhc)
+{
+       uwb_pal_unregister(wusbhc->uwb_rc, &wusbhc->pal);
+}
diff --git a/drivers/usb/wusbcore/reservation.c b/drivers/usb/wusbcore/reservation.c
new file mode 100644 (file)
index 0000000..fc63e77
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * WUSB cluster reservation management
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/kernel.h>
+#include <linux/uwb.h>
+
+#include "wusbhc.h"
+
+/*
+ * WUSB cluster reservations are multicast reservations with the
+ * broadcast cluster ID (BCID) as the target DevAddr.
+ *
+ * FIXME: consider adjusting the reservation depending on what devices
+ * are attached.
+ */
+
+static int wusbhc_bwa_set(struct wusbhc *wusbhc, u8 stream,
+       const struct uwb_mas_bm *mas)
+{
+       if (mas == NULL)
+               mas = &uwb_mas_bm_zero;
+       return wusbhc->bwa_set(wusbhc, stream, mas);
+}
+
+/**
+ * wusbhc_rsv_complete_cb - WUSB HC reservation complete callback
+ * @rsv:    the reservation
+ *
+ * Either set or clear the HC's view of the reservation.
+ *
+ * FIXME: when a reservation is denied the HC should be stopped.
+ */
+static void wusbhc_rsv_complete_cb(struct uwb_rsv *rsv)
+{
+       struct wusbhc *wusbhc = rsv->pal_priv;
+       struct device *dev = wusbhc->dev;
+       char buf[72];
+
+       switch (rsv->state) {
+       case UWB_RSV_STATE_O_ESTABLISHED:
+               bitmap_scnprintf(buf, sizeof(buf), rsv->mas.bm, UWB_NUM_MAS);
+               dev_dbg(dev, "established reservation: %s\n", buf);
+               wusbhc_bwa_set(wusbhc, rsv->stream, &rsv->mas);
+               break;
+       case UWB_RSV_STATE_NONE:
+               dev_dbg(dev, "removed reservation\n");
+               wusbhc_bwa_set(wusbhc, 0, NULL);
+               wusbhc->rsv = NULL;
+               break;
+       default:
+               dev_dbg(dev, "unexpected reservation state: %d\n", rsv->state);
+               break;
+       }
+}
+
+
+/**
+ * wusbhc_rsv_establish - establish a reservation for the cluster
+ * @wusbhc: the WUSB HC requesting a bandwith reservation
+ */
+int wusbhc_rsv_establish(struct wusbhc *wusbhc)
+{
+       struct uwb_rc *rc = wusbhc->uwb_rc;
+       struct uwb_rsv *rsv;
+       struct uwb_dev_addr bcid;
+       int ret;
+
+       rsv = uwb_rsv_create(rc, wusbhc_rsv_complete_cb, wusbhc);
+       if (rsv == NULL)
+               return -ENOMEM;
+
+       bcid.data[0] = wusbhc->cluster_id;
+       bcid.data[1] = 0;
+
+       rsv->owner = &rc->uwb_dev;
+       rsv->target.type = UWB_RSV_TARGET_DEVADDR;
+       rsv->target.devaddr = bcid;
+       rsv->type = UWB_DRP_TYPE_PRIVATE;
+       rsv->max_mas = 256;
+       rsv->min_mas = 16;  /* one MAS per zone? */
+       rsv->sparsity = 16; /* at least one MAS in each zone? */
+       rsv->is_multicast = true;
+
+       ret = uwb_rsv_establish(rsv);
+       if (ret == 0)
+               wusbhc->rsv = rsv;
+       else
+               uwb_rsv_destroy(rsv);
+       return ret;
+}
+
+
+/**
+ * wusbhc_rsv_terminate - terminate any cluster reservation
+ * @wusbhc: the WUSB host whose reservation is to be terminated
+ */
+void wusbhc_rsv_terminate(struct wusbhc *wusbhc)
+{
+       if (wusbhc->rsv)
+               uwb_rsv_terminate(wusbhc->rsv);
+}
diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c
new file mode 100644 (file)
index 0000000..267a643
--- /dev/null
@@ -0,0 +1,477 @@
+/*
+ * Wireless USB Host Controller
+ * Root Hub operations
+ *
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * We fake a root hub that has fake ports (as many as simultaneous
+ * devices the Wireless USB Host Controller can deal with). For each
+ * port we keep an state in @wusbhc->port[index] identical to the one
+ * specified in the USB2.0[ch11] spec and some extra device
+ * information that complements the one in 'struct usb_device' (as
+ * this lacs a hcpriv pointer).
+ *
+ * Note this is common to WHCI and HWA host controllers.
+ *
+ * Through here we enable most of the state changes that the USB stack
+ * will use to connect or disconnect devices. We need to do some
+ * forced adaptation of Wireless USB device states vs. wired:
+ *
+ *        USB:                 WUSB:
+ *
+ * Port   Powered-off          port slot n/a
+ *        Powered-on           port slot available
+ *        Disconnected         port slot available
+ *        Connected            port slot assigned device
+ *                            device sent DN_Connect
+ *                             device was authenticated
+ *        Enabled              device is authenticated, transitioned
+ *                             from unauth -> auth -> default address
+ *                             -> enabled
+ *        Reset                disconnect
+ *        Disable              disconnect
+ *
+ * This maps the standard USB port states with the WUSB device states
+ * so we can fake ports without having to modify the USB stack.
+ *
+ * FIXME: this process will change in the future
+ *
+ *
+ * ENTRY POINTS
+ *
+ * Our entry points into here are, as in hcd.c, the USB stack root hub
+ * ops defined in the usb_hcd struct:
+ *
+ * wusbhc_rh_status_data()     Provide hub and port status data bitmap
+ *
+ * wusbhc_rh_control()          Execution of all the major requests
+ *                              you can do to a hub (Set|Clear
+ *                              features, get descriptors, status, etc).
+ *
+ * wusbhc_rh_[suspend|resume]() That
+ *
+ * wusbhc_rh_start_port_reset() ??? unimplemented
+ */
+#include "wusbhc.h"
+
+#define D_LOCAL 0
+#include <linux/uwb/debug.h>
+
+/*
+ * Reset a fake port
+ *
+ * This can be called to reset a port from any other state or to reset
+ * it when connecting. In Wireless USB they are different; when doing
+ * a new connect that involves going over the authentication. When
+ * just reseting, its a different story.
+ *
+ * The Linux USB stack resets a port twice before it considers it
+ * enabled, so we have to detect and ignore that.
+ *
+ * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
+ *
+ * Supposedly we are the only thread accesing @wusbhc->port; in any
+ * case, maybe we should move the mutex locking from
+ * wusbhc_devconnect_auth() to here.
+ *
+ * @port_idx refers to the wusbhc's port index, not the USB port number
+ */
+static int wusbhc_rh_port_reset(struct wusbhc *wusbhc, u8 port_idx)
+{
+       int result = 0;
+       struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx);
+
+       d_fnstart(3, wusbhc->dev, "(wusbhc %p port_idx %u)\n",
+                 wusbhc, port_idx);
+       if (port->reset_count == 0) {
+               wusbhc_devconnect_auth(wusbhc, port_idx);
+               port->reset_count++;
+       } else if (port->reset_count == 1)
+               /* see header */
+               d_printf(2, wusbhc->dev, "Ignoring second reset on port_idx "
+                       "%u\n", port_idx);
+       else
+               result = wusbhc_dev_reset(wusbhc, port_idx);
+       d_fnend(3, wusbhc->dev, "(wusbhc %p port_idx %u) = %d\n",
+               wusbhc, port_idx, result);
+       return result;
+}
+
+/*
+ * Return the hub change status bitmap
+ *
+ * The bits in the change status bitmap are cleared when a
+ * ClearPortFeature request is issued (USB2.0[11.12.3,11.12.4].
+ *
+ * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
+ *
+ * WARNING!! This gets called from atomic context; we cannot get the
+ *           mutex--the only race condition we can find is some bit
+ *           changing just after we copy it, which shouldn't be too
+ *           big of a problem [and we can't make it an spinlock
+ *           because other parts need to take it and sleep] .
+ *
+ *           @usb_hcd is refcounted, so it won't dissapear under us
+ *           and before killing a host, the polling of the root hub
+ *           would be stopped anyway.
+ */
+int wusbhc_rh_status_data(struct usb_hcd *usb_hcd, char *_buf)
+{
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       size_t cnt, size;
+       unsigned long *buf = (unsigned long *) _buf;
+
+       d_fnstart(1, wusbhc->dev, "(wusbhc %p)\n", wusbhc);
+       /* WE DON'T LOCK, see comment */
+       size = wusbhc->ports_max + 1 /* hub bit */;
+       size = (size + 8 - 1) / 8;      /* round to bytes */
+       for (cnt = 0; cnt < wusbhc->ports_max; cnt++)
+               if (wusb_port_by_idx(wusbhc, cnt)->change)
+                       set_bit(cnt + 1, buf);
+               else
+                       clear_bit(cnt + 1, buf);
+       d_fnend(1, wusbhc->dev, "(wusbhc %p) %u, buffer:\n", wusbhc, (int)size);
+       d_dump(1, wusbhc->dev, _buf, size);
+       return size;
+}
+EXPORT_SYMBOL_GPL(wusbhc_rh_status_data);
+
+/*
+ * Return the hub's desciptor
+ *
+ * NOTE: almost cut and paste from ehci-hub.c
+ *
+ * @wusbhc is assumed referenced and @wusbhc->mutex unlocked
+ */
+static int wusbhc_rh_get_hub_descr(struct wusbhc *wusbhc, u16 wValue,
+                                  u16 wIndex,
+                                  struct usb_hub_descriptor *descr,
+                                  u16 wLength)
+{
+       u16 temp = 1 + (wusbhc->ports_max / 8);
+       u8 length = 7 + 2 * temp;
+
+       if (wLength < length)
+               return -ENOSPC;
+       descr->bDescLength = 7 + 2 * temp;
+       descr->bDescriptorType = 0x29;  /* HUB type */
+       descr->bNbrPorts = wusbhc->ports_max;
+       descr->wHubCharacteristics = cpu_to_le16(
+               0x00                    /* All ports power at once */
+               | 0x00                  /* not part of compound device */
+               | 0x10                  /* No overcurrent protection */
+               | 0x00                  /* 8 FS think time FIXME ?? */
+               | 0x00);                /* No port indicators */
+       descr->bPwrOn2PwrGood = 0;
+       descr->bHubContrCurrent = 0;
+       /* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */
+       memset(&descr->bitmap[0], 0, temp);
+       memset(&descr->bitmap[temp], 0xff, temp);
+       return 0;
+}
+
+/*
+ * Clear a hub feature
+ *
+ * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
+ *
+ * Nothing to do, so no locking needed ;)
+ */
+static int wusbhc_rh_clear_hub_feat(struct wusbhc *wusbhc, u16 feature)
+{
+       int result;
+       struct device *dev = wusbhc->dev;
+
+       d_fnstart(4, dev, "(%p, feature 0x%04u)\n", wusbhc, feature);
+       switch (feature) {
+       case C_HUB_LOCAL_POWER:
+               /* FIXME: maybe plug bit 0 to the power input status,
+                * if any?
+                * see wusbhc_rh_get_hub_status() */
+       case C_HUB_OVER_CURRENT:
+               result = 0;
+               break;
+       default:
+               result = -EPIPE;
+       }
+       d_fnend(4, dev, "(%p, feature 0x%04u), %d\n", wusbhc, feature, result);
+       return result;
+}
+
+/*
+ * Return hub status (it is always zero...)
+ *
+ * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
+ *
+ * Nothing to do, so no locking needed ;)
+ */
+static int wusbhc_rh_get_hub_status(struct wusbhc *wusbhc, u32 *buf,
+                                   u16 wLength)
+{
+       /* FIXME: maybe plug bit 0 to the power input status (if any)? */
+       *buf = 0;
+       return 0;
+}
+
+/*
+ * Set a port feature
+ *
+ * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
+ */
+static int wusbhc_rh_set_port_feat(struct wusbhc *wusbhc, u16 feature,
+                                  u8 selector, u8 port_idx)
+{
+       int result = -EINVAL;
+       struct device *dev = wusbhc->dev;
+
+       d_fnstart(4, dev, "(feat 0x%04u, selector 0x%u, port_idx %d)\n",
+                 feature, selector, port_idx);
+
+       if (port_idx > wusbhc->ports_max)
+               goto error;
+
+       switch (feature) {
+               /* According to USB2.0[11.24.2.13]p2, these features
+                * are not required to be implemented. */
+       case USB_PORT_FEAT_C_OVER_CURRENT:
+       case USB_PORT_FEAT_C_ENABLE:
+       case USB_PORT_FEAT_C_SUSPEND:
+       case USB_PORT_FEAT_C_CONNECTION:
+       case USB_PORT_FEAT_C_RESET:
+               result = 0;
+               break;
+
+       case USB_PORT_FEAT_POWER:
+               /* No such thing, but we fake it works */
+               mutex_lock(&wusbhc->mutex);
+               wusb_port_by_idx(wusbhc, port_idx)->status |= USB_PORT_STAT_POWER;
+               mutex_unlock(&wusbhc->mutex);
+               result = 0;
+               break;
+       case USB_PORT_FEAT_RESET:
+               result = wusbhc_rh_port_reset(wusbhc, port_idx);
+               break;
+       case USB_PORT_FEAT_ENABLE:
+       case USB_PORT_FEAT_SUSPEND:
+               dev_err(dev, "(port_idx %d) set feat %d/%d UNIMPLEMENTED\n",
+                       port_idx, feature, selector);
+               result = -ENOSYS;
+               break;
+       default:
+               dev_err(dev, "(port_idx %d) set feat %d/%d UNKNOWN\n",
+                       port_idx, feature, selector);
+               result = -EPIPE;
+               break;
+       }
+error:
+       d_fnend(4, dev, "(feat 0x%04u, selector 0x%u, port_idx %d) = %d\n",
+               feature, selector, port_idx, result);
+       return result;
+}
+
+/*
+ * Clear a port feature...
+ *
+ * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
+ */
+static int wusbhc_rh_clear_port_feat(struct wusbhc *wusbhc, u16 feature,
+                                    u8 selector, u8 port_idx)
+{
+       int result = -EINVAL;
+       struct device *dev = wusbhc->dev;
+
+       d_fnstart(4, dev, "(wusbhc %p feat 0x%04x selector %d port_idx %d)\n",
+                 wusbhc, feature, selector, port_idx);
+
+       if (port_idx > wusbhc->ports_max)
+               goto error;
+
+       mutex_lock(&wusbhc->mutex);
+       result = 0;
+       switch (feature) {
+       case USB_PORT_FEAT_POWER:       /* fake port always on */
+               /* According to USB2.0[11.24.2.7.1.4], no need to implement? */
+       case USB_PORT_FEAT_C_OVER_CURRENT:
+               break;
+       case USB_PORT_FEAT_C_RESET:
+               wusb_port_by_idx(wusbhc, port_idx)->change &= ~USB_PORT_STAT_C_RESET;
+               break;
+       case USB_PORT_FEAT_C_CONNECTION:
+               wusb_port_by_idx(wusbhc, port_idx)->change &= ~USB_PORT_STAT_C_CONNECTION;
+               break;
+       case USB_PORT_FEAT_ENABLE:
+               __wusbhc_dev_disable(wusbhc, port_idx);
+               break;
+       case USB_PORT_FEAT_C_ENABLE:
+               wusb_port_by_idx(wusbhc, port_idx)->change &= ~USB_PORT_STAT_C_ENABLE;
+               break;
+       case USB_PORT_FEAT_SUSPEND:
+       case USB_PORT_FEAT_C_SUSPEND:
+       case 0xffff:            /* ??? FIXME */
+               dev_err(dev, "(port_idx %d) Clear feat %d/%d UNIMPLEMENTED\n",
+                       port_idx, feature, selector);
+               /* dump_stack(); */
+               result = -ENOSYS;
+               break;
+       default:
+               dev_err(dev, "(port_idx %d) Clear feat %d/%d UNKNOWN\n",
+                       port_idx, feature, selector);
+               result = -EPIPE;
+               break;
+       }
+       mutex_unlock(&wusbhc->mutex);
+error:
+       d_fnend(4, dev, "(wusbhc %p feat 0x%04x selector %d port_idx %d) = "
+               "%d\n", wusbhc, feature, selector, port_idx, result);
+       return result;
+}
+
+/*
+ * Return the port's status
+ *
+ * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
+ */
+static int wusbhc_rh_get_port_status(struct wusbhc *wusbhc, u16 port_idx,
+                                    u32 *_buf, u16 wLength)
+{
+       int result = -EINVAL;
+       u16 *buf = (u16 *) _buf;
+
+       d_fnstart(1, wusbhc->dev, "(wusbhc %p port_idx %u wLength %u)\n",
+                 wusbhc, port_idx, wLength);
+       if (port_idx > wusbhc->ports_max)
+               goto error;
+       mutex_lock(&wusbhc->mutex);
+       buf[0] = cpu_to_le16(wusb_port_by_idx(wusbhc, port_idx)->status);
+       buf[1] = cpu_to_le16(wusb_port_by_idx(wusbhc, port_idx)->change);
+       result = 0;
+       mutex_unlock(&wusbhc->mutex);
+error:
+       d_fnend(1, wusbhc->dev, "(wusbhc %p) = %d, buffer:\n", wusbhc, result);
+       d_dump(1, wusbhc->dev, _buf, wLength);
+       return result;
+}
+
+/*
+ * Entry point for Root Hub operations
+ *
+ * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
+ */
+int wusbhc_rh_control(struct usb_hcd *usb_hcd, u16 reqntype, u16 wValue,
+                     u16 wIndex, char *buf, u16 wLength)
+{
+       int result = -ENOSYS;
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+
+       switch (reqntype) {
+       case GetHubDescriptor:
+               result = wusbhc_rh_get_hub_descr(
+                       wusbhc, wValue, wIndex,
+                       (struct usb_hub_descriptor *) buf, wLength);
+               break;
+       case ClearHubFeature:
+               result = wusbhc_rh_clear_hub_feat(wusbhc, wValue);
+               break;
+       case GetHubStatus:
+               result = wusbhc_rh_get_hub_status(wusbhc, (u32 *)buf, wLength);
+               break;
+
+       case SetPortFeature:
+               result = wusbhc_rh_set_port_feat(wusbhc, wValue, wIndex >> 8,
+                                                (wIndex & 0xff) - 1);
+               break;
+       case ClearPortFeature:
+               result = wusbhc_rh_clear_port_feat(wusbhc, wValue, wIndex >> 8,
+                                                  (wIndex & 0xff) - 1);
+               break;
+       case GetPortStatus:
+               result = wusbhc_rh_get_port_status(wusbhc, wIndex - 1,
+                                                  (u32 *)buf, wLength);
+               break;
+
+       case SetHubFeature:
+       default:
+               dev_err(wusbhc->dev, "%s (%p [%p], %x, %x, %x, %p, %x) "
+                       "UNIMPLEMENTED\n", __func__, usb_hcd, wusbhc, reqntype,
+                       wValue, wIndex, buf, wLength);
+               /* dump_stack(); */
+               result = -ENOSYS;
+       }
+       return result;
+}
+EXPORT_SYMBOL_GPL(wusbhc_rh_control);
+
+int wusbhc_rh_suspend(struct usb_hcd *usb_hcd)
+{
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       dev_err(wusbhc->dev, "%s (%p [%p]) UNIMPLEMENTED\n", __func__,
+               usb_hcd, wusbhc);
+       /* dump_stack(); */
+       return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(wusbhc_rh_suspend);
+
+int wusbhc_rh_resume(struct usb_hcd *usb_hcd)
+{
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       dev_err(wusbhc->dev, "%s (%p [%p]) UNIMPLEMENTED\n", __func__,
+               usb_hcd, wusbhc);
+       /* dump_stack(); */
+       return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(wusbhc_rh_resume);
+
+int wusbhc_rh_start_port_reset(struct usb_hcd *usb_hcd, unsigned port_idx)
+{
+       struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+       dev_err(wusbhc->dev, "%s (%p [%p], port_idx %u) UNIMPLEMENTED\n",
+               __func__, usb_hcd, wusbhc, port_idx);
+       WARN_ON(1);
+       return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(wusbhc_rh_start_port_reset);
+
+static void wusb_port_init(struct wusb_port *port)
+{
+       port->status |= USB_PORT_STAT_HIGH_SPEED;
+}
+
+/*
+ * Alloc fake port specific fields and status.
+ */
+int wusbhc_rh_create(struct wusbhc *wusbhc)
+{
+       int result = -ENOMEM;
+       size_t port_size, itr;
+       port_size = wusbhc->ports_max * sizeof(wusbhc->port[0]);
+       wusbhc->port = kzalloc(port_size, GFP_KERNEL);
+       if (wusbhc->port == NULL)
+               goto error_port_alloc;
+       for (itr = 0; itr < wusbhc->ports_max; itr++)
+               wusb_port_init(&wusbhc->port[itr]);
+       result = 0;
+error_port_alloc:
+       return result;
+}
+
+void wusbhc_rh_destroy(struct wusbhc *wusbhc)
+{
+       kfree(wusbhc->port);
+}
diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c
new file mode 100644 (file)
index 0000000..a101cad
--- /dev/null
@@ -0,0 +1,642 @@
+/*
+ * Wireless USB Host Controller
+ * Security support: encryption enablement, etc
+ *
+ * Copyright (C) 2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ */
+#include <linux/types.h>
+#include <linux/usb/ch9.h>
+#include <linux/random.h>
+#include "wusbhc.h"
+
+/*
+ * DEBUG & SECURITY WARNING!!!!
+ *
+ * If you enable this past 1, the debug code will weaken the
+ * cryptographic safety of the system (on purpose, for debugging).
+ *
+ * Weaken means:
+ *   we print secret keys and intermediate values all the way,
+ */
+#undef D_LOCAL
+#define D_LOCAL 2
+#include <linux/uwb/debug.h>
+
+static void wusbhc_set_gtk_callback(struct urb *urb);
+static void wusbhc_gtk_rekey_done_work(struct work_struct *work);
+
+int wusbhc_sec_create(struct wusbhc *wusbhc)
+{
+       wusbhc->gtk.descr.bLength = sizeof(wusbhc->gtk.descr) + sizeof(wusbhc->gtk.data);
+       wusbhc->gtk.descr.bDescriptorType = USB_DT_KEY;
+       wusbhc->gtk.descr.bReserved = 0;
+
+       wusbhc->gtk_index = wusb_key_index(0, WUSB_KEY_INDEX_TYPE_GTK,
+                                          WUSB_KEY_INDEX_ORIGINATOR_HOST);
+
+       INIT_WORK(&wusbhc->gtk_rekey_done_work, wusbhc_gtk_rekey_done_work);
+
+       return 0;
+}
+
+
+/* Called when the HC is destroyed */
+void wusbhc_sec_destroy(struct wusbhc *wusbhc)
+{
+}
+
+
+/**
+ * wusbhc_next_tkid - generate a new, currently unused, TKID
+ * @wusbhc:   the WUSB host controller
+ * @wusb_dev: the device whose PTK the TKID is for
+ *            (or NULL for a TKID for a GTK)
+ *
+ * The generated TKID consist of two parts: the device's authenicated
+ * address (or 0 or a GTK); and an incrementing number.  This ensures
+ * that TKIDs cannot be shared between devices and by the time the
+ * incrementing number wraps around the older TKIDs will no longer be
+ * in use (a maximum of two keys may be active at any one time).
+ */
+static u32 wusbhc_next_tkid(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
+{
+       u32 *tkid;
+       u32 addr;
+
+       if (wusb_dev == NULL) {
+               tkid = &wusbhc->gtk_tkid;
+               addr = 0;
+       } else {
+               tkid = &wusb_port_by_idx(wusbhc, wusb_dev->port_idx)->ptk_tkid;
+               addr = wusb_dev->addr & 0x7f;
+       }
+
+       *tkid = (addr << 8) | ((*tkid + 1) & 0xff);
+
+       return *tkid;
+}
+
+static void wusbhc_generate_gtk(struct wusbhc *wusbhc)
+{
+       const size_t key_size = sizeof(wusbhc->gtk.data);
+       u32 tkid;
+
+       tkid = wusbhc_next_tkid(wusbhc, NULL);
+
+       wusbhc->gtk.descr.tTKID[0] = (tkid >>  0) & 0xff;
+       wusbhc->gtk.descr.tTKID[1] = (tkid >>  8) & 0xff;
+       wusbhc->gtk.descr.tTKID[2] = (tkid >> 16) & 0xff;
+
+       get_random_bytes(wusbhc->gtk.descr.bKeyData, key_size);
+}
+
+/**
+ * wusbhc_sec_start - start the security management process
+ * @wusbhc: the WUSB host controller
+ *
+ * Generate and set an initial GTK on the host controller.
+ *
+ * Called when the HC is started.
+ */
+int wusbhc_sec_start(struct wusbhc *wusbhc)
+{
+       const size_t key_size = sizeof(wusbhc->gtk.data);
+       int result;
+
+       wusbhc_generate_gtk(wusbhc);
+
+       result = wusbhc->set_gtk(wusbhc, wusbhc->gtk_tkid,
+                                &wusbhc->gtk.descr.bKeyData, key_size);
+       if (result < 0)
+               dev_err(wusbhc->dev, "cannot set GTK for the host: %d\n",
+                       result);
+
+       return result;
+}
+
+/**
+ * wusbhc_sec_stop - stop the security management process
+ * @wusbhc: the WUSB host controller
+ *
+ * Wait for any pending GTK rekeys to stop.
+ */
+void wusbhc_sec_stop(struct wusbhc *wusbhc)
+{
+       cancel_work_sync(&wusbhc->gtk_rekey_done_work);
+}
+
+
+/** @returns encryption type name */
+const char *wusb_et_name(u8 x)
+{
+       switch (x) {
+       case USB_ENC_TYPE_UNSECURE:     return "unsecure";
+       case USB_ENC_TYPE_WIRED:        return "wired";
+       case USB_ENC_TYPE_CCM_1:        return "CCM-1";
+       case USB_ENC_TYPE_RSA_1:        return "RSA-1";
+       default:                        return "unknown";
+       }
+}
+EXPORT_SYMBOL_GPL(wusb_et_name);
+
+/*
+ * Set the device encryption method
+ *
+ * We tell the device which encryption method to use; we do this when
+ * setting up the device's security.
+ */
+static int wusb_dev_set_encryption(struct usb_device *usb_dev, int value)
+{
+       int result;
+       struct device *dev = &usb_dev->dev;
+       struct wusb_dev *wusb_dev = usb_dev->wusb_dev;
+
+       if (value) {
+               value = wusb_dev->ccm1_etd.bEncryptionValue;
+       } else {
+               /* FIXME: should be wusb_dev->etd[UNSECURE].bEncryptionValue */
+               value = 0;
+       }
+       /* Set device's */
+       result = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
+                       USB_REQ_SET_ENCRYPTION,
+                       USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
+                       value, 0, NULL, 0, 1000 /* FIXME: arbitrary */);
+       if (result < 0)
+               dev_err(dev, "Can't set device's WUSB encryption to "
+                       "%s (value %d): %d\n",
+                       wusb_et_name(wusb_dev->ccm1_etd.bEncryptionType),
+                       wusb_dev->ccm1_etd.bEncryptionValue,  result);
+       return result;
+}
+
+/*
+ * Set the GTK to be used by a device.
+ *
+ * The device must be authenticated.
+ */
+static int wusb_dev_set_gtk(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
+{
+       struct usb_device *usb_dev = wusb_dev->usb_dev;
+
+       return usb_control_msg(
+               usb_dev, usb_sndctrlpipe(usb_dev, 0),
+               USB_REQ_SET_DESCRIPTOR,
+               USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
+               USB_DT_KEY << 8 | wusbhc->gtk_index, 0,
+               &wusbhc->gtk.descr, wusbhc->gtk.descr.bLength,
+               1000);
+}
+
+
+/* FIXME: prototype for adding security */
+int wusb_dev_sec_add(struct wusbhc *wusbhc,
+                    struct usb_device *usb_dev, struct wusb_dev *wusb_dev)
+{
+       int result, bytes, secd_size;
+       struct device *dev = &usb_dev->dev;
+       struct usb_security_descriptor secd;
+       const struct usb_encryption_descriptor *etd, *ccm1_etd = NULL;
+       void *secd_buf;
+       const void *itr, *top;
+       char buf[64];
+
+       d_fnstart(3, dev, "(usb_dev %p, wusb_dev %p)\n", usb_dev, wusb_dev);
+       result = usb_get_descriptor(usb_dev, USB_DT_SECURITY,
+                                   0, &secd, sizeof(secd));
+       if (result < sizeof(secd)) {
+               dev_err(dev, "Can't read security descriptor or "
+                       "not enough data: %d\n", result);
+               goto error_secd;
+       }
+       secd_size = le16_to_cpu(secd.wTotalLength);
+       d_printf(5, dev, "got %d bytes of sec descriptor, total is %d\n",
+                result, secd_size);
+       secd_buf = kmalloc(secd_size, GFP_KERNEL);
+       if (secd_buf == NULL) {
+               dev_err(dev, "Can't allocate space for security descriptors\n");
+               goto error_secd_alloc;
+       }
+       result = usb_get_descriptor(usb_dev, USB_DT_SECURITY,
+                                   0, secd_buf, secd_size);
+       if (result < secd_size) {
+               dev_err(dev, "Can't read security descriptor or "
+                       "not enough data: %d\n", result);
+               goto error_secd_all;
+       }
+       d_printf(5, dev, "got %d bytes of sec descriptors\n", result);
+       bytes = 0;
+       itr = secd_buf + sizeof(secd);
+       top = secd_buf + result;
+       while (itr < top) {
+               etd = itr;
+               if (top - itr < sizeof(*etd)) {
+                       dev_err(dev, "BUG: bad device security descriptor; "
+                               "not enough data (%zu vs %zu bytes left)\n",
+                               top - itr, sizeof(*etd));
+                       break;
+               }
+               if (etd->bLength < sizeof(*etd)) {
+                       dev_err(dev, "BUG: bad device encryption descriptor; "
+                               "descriptor is too short "
+                               "(%u vs %zu needed)\n",
+                               etd->bLength, sizeof(*etd));
+                       break;
+               }
+               itr += etd->bLength;
+               bytes += snprintf(buf + bytes, sizeof(buf) - bytes,
+                                 "%s (0x%02x/%02x) ",
+                                 wusb_et_name(etd->bEncryptionType),
+                                 etd->bEncryptionValue, etd->bAuthKeyIndex);
+               if (etd->bEncryptionType == USB_ENC_TYPE_CCM_1)
+                       ccm1_etd = etd;
+       }
+       /* This code only supports CCM1 as of now. */
+       /* FIXME: user has to choose which sec mode to use?
+        * In theory we want CCM */
+       if (ccm1_etd == NULL) {
+               dev_err(dev, "WUSB device doesn't support CCM1 encryption, "
+                       "can't use!\n");
+               result = -EINVAL;
+               goto error_no_ccm1;
+       }
+       wusb_dev->ccm1_etd = *ccm1_etd;
+       dev_info(dev, "supported encryption: %s; using %s (0x%02x/%02x)\n",
+                buf, wusb_et_name(ccm1_etd->bEncryptionType),
+                ccm1_etd->bEncryptionValue, ccm1_etd->bAuthKeyIndex);
+       result = 0;
+       kfree(secd_buf);
+out:
+       d_fnend(3, dev, "(usb_dev %p, wusb_dev %p) = %d\n",
+               usb_dev, wusb_dev, result);
+       return result;
+
+
+error_no_ccm1:
+error_secd_all:
+       kfree(secd_buf);
+error_secd_alloc:
+error_secd:
+       goto out;
+}
+
+void wusb_dev_sec_rm(struct wusb_dev *wusb_dev)
+{
+       /* Nothing so far */
+}
+
+static void hs_printk(unsigned level, struct device *dev,
+                     struct usb_handshake *hs)
+{
+       d_printf(level, dev,
+                "  bMessageNumber: %u\n"
+                "  bStatus:        %u\n"
+                "  tTKID:          %02x %02x %02x\n"
+                "  CDID:           %02x %02x %02x %02x %02x %02x %02x %02x\n"
+                "                  %02x %02x %02x %02x %02x %02x %02x %02x\n"
+                "  nonce:          %02x %02x %02x %02x %02x %02x %02x %02x\n"
+                "                  %02x %02x %02x %02x %02x %02x %02x %02x\n"
+                "  MIC:            %02x %02x %02x %02x %02x %02x %02x %02x\n",
+                hs->bMessageNumber, hs->bStatus,
+                hs->tTKID[2], hs->tTKID[1], hs->tTKID[0],
+                hs->CDID[0], hs->CDID[1], hs->CDID[2], hs->CDID[3],
+                hs->CDID[4], hs->CDID[5], hs->CDID[6], hs->CDID[7],
+                hs->CDID[8], hs->CDID[9], hs->CDID[10], hs->CDID[11],
+                hs->CDID[12], hs->CDID[13], hs->CDID[14], hs->CDID[15],
+                hs->nonce[0], hs->nonce[1], hs->nonce[2], hs->nonce[3],
+                hs->nonce[4], hs->nonce[5], hs->nonce[6], hs->nonce[7],
+                hs->nonce[8], hs->nonce[9], hs->nonce[10], hs->nonce[11],
+                hs->nonce[12], hs->nonce[13], hs->nonce[14], hs->nonce[15],
+                hs->MIC[0], hs->MIC[1], hs->MIC[2], hs->MIC[3],
+                hs->MIC[4], hs->MIC[5], hs->MIC[6], hs->MIC[7]);
+}
+
+/**
+ * Update the address of an unauthenticated WUSB device
+ *
+ * Once we have successfully authenticated, we take it to addr0 state
+ * and then to a normal address.
+ *
+ * Before the device's address (as known by it) was usb_dev->devnum |
+ * 0x80 (unauthenticated address). With this we update it to usb_dev->devnum.
+ */
+static int wusb_dev_update_address(struct wusbhc *wusbhc,
+                                  struct wusb_dev *wusb_dev)
+{
+       int result = -ENOMEM;
+       struct usb_device *usb_dev = wusb_dev->usb_dev;
+       struct device *dev = &usb_dev->dev;
+       u8 new_address = wusb_dev->addr & 0x7F;
+
+       /* Set address 0 */
+       result = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
+                                USB_REQ_SET_ADDRESS, 0,
+                                0, 0, NULL, 0, 1000 /* FIXME: arbitrary */);
+       if (result < 0) {
+               dev_err(dev, "auth failed: can't set address 0: %d\n",
+                       result);
+               goto error_addr0;
+       }
+       result = wusb_set_dev_addr(wusbhc, wusb_dev, 0);
+       if (result < 0)
+               goto error_addr0;
+       usb_ep0_reinit(usb_dev);
+
+       /* Set new (authenticated) address. */
+       result = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
+                                USB_REQ_SET_ADDRESS, 0,
+                                new_address, 0, NULL, 0,
+                                1000 /* FIXME: arbitrary */);
+       if (result < 0) {
+               dev_err(dev, "auth failed: can't set address %u: %d\n",
+                       new_address, result);
+               goto error_addr;
+       }
+       result = wusb_set_dev_addr(wusbhc, wusb_dev, new_address);
+       if (result < 0)
+               goto error_addr;
+       usb_ep0_reinit(usb_dev);
+       usb_dev->authenticated = 1;
+error_addr:
+error_addr0:
+       return result;
+}
+
+/*
+ *
+ *
+ */
+/* FIXME: split and cleanup */
+int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev,
+                           struct wusb_ckhdid *ck)
+{
+       int result = -ENOMEM;
+       struct usb_device *usb_dev = wusb_dev->usb_dev;
+       struct device *dev = &usb_dev->dev;
+       u32 tkid;
+       __le32 tkid_le;
+       struct usb_handshake *hs;
+       struct aes_ccm_nonce ccm_n;
+       u8 mic[8];
+       struct wusb_keydvt_in keydvt_in;
+       struct wusb_keydvt_out keydvt_out;
+
+       hs = kzalloc(3*sizeof(hs[0]), GFP_KERNEL);
+       if (hs == NULL) {
+               dev_err(dev, "can't allocate handshake data\n");
+               goto error_kzalloc;
+       }
+
+       /* We need to turn encryption before beginning the 4way
+        * hshake (WUSB1.0[.3.2.2]) */
+       result = wusb_dev_set_encryption(usb_dev, 1);
+       if (result < 0)
+               goto error_dev_set_encryption;
+
+       tkid = wusbhc_next_tkid(wusbhc, wusb_dev);
+       tkid_le = cpu_to_le32(tkid);
+
+       hs[0].bMessageNumber = 1;
+       hs[0].bStatus = 0;
+       memcpy(hs[0].tTKID, &tkid_le, sizeof(hs[0].tTKID));
+       hs[0].bReserved = 0;
+       memcpy(hs[0].CDID, &wusb_dev->cdid, sizeof(hs[0].CDID));
+       get_random_bytes(&hs[0].nonce, sizeof(hs[0].nonce));
+       memset(hs[0].MIC, 0, sizeof(hs[0].MIC));        /* Per WUSB1.0[T7-22] */
+
+       d_printf(1, dev, "I: sending hs1:\n");
+       hs_printk(2, dev, &hs[0]);
+
+       result = usb_control_msg(
+               usb_dev, usb_sndctrlpipe(usb_dev, 0),
+               USB_REQ_SET_HANDSHAKE,
+               USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
+               1, 0, &hs[0], sizeof(hs[0]), 1000 /* FIXME: arbitrary */);
+       if (result < 0) {
+               dev_err(dev, "Handshake1: request failed: %d\n", result);
+               goto error_hs1;
+       }
+
+       /* Handshake 2, from the device -- need to verify fields */
+       result = usb_control_msg(
+               usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+               USB_REQ_GET_HANDSHAKE,
+               USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
+               2, 0, &hs[1], sizeof(hs[1]), 1000 /* FIXME: arbitrary */);
+       if (result < 0) {
+               dev_err(dev, "Handshake2: request failed: %d\n", result);
+               goto error_hs2;
+       }
+       d_printf(1, dev, "got HS2:\n");
+       hs_printk(2, dev, &hs[1]);
+
+       result = -EINVAL;
+       if (hs[1].bMessageNumber != 2) {
+               dev_err(dev, "Handshake2 failed: bad message number %u\n",
+                       hs[1].bMessageNumber);
+               goto error_hs2;
+       }
+       if (hs[1].bStatus != 0) {
+               dev_err(dev, "Handshake2 failed: bad status %u\n",
+                       hs[1].bStatus);
+               goto error_hs2;
+       }
+       if (memcmp(hs[0].tTKID, hs[1].tTKID, sizeof(hs[0].tTKID))) {
+               dev_err(dev, "Handshake2 failed: TKID mismatch "
+                       "(#1 0x%02x%02x%02x vs #2 0x%02x%02x%02x)\n",
+                       hs[0].tTKID[0], hs[0].tTKID[1], hs[0].tTKID[2],
+                       hs[1].tTKID[0], hs[1].tTKID[1], hs[1].tTKID[2]);
+               goto error_hs2;
+       }
+       if (memcmp(hs[0].CDID, hs[1].CDID, sizeof(hs[0].CDID))) {
+               dev_err(dev, "Handshake2 failed: CDID mismatch\n");
+               goto error_hs2;
+       }
+
+       /* Setup the CCM nonce */
+       memset(&ccm_n.sfn, 0, sizeof(ccm_n.sfn));       /* Per WUSB1.0[6.5.2] */
+       memcpy(ccm_n.tkid, &tkid_le, sizeof(ccm_n.tkid));
+       ccm_n.src_addr = wusbhc->uwb_rc->uwb_dev.dev_addr;
+       ccm_n.dest_addr.data[0] = wusb_dev->addr;
+       ccm_n.dest_addr.data[1] = 0;
+
+       /* Derive the KCK and PTK from CK, the CCM, H and D nonces */
+       memcpy(keydvt_in.hnonce, hs[0].nonce, sizeof(keydvt_in.hnonce));
+       memcpy(keydvt_in.dnonce, hs[1].nonce, sizeof(keydvt_in.dnonce));
+       result = wusb_key_derive(&keydvt_out, ck->data, &ccm_n, &keydvt_in);
+       if (result < 0) {
+               dev_err(dev, "Handshake2 failed: cannot derive keys: %d\n",
+                       result);
+               goto error_hs2;
+       }
+       d_printf(2, dev, "KCK:\n");
+       d_dump(2, dev, keydvt_out.kck, sizeof(keydvt_out.kck));
+       d_printf(2, dev, "PTK:\n");
+       d_dump(2, dev, keydvt_out.ptk, sizeof(keydvt_out.ptk));
+
+       /* Compute MIC and verify it */
+       result = wusb_oob_mic(mic, keydvt_out.kck, &ccm_n, &hs[1]);
+       if (result < 0) {
+               dev_err(dev, "Handshake2 failed: cannot compute MIC: %d\n",
+                       result);
+               goto error_hs2;
+       }
+
+       d_printf(2, dev, "MIC:\n");
+       d_dump(2, dev, mic, sizeof(mic));
+       if (memcmp(hs[1].MIC, mic, sizeof(hs[1].MIC))) {
+               dev_err(dev, "Handshake2 failed: MIC mismatch\n");
+               goto error_hs2;
+       }
+
+       /* Send Handshake3 */
+       hs[2].bMessageNumber = 3;
+       hs[2].bStatus = 0;
+       memcpy(hs[2].tTKID, &tkid_le, sizeof(hs[2].tTKID));
+       hs[2].bReserved = 0;
+       memcpy(hs[2].CDID, &wusb_dev->cdid, sizeof(hs[2].CDID));
+       memcpy(hs[2].nonce, hs[0].nonce, sizeof(hs[2].nonce));
+       result = wusb_oob_mic(hs[2].MIC, keydvt_out.kck, &ccm_n, &hs[2]);
+       if (result < 0) {
+               dev_err(dev, "Handshake3 failed: cannot compute MIC: %d\n",
+                       result);
+               goto error_hs2;
+       }
+
+       d_printf(1, dev, "I: sending hs3:\n");
+       hs_printk(2, dev, &hs[2]);
+
+       result = usb_control_msg(
+               usb_dev, usb_sndctrlpipe(usb_dev, 0),
+               USB_REQ_SET_HANDSHAKE,
+               USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
+               3, 0, &hs[2], sizeof(hs[2]), 1000 /* FIXME: arbitrary */);
+       if (result < 0) {
+               dev_err(dev, "Handshake3: request failed: %d\n", result);
+               goto error_hs3;
+       }
+
+       d_printf(1, dev, "I: turning on encryption on host for device\n");
+       d_dump(2, dev, keydvt_out.ptk, sizeof(keydvt_out.ptk));
+       result = wusbhc->set_ptk(wusbhc, wusb_dev->port_idx, tkid,
+                                keydvt_out.ptk, sizeof(keydvt_out.ptk));
+       if (result < 0)
+               goto error_wusbhc_set_ptk;
+
+       d_printf(1, dev, "I: setting a GTK\n");
+       result = wusb_dev_set_gtk(wusbhc, wusb_dev);
+       if (result < 0) {
+               dev_err(dev, "Set GTK for device: request failed: %d\n",
+                       result);
+               goto error_wusbhc_set_gtk;
+       }
+
+       /* Update the device's address from unauth to auth */
+       if (usb_dev->authenticated == 0) {
+               d_printf(1, dev, "I: updating addres to auth from non-auth\n");
+               result = wusb_dev_update_address(wusbhc, wusb_dev);
+               if (result < 0)
+                       goto error_dev_update_address;
+       }
+       result = 0;
+       d_printf(1, dev, "I: 4way handshke done, device authenticated\n");
+
+error_dev_update_address:
+error_wusbhc_set_gtk:
+error_wusbhc_set_ptk:
+error_hs3:
+error_hs2:
+error_hs1:
+       memset(hs, 0, 3*sizeof(hs[0]));
+       memset(&keydvt_out, 0, sizeof(keydvt_out));
+       memset(&keydvt_in, 0, sizeof(keydvt_in));
+       memset(&ccm_n, 0, sizeof(ccm_n));
+       memset(mic, 0, sizeof(mic));
+       if (result < 0) {
+               /* error path */
+               wusb_dev_set_encryption(usb_dev, 0);
+       }
+error_dev_set_encryption:
+       kfree(hs);
+error_kzalloc:
+       return result;
+}
+
+/*
+ * Once all connected and authenticated devices have received the new
+ * GTK, switch the host to using it.
+ */
+static void wusbhc_gtk_rekey_done_work(struct work_struct *work)
+{
+       struct wusbhc *wusbhc = container_of(work, struct wusbhc, gtk_rekey_done_work);
+       size_t key_size = sizeof(wusbhc->gtk.data);
+
+       mutex_lock(&wusbhc->mutex);
+
+       if (--wusbhc->pending_set_gtks == 0)
+               wusbhc->set_gtk(wusbhc, wusbhc->gtk_tkid, &wusbhc->gtk.descr.bKeyData, key_size);
+
+       mutex_unlock(&wusbhc->mutex);
+}
+
+static void wusbhc_set_gtk_callback(struct urb *urb)
+{
+       struct wusbhc *wusbhc = urb->context;
+
+       queue_work(wusbd, &wusbhc->gtk_rekey_done_work);
+}
+
+/**
+ * wusbhc_gtk_rekey - generate and distribute a new GTK
+ * @wusbhc: the WUSB host controller
+ *
+ * Generate a new GTK and distribute it to all connected and
+ * authenticated devices.  When all devices have the new GTK, the host
+ * starts using it.
+ *
+ * This must be called after every device disconnect (see [WUSB]
+ * section 6.2.11.2).
+ */
+void wusbhc_gtk_rekey(struct wusbhc *wusbhc)
+{
+       static const size_t key_size = sizeof(wusbhc->gtk.data);
+       int p;
+
+       wusbhc_generate_gtk(wusbhc);
+
+       for (p = 0; p < wusbhc->ports_max; p++) {
+               struct wusb_dev *wusb_dev;
+
+               wusb_dev = wusbhc->port[p].wusb_dev;
+               if (!wusb_dev || !wusb_dev->usb_dev | !wusb_dev->usb_dev->authenticated)
+                       continue;
+
+               usb_fill_control_urb(wusb_dev->set_gtk_urb, wusb_dev->usb_dev,
+                                    usb_sndctrlpipe(wusb_dev->usb_dev, 0),
+                                    (void *)wusb_dev->set_gtk_req,
+                                    &wusbhc->gtk.descr, wusbhc->gtk.descr.bLength,
+                                    wusbhc_set_gtk_callback, wusbhc);
+               if (usb_submit_urb(wusb_dev->set_gtk_urb, GFP_KERNEL) == 0)
+                       wusbhc->pending_set_gtks++;
+       }
+       if (wusbhc->pending_set_gtks == 0)
+               wusbhc->set_gtk(wusbhc, wusbhc->gtk_tkid, &wusbhc->gtk.descr.bKeyData, key_size);
+}
diff --git a/drivers/usb/wusbcore/wa-hc.c b/drivers/usb/wusbcore/wa-hc.c
new file mode 100644 (file)
index 0000000..9d04722
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Wire Adapter Host Controller Driver
+ * Common items to HWA and DWA based HCDs
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ */
+#include "wusbhc.h"
+#include "wa-hc.h"
+
+/**
+ * Assumes
+ *
+ * wa->usb_dev and wa->usb_iface initialized and refcounted,
+ * wa->wa_descr initialized.
+ */
+int wa_create(struct wahc *wa, struct usb_interface *iface)
+{
+       int result;
+       struct device *dev = &iface->dev;
+
+       result = wa_rpipes_create(wa);
+       if (result < 0)
+               goto error_rpipes_create;
+       /* Fill up Data Transfer EP pointers */
+       wa->dti_epd = &iface->cur_altsetting->endpoint[1].desc;
+       wa->dto_epd = &iface->cur_altsetting->endpoint[2].desc;
+       wa->xfer_result_size = le16_to_cpu(wa->dti_epd->wMaxPacketSize);
+       wa->xfer_result = kmalloc(wa->xfer_result_size, GFP_KERNEL);
+       if (wa->xfer_result == NULL)
+               goto error_xfer_result_alloc;
+       result = wa_nep_create(wa, iface);
+       if (result < 0) {
+               dev_err(dev, "WA-CDS: can't initialize notif endpoint: %d\n",
+                       result);
+               goto error_nep_create;
+       }
+       return 0;
+
+error_nep_create:
+       kfree(wa->xfer_result);
+error_xfer_result_alloc:
+       wa_rpipes_destroy(wa);
+error_rpipes_create:
+       return result;
+}
+EXPORT_SYMBOL_GPL(wa_create);
+
+
+void __wa_destroy(struct wahc *wa)
+{
+       if (wa->dti_urb) {
+               usb_kill_urb(wa->dti_urb);
+               usb_put_urb(wa->dti_urb);
+               usb_kill_urb(wa->buf_in_urb);
+               usb_put_urb(wa->buf_in_urb);
+       }
+       kfree(wa->xfer_result);
+       wa_nep_destroy(wa);
+       wa_rpipes_destroy(wa);
+}
+EXPORT_SYMBOL_GPL(__wa_destroy);
+
+/**
+ * wa_reset_all - reset the WA device
+ * @wa: the WA to be reset
+ *
+ * For HWAs the radio controller and all other PALs are also reset.
+ */
+void wa_reset_all(struct wahc *wa)
+{
+       /* FIXME: assuming HWA. */
+       wusbhc_reset_all(wa->wusb);
+}
+
+MODULE_AUTHOR("Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>");
+MODULE_DESCRIPTION("Wireless USB Wire Adapter core");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/wusbcore/wa-hc.h b/drivers/usb/wusbcore/wa-hc.h
new file mode 100644 (file)
index 0000000..586d350
--- /dev/null
@@ -0,0 +1,417 @@
+/*
+ * HWA Host Controller Driver
+ * Wire Adapter Control/Data Streaming Iface (WUSB1.0[8])
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * This driver implements a USB Host Controller (struct usb_hcd) for a
+ * Wireless USB Host Controller based on the Wireless USB 1.0
+ * Host-Wire-Adapter specification (in layman terms, a USB-dongle that
+ * implements a Wireless USB host).
+ *
+ * Check out the Design-overview.txt file in the source documentation
+ * for other details on the implementation.
+ *
+ * Main blocks:
+ *
+ *  driver     glue with the driver API, workqueue daemon
+ *
+ *  lc         RC instance life cycle management (create, destroy...)
+ *
+ *  hcd        glue with the USB API Host Controller Interface API.
+ *
+ *  nep        Notification EndPoint managent: collect notifications
+ *             and queue them with the workqueue daemon.
+ *
+ *             Handle notifications as coming from the NEP. Sends them
+ *             off others to their respective modules (eg: connect,
+ *             disconnect and reset go to devconnect).
+ *
+ *  rpipe      Remote Pipe management; rpipe is what we use to write
+ *             to an endpoint on a WUSB device that is connected to a
+ *             HWA RC.
+ *
+ *  xfer       Transfer managment -- this is all the code that gets a
+ *             buffer and pushes it to a device (or viceversa). *
+ *
+ * Some day a lot of this code will be shared between this driver and
+ * the drivers for DWA (xfer, rpipe).
+ *
+ * All starts at driver.c:hwahc_probe(), when one of this guys is
+ * connected. hwahc_disconnect() stops it.
+ *
+ * During operation, the main driver is devices connecting or
+ * disconnecting. They cause the HWA RC to send notifications into
+ * nep.c:hwahc_nep_cb() that will dispatch them to
+ * notif.c:wa_notif_dispatch(). From there they will fan to cause
+ * device connects, disconnects, etc.
+ *
+ * Note much of the activity is difficult to follow. For example a
+ * device connect goes to devconnect, which will cause the "fake" root
+ * hub port to show a connect and stop there. Then khubd will notice
+ * and call into the rh.c:hwahc_rc_port_reset() code to authenticate
+ * the device (and this might require user intervention) and enable
+ * the port.
+ *
+ * We also have a timer workqueue going from devconnect.c that
+ * schedules in hwahc_devconnect_create().
+ *
+ * The rest of the traffic is in the usual entry points of a USB HCD,
+ * which are hooked up in driver.c:hwahc_rc_driver, and defined in
+ * hcd.c.
+ */
+
+#ifndef __HWAHC_INTERNAL_H__
+#define __HWAHC_INTERNAL_H__
+
+#include <linux/completion.h>
+#include <linux/usb.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/uwb.h>
+#include <linux/usb/wusb.h>
+#include <linux/usb/wusb-wa.h>
+
+struct wusbhc;
+struct wahc;
+extern void wa_urb_enqueue_run(struct work_struct *ws);
+
+/**
+ * RPipe instance
+ *
+ * @descr's fields are kept in LE, as we need to send it back and
+ * forth.
+ *
+ * @wa is referenced when set
+ *
+ * @segs_available is the number of requests segments that still can
+ *                 be submitted to the controller without overloading
+ *                 it. It is initialized to descr->wRequests when
+ *                 aiming.
+ *
+ * A rpipe supports a max of descr->wRequests at the same time; before
+ * submitting seg_lock has to be taken. If segs_avail > 0, then we can
+ * submit; if not, we have to queue them.
+ */
+struct wa_rpipe {
+       struct kref refcnt;
+       struct usb_rpipe_descriptor descr;
+       struct usb_host_endpoint *ep;
+       struct wahc *wa;
+       spinlock_t seg_lock;
+       struct list_head seg_list;
+       atomic_t segs_available;
+       u8 buffer[1];   /* For reads/writes on USB */
+};
+
+
+/**
+ * Instance of a HWA Host Controller
+ *
+ * Except where a more specific lock/mutex applies or atomic, all
+ * fields protected by @mutex.
+ *
+ * @wa_descr  Can be accessed without locking because it is in
+ *            the same area where the device descriptors were
+ *            read, so it is guaranteed to exist umodified while
+ *            the device exists.
+ *
+ *            Endianess has been converted to CPU's.
+ *
+ * @nep_* can be accessed without locking as its processing is
+ *        serialized; we submit a NEP URB and it comes to
+ *        hwahc_nep_cb(), which won't issue another URB until it is
+ *        done processing it.
+ *
+ * @xfer_list:
+ *
+ *   List of active transfers to verify existence from a xfer id
+ *   gotten from the xfer result message. Can't use urb->list because
+ *   it goes by endpoint, and we don't know the endpoint at the time
+ *   when we get the xfer result message. We can't really rely on the
+ *   pointer (will have to change for 64 bits) as the xfer id is 32 bits.
+ *
+ * @xfer_delayed_list:   List of transfers that need to be started
+ *                       (with a workqueue, because they were
+ *                       submitted from an atomic context).
+ *
+ * FIXME: this needs to be layered up: a wusbhc layer (for sharing
+ *        comonalities with WHCI), a wa layer (for sharing
+ *        comonalities with DWA-RC).
+ */
+struct wahc {
+       struct usb_device *usb_dev;
+       struct usb_interface *usb_iface;
+
+       /* HC to deliver notifications */
+       union {
+               struct wusbhc *wusb;
+               struct dwahc *dwa;
+       };
+
+       const struct usb_endpoint_descriptor *dto_epd, *dti_epd;
+       const struct usb_wa_descriptor *wa_descr;
+
+       struct urb *nep_urb;            /* Notification EndPoint [lockless] */
+       struct edc nep_edc;
+       void *nep_buffer;
+       size_t nep_buffer_size;
+
+       atomic_t notifs_queued;
+
+       u16 rpipes;
+       unsigned long *rpipe_bm;        /* rpipe usage bitmap */
+       spinlock_t rpipe_bm_lock;       /* protect rpipe_bm */
+       struct mutex rpipe_mutex;       /* assigning resources to endpoints */
+
+       struct urb *dti_urb;            /* URB for reading xfer results */
+       struct urb *buf_in_urb;         /* URB for reading data in */
+       struct edc dti_edc;             /* DTI error density counter */
+       struct wa_xfer_result *xfer_result; /* real size = dti_ep maxpktsize */
+       size_t xfer_result_size;
+
+       s32 status;                     /* For reading status */
+
+       struct list_head xfer_list;
+       struct list_head xfer_delayed_list;
+       spinlock_t xfer_list_lock;
+       struct work_struct xfer_work;
+       atomic_t xfer_id_count;
+};
+
+
+extern int wa_create(struct wahc *wa, struct usb_interface *iface);
+extern void __wa_destroy(struct wahc *wa);
+void wa_reset_all(struct wahc *wa);
+
+
+/* Miscellaneous constants */
+enum {
+       /** Max number of EPROTO errors we tolerate on the NEP in a
+        * period of time */
+       HWAHC_EPROTO_MAX = 16,
+       /** Period of time for EPROTO errors (in jiffies) */
+       HWAHC_EPROTO_PERIOD = 4 * HZ,
+};
+
+
+/* Notification endpoint handling */
+extern int wa_nep_create(struct wahc *, struct usb_interface *);
+extern void wa_nep_destroy(struct wahc *);
+
+static inline int wa_nep_arm(struct wahc *wa, gfp_t gfp_mask)
+{
+       struct urb *urb = wa->nep_urb;
+       urb->transfer_buffer = wa->nep_buffer;
+       urb->transfer_buffer_length = wa->nep_buffer_size;
+       return usb_submit_urb(urb, gfp_mask);
+}
+
+static inline void wa_nep_disarm(struct wahc *wa)
+{
+       usb_kill_urb(wa->nep_urb);
+}
+
+
+/* RPipes */
+static inline void wa_rpipe_init(struct wahc *wa)
+{
+       spin_lock_init(&wa->rpipe_bm_lock);
+       mutex_init(&wa->rpipe_mutex);
+}
+
+static inline void wa_init(struct wahc *wa)
+{
+       edc_init(&wa->nep_edc);
+       atomic_set(&wa->notifs_queued, 0);
+       wa_rpipe_init(wa);
+       edc_init(&wa->dti_edc);
+       INIT_LIST_HEAD(&wa->xfer_list);
+       INIT_LIST_HEAD(&wa->xfer_delayed_list);
+       spin_lock_init(&wa->xfer_list_lock);
+       INIT_WORK(&wa->xfer_work, wa_urb_enqueue_run);
+       atomic_set(&wa->xfer_id_count, 1);
+}
+
+/**
+ * Destroy a pipe (when refcount drops to zero)
+ *
+ * Assumes it has been moved to the "QUIESCING" state.
+ */
+struct wa_xfer;
+extern void rpipe_destroy(struct kref *_rpipe);
+static inline
+void __rpipe_get(struct wa_rpipe *rpipe)
+{
+       kref_get(&rpipe->refcnt);
+}
+extern int rpipe_get_by_ep(struct wahc *, struct usb_host_endpoint *,
+                          struct urb *, gfp_t);
+static inline void rpipe_put(struct wa_rpipe *rpipe)
+{
+       kref_put(&rpipe->refcnt, rpipe_destroy);
+
+}
+extern void rpipe_ep_disable(struct wahc *, struct usb_host_endpoint *);
+extern int wa_rpipes_create(struct wahc *);
+extern void wa_rpipes_destroy(struct wahc *);
+static inline void rpipe_avail_dec(struct wa_rpipe *rpipe)
+{
+       atomic_dec(&rpipe->segs_available);
+}
+
+/**
+ * Returns true if the rpipe is ready to submit more segments.
+ */
+static inline int rpipe_avail_inc(struct wa_rpipe *rpipe)
+{
+       return atomic_inc_return(&rpipe->segs_available) > 0
+               && !list_empty(&rpipe->seg_list);
+}
+
+
+/* Transferring data */
+extern int wa_urb_enqueue(struct wahc *, struct usb_host_endpoint *,
+                         struct urb *, gfp_t);
+extern int wa_urb_dequeue(struct wahc *, struct urb *);
+extern void wa_handle_notif_xfer(struct wahc *, struct wa_notif_hdr *);
+
+
+/* Misc
+ *
+ * FIXME: Refcounting for the actual @hwahc object is not correct; I
+ *        mean, this should be refcounting on the HCD underneath, but
+ *        it is not. In any case, the semantics for HCD refcounting
+ *        are *weird*...on refcount reaching zero it just frees
+ *        it...no RC specific function is called...unless I miss
+ *        something.
+ *
+ * FIXME: has to go away in favour of an 'struct' hcd based sollution
+ */
+static inline struct wahc *wa_get(struct wahc *wa)
+{
+       usb_get_intf(wa->usb_iface);
+       return wa;
+}
+
+static inline void wa_put(struct wahc *wa)
+{
+       usb_put_intf(wa->usb_iface);
+}
+
+
+static inline int __wa_feature(struct wahc *wa, unsigned op, u16 feature)
+{
+       return usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
+                       op ? USB_REQ_SET_FEATURE : USB_REQ_CLEAR_FEATURE,
+                       USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+                       feature,
+                       wa->usb_iface->cur_altsetting->desc.bInterfaceNumber,
+                       NULL, 0, 1000 /* FIXME: arbitrary */);
+}
+
+
+static inline int __wa_set_feature(struct wahc *wa, u16 feature)
+{
+       return  __wa_feature(wa, 1, feature);
+}
+
+
+static inline int __wa_clear_feature(struct wahc *wa, u16 feature)
+{
+       return __wa_feature(wa, 0, feature);
+}
+
+
+/**
+ * Return the status of a Wire Adapter
+ *
+ * @wa:                Wire Adapter instance
+ * @returns     < 0 errno code on error, or status bitmap as described
+ *              in WUSB1.0[8.3.1.6].
+ *
+ * NOTE: need malloc, some arches don't take USB from the stack
+ */
+static inline
+s32 __wa_get_status(struct wahc *wa)
+{
+       s32 result;
+       result = usb_control_msg(
+               wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0),
+               USB_REQ_GET_STATUS,
+               USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+               0, wa->usb_iface->cur_altsetting->desc.bInterfaceNumber,
+               &wa->status, sizeof(wa->status),
+               1000 /* FIXME: arbitrary */);
+       if (result >= 0)
+               result = wa->status;
+       return result;
+}
+
+
+/**
+ * Waits until the Wire Adapter's status matches @mask/@value
+ *
+ * @wa:                Wire Adapter instance.
+ * @returns     < 0 errno code on error, otherwise status.
+ *
+ * Loop until the WAs status matches the mask and value (status & mask
+ * == value). Timeout if it doesn't happen.
+ *
+ * FIXME: is there an official specification on how long status
+ *        changes can take?
+ */
+static inline s32 __wa_wait_status(struct wahc *wa, u32 mask, u32 value)
+{
+       s32 result;
+       unsigned loops = 10;
+       do {
+               msleep(50);
+               result = __wa_get_status(wa);
+               if ((result & mask) == value)
+                       break;
+               if (loops-- == 0) {
+                       result = -ETIMEDOUT;
+                       break;
+               }
+       } while (result >= 0);
+       return result;
+}
+
+
+/** Command @hwahc to stop, @returns 0 if ok, < 0 errno code on error */
+static inline int __wa_stop(struct wahc *wa)
+{
+       int result;
+       struct device *dev = &wa->usb_iface->dev;
+
+       result = __wa_clear_feature(wa, WA_ENABLE);
+       if (result < 0 && result != -ENODEV) {
+               dev_err(dev, "error commanding HC to stop: %d\n", result);
+               goto out;
+       }
+       result = __wa_wait_status(wa, WA_ENABLE, 0);
+       if (result < 0 && result != -ENODEV)
+               dev_err(dev, "error waiting for HC to stop: %d\n", result);
+out:
+       return 0;
+}
+
+
+#endif /* #ifndef __HWAHC_INTERNAL_H__ */
diff --git a/drivers/usb/wusbcore/wa-nep.c b/drivers/usb/wusbcore/wa-nep.c
new file mode 100644 (file)
index 0000000..3f54299
--- /dev/null
@@ -0,0 +1,310 @@
+/*
+ * WUSB Wire Adapter: Control/Data Streaming Interface (WUSB[8])
+ * Notification EndPoint support
+ *
+ * Copyright (C) 2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * This part takes care of getting the notification from the hw
+ * only and dispatching through wusbwad into
+ * wa_notif_dispatch. Handling is done there.
+ *
+ * WA notifications are limited in size; most of them are three or
+ * four bytes long, and the longest is the HWA Device Notification,
+ * which would not exceed 38 bytes (DNs are limited in payload to 32
+ * bytes plus 3 bytes header (WUSB1.0[7.6p2]), plus 3 bytes HWA
+ * header (WUSB1.0[8.5.4.2]).
+ *
+ * It is not clear if more than one Device Notification can be packed
+ * in a HWA Notification, I assume no because of the wording in
+ * WUSB1.0[8.5.4.2]. In any case, the bigger any notification could
+ * get is 256 bytes (as the bLength field is a byte).
+ *
+ * So what we do is we have this buffer and read into it; when a
+ * notification arrives we schedule work to a specific, single thread
+ * workqueue (so notifications are serialized) and copy the
+ * notification data. After scheduling the work, we rearm the read from
+ * the notification endpoint.
+ *
+ * Entry points here are:
+ *
+ * wa_nep_[create|destroy]()   To initialize/release this subsystem
+ *
+ * wa_nep_cb()                 Callback for the notification
+ *                                endpoint; when data is ready, this
+ *                                does the dispatching.
+ */
+#include <linux/workqueue.h>
+#include <linux/ctype.h>
+#include <linux/uwb/debug.h>
+#include "wa-hc.h"
+#include "wusbhc.h"
+
+/* Structure for queueing notifications to the workqueue */
+struct wa_notif_work {
+       struct work_struct work;
+       struct wahc *wa;
+       size_t size;
+       u8 data[];
+};
+
+/*
+ * Process incoming notifications from the WA's Notification EndPoint
+ * [the wuswad daemon, basically]
+ *
+ * @_nw:       Pointer to a descriptor which has the pointer to the
+ *             @wa, the size of the buffer and the work queue
+ *             structure (so we can free all when done).
+ * @returns     0 if ok, < 0 errno code on error.
+ *
+ * All notifications follow the same format; they need to start with a
+ * 'struct wa_notif_hdr' header, so it is easy to parse through
+ * them. We just break the buffer in individual notifications (the
+ * standard doesn't say if it can be done or is forbidden, so we are
+ * cautious) and dispatch each.
+ *
+ * So the handling layers are is:
+ *
+ *   WA specific notification (from NEP)
+ *      Device Notification Received -> wa_handle_notif_dn()
+ *        WUSB Device notification generic handling
+ *      BPST Adjustment -> wa_handle_notif_bpst_adj()
+ *      ... -> ...
+ *
+ * @wa has to be referenced
+ */
+static void wa_notif_dispatch(struct work_struct *ws)
+{
+       void *itr;
+       u8 missing = 0;
+       struct wa_notif_work *nw = container_of(ws, struct wa_notif_work, work);
+       struct wahc *wa = nw->wa;
+       struct wa_notif_hdr *notif_hdr;
+       size_t size;
+
+       struct device *dev = &wa->usb_iface->dev;
+
+#if 0
+       /* FIXME: need to check for this??? */
+       if (usb_hcd->state == HC_STATE_QUIESCING)       /* Going down? */
+               goto out;                               /* screw it */
+#endif
+       atomic_dec(&wa->notifs_queued);         /* Throttling ctl */
+       dev = &wa->usb_iface->dev;
+       size = nw->size;
+       itr = nw->data;
+
+       while (size) {
+               if (size < sizeof(*notif_hdr)) {
+                       missing = sizeof(*notif_hdr) - size;
+                       goto exhausted_buffer;
+               }
+               notif_hdr = itr;
+               if (size < notif_hdr->bLength)
+                       goto exhausted_buffer;
+               itr += notif_hdr->bLength;
+               size -= notif_hdr->bLength;
+               /* Dispatch the notification [don't use itr or size!] */
+               switch (notif_hdr->bNotifyType) {
+               case HWA_NOTIF_DN: {
+                       struct hwa_notif_dn *hwa_dn;
+                       hwa_dn = container_of(notif_hdr, struct hwa_notif_dn,
+                                             hdr);
+                       wusbhc_handle_dn(wa->wusb, hwa_dn->bSourceDeviceAddr,
+                                        hwa_dn->dndata,
+                                        notif_hdr->bLength - sizeof(*hwa_dn));
+                       break;
+               }
+               case WA_NOTIF_TRANSFER:
+                       wa_handle_notif_xfer(wa, notif_hdr);
+                       break;
+               case DWA_NOTIF_RWAKE:
+               case DWA_NOTIF_PORTSTATUS:
+               case HWA_NOTIF_BPST_ADJ:
+                       /* FIXME: unimplemented WA NOTIFs */
+                       /* fallthru */
+               default:
+                       if (printk_ratelimit()) {
+                               dev_err(dev, "HWA: unknown notification 0x%x, "
+                                       "%zu bytes; discarding\n",
+                                       notif_hdr->bNotifyType,
+                                       (size_t)notif_hdr->bLength);
+                               dump_bytes(dev, notif_hdr, 16);
+                       }
+                       break;
+               }
+       }
+out:
+       wa_put(wa);
+       kfree(nw);
+       return;
+
+       /* THIS SHOULD NOT HAPPEN
+        *
+        * Buffer exahusted with partial data remaining; just warn and
+        * discard the data, as this should not happen.
+        */
+exhausted_buffer:
+       if (!printk_ratelimit())
+               goto out;
+       dev_warn(dev, "HWA: device sent short notification, "
+                "%d bytes missing; discarding %d bytes.\n",
+                missing, (int)size);
+       dump_bytes(dev, itr, size);
+       goto out;
+}
+
+/*
+ * Deliver incoming WA notifications to the wusbwa workqueue
+ *
+ * @wa:        Pointer the Wire Adapter Controller Data Streaming
+ *              instance (part of an 'struct usb_hcd').
+ * @size:       Size of the received buffer
+ * @returns     0 if ok, < 0 errno code on error.
+ *
+ * The input buffer is @wa->nep_buffer, with @size bytes
+ * (guaranteed to fit in the allocated space,
+ * @wa->nep_buffer_size).
+ */
+static int wa_nep_queue(struct wahc *wa, size_t size)
+{
+       int result = 0;
+       struct device *dev = &wa->usb_iface->dev;
+       struct wa_notif_work *nw;
+
+       /* dev_fnstart(dev, "(wa %p, size %zu)\n", wa, size); */
+       BUG_ON(size > wa->nep_buffer_size);
+       if (size == 0)
+               goto out;
+       if (atomic_read(&wa->notifs_queued) > 200) {
+               if (printk_ratelimit())
+                       dev_err(dev, "Too many notifications queued, "
+                               "throttling back\n");
+               goto out;
+       }
+       nw = kzalloc(sizeof(*nw) + size, GFP_ATOMIC);
+       if (nw == NULL) {
+               if (printk_ratelimit())
+                       dev_err(dev, "No memory to queue notification\n");
+               goto out;
+       }
+       INIT_WORK(&nw->work, wa_notif_dispatch);
+       nw->wa = wa_get(wa);
+       nw->size = size;
+       memcpy(nw->data, wa->nep_buffer, size);
+       atomic_inc(&wa->notifs_queued);         /* Throttling ctl */
+       queue_work(wusbd, &nw->work);
+out:
+       /* dev_fnend(dev, "(wa %p, size %zu) = result\n", wa, size, result); */
+       return result;
+}
+
+/*
+ * Callback for the notification event endpoint
+ *
+ * Check's that everything is fine and then passes the data to be
+ * queued to the workqueue.
+ */
+static void wa_nep_cb(struct urb *urb)
+{
+       int result;
+       struct wahc *wa = urb->context;
+       struct device *dev = &wa->usb_iface->dev;
+
+       switch (result = urb->status) {
+       case 0:
+               result = wa_nep_queue(wa, urb->actual_length);
+               if (result < 0)
+                       dev_err(dev, "NEP: unable to process notification(s): "
+                               "%d\n", result);
+               break;
+       case -ECONNRESET:       /* Not an error, but a controlled situation; */
+       case -ENOENT:           /* (we killed the URB)...so, no broadcast */
+       case -ESHUTDOWN:
+               dev_dbg(dev, "NEP: going down %d\n", urb->status);
+               goto out;
+       default:        /* On general errors, we retry unless it gets ugly */
+               if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS,
+                           EDC_ERROR_TIMEFRAME)) {
+                       dev_err(dev, "NEP: URB max acceptable errors "
+                               "exceeded, resetting device\n");
+                       wa_reset_all(wa);
+                       goto out;
+               }
+               dev_err(dev, "NEP: URB error %d\n", urb->status);
+       }
+       result = wa_nep_arm(wa, GFP_ATOMIC);
+       if (result < 0) {
+               dev_err(dev, "NEP: cannot submit URB: %d\n", result);
+               wa_reset_all(wa);
+       }
+out:
+       return;
+}
+
+/*
+ * Initialize @wa's notification and event's endpoint stuff
+ *
+ * This includes the allocating the read buffer, the context ID
+ * allocation bitmap, the URB and submitting the URB.
+ */
+int wa_nep_create(struct wahc *wa, struct usb_interface *iface)
+{
+       int result;
+       struct usb_endpoint_descriptor *epd;
+       struct usb_device *usb_dev = interface_to_usbdev(iface);
+       struct device *dev = &iface->dev;
+
+       edc_init(&wa->nep_edc);
+       epd = &iface->cur_altsetting->endpoint[0].desc;
+       wa->nep_buffer_size = 1024;
+       wa->nep_buffer = kmalloc(wa->nep_buffer_size, GFP_KERNEL);
+       if (wa->nep_buffer == NULL) {
+               dev_err(dev, "Unable to allocate notification's read buffer\n");
+               goto error_nep_buffer;
+       }
+       wa->nep_urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (wa->nep_urb == NULL) {
+               dev_err(dev, "Unable to allocate notification URB\n");
+               goto error_urb_alloc;
+       }
+       usb_fill_int_urb(wa->nep_urb, usb_dev,
+                        usb_rcvintpipe(usb_dev, epd->bEndpointAddress),
+                        wa->nep_buffer, wa->nep_buffer_size,
+                        wa_nep_cb, wa, epd->bInterval);
+       result = wa_nep_arm(wa, GFP_KERNEL);
+       if (result < 0) {
+               dev_err(dev, "Cannot submit notification URB: %d\n", result);
+               goto error_nep_arm;
+       }
+       return 0;
+
+error_nep_arm:
+       usb_free_urb(wa->nep_urb);
+error_urb_alloc:
+       kfree(wa->nep_buffer);
+error_nep_buffer:
+       return -ENOMEM;
+}
+
+void wa_nep_destroy(struct wahc *wa)
+{
+       wa_nep_disarm(wa);
+       usb_free_urb(wa->nep_urb);
+       kfree(wa->nep_buffer);
+}
diff --git a/drivers/usb/wusbcore/wa-rpipe.c b/drivers/usb/wusbcore/wa-rpipe.c
new file mode 100644 (file)
index 0000000..f18e4aa
--- /dev/null
@@ -0,0 +1,562 @@
+/*
+ * WUSB Wire Adapter
+ * rpipe management
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ *
+ * RPIPE
+ *
+ *   Targetted at different downstream endpoints
+ *
+ *   Descriptor: use to config the remote pipe.
+ *
+ *   The number of blocks could be dynamic (wBlocks in descriptor is
+ *   0)--need to schedule them then.
+ *
+ * Each bit in wa->rpipe_bm represents if an rpipe is being used or
+ * not. Rpipes are represented with a 'struct wa_rpipe' that is
+ * attached to the hcpriv member of a 'struct usb_host_endpoint'.
+ *
+ * When you need to xfer data to an endpoint, you get an rpipe for it
+ * with wa_ep_rpipe_get(), which gives you a reference to the rpipe
+ * and keeps a single one (the first one) with the endpoint. When you
+ * are done transferring, you drop that reference. At the end the
+ * rpipe is always allocated and bound to the endpoint. There it might
+ * be recycled when not used.
+ *
+ * Addresses:
+ *
+ *  We use a 1:1 mapping mechanism between port address (0 based
+ *  index, actually) and the address. The USB stack knows about this.
+ *
+ *  USB Stack port number    4 (1 based)
+ *  WUSB code port index     3 (0 based)
+ *  USB Addresss             5 (2 based -- 0 is for default, 1 for root hub)
+ *
+ *  Now, because we don't use the concept as default address exactly
+ *  like the (wired) USB code does, we need to kind of skip it. So we
+ *  never take addresses from the urb->pipe, but from the
+ *  urb->dev->devnum, to make sure that we always have the right
+ *  destination address.
+ */
+#include <linux/init.h>
+#include <asm/atomic.h>
+#include <linux/bitmap.h>
+#include "wusbhc.h"
+#include "wa-hc.h"
+
+#define D_LOCAL 0
+#include <linux/uwb/debug.h>
+
+
+static int __rpipe_get_descr(struct wahc *wa,
+                            struct usb_rpipe_descriptor *descr, u16 index)
+{
+       ssize_t result;
+       struct device *dev = &wa->usb_iface->dev;
+
+       /* Get the RPIPE descriptor -- we cannot use the usb_get_descriptor()
+        * function because the arguments are different.
+        */
+       d_printf(1, dev, "rpipe %u: get descr\n", index);
+       result = usb_control_msg(
+               wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0),
+               USB_REQ_GET_DESCRIPTOR,
+               USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_RPIPE,
+               USB_DT_RPIPE<<8, index, descr, sizeof(*descr),
+               1000 /* FIXME: arbitrary */);
+       if (result < 0) {
+               dev_err(dev, "rpipe %u: get descriptor failed: %d\n",
+                       index, (int)result);
+               goto error;
+       }
+       if (result < sizeof(*descr)) {
+               dev_err(dev, "rpipe %u: got short descriptor "
+                       "(%zd vs %zd bytes needed)\n",
+                       index, result, sizeof(*descr));
+               result = -EINVAL;
+               goto error;
+       }
+       result = 0;
+
+error:
+       return result;
+}
+
+/*
+ *
+ * The descriptor is assumed to be properly initialized (ie: you got
+ * it through __rpipe_get_descr()).
+ */
+static int __rpipe_set_descr(struct wahc *wa,
+                            struct usb_rpipe_descriptor *descr, u16 index)
+{
+       ssize_t result;
+       struct device *dev = &wa->usb_iface->dev;
+
+       /* we cannot use the usb_get_descriptor() function because the
+        * arguments are different.
+        */
+       d_printf(1, dev, "rpipe %u: set descr\n", index);
+       result = usb_control_msg(
+               wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
+               USB_REQ_SET_DESCRIPTOR,
+               USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE,
+               USB_DT_RPIPE<<8, index, descr, sizeof(*descr),
+               HZ / 10);
+       if (result < 0) {
+               dev_err(dev, "rpipe %u: set descriptor failed: %d\n",
+                       index, (int)result);
+               goto error;
+       }
+       if (result < sizeof(*descr)) {
+               dev_err(dev, "rpipe %u: sent short descriptor "
+                       "(%zd vs %zd bytes required)\n",
+                       index, result, sizeof(*descr));
+               result = -EINVAL;
+               goto error;
+       }
+       result = 0;
+
+error:
+       return result;
+
+}
+
+static void rpipe_init(struct wa_rpipe *rpipe)
+{
+       kref_init(&rpipe->refcnt);
+       spin_lock_init(&rpipe->seg_lock);
+       INIT_LIST_HEAD(&rpipe->seg_list);
+}
+
+static unsigned rpipe_get_idx(struct wahc *wa, unsigned rpipe_idx)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&wa->rpipe_bm_lock, flags);
+       rpipe_idx = find_next_zero_bit(wa->rpipe_bm, wa->rpipes, rpipe_idx);
+       if (rpipe_idx < wa->rpipes)
+               set_bit(rpipe_idx, wa->rpipe_bm);
+       spin_unlock_irqrestore(&wa->rpipe_bm_lock, flags);
+
+       return rpipe_idx;
+}
+
+static void rpipe_put_idx(struct wahc *wa, unsigned rpipe_idx)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&wa->rpipe_bm_lock, flags);
+       clear_bit(rpipe_idx, wa->rpipe_bm);
+       spin_unlock_irqrestore(&wa->rpipe_bm_lock, flags);
+}
+
+void rpipe_destroy(struct kref *_rpipe)
+{
+       struct wa_rpipe *rpipe = container_of(_rpipe, struct wa_rpipe, refcnt);
+       u8 index = le16_to_cpu(rpipe->descr.wRPipeIndex);
+       d_fnstart(1, NULL, "(rpipe %p %u)\n", rpipe, index);
+       if (rpipe->ep)
+               rpipe->ep->hcpriv = NULL;
+       rpipe_put_idx(rpipe->wa, index);
+       wa_put(rpipe->wa);
+       kfree(rpipe);
+       d_fnend(1, NULL, "(rpipe %p %u)\n", rpipe, index);
+}
+EXPORT_SYMBOL_GPL(rpipe_destroy);
+
+/*
+ * Locate an idle rpipe, create an structure for it and return it
+ *
+ * @wa           is referenced and unlocked
+ * @crs   enum rpipe_attr, required endpoint characteristics
+ *
+ * The rpipe can be used only sequentially (not in parallel).
+ *
+ * The rpipe is moved into the "ready" state.
+ */
+static int rpipe_get_idle(struct wa_rpipe **prpipe, struct wahc *wa, u8 crs,
+                         gfp_t gfp)
+{
+       int result;
+       unsigned rpipe_idx;
+       struct wa_rpipe *rpipe;
+       struct device *dev = &wa->usb_iface->dev;
+
+       d_fnstart(3, dev, "(wa %p crs 0x%02x)\n", wa, crs);
+       rpipe = kzalloc(sizeof(*rpipe), gfp);
+       if (rpipe == NULL)
+               return -ENOMEM;
+       rpipe_init(rpipe);
+
+       /* Look for an idle pipe */
+       for (rpipe_idx = 0; rpipe_idx < wa->rpipes; rpipe_idx++) {
+               rpipe_idx = rpipe_get_idx(wa, rpipe_idx);
+               if (rpipe_idx >= wa->rpipes)    /* no more pipes :( */
+                       break;
+               result =  __rpipe_get_descr(wa, &rpipe->descr, rpipe_idx);
+               if (result < 0)
+                       dev_err(dev, "Can't get descriptor for rpipe %u: %d\n",
+                               rpipe_idx, result);
+               else if ((rpipe->descr.bmCharacteristics & crs) != 0)
+                       goto found;
+               rpipe_put_idx(wa, rpipe_idx);
+       }
+       *prpipe = NULL;
+       kfree(rpipe);
+       d_fnend(3, dev, "(wa %p crs 0x%02x) = -ENXIO\n", wa, crs);
+       return -ENXIO;
+
+found:
+       set_bit(rpipe_idx, wa->rpipe_bm);
+       rpipe->wa = wa_get(wa);
+       *prpipe = rpipe;
+       d_fnstart(3, dev, "(wa %p crs 0x%02x) = 0\n", wa, crs);
+       return 0;
+}
+
+static int __rpipe_reset(struct wahc *wa, unsigned index)
+{
+       int result;
+       struct device *dev = &wa->usb_iface->dev;
+
+       d_printf(1, dev, "rpipe %u: reset\n", index);
+       result = usb_control_msg(
+               wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
+               USB_REQ_RPIPE_RESET,
+               USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE,
+               0, index, NULL, 0, 1000 /* FIXME: arbitrary */);
+       if (result < 0)
+               dev_err(dev, "rpipe %u: reset failed: %d\n",
+                       index, result);
+       return result;
+}
+
+/*
+ * Fake companion descriptor for ep0
+ *
+ * See WUSB1.0[7.4.4], most of this is zero for bulk/int/ctl
+ */
+static struct usb_wireless_ep_comp_descriptor epc0 = {
+       .bLength = sizeof(epc0),
+       .bDescriptorType = USB_DT_WIRELESS_ENDPOINT_COMP,
+/*     .bMaxBurst = 1, */
+       .bMaxSequence = 31,
+};
+
+/*
+ * Look for EP companion descriptor
+ *
+ * Get there, look for Inara in the endpoint's extra descriptors
+ */
+static struct usb_wireless_ep_comp_descriptor *rpipe_epc_find(
+               struct device *dev, struct usb_host_endpoint *ep)
+{
+       void *itr;
+       size_t itr_size;
+       struct usb_descriptor_header *hdr;
+       struct usb_wireless_ep_comp_descriptor *epcd;
+
+       d_fnstart(3, dev, "(ep %p)\n", ep);
+       if (ep->desc.bEndpointAddress == 0) {
+               epcd = &epc0;
+               goto out;
+       }
+       itr = ep->extra;
+       itr_size = ep->extralen;
+       epcd = NULL;
+       while (itr_size > 0) {
+               if (itr_size < sizeof(*hdr)) {
+                       dev_err(dev, "HW Bug? ep 0x%02x: extra descriptors "
+                               "at offset %zu: only %zu bytes left\n",
+                               ep->desc.bEndpointAddress,
+                               itr - (void *) ep->extra, itr_size);
+                       break;
+               }
+               hdr = itr;
+               if (hdr->bDescriptorType == USB_DT_WIRELESS_ENDPOINT_COMP) {
+                       epcd = itr;
+                       break;
+               }
+               if (hdr->bLength > itr_size) {
+                       dev_err(dev, "HW Bug? ep 0x%02x: extra descriptor "
+                               "at offset %zu (type 0x%02x) "
+                               "length %d but only %zu bytes left\n",
+                               ep->desc.bEndpointAddress,
+                               itr - (void *) ep->extra, hdr->bDescriptorType,
+                               hdr->bLength, itr_size);
+                       break;
+               }
+               itr += hdr->bLength;
+               itr_size -= hdr->bDescriptorType;
+       }
+out:
+       d_fnend(3, dev, "(ep %p) = %p\n", ep, epcd);
+       return epcd;
+}
+
+/*
+ * Aim an rpipe to its device & endpoint destination
+ *
+ * Make sure we change the address to unauthenticathed if the device
+ * is WUSB and it is not authenticated.
+ */
+static int rpipe_aim(struct wa_rpipe *rpipe, struct wahc *wa,
+                    struct usb_host_endpoint *ep, struct urb *urb, gfp_t gfp)
+{
+       int result = -ENOMSG;   /* better code for lack of companion? */
+       struct device *dev = &wa->usb_iface->dev;
+       struct usb_device *usb_dev = urb->dev;
+       struct usb_wireless_ep_comp_descriptor *epcd;
+       u8 unauth;
+
+       d_fnstart(3, dev, "(rpipe %p wa %p ep %p, urb %p)\n",
+                   rpipe, wa, ep, urb);
+       epcd = rpipe_epc_find(dev, ep);
+       if (epcd == NULL) {
+               dev_err(dev, "ep 0x%02x: can't find companion descriptor\n",
+                       ep->desc.bEndpointAddress);
+               goto error;
+       }
+       unauth = usb_dev->wusb && !usb_dev->authenticated ? 0x80 : 0;
+       __rpipe_reset(wa, le16_to_cpu(rpipe->descr.wRPipeIndex));
+       atomic_set(&rpipe->segs_available, le16_to_cpu(rpipe->descr.wRequests));
+       /* FIXME: block allocation system; request with queuing and timeout */
+       /* FIXME: compute so seg_size > ep->maxpktsize */
+       rpipe->descr.wBlocks = cpu_to_le16(16);         /* given */
+       /* ep0 maxpktsize is 0x200 (WUSB1.0[4.8.1]) */
+       rpipe->descr.wMaxPacketSize = cpu_to_le16(ep->desc.wMaxPacketSize);
+       rpipe->descr.bHSHubAddress = 0;                 /* reserved: zero */
+       rpipe->descr.bHSHubPort = wusb_port_no_to_idx(urb->dev->portnum);
+       /* FIXME: use maximum speed as supported or recommended by device */
+       rpipe->descr.bSpeed = usb_pipeendpoint(urb->pipe) == 0 ?
+               UWB_PHY_RATE_53 : UWB_PHY_RATE_200;
+       d_printf(2, dev, "addr %u (0x%02x) rpipe #%u ep# %u speed %d\n",
+                urb->dev->devnum, urb->dev->devnum | unauth,
+                le16_to_cpu(rpipe->descr.wRPipeIndex),
+                usb_pipeendpoint(urb->pipe), rpipe->descr.bSpeed);
+       /* see security.c:wusb_update_address() */
+       if (unlikely(urb->dev->devnum == 0x80))
+               rpipe->descr.bDeviceAddress = 0;
+       else
+               rpipe->descr.bDeviceAddress = urb->dev->devnum | unauth;
+       rpipe->descr.bEndpointAddress = ep->desc.bEndpointAddress;
+       /* FIXME: bDataSequence */
+       rpipe->descr.bDataSequence = 0;
+       /* FIXME: dwCurrentWindow */
+       rpipe->descr.dwCurrentWindow = cpu_to_le32(1);
+       /* FIXME: bMaxDataSequence */
+       rpipe->descr.bMaxDataSequence = epcd->bMaxSequence - 1;
+       rpipe->descr.bInterval = ep->desc.bInterval;
+       /* FIXME: bOverTheAirInterval */
+       rpipe->descr.bOverTheAirInterval = 0;   /* 0 if not isoc */
+       /* FIXME: xmit power & preamble blah blah */
+       rpipe->descr.bmAttribute = ep->desc.bmAttributes & 0x03;
+       /* rpipe->descr.bmCharacteristics RO */
+       /* FIXME: bmRetryOptions */
+       rpipe->descr.bmRetryOptions = 15;
+       /* FIXME: use for assessing link quality? */
+       rpipe->descr.wNumTransactionErrors = 0;
+       result = __rpipe_set_descr(wa, &rpipe->descr,
+                                  le16_to_cpu(rpipe->descr.wRPipeIndex));
+       if (result < 0) {
+               dev_err(dev, "Cannot aim rpipe: %d\n", result);
+               goto error;
+       }
+       result = 0;
+error:
+       d_fnend(3, dev, "(rpipe %p wa %p ep %p urb %p) = %d\n",
+                 rpipe, wa, ep, urb, result);
+       return result;
+}
+
+/*
+ * Check an aimed rpipe to make sure it points to where we want
+ *
+ * We use bit 19 of the Linux USB pipe bitmap for unauth vs auth
+ * space; when it is like that, we or 0x80 to make an unauth address.
+ */
+static int rpipe_check_aim(const struct wa_rpipe *rpipe, const struct wahc *wa,
+                          const struct usb_host_endpoint *ep,
+                          const struct urb *urb, gfp_t gfp)
+{
+       int result = 0;         /* better code for lack of companion? */
+       struct device *dev = &wa->usb_iface->dev;
+       struct usb_device *usb_dev = urb->dev;
+       u8 unauth = (usb_dev->wusb && !usb_dev->authenticated) ? 0x80 : 0;
+       u8 portnum = wusb_port_no_to_idx(urb->dev->portnum);
+
+       d_fnstart(3, dev, "(rpipe %p wa %p ep %p, urb %p)\n",
+                   rpipe, wa, ep, urb);
+#define AIM_CHECK(rdf, val, text)                                      \
+       do {                                                            \
+               if (rpipe->descr.rdf != (val)) {                        \
+                       dev_err(dev,                                    \
+                               "rpipe aim discrepancy: " #rdf " " text "\n", \
+                               rpipe->descr.rdf, (val));               \
+                       result = -EINVAL;                               \
+                       WARN_ON(1);                                     \
+               }                                                       \
+       } while (0)
+       AIM_CHECK(wMaxPacketSize, cpu_to_le16(ep->desc.wMaxPacketSize),
+                 "(%u vs %u)");
+       AIM_CHECK(bHSHubPort, portnum, "(%u vs %u)");
+       AIM_CHECK(bSpeed, usb_pipeendpoint(urb->pipe) == 0 ?
+                       UWB_PHY_RATE_53 : UWB_PHY_RATE_200,
+                 "(%u vs %u)");
+       AIM_CHECK(bDeviceAddress, urb->dev->devnum | unauth, "(%u vs %u)");
+       AIM_CHECK(bEndpointAddress, ep->desc.bEndpointAddress, "(%u vs %u)");
+       AIM_CHECK(bInterval, ep->desc.bInterval, "(%u vs %u)");
+       AIM_CHECK(bmAttribute, ep->desc.bmAttributes & 0x03, "(%u vs %u)");
+#undef AIM_CHECK
+       return result;
+}
+
+#ifndef CONFIG_BUG
+#define CONFIG_BUG 0
+#endif
+
+/*
+ * Make sure there is an rpipe allocated for an endpoint
+ *
+ * If already allocated, we just refcount it; if not, we get an
+ * idle one, aim it to the right location and take it.
+ *
+ * Attaches to ep->hcpriv and rpipe->ep to ep.
+ */
+int rpipe_get_by_ep(struct wahc *wa, struct usb_host_endpoint *ep,
+                   struct urb *urb, gfp_t gfp)
+{
+       int result = 0;
+       struct device *dev = &wa->usb_iface->dev;
+       struct wa_rpipe *rpipe;
+       u8 eptype;
+
+       d_fnstart(3, dev, "(wa %p ep %p urb %p gfp 0x%08x)\n", wa, ep, urb,
+                 gfp);
+       mutex_lock(&wa->rpipe_mutex);
+       rpipe = ep->hcpriv;
+       if (rpipe != NULL) {
+               if (CONFIG_BUG == 1) {
+                       result = rpipe_check_aim(rpipe, wa, ep, urb, gfp);
+                       if (result < 0)
+                               goto error;
+               }
+               __rpipe_get(rpipe);
+               d_printf(2, dev, "ep 0x%02x: reusing rpipe %u\n",
+                        ep->desc.bEndpointAddress,
+                        le16_to_cpu(rpipe->descr.wRPipeIndex));
+       } else {
+               /* hmm, assign idle rpipe, aim it */
+               result = -ENOBUFS;
+               eptype = ep->desc.bmAttributes & 0x03;
+               result = rpipe_get_idle(&rpipe, wa, 1 << eptype, gfp);
+               if (result < 0)
+                       goto error;
+               result = rpipe_aim(rpipe, wa, ep, urb, gfp);
+               if (result < 0) {
+                       rpipe_put(rpipe);
+                       goto error;
+               }
+               ep->hcpriv = rpipe;
+               rpipe->ep = ep;
+               __rpipe_get(rpipe);     /* for caching into ep->hcpriv */
+               d_printf(2, dev, "ep 0x%02x: using rpipe %u\n",
+                        ep->desc.bEndpointAddress,
+                        le16_to_cpu(rpipe->descr.wRPipeIndex));
+       }
+       d_dump(4, dev, &rpipe->descr, sizeof(rpipe->descr));
+error:
+       mutex_unlock(&wa->rpipe_mutex);
+       d_fnend(3, dev, "(wa %p ep %p urb %p gfp 0x%08x)\n", wa, ep, urb, gfp);
+       return result;
+}
+
+/*
+ * Allocate the bitmap for each rpipe.
+ */
+int wa_rpipes_create(struct wahc *wa)
+{
+       wa->rpipes = wa->wa_descr->wNumRPipes;
+       wa->rpipe_bm = kzalloc(BITS_TO_LONGS(wa->rpipes)*sizeof(unsigned long),
+                              GFP_KERNEL);
+       if (wa->rpipe_bm == NULL)
+               return -ENOMEM;
+       return 0;
+}
+
+void wa_rpipes_destroy(struct wahc *wa)
+{
+       struct device *dev = &wa->usb_iface->dev;
+       d_fnstart(3, dev, "(wa %p)\n", wa);
+       if (!bitmap_empty(wa->rpipe_bm, wa->rpipes)) {
+               char buf[256];
+               WARN_ON(1);
+               bitmap_scnprintf(buf, sizeof(buf), wa->rpipe_bm, wa->rpipes);
+               dev_err(dev, "BUG: pipes not released on exit: %s\n", buf);
+       }
+       kfree(wa->rpipe_bm);
+       d_fnend(3, dev, "(wa %p)\n", wa);
+}
+
+/*
+ * Release resources allocated for an endpoint
+ *
+ * If there is an associated rpipe to this endpoint, Abort any pending
+ * transfers and put it. If the rpipe ends up being destroyed,
+ * __rpipe_destroy() will cleanup ep->hcpriv.
+ *
+ * This is called before calling hcd->stop(), so you don't need to do
+ * anything else in there.
+ */
+void rpipe_ep_disable(struct wahc *wa, struct usb_host_endpoint *ep)
+{
+       struct device *dev = &wa->usb_iface->dev;
+       struct wa_rpipe *rpipe;
+       d_fnstart(2, dev, "(wa %p ep %p)\n", wa, ep);
+       mutex_lock(&wa->rpipe_mutex);
+       rpipe = ep->hcpriv;
+       if (rpipe != NULL) {
+               unsigned rc = atomic_read(&rpipe->refcnt.refcount);
+               int result;
+               u16 index = le16_to_cpu(rpipe->descr.wRPipeIndex);
+
+               if (rc != 1)
+                       d_printf(1, dev, "(wa %p ep %p) rpipe %p refcnt %u\n",
+                                wa, ep, rpipe, rc);
+
+               d_printf(1, dev, "rpipe %u: abort\n", index);
+               result = usb_control_msg(
+                       wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0),
+                       USB_REQ_RPIPE_ABORT,
+                       USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE,
+                       0, index, NULL, 0, 1000 /* FIXME: arbitrary */);
+               if (result < 0 && result != -ENODEV /* dev is gone */)
+                       d_printf(1, dev, "(wa %p rpipe %u): abort failed: %d\n",
+                                wa, index, result);
+               rpipe_put(rpipe);
+       }
+       mutex_unlock(&wa->rpipe_mutex);
+       d_fnend(2, dev, "(wa %p ep %p)\n", wa, ep);
+       return;
+}
+EXPORT_SYMBOL_GPL(rpipe_ep_disable);
diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c
new file mode 100644 (file)
index 0000000..c038635
--- /dev/null
@@ -0,0 +1,1709 @@
+/*
+ * WUSB Wire Adapter
+ * Data transfer and URB enqueing
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * How transfers work: get a buffer, break it up in segments (segment
+ * size is a multiple of the maxpacket size). For each segment issue a
+ * segment request (struct wa_xfer_*), then send the data buffer if
+ * out or nothing if in (all over the DTO endpoint).
+ *
+ * For each submitted segment request, a notification will come over
+ * the NEP endpoint and a transfer result (struct xfer_result) will
+ * arrive in the DTI URB. Read it, get the xfer ID, see if there is
+ * data coming (inbound transfer), schedule a read and handle it.
+ *
+ * Sounds simple, it is a pain to implement.
+ *
+ *
+ * ENTRY POINTS
+ *
+ *   FIXME
+ *
+ * LIFE CYCLE / STATE DIAGRAM
+ *
+ *   FIXME
+ *
+ * THIS CODE IS DISGUSTING
+ *
+ *   Warned you are; it's my second try and still not happy with it.
+ *
+ * NOTES:
+ *
+ *   - No iso
+ *
+ *   - Supports DMA xfers, control, bulk and maybe interrupt
+ *
+ *   - Does not recycle unused rpipes
+ *
+ *     An rpipe is assigned to an endpoint the first time it is used,
+ *     and then it's there, assigned, until the endpoint is disabled
+ *     (destroyed [{h,d}wahc_op_ep_disable()]. The assignment of the
+ *     rpipe to the endpoint is done under the wa->rpipe_sem semaphore
+ *     (should be a mutex).
+ *
+ *     Two methods it could be done:
+ *
+ *     (a) set up a timer everytime an rpipe's use count drops to 1
+ *         (which means unused) or when a transfer ends. Reset the
+ *         timer when a xfer is queued. If the timer expires, release
+ *         the rpipe [see rpipe_ep_disable()].
+ *
+ *     (b) when looking for free rpipes to attach [rpipe_get_by_ep()],
+ *         when none are found go over the list, check their endpoint
+ *         and their activity record (if no last-xfer-done-ts in the
+ *         last x seconds) take it
+ *
+ *     However, due to the fact that we have a set of limited
+ *     resources (max-segments-at-the-same-time per xfer,
+ *     xfers-per-ripe, blocks-per-rpipe, rpipes-per-host), at the end
+ *     we are going to have to rebuild all this based on an scheduler,
+ *     to where we have a list of transactions to do and based on the
+ *     availability of the different requried components (blocks,
+ *     rpipes, segment slots, etc), we go scheduling them. Painful.
+ */
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/hash.h>
+#include "wa-hc.h"
+#include "wusbhc.h"
+
+#undef D_LOCAL
+#define D_LOCAL 0 /* 0 disabled, > 0 different levels... */
+#include <linux/uwb/debug.h>
+
+enum {
+       WA_SEGS_MAX = 255,
+};
+
+enum wa_seg_status {
+       WA_SEG_NOTREADY,
+       WA_SEG_READY,
+       WA_SEG_DELAYED,
+       WA_SEG_SUBMITTED,
+       WA_SEG_PENDING,
+       WA_SEG_DTI_PENDING,
+       WA_SEG_DONE,
+       WA_SEG_ERROR,
+       WA_SEG_ABORTED,
+};
+
+static void wa_xfer_delayed_run(struct wa_rpipe *);
+
+/*
+ * Life cycle governed by 'struct urb' (the refcount of the struct is
+ * that of the 'struct urb' and usb_free_urb() would free the whole
+ * struct).
+ */
+struct wa_seg {
+       struct urb urb;
+       struct urb *dto_urb;            /* for data output? */
+       struct list_head list_node;     /* for rpipe->req_list */
+       struct wa_xfer *xfer;           /* out xfer */
+       u8 index;                       /* which segment we are */
+       enum wa_seg_status status;
+       ssize_t result;                 /* bytes xfered or error */
+       struct wa_xfer_hdr xfer_hdr;
+       u8 xfer_extra[];                /* xtra space for xfer_hdr_ctl */
+};
+
+static void wa_seg_init(struct wa_seg *seg)
+{
+       /* usb_init_urb() repeats a lot of work, so we do it here */
+       kref_init(&seg->urb.kref);
+}
+
+/*
+ * Protected by xfer->lock
+ *
+ */
+struct wa_xfer {
+       struct kref refcnt;
+       struct list_head list_node;
+       spinlock_t lock;
+       u32 id;
+
+       struct wahc *wa;                /* Wire adapter we are plugged to */
+       struct usb_host_endpoint *ep;
+       struct urb *urb;                /* URB we are transfering for */
+       struct wa_seg **seg;            /* transfer segments */
+       u8 segs, segs_submitted, segs_done;
+       unsigned is_inbound:1;
+       unsigned is_dma:1;
+       size_t seg_size;
+       int result;
+
+       gfp_t gfp;                      /* allocation mask */
+
+       struct wusb_dev *wusb_dev;      /* for activity timestamps */
+};
+
+static inline void wa_xfer_init(struct wa_xfer *xfer)
+{
+       kref_init(&xfer->refcnt);
+       INIT_LIST_HEAD(&xfer->list_node);
+       spin_lock_init(&xfer->lock);
+}
+
+/*
+ * Destory a transfer structure
+ *
+ * Note that the xfer->seg[index] thingies follow the URB life cycle,
+ * so we need to put them, not free them.
+ */
+static void wa_xfer_destroy(struct kref *_xfer)
+{
+       struct wa_xfer *xfer = container_of(_xfer, struct wa_xfer, refcnt);
+       if (xfer->seg) {
+               unsigned cnt;
+               for (cnt = 0; cnt < xfer->segs; cnt++) {
+                       if (xfer->is_inbound)
+                               usb_put_urb(xfer->seg[cnt]->dto_urb);
+                       usb_put_urb(&xfer->seg[cnt]->urb);
+               }
+       }
+       kfree(xfer);
+       d_printf(2, NULL, "xfer %p destroyed\n", xfer);
+}
+
+static void wa_xfer_get(struct wa_xfer *xfer)
+{
+       kref_get(&xfer->refcnt);
+}
+
+static void wa_xfer_put(struct wa_xfer *xfer)
+{
+       d_fnstart(3, NULL, "(xfer %p) -- ref count bef put %d\n",
+                   xfer, atomic_read(&xfer->refcnt.refcount));
+       kref_put(&xfer->refcnt, wa_xfer_destroy);
+       d_fnend(3, NULL, "(xfer %p) = void\n", xfer);
+}
+
+/*
+ * xfer is referenced
+ *
+ * xfer->lock has to be unlocked
+ *
+ * We take xfer->lock for setting the result; this is a barrier
+ * against drivers/usb/core/hcd.c:unlink1() being called after we call
+ * usb_hcd_giveback_urb() and wa_urb_dequeue() trying to get a
+ * reference to the transfer.
+ */
+static void wa_xfer_giveback(struct wa_xfer *xfer)
+{
+       unsigned long flags;
+       d_fnstart(3, NULL, "(xfer %p)\n", xfer);
+       spin_lock_irqsave(&xfer->wa->xfer_list_lock, flags);
+       list_del_init(&xfer->list_node);
+       spin_unlock_irqrestore(&xfer->wa->xfer_list_lock, flags);
+       /* FIXME: segmentation broken -- kills DWA */
+       wusbhc_giveback_urb(xfer->wa->wusb, xfer->urb, xfer->result);
+       wa_put(xfer->wa);
+       wa_xfer_put(xfer);
+       d_fnend(3, NULL, "(xfer %p) = void\n", xfer);
+}
+
+/*
+ * xfer is referenced
+ *
+ * xfer->lock has to be unlocked
+ */
+static void wa_xfer_completion(struct wa_xfer *xfer)
+{
+       d_fnstart(3, NULL, "(xfer %p)\n", xfer);
+       if (xfer->wusb_dev)
+               wusb_dev_put(xfer->wusb_dev);
+       rpipe_put(xfer->ep->hcpriv);
+       wa_xfer_giveback(xfer);
+       d_fnend(3, NULL, "(xfer %p) = void\n", xfer);
+       return;
+}
+
+/*
+ * If transfer is done, wrap it up and return true
+ *
+ * xfer->lock has to be locked
+ */
+static unsigned __wa_xfer_is_done(struct wa_xfer *xfer)
+{
+       unsigned result, cnt;
+       struct wa_seg *seg;
+       struct urb *urb = xfer->urb;
+       unsigned found_short = 0;
+
+       d_fnstart(3, NULL, "(xfer %p)\n", xfer);
+       result = xfer->segs_done == xfer->segs_submitted;
+       if (result == 0)
+               goto out;
+       urb->actual_length = 0;
+       for (cnt = 0; cnt < xfer->segs; cnt++) {
+               seg = xfer->seg[cnt];
+               switch (seg->status) {
+               case WA_SEG_DONE:
+                       if (found_short && seg->result > 0) {
+                               if (printk_ratelimit())
+                                       printk(KERN_ERR "xfer %p#%u: bad short "
+                                              "segments (%zu)\n", xfer, cnt,
+                                              seg->result);
+                               urb->status = -EINVAL;
+                               goto out;
+                       }
+                       urb->actual_length += seg->result;
+                       if (seg->result < xfer->seg_size
+                           && cnt != xfer->segs-1)
+                               found_short = 1;
+                       d_printf(2, NULL, "xfer %p#%u: DONE short %d "
+                                "result %zu urb->actual_length %d\n",
+                                xfer, seg->index, found_short, seg->result,
+                                urb->actual_length);
+                       break;
+               case WA_SEG_ERROR:
+                       xfer->result = seg->result;
+                       d_printf(2, NULL, "xfer %p#%u: ERROR result %zu\n",
+                                xfer, seg->index, seg->result);
+                       goto out;
+               case WA_SEG_ABORTED:
+                       WARN_ON(urb->status != -ECONNRESET
+                               && urb->status != -ENOENT);
+                       d_printf(2, NULL, "xfer %p#%u ABORTED: result %d\n",
+                                xfer, seg->index, urb->status);
+                       xfer->result = urb->status;
+                       goto out;
+               default:
+                       /* if (printk_ratelimit()) */
+                               printk(KERN_ERR "xfer %p#%u: "
+                                      "is_done bad state %d\n",
+                                      xfer, cnt, seg->status);
+                       xfer->result = -EINVAL;
+                       WARN_ON(1);
+                       goto out;
+               }
+       }
+       xfer->result = 0;
+out:
+       d_fnend(3, NULL, "(xfer %p) = void\n", xfer);
+       return result;
+}
+
+/*
+ * Initialize a transfer's ID
+ *
+ * We need to use a sequential number; if we use the pointer or the
+ * hash of the pointer, it can repeat over sequential transfers and
+ * then it will confuse the HWA....wonder why in hell they put a 32
+ * bit handle in there then.
+ */
+static void wa_xfer_id_init(struct wa_xfer *xfer)
+{
+       xfer->id = atomic_add_return(1, &xfer->wa->xfer_id_count);
+}
+
+/*
+ * Return the xfer's ID associated with xfer
+ *
+ * Need to generate a
+ */
+static u32 wa_xfer_id(struct wa_xfer *xfer)
+{
+       return xfer->id;
+}
+
+/*
+ * Search for a transfer list ID on the HCD's URB list
+ *
+ * For 32 bit architectures, we use the pointer itself; for 64 bits, a
+ * 32-bit hash of the pointer.
+ *
+ * @returns NULL if not found.
+ */
+static struct wa_xfer *wa_xfer_get_by_id(struct wahc *wa, u32 id)
+{
+       unsigned long flags;
+       struct wa_xfer *xfer_itr;
+       spin_lock_irqsave(&wa->xfer_list_lock, flags);
+       list_for_each_entry(xfer_itr, &wa->xfer_list, list_node) {
+               if (id == xfer_itr->id) {
+                       wa_xfer_get(xfer_itr);
+                       goto out;
+               }
+       }
+       xfer_itr = NULL;
+out:
+       spin_unlock_irqrestore(&wa->xfer_list_lock, flags);
+       return xfer_itr;
+}
+
+struct wa_xfer_abort_buffer {
+       struct urb urb;
+       struct wa_xfer_abort cmd;
+};
+
+static void __wa_xfer_abort_cb(struct urb *urb)
+{
+       struct wa_xfer_abort_buffer *b = urb->context;
+       usb_put_urb(&b->urb);
+}
+
+/*
+ * Aborts an ongoing transaction
+ *
+ * Assumes the transfer is referenced and locked and in a submitted
+ * state (mainly that there is an endpoint/rpipe assigned).
+ *
+ * The callback (see above) does nothing but freeing up the data by
+ * putting the URB. Because the URB is allocated at the head of the
+ * struct, the whole space we allocated is kfreed.
+ *
+ * We'll get an 'aborted transaction' xfer result on DTI, that'll
+ * politely ignore because at this point the transaction has been
+ * marked as aborted already.
+ */
+static void __wa_xfer_abort(struct wa_xfer *xfer)
+{
+       int result;
+       struct device *dev = &xfer->wa->usb_iface->dev;
+       struct wa_xfer_abort_buffer *b;
+       struct wa_rpipe *rpipe = xfer->ep->hcpriv;
+
+       b = kmalloc(sizeof(*b), GFP_ATOMIC);
+       if (b == NULL)
+               goto error_kmalloc;
+       b->cmd.bLength =  sizeof(b->cmd);
+       b->cmd.bRequestType = WA_XFER_ABORT;
+       b->cmd.wRPipe = rpipe->descr.wRPipeIndex;
+       b->cmd.dwTransferID = wa_xfer_id(xfer);
+
+       usb_init_urb(&b->urb);
+       usb_fill_bulk_urb(&b->urb, xfer->wa->usb_dev,
+               usb_sndbulkpipe(xfer->wa->usb_dev,
+                               xfer->wa->dto_epd->bEndpointAddress),
+               &b->cmd, sizeof(b->cmd), __wa_xfer_abort_cb, b);
+       result = usb_submit_urb(&b->urb, GFP_ATOMIC);
+       if (result < 0)
+               goto error_submit;
+       return;                         /* callback frees! */
+
+
+error_submit:
+       if (printk_ratelimit())
+               dev_err(dev, "xfer %p: Can't submit abort request: %d\n",
+                       xfer, result);
+       kfree(b);
+error_kmalloc:
+       return;
+
+}
+
+/*
+ *
+ * @returns < 0 on error, transfer segment request size if ok
+ */
+static ssize_t __wa_xfer_setup_sizes(struct wa_xfer *xfer,
+                                    enum wa_xfer_type *pxfer_type)
+{
+       ssize_t result;
+       struct device *dev = &xfer->wa->usb_iface->dev;
+       size_t maxpktsize;
+       struct urb *urb = xfer->urb;
+       struct wa_rpipe *rpipe = xfer->ep->hcpriv;
+
+       d_fnstart(3, dev, "(xfer %p [rpipe %p] urb %p)\n",
+                 xfer, rpipe, urb);
+       switch (rpipe->descr.bmAttribute & 0x3) {
+       case USB_ENDPOINT_XFER_CONTROL:
+               *pxfer_type = WA_XFER_TYPE_CTL;
+               result = sizeof(struct wa_xfer_ctl);
+               break;
+       case USB_ENDPOINT_XFER_INT:
+       case USB_ENDPOINT_XFER_BULK:
+               *pxfer_type = WA_XFER_TYPE_BI;
+               result = sizeof(struct wa_xfer_bi);
+               break;
+       case USB_ENDPOINT_XFER_ISOC:
+               dev_err(dev, "FIXME: ISOC not implemented\n");
+               result = -ENOSYS;
+               goto error;
+       default:
+               /* never happens */
+               BUG();
+               result = -EINVAL;       /* shut gcc up */
+       };
+       xfer->is_inbound = urb->pipe & USB_DIR_IN ? 1 : 0;
+       xfer->is_dma = urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP ? 1 : 0;
+       xfer->seg_size = le16_to_cpu(rpipe->descr.wBlocks)
+               * 1 << (xfer->wa->wa_descr->bRPipeBlockSize - 1);
+       /* Compute the segment size and make sure it is a multiple of
+        * the maxpktsize (WUSB1.0[8.3.3.1])...not really too much of
+        * a check (FIXME) */
+       maxpktsize = le16_to_cpu(rpipe->descr.wMaxPacketSize);
+       if (xfer->seg_size < maxpktsize) {
+               dev_err(dev, "HW BUG? seg_size %zu smaller than maxpktsize "
+                       "%zu\n", xfer->seg_size, maxpktsize);
+               result = -EINVAL;
+               goto error;
+       }
+       xfer->seg_size = (xfer->seg_size / maxpktsize) * maxpktsize;
+       xfer->segs = (urb->transfer_buffer_length + xfer->seg_size - 1)
+               / xfer->seg_size;
+       if (xfer->segs >= WA_SEGS_MAX) {
+               dev_err(dev, "BUG? ops, number of segments %d bigger than %d\n",
+                       (int)(urb->transfer_buffer_length / xfer->seg_size),
+                       WA_SEGS_MAX);
+               result = -EINVAL;
+               goto error;
+       }
+       if (xfer->segs == 0 && *pxfer_type == WA_XFER_TYPE_CTL)
+               xfer->segs = 1;
+error:
+       d_fnend(3, dev, "(xfer %p [rpipe %p] urb %p) = %d\n",
+               xfer, rpipe, urb, (int)result);
+       return result;
+}
+
+/** Fill in the common request header and xfer-type specific data. */
+static void __wa_xfer_setup_hdr0(struct wa_xfer *xfer,
+                                struct wa_xfer_hdr *xfer_hdr0,
+                                enum wa_xfer_type xfer_type,
+                                size_t xfer_hdr_size)
+{
+       struct wa_rpipe *rpipe = xfer->ep->hcpriv;
+
+       xfer_hdr0 = &xfer->seg[0]->xfer_hdr;
+       xfer_hdr0->bLength = xfer_hdr_size;
+       xfer_hdr0->bRequestType = xfer_type;
+       xfer_hdr0->wRPipe = rpipe->descr.wRPipeIndex;
+       xfer_hdr0->dwTransferID = wa_xfer_id(xfer);
+       xfer_hdr0->bTransferSegment = 0;
+       switch (xfer_type) {
+       case WA_XFER_TYPE_CTL: {
+               struct wa_xfer_ctl *xfer_ctl =
+                       container_of(xfer_hdr0, struct wa_xfer_ctl, hdr);
+               xfer_ctl->bmAttribute = xfer->is_inbound ? 1 : 0;
+               BUG_ON(xfer->urb->transfer_flags & URB_NO_SETUP_DMA_MAP
+                      && xfer->urb->setup_packet == NULL);
+               memcpy(&xfer_ctl->baSetupData, xfer->urb->setup_packet,
+                      sizeof(xfer_ctl->baSetupData));
+               break;
+       }
+       case WA_XFER_TYPE_BI:
+               break;
+       case WA_XFER_TYPE_ISO:
+               printk(KERN_ERR "FIXME: ISOC not implemented\n");
+       default:
+               BUG();
+       };
+}
+
+/*
+ * Callback for the OUT data phase of the segment request
+ *
+ * Check wa_seg_cb(); most comments also apply here because this
+ * function does almost the same thing and they work closely
+ * together.
+ *
+ * If the seg request has failed but this DTO phase has suceeded,
+ * wa_seg_cb() has already failed the segment and moved the
+ * status to WA_SEG_ERROR, so this will go through 'case 0' and
+ * effectively do nothing.
+ */
+static void wa_seg_dto_cb(struct urb *urb)
+{
+       struct wa_seg *seg = urb->context;
+       struct wa_xfer *xfer = seg->xfer;
+       struct wahc *wa;
+       struct device *dev;
+       struct wa_rpipe *rpipe;
+       unsigned long flags;
+       unsigned rpipe_ready = 0;
+       u8 done = 0;
+
+       d_fnstart(3, NULL, "(urb %p [%d])\n", urb, urb->status);
+       switch (urb->status) {
+       case 0:
+               spin_lock_irqsave(&xfer->lock, flags);
+               wa = xfer->wa;
+               dev = &wa->usb_iface->dev;
+               d_printf(2, dev, "xfer %p#%u: data out done (%d bytes)\n",
+                          xfer, seg->index, urb->actual_length);
+               if (seg->status < WA_SEG_PENDING)
+                       seg->status = WA_SEG_PENDING;
+               seg->result = urb->actual_length;
+               spin_unlock_irqrestore(&xfer->lock, flags);
+               break;
+       case -ECONNRESET:       /* URB unlinked; no need to do anything */
+       case -ENOENT:           /* as it was done by the who unlinked us */
+               break;
+       default:                /* Other errors ... */
+               spin_lock_irqsave(&xfer->lock, flags);
+               wa = xfer->wa;
+               dev = &wa->usb_iface->dev;
+               rpipe = xfer->ep->hcpriv;
+               if (printk_ratelimit())
+                       dev_err(dev, "xfer %p#%u: data out error %d\n",
+                               xfer, seg->index, urb->status);
+               if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS,
+                           EDC_ERROR_TIMEFRAME)){
+                       dev_err(dev, "DTO: URB max acceptable errors "
+                               "exceeded, resetting device\n");
+                       wa_reset_all(wa);
+               }
+               if (seg->status != WA_SEG_ERROR) {
+                       seg->status = WA_SEG_ERROR;
+                       seg->result = urb->status;
+                       xfer->segs_done++;
+                       __wa_xfer_abort(xfer);
+                       rpipe_ready = rpipe_avail_inc(rpipe);
+                       done = __wa_xfer_is_done(xfer);
+               }
+               spin_unlock_irqrestore(&xfer->lock, flags);
+               if (done)
+                       wa_xfer_completion(xfer);
+               if (rpipe_ready)
+                       wa_xfer_delayed_run(rpipe);
+       }
+       d_fnend(3, NULL, "(urb %p [%d]) = void\n", urb, urb->status);
+}
+
+/*
+ * Callback for the segment request
+ *
+ * If succesful transition state (unless already transitioned or
+ * outbound transfer); otherwise, take a note of the error, mark this
+ * segment done and try completion.
+ *
+ * Note we don't access until we are sure that the transfer hasn't
+ * been cancelled (ECONNRESET, ENOENT), which could mean that
+ * seg->xfer could be already gone.
+ *
+ * We have to check before setting the status to WA_SEG_PENDING
+ * because sometimes the xfer result callback arrives before this
+ * callback (geeeeeeze), so it might happen that we are already in
+ * another state. As well, we don't set it if the transfer is inbound,
+ * as in that case, wa_seg_dto_cb will do it when the OUT data phase
+ * finishes.
+ */
+static void wa_seg_cb(struct urb *urb)
+{
+       struct wa_seg *seg = urb->context;
+       struct wa_xfer *xfer = seg->xfer;
+       struct wahc *wa;
+       struct device *dev;
+       struct wa_rpipe *rpipe;
+       unsigned long flags;
+       unsigned rpipe_ready;
+       u8 done = 0;
+
+       d_fnstart(3, NULL, "(urb %p [%d])\n", urb, urb->status);
+       switch (urb->status) {
+       case 0:
+               spin_lock_irqsave(&xfer->lock, flags);
+               wa = xfer->wa;
+               dev = &wa->usb_iface->dev;
+               d_printf(2, dev, "xfer %p#%u: request done\n",
+                          xfer, seg->index);
+               if (xfer->is_inbound && seg->status < WA_SEG_PENDING)
+                       seg->status = WA_SEG_PENDING;
+               spin_unlock_irqrestore(&xfer->lock, flags);
+               break;
+       case -ECONNRESET:       /* URB unlinked; no need to do anything */
+       case -ENOENT:           /* as it was done by the who unlinked us */
+               break;
+       default:                /* Other errors ... */
+               spin_lock_irqsave(&xfer->lock, flags);
+               wa = xfer->wa;
+               dev = &wa->usb_iface->dev;
+               rpipe = xfer->ep->hcpriv;
+               if (printk_ratelimit())
+                       dev_err(dev, "xfer %p#%u: request error %d\n",
+                               xfer, seg->index, urb->status);
+               if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS,
+                           EDC_ERROR_TIMEFRAME)){
+                       dev_err(dev, "DTO: URB max acceptable errors "
+                               "exceeded, resetting device\n");
+                       wa_reset_all(wa);
+               }
+               usb_unlink_urb(seg->dto_urb);
+               seg->status = WA_SEG_ERROR;
+               seg->result = urb->status;
+               xfer->segs_done++;
+               __wa_xfer_abort(xfer);
+               rpipe_ready = rpipe_avail_inc(rpipe);
+               done = __wa_xfer_is_done(xfer);
+               spin_unlock_irqrestore(&xfer->lock, flags);
+               if (done)
+                       wa_xfer_completion(xfer);
+               if (rpipe_ready)
+                       wa_xfer_delayed_run(rpipe);
+       }
+       d_fnend(3, NULL, "(urb %p [%d]) = void\n", urb, urb->status);
+}
+
+/*
+ * Allocate the segs array and initialize each of them
+ *
+ * The segments are freed by wa_xfer_destroy() when the xfer use count
+ * drops to zero; however, because each segment is given the same life
+ * cycle as the USB URB it contains, it is actually freed by
+ * usb_put_urb() on the contained USB URB (twisted, eh?).
+ */
+static int __wa_xfer_setup_segs(struct wa_xfer *xfer, size_t xfer_hdr_size)
+{
+       int result, cnt;
+       size_t alloc_size = sizeof(*xfer->seg[0])
+               - sizeof(xfer->seg[0]->xfer_hdr) + xfer_hdr_size;
+       struct usb_device *usb_dev = xfer->wa->usb_dev;
+       const struct usb_endpoint_descriptor *dto_epd = xfer->wa->dto_epd;
+       struct wa_seg *seg;
+       size_t buf_itr, buf_size, buf_itr_size;
+
+       result = -ENOMEM;
+       xfer->seg = kcalloc(xfer->segs, sizeof(xfer->seg[0]), GFP_ATOMIC);
+       if (xfer->seg == NULL)
+               goto error_segs_kzalloc;
+       buf_itr = 0;
+       buf_size = xfer->urb->transfer_buffer_length;
+       for (cnt = 0; cnt < xfer->segs; cnt++) {
+               seg = xfer->seg[cnt] = kzalloc(alloc_size, GFP_ATOMIC);
+               if (seg == NULL)
+                       goto error_seg_kzalloc;
+               wa_seg_init(seg);
+               seg->xfer = xfer;
+               seg->index = cnt;
+               usb_fill_bulk_urb(&seg->urb, usb_dev,
+                                 usb_sndbulkpipe(usb_dev,
+                                                 dto_epd->bEndpointAddress),
+                                 &seg->xfer_hdr, xfer_hdr_size,
+                                 wa_seg_cb, seg);
+               buf_itr_size = buf_size > xfer->seg_size ?
+                       xfer->seg_size : buf_size;
+               if (xfer->is_inbound == 0 && buf_size > 0) {
+                       seg->dto_urb = usb_alloc_urb(0, GFP_ATOMIC);
+                       if (seg->dto_urb == NULL)
+                               goto error_dto_alloc;
+                       usb_fill_bulk_urb(
+                               seg->dto_urb, usb_dev,
+                               usb_sndbulkpipe(usb_dev,
+                                               dto_epd->bEndpointAddress),
+                               NULL, 0, wa_seg_dto_cb, seg);
+                       if (xfer->is_dma) {
+                               seg->dto_urb->transfer_dma =
+                                       xfer->urb->transfer_dma + buf_itr;
+                               seg->dto_urb->transfer_flags |=
+                                       URB_NO_TRANSFER_DMA_MAP;
+                       } else
+                               seg->dto_urb->transfer_buffer =
+                                       xfer->urb->transfer_buffer + buf_itr;
+                       seg->dto_urb->transfer_buffer_length = buf_itr_size;
+               }
+               seg->status = WA_SEG_READY;
+               buf_itr += buf_itr_size;
+               buf_size -= buf_itr_size;
+       }
+       return 0;
+
+error_dto_alloc:
+       kfree(xfer->seg[cnt]);
+       cnt--;
+error_seg_kzalloc:
+       /* use the fact that cnt is left at were it failed */
+       for (; cnt > 0; cnt--) {
+               if (xfer->is_inbound == 0)
+                       kfree(xfer->seg[cnt]->dto_urb);
+               kfree(xfer->seg[cnt]);
+       }
+error_segs_kzalloc:
+       return result;
+}
+
+/*
+ * Allocates all the stuff needed to submit a transfer
+ *
+ * Breaks the whole data buffer in a list of segments, each one has a
+ * structure allocated to it and linked in xfer->seg[index]
+ *
+ * FIXME: merge setup_segs() and the last part of this function, no
+ *        need to do two for loops when we could run everything in a
+ *        single one
+ */
+static int __wa_xfer_setup(struct wa_xfer *xfer, struct urb *urb)
+{
+       int result;
+       struct device *dev = &xfer->wa->usb_iface->dev;
+       enum wa_xfer_type xfer_type = 0; /* shut up GCC */
+       size_t xfer_hdr_size, cnt, transfer_size;
+       struct wa_xfer_hdr *xfer_hdr0, *xfer_hdr;
+
+       d_fnstart(3, dev, "(xfer %p [rpipe %p] urb %p)\n",
+                 xfer, xfer->ep->hcpriv, urb);
+
+       result = __wa_xfer_setup_sizes(xfer, &xfer_type);
+       if (result < 0)
+               goto error_setup_sizes;
+       xfer_hdr_size = result;
+       result = __wa_xfer_setup_segs(xfer, xfer_hdr_size);
+       if (result < 0) {
+               dev_err(dev, "xfer %p: Failed to allocate %d segments: %d\n",
+                       xfer, xfer->segs, result);
+               goto error_setup_segs;
+       }
+       /* Fill the first header */
+       xfer_hdr0 = &xfer->seg[0]->xfer_hdr;
+       wa_xfer_id_init(xfer);
+       __wa_xfer_setup_hdr0(xfer, xfer_hdr0, xfer_type, xfer_hdr_size);
+
+       /* Fill remainig headers */
+       xfer_hdr = xfer_hdr0;
+       transfer_size = urb->transfer_buffer_length;
+       xfer_hdr0->dwTransferLength = transfer_size > xfer->seg_size ?
+               xfer->seg_size : transfer_size;
+       transfer_size -=  xfer->seg_size;
+       for (cnt = 1; cnt < xfer->segs; cnt++) {
+               xfer_hdr = &xfer->seg[cnt]->xfer_hdr;
+               memcpy(xfer_hdr, xfer_hdr0, xfer_hdr_size);
+               xfer_hdr->bTransferSegment = cnt;
+               xfer_hdr->dwTransferLength = transfer_size > xfer->seg_size ?
+                       cpu_to_le32(xfer->seg_size)
+                       : cpu_to_le32(transfer_size);
+               xfer->seg[cnt]->status = WA_SEG_READY;
+               transfer_size -=  xfer->seg_size;
+       }
+       xfer_hdr->bTransferSegment |= 0x80;     /* this is the last segment */
+       result = 0;
+error_setup_segs:
+error_setup_sizes:
+       d_fnend(3, dev, "(xfer %p [rpipe %p] urb %p) = %d\n",
+               xfer, xfer->ep->hcpriv, urb, result);
+       return result;
+}
+
+/*
+ *
+ *
+ * rpipe->seg_lock is held!
+ */
+static int __wa_seg_submit(struct wa_rpipe *rpipe, struct wa_xfer *xfer,
+                          struct wa_seg *seg)
+{
+       int result;
+       result = usb_submit_urb(&seg->urb, GFP_ATOMIC);
+       if (result < 0) {
+               printk(KERN_ERR "xfer %p#%u: REQ submit failed: %d\n",
+                      xfer, seg->index, result);
+               goto error_seg_submit;
+       }
+       if (seg->dto_urb) {
+               result = usb_submit_urb(seg->dto_urb, GFP_ATOMIC);
+               if (result < 0) {
+                       printk(KERN_ERR "xfer %p#%u: DTO submit failed: %d\n",
+                              xfer, seg->index, result);
+                       goto error_dto_submit;
+               }
+       }
+       seg->status = WA_SEG_SUBMITTED;
+       rpipe_avail_dec(rpipe);
+       return 0;
+
+error_dto_submit:
+       usb_unlink_urb(&seg->urb);
+error_seg_submit:
+       seg->status = WA_SEG_ERROR;
+       seg->result = result;
+       return result;
+}
+
+/*
+ * Execute more queued request segments until the maximum concurrent allowed
+ *
+ * The ugly unlock/lock sequence on the error path is needed as the
+ * xfer->lock normally nests the seg_lock and not viceversa.
+ *
+ */
+static void wa_xfer_delayed_run(struct wa_rpipe *rpipe)
+{
+       int result;
+       struct device *dev = &rpipe->wa->usb_iface->dev;
+       struct wa_seg *seg;
+       struct wa_xfer *xfer;
+       unsigned long flags;
+
+       d_fnstart(1, dev, "(rpipe #%d) %d segments available\n",
+                 le16_to_cpu(rpipe->descr.wRPipeIndex),
+                 atomic_read(&rpipe->segs_available));
+       spin_lock_irqsave(&rpipe->seg_lock, flags);
+       while (atomic_read(&rpipe->segs_available) > 0
+             && !list_empty(&rpipe->seg_list)) {
+               seg = list_entry(rpipe->seg_list.next, struct wa_seg,
+                                list_node);
+               list_del(&seg->list_node);
+               xfer = seg->xfer;
+               result = __wa_seg_submit(rpipe, xfer, seg);
+               d_printf(1, dev, "xfer %p#%u submitted from delayed "
+                        "[%d segments available] %d\n",
+                        xfer, seg->index,
+                        atomic_read(&rpipe->segs_available), result);
+               if (unlikely(result < 0)) {
+                       spin_unlock_irqrestore(&rpipe->seg_lock, flags);
+                       spin_lock_irqsave(&xfer->lock, flags);
+                       __wa_xfer_abort(xfer);
+                       xfer->segs_done++;
+                       spin_unlock_irqrestore(&xfer->lock, flags);
+                       spin_lock_irqsave(&rpipe->seg_lock, flags);
+               }
+       }
+       spin_unlock_irqrestore(&rpipe->seg_lock, flags);
+       d_fnend(1, dev, "(rpipe #%d) = void, %d segments available\n",
+               le16_to_cpu(rpipe->descr.wRPipeIndex),
+               atomic_read(&rpipe->segs_available));
+
+}
+
+/*
+ *
+ * xfer->lock is taken
+ *
+ * On failure submitting we just stop submitting and return error;
+ * wa_urb_enqueue_b() will execute the completion path
+ */
+static int __wa_xfer_submit(struct wa_xfer *xfer)
+{
+       int result;
+       struct wahc *wa = xfer->wa;
+       struct device *dev = &wa->usb_iface->dev;
+       unsigned cnt;
+       struct wa_seg *seg;
+       unsigned long flags;
+       struct wa_rpipe *rpipe = xfer->ep->hcpriv;
+       size_t maxrequests = le16_to_cpu(rpipe->descr.wRequests);
+       u8 available;
+       u8 empty;
+
+       d_fnstart(3, dev, "(xfer %p [rpipe %p])\n",
+                 xfer, xfer->ep->hcpriv);
+
+       spin_lock_irqsave(&wa->xfer_list_lock, flags);
+       list_add_tail(&xfer->list_node, &wa->xfer_list);
+       spin_unlock_irqrestore(&wa->xfer_list_lock, flags);
+
+       BUG_ON(atomic_read(&rpipe->segs_available) > maxrequests);
+       result = 0;
+       spin_lock_irqsave(&rpipe->seg_lock, flags);
+       for (cnt = 0; cnt < xfer->segs; cnt++) {
+               available = atomic_read(&rpipe->segs_available);
+               empty = list_empty(&rpipe->seg_list);
+               seg = xfer->seg[cnt];
+               d_printf(2, dev, "xfer %p#%u: available %u empty %u (%s)\n",
+                        xfer, cnt, available, empty,
+                        available == 0 || !empty ? "delayed" : "submitted");
+               if (available == 0 || !empty) {
+                       d_printf(1, dev, "xfer %p#%u: delayed\n", xfer, cnt);
+                       seg->status = WA_SEG_DELAYED;
+                       list_add_tail(&seg->list_node, &rpipe->seg_list);
+               } else {
+                       result = __wa_seg_submit(rpipe, xfer, seg);
+                       if (result < 0)
+                               goto error_seg_submit;
+               }
+               xfer->segs_submitted++;
+       }
+       spin_unlock_irqrestore(&rpipe->seg_lock, flags);
+       d_fnend(3, dev, "(xfer %p [rpipe %p]) = void\n", xfer,
+               xfer->ep->hcpriv);
+       return result;
+
+error_seg_submit:
+       __wa_xfer_abort(xfer);
+       spin_unlock_irqrestore(&rpipe->seg_lock, flags);
+       d_fnend(3, dev, "(xfer %p [rpipe %p]) = void\n", xfer,
+               xfer->ep->hcpriv);
+       return result;
+}
+
+/*
+ * Second part of a URB/transfer enqueuement
+ *
+ * Assumes this comes from wa_urb_enqueue() [maybe through
+ * wa_urb_enqueue_run()]. At this point:
+ *
+ * xfer->wa    filled and refcounted
+ * xfer->ep    filled with rpipe refcounted if
+ *              delayed == 0
+ * xfer->urb   filled and refcounted (this is the case when called
+ *              from wa_urb_enqueue() as we come from usb_submit_urb()
+ *              and when called by wa_urb_enqueue_run(), as we took an
+ *              extra ref dropped by _run() after we return).
+ * xfer->gfp   filled
+ *
+ * If we fail at __wa_xfer_submit(), then we just check if we are done
+ * and if so, we run the completion procedure. However, if we are not
+ * yet done, we do nothing and wait for the completion handlers from
+ * the submitted URBs or from the xfer-result path to kick in. If xfer
+ * result never kicks in, the xfer will timeout from the USB code and
+ * dequeue() will be called.
+ */
+static void wa_urb_enqueue_b(struct wa_xfer *xfer)
+{
+       int result;
+       unsigned long flags;
+       struct urb *urb = xfer->urb;
+       struct wahc *wa = xfer->wa;
+       struct wusbhc *wusbhc = wa->wusb;
+       struct device *dev = &wa->usb_iface->dev;
+       struct wusb_dev *wusb_dev;
+       unsigned done;
+
+       d_fnstart(3, dev, "(wa %p urb %p)\n", wa, urb);
+       result = rpipe_get_by_ep(wa, xfer->ep, urb, xfer->gfp);
+       if (result < 0)
+               goto error_rpipe_get;
+       result = -ENODEV;
+       /* FIXME: segmentation broken -- kills DWA */
+       mutex_lock(&wusbhc->mutex);             /* get a WUSB dev */
+       if (urb->dev == NULL)
+               goto error_dev_gone;
+       wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev);
+       if (wusb_dev == NULL) {
+               mutex_unlock(&wusbhc->mutex);
+               goto error_dev_gone;
+       }
+       mutex_unlock(&wusbhc->mutex);
+
+       spin_lock_irqsave(&xfer->lock, flags);
+       xfer->wusb_dev = wusb_dev;
+       result = urb->status;
+       if (urb->status != -EINPROGRESS)
+               goto error_dequeued;
+
+       result = __wa_xfer_setup(xfer, urb);
+       if (result < 0)
+               goto error_xfer_setup;
+       result = __wa_xfer_submit(xfer);
+       if (result < 0)
+               goto error_xfer_submit;
+       spin_unlock_irqrestore(&xfer->lock, flags);
+       d_fnend(3, dev, "(wa %p urb %p) = void\n", wa, urb);
+       return;
+
+       /* this is basically wa_xfer_completion() broken up wa_xfer_giveback()
+        * does a wa_xfer_put() that will call wa_xfer_destroy() and clean
+        * upundo setup().
+        */
+error_xfer_setup:
+error_dequeued:
+       spin_unlock_irqrestore(&xfer->lock, flags);
+       /* FIXME: segmentation broken, kills DWA */
+       if (wusb_dev)
+               wusb_dev_put(wusb_dev);
+error_dev_gone:
+       rpipe_put(xfer->ep->hcpriv);
+error_rpipe_get:
+       xfer->result = result;
+       wa_xfer_giveback(xfer);
+       d_fnend(3, dev, "(wa %p urb %p) = (void) %d\n", wa, urb, result);
+       return;
+
+error_xfer_submit:
+       done = __wa_xfer_is_done(xfer);
+       xfer->result = result;
+       spin_unlock_irqrestore(&xfer->lock, flags);
+       if (done)
+               wa_xfer_completion(xfer);
+       d_fnend(3, dev, "(wa %p urb %p) = (void) %d\n", wa, urb, result);
+       return;
+}
+
+/*
+ * Execute the delayed transfers in the Wire Adapter @wa
+ *
+ * We need to be careful here, as dequeue() could be called in the
+ * middle.  That's why we do the whole thing under the
+ * wa->xfer_list_lock. If dequeue() jumps in, it first locks urb->lock
+ * and then checks the list -- so as we would be acquiring in inverse
+ * order, we just drop the lock once we have the xfer and reacquire it
+ * later.
+ */
+void wa_urb_enqueue_run(struct work_struct *ws)
+{
+       struct wahc *wa = container_of(ws, struct wahc, xfer_work);
+       struct device *dev = &wa->usb_iface->dev;
+       struct wa_xfer *xfer, *next;
+       struct urb *urb;
+
+       d_fnstart(3, dev, "(wa %p)\n", wa);
+       spin_lock_irq(&wa->xfer_list_lock);
+       list_for_each_entry_safe(xfer, next, &wa->xfer_delayed_list,
+                                list_node) {
+               list_del_init(&xfer->list_node);
+               spin_unlock_irq(&wa->xfer_list_lock);
+
+               urb = xfer->urb;
+               wa_urb_enqueue_b(xfer);
+               usb_put_urb(urb);       /* taken when queuing */
+
+               spin_lock_irq(&wa->xfer_list_lock);
+       }
+       spin_unlock_irq(&wa->xfer_list_lock);
+       d_fnend(3, dev, "(wa %p) = void\n", wa);
+}
+EXPORT_SYMBOL_GPL(wa_urb_enqueue_run);
+
+/*
+ * Submit a transfer to the Wire Adapter in a delayed way
+ *
+ * The process of enqueuing involves possible sleeps() [see
+ * enqueue_b(), for the rpipe_get() and the mutex_lock()]. If we are
+ * in an atomic section, we defer the enqueue_b() call--else we call direct.
+ *
+ * @urb: We own a reference to it done by the HCI Linux USB stack that
+ *       will be given up by calling usb_hcd_giveback_urb() or by
+ *       returning error from this function -> ergo we don't have to
+ *       refcount it.
+ */
+int wa_urb_enqueue(struct wahc *wa, struct usb_host_endpoint *ep,
+                  struct urb *urb, gfp_t gfp)
+{
+       int result;
+       struct device *dev = &wa->usb_iface->dev;
+       struct wa_xfer *xfer;
+       unsigned long my_flags;
+       unsigned cant_sleep = irqs_disabled() | in_atomic();
+
+       d_fnstart(3, dev, "(wa %p ep %p urb %p [%d] gfp 0x%x)\n",
+                 wa, ep, urb, urb->transfer_buffer_length, gfp);
+
+       if (urb->transfer_buffer == NULL
+           && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
+           && urb->transfer_buffer_length != 0) {
+               dev_err(dev, "BUG? urb %p: NULL xfer buffer & NODMA\n", urb);
+               dump_stack();
+       }
+
+       result = -ENOMEM;
+       xfer = kzalloc(sizeof(*xfer), gfp);
+       if (xfer == NULL)
+               goto error_kmalloc;
+
+       result = -ENOENT;
+       if (urb->status != -EINPROGRESS)        /* cancelled */
+               goto error_dequeued;            /* before starting? */
+       wa_xfer_init(xfer);
+       xfer->wa = wa_get(wa);
+       xfer->urb = urb;
+       xfer->gfp = gfp;
+       xfer->ep = ep;
+       urb->hcpriv = xfer;
+       d_printf(2, dev, "xfer %p urb %p pipe 0x%02x [%d bytes] %s %s %s\n",
+                xfer, urb, urb->pipe, urb->transfer_buffer_length,
+                urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP ? "dma" : "nodma",
+                urb->pipe & USB_DIR_IN ? "inbound" : "outbound",
+                cant_sleep ? "deferred" : "inline");
+       if (cant_sleep) {
+               usb_get_urb(urb);
+               spin_lock_irqsave(&wa->xfer_list_lock, my_flags);
+               list_add_tail(&xfer->list_node, &wa->xfer_delayed_list);
+               spin_unlock_irqrestore(&wa->xfer_list_lock, my_flags);
+               queue_work(wusbd, &wa->xfer_work);
+       } else {
+               wa_urb_enqueue_b(xfer);
+       }
+       d_fnend(3, dev, "(wa %p ep %p urb %p [%d] gfp 0x%x) = 0\n",
+               wa, ep, urb, urb->transfer_buffer_length, gfp);
+       return 0;
+
+error_dequeued:
+       kfree(xfer);
+error_kmalloc:
+       d_fnend(3, dev, "(wa %p ep %p urb %p [%d] gfp 0x%x) = %d\n",
+               wa, ep, urb, urb->transfer_buffer_length, gfp, result);
+       return result;
+}
+EXPORT_SYMBOL_GPL(wa_urb_enqueue);
+
+/*
+ * Dequeue a URB and make sure uwb_hcd_giveback_urb() [completion
+ * handler] is called.
+ *
+ * Until a transfer goes successfully through wa_urb_enqueue() it
+ * needs to be dequeued with completion calling; when stuck in delayed
+ * or before wa_xfer_setup() is called, we need to do completion.
+ *
+ *  not setup  If there is no hcpriv yet, that means that that enqueue
+ *             still had no time to set the xfer up. Because
+ *             urb->status should be other than -EINPROGRESS,
+ *             enqueue() will catch that and bail out.
+ *
+ * If the transfer has gone through setup, we just need to clean it
+ * up. If it has gone through submit(), we have to abort it [with an
+ * asynch request] and then make sure we cancel each segment.
+ *
+ */
+int wa_urb_dequeue(struct wahc *wa, struct urb *urb)
+{
+       struct device *dev = &wa->usb_iface->dev;
+       unsigned long flags, flags2;
+       struct wa_xfer *xfer;
+       struct wa_seg *seg;
+       struct wa_rpipe *rpipe;
+       unsigned cnt;
+       unsigned rpipe_ready = 0;
+
+       d_fnstart(3, dev, "(wa %p, urb %p)\n", wa, urb);
+
+       d_printf(1, dev, "xfer %p urb %p: aborting\n", urb->hcpriv, urb);
+       xfer = urb->hcpriv;
+       if (xfer == NULL) {
+               /* NOthing setup yet enqueue will see urb->status !=
+                * -EINPROGRESS (by hcd layer) and bail out with
+                * error, no need to do completion
+                */
+               BUG_ON(urb->status == -EINPROGRESS);
+               goto out;
+       }
+       spin_lock_irqsave(&xfer->lock, flags);
+       rpipe = xfer->ep->hcpriv;
+       /* Check the delayed list -> if there, release and complete */
+       spin_lock_irqsave(&wa->xfer_list_lock, flags2);
+       if (!list_empty(&xfer->list_node) && xfer->seg == NULL)
+               goto dequeue_delayed;
+       spin_unlock_irqrestore(&wa->xfer_list_lock, flags2);
+       if (xfer->seg == NULL)          /* still hasn't reached */
+               goto out_unlock;        /* setup(), enqueue_b() completes */
+       /* Ok, the xfer is in flight already, it's been setup and submitted.*/
+       __wa_xfer_abort(xfer);
+       for (cnt = 0; cnt < xfer->segs; cnt++) {
+               seg = xfer->seg[cnt];
+               switch (seg->status) {
+               case WA_SEG_NOTREADY:
+               case WA_SEG_READY:
+                       printk(KERN_ERR "xfer %p#%u: dequeue bad state %u\n",
+                              xfer, cnt, seg->status);
+                       WARN_ON(1);
+                       break;
+               case WA_SEG_DELAYED:
+                       seg->status = WA_SEG_ABORTED;
+                       spin_lock_irqsave(&rpipe->seg_lock, flags2);
+                       list_del(&seg->list_node);
+                       xfer->segs_done++;
+                       rpipe_ready = rpipe_avail_inc(rpipe);
+                       spin_unlock_irqrestore(&rpipe->seg_lock, flags2);
+                       break;
+               case WA_SEG_SUBMITTED:
+                       seg->status = WA_SEG_ABORTED;
+                       usb_unlink_urb(&seg->urb);
+                       if (xfer->is_inbound == 0)
+                               usb_unlink_urb(seg->dto_urb);
+                       xfer->segs_done++;
+                       rpipe_ready = rpipe_avail_inc(rpipe);
+                       break;
+               case WA_SEG_PENDING:
+                       seg->status = WA_SEG_ABORTED;
+                       xfer->segs_done++;
+                       rpipe_ready = rpipe_avail_inc(rpipe);
+                       break;
+               case WA_SEG_DTI_PENDING:
+                       usb_unlink_urb(wa->dti_urb);
+                       seg->status = WA_SEG_ABORTED;
+                       xfer->segs_done++;
+                       rpipe_ready = rpipe_avail_inc(rpipe);
+                       break;
+               case WA_SEG_DONE:
+               case WA_SEG_ERROR:
+               case WA_SEG_ABORTED:
+                       break;
+               }
+       }
+       xfer->result = urb->status;     /* -ENOENT or -ECONNRESET */
+       __wa_xfer_is_done(xfer);
+       spin_unlock_irqrestore(&xfer->lock, flags);
+       wa_xfer_completion(xfer);
+       if (rpipe_ready)
+               wa_xfer_delayed_run(rpipe);
+       d_fnend(3, dev, "(wa %p, urb %p) = 0\n", wa, urb);
+       return 0;
+
+out_unlock:
+       spin_unlock_irqrestore(&xfer->lock, flags);
+out:
+       d_fnend(3, dev, "(wa %p, urb %p) = 0\n", wa, urb);
+       return 0;
+
+dequeue_delayed:
+       list_del_init(&xfer->list_node);
+       spin_unlock_irqrestore(&wa->xfer_list_lock, flags2);
+       xfer->result = urb->status;
+       spin_unlock_irqrestore(&xfer->lock, flags);
+       wa_xfer_giveback(xfer);
+       usb_put_urb(urb);               /* we got a ref in enqueue() */
+       d_fnend(3, dev, "(wa %p, urb %p) = 0\n", wa, urb);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(wa_urb_dequeue);
+
+/*
+ * Translation from WA status codes (WUSB1.0 Table 8.15) to errno
+ * codes
+ *
+ * Positive errno values are internal inconsistencies and should be
+ * flagged louder. Negative are to be passed up to the user in the
+ * normal way.
+ *
+ * @status: USB WA status code -- high two bits are stripped.
+ */
+static int wa_xfer_status_to_errno(u8 status)
+{
+       int errno;
+       u8 real_status = status;
+       static int xlat[] = {
+               [WA_XFER_STATUS_SUCCESS] =              0,
+               [WA_XFER_STATUS_HALTED] =               -EPIPE,
+               [WA_XFER_STATUS_DATA_BUFFER_ERROR] =    -ENOBUFS,
+               [WA_XFER_STATUS_BABBLE] =               -EOVERFLOW,
+               [WA_XFER_RESERVED] =                    EINVAL,
+               [WA_XFER_STATUS_NOT_FOUND] =            0,
+               [WA_XFER_STATUS_INSUFFICIENT_RESOURCE] = -ENOMEM,
+               [WA_XFER_STATUS_TRANSACTION_ERROR] =    -EILSEQ,
+               [WA_XFER_STATUS_ABORTED] =              -EINTR,
+               [WA_XFER_STATUS_RPIPE_NOT_READY] =      EINVAL,
+               [WA_XFER_INVALID_FORMAT] =              EINVAL,
+               [WA_XFER_UNEXPECTED_SEGMENT_NUMBER] =   EINVAL,
+               [WA_XFER_STATUS_RPIPE_TYPE_MISMATCH] =  EINVAL,
+       };
+       status &= 0x3f;
+
+       if (status == 0)
+               return 0;
+       if (status >= ARRAY_SIZE(xlat)) {
+               if (printk_ratelimit())
+                       printk(KERN_ERR "%s(): BUG? "
+                              "Unknown WA transfer status 0x%02x\n",
+                              __func__, real_status);
+               return -EINVAL;
+       }
+       errno = xlat[status];
+       if (unlikely(errno > 0)) {
+               if (printk_ratelimit())
+                       printk(KERN_ERR "%s(): BUG? "
+                              "Inconsistent WA status: 0x%02x\n",
+                              __func__, real_status);
+               errno = -errno;
+       }
+       return errno;
+}
+
+/*
+ * Process a xfer result completion message
+ *
+ * inbound transfers: need to schedule a DTI read
+ *
+ * FIXME: this functio needs to be broken up in parts
+ */
+static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer)
+{
+       int result;
+       struct device *dev = &wa->usb_iface->dev;
+       unsigned long flags;
+       u8 seg_idx;
+       struct wa_seg *seg;
+       struct wa_rpipe *rpipe;
+       struct wa_xfer_result *xfer_result = wa->xfer_result;
+       u8 done = 0;
+       u8 usb_status;
+       unsigned rpipe_ready = 0;
+
+       d_fnstart(3, dev, "(wa %p xfer %p)\n", wa, xfer);
+       spin_lock_irqsave(&xfer->lock, flags);
+       seg_idx = xfer_result->bTransferSegment & 0x7f;
+       if (unlikely(seg_idx >= xfer->segs))
+               goto error_bad_seg;
+       seg = xfer->seg[seg_idx];
+       rpipe = xfer->ep->hcpriv;
+       usb_status = xfer_result->bTransferStatus;
+       d_printf(2, dev, "xfer %p#%u: bTransferStatus 0x%02x (seg %u)\n",
+                xfer, seg_idx, usb_status, seg->status);
+       if (seg->status == WA_SEG_ABORTED
+           || seg->status == WA_SEG_ERROR)     /* already handled */
+               goto segment_aborted;
+       if (seg->status == WA_SEG_SUBMITTED)    /* ops, got here */
+               seg->status = WA_SEG_PENDING;   /* before wa_seg{_dto}_cb() */
+       if (seg->status != WA_SEG_PENDING) {
+               if (printk_ratelimit())
+                       dev_err(dev, "xfer %p#%u: Bad segment state %u\n",
+                               xfer, seg_idx, seg->status);
+               seg->status = WA_SEG_PENDING;   /* workaround/"fix" it */
+       }
+       if (usb_status & 0x80) {
+               seg->result = wa_xfer_status_to_errno(usb_status);
+               dev_err(dev, "DTI: xfer %p#%u failed (0x%02x)\n",
+                       xfer, seg->index, usb_status);
+               goto error_complete;
+       }
+       /* FIXME: we ignore warnings, tally them for stats */
+       if (usb_status & 0x40)          /* Warning?... */
+               usb_status = 0;         /* ... pass */
+       if (xfer->is_inbound) { /* IN data phase: read to buffer */
+               seg->status = WA_SEG_DTI_PENDING;
+               BUG_ON(wa->buf_in_urb->status == -EINPROGRESS);
+               if (xfer->is_dma) {
+                       wa->buf_in_urb->transfer_dma =
+                               xfer->urb->transfer_dma
+                               + seg_idx * xfer->seg_size;
+                       wa->buf_in_urb->transfer_flags
+                               |= URB_NO_TRANSFER_DMA_MAP;
+               } else {
+                       wa->buf_in_urb->transfer_buffer =
+                               xfer->urb->transfer_buffer
+                               + seg_idx * xfer->seg_size;
+                       wa->buf_in_urb->transfer_flags
+                               &= ~URB_NO_TRANSFER_DMA_MAP;
+               }
+               wa->buf_in_urb->transfer_buffer_length =
+                       le32_to_cpu(xfer_result->dwTransferLength);
+               wa->buf_in_urb->context = seg;
+               result = usb_submit_urb(wa->buf_in_urb, GFP_ATOMIC);
+               if (result < 0)
+                       goto error_submit_buf_in;
+       } else {
+               /* OUT data phase, complete it -- */
+               seg->status = WA_SEG_DONE;
+               seg->result = le32_to_cpu(xfer_result->dwTransferLength);
+               xfer->segs_done++;
+               rpipe_ready = rpipe_avail_inc(rpipe);
+               done = __wa_xfer_is_done(xfer);
+       }
+       spin_unlock_irqrestore(&xfer->lock, flags);
+       if (done)
+               wa_xfer_completion(xfer);
+       if (rpipe_ready)
+               wa_xfer_delayed_run(rpipe);
+       d_fnend(3, dev, "(wa %p xfer %p) = void\n", wa, xfer);
+       return;
+
+
+error_submit_buf_in:
+       if (edc_inc(&wa->dti_edc, EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) {
+               dev_err(dev, "DTI: URB max acceptable errors "
+                       "exceeded, resetting device\n");
+               wa_reset_all(wa);
+       }
+       if (printk_ratelimit())
+               dev_err(dev, "xfer %p#%u: can't submit DTI data phase: %d\n",
+                       xfer, seg_idx, result);
+       seg->result = result;
+error_complete:
+       seg->status = WA_SEG_ERROR;
+       xfer->segs_done++;
+       rpipe_ready = rpipe_avail_inc(rpipe);
+       __wa_xfer_abort(xfer);
+       done = __wa_xfer_is_done(xfer);
+       spin_unlock_irqrestore(&xfer->lock, flags);
+       if (done)
+               wa_xfer_completion(xfer);
+       if (rpipe_ready)
+               wa_xfer_delayed_run(rpipe);
+       d_fnend(3, dev, "(wa %p xfer %p) = void [segment/DTI-submit error]\n",
+               wa, xfer);
+       return;
+
+
+error_bad_seg:
+       spin_unlock_irqrestore(&xfer->lock, flags);
+       wa_urb_dequeue(wa, xfer->urb);
+       if (printk_ratelimit())
+               dev_err(dev, "xfer %p#%u: bad segment\n", xfer, seg_idx);
+       if (edc_inc(&wa->dti_edc, EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) {
+               dev_err(dev, "DTI: URB max acceptable errors "
+                       "exceeded, resetting device\n");
+               wa_reset_all(wa);
+       }
+       d_fnend(3, dev, "(wa %p xfer %p) = void [bad seg]\n", wa, xfer);
+       return;
+
+
+segment_aborted:
+       /* nothing to do, as the aborter did the completion */
+       spin_unlock_irqrestore(&xfer->lock, flags);
+       d_fnend(3, dev, "(wa %p xfer %p) = void [segment aborted]\n",
+               wa, xfer);
+       return;
+
+}
+
+/*
+ * Callback for the IN data phase
+ *
+ * If succesful transition state; otherwise, take a note of the
+ * error, mark this segment done and try completion.
+ *
+ * Note we don't access until we are sure that the transfer hasn't
+ * been cancelled (ECONNRESET, ENOENT), which could mean that
+ * seg->xfer could be already gone.
+ */
+static void wa_buf_in_cb(struct urb *urb)
+{
+       struct wa_seg *seg = urb->context;
+       struct wa_xfer *xfer = seg->xfer;
+       struct wahc *wa;
+       struct device *dev;
+       struct wa_rpipe *rpipe;
+       unsigned rpipe_ready;
+       unsigned long flags;
+       u8 done = 0;
+
+       d_fnstart(3, NULL, "(urb %p [%d])\n", urb, urb->status);
+       switch (urb->status) {
+       case 0:
+               spin_lock_irqsave(&xfer->lock, flags);
+               wa = xfer->wa;
+               dev = &wa->usb_iface->dev;
+               rpipe = xfer->ep->hcpriv;
+               d_printf(2, dev, "xfer %p#%u: data in done (%zu bytes)\n",
+                          xfer, seg->index, (size_t)urb->actual_length);
+               seg->status = WA_SEG_DONE;
+               seg->result = urb->actual_length;
+               xfer->segs_done++;
+               rpipe_ready = rpipe_avail_inc(rpipe);
+               done = __wa_xfer_is_done(xfer);
+               spin_unlock_irqrestore(&xfer->lock, flags);
+               if (done)
+                       wa_xfer_completion(xfer);
+               if (rpipe_ready)
+                       wa_xfer_delayed_run(rpipe);
+               break;
+       case -ECONNRESET:       /* URB unlinked; no need to do anything */
+       case -ENOENT:           /* as it was done by the who unlinked us */
+               break;
+       default:                /* Other errors ... */
+               spin_lock_irqsave(&xfer->lock, flags);
+               wa = xfer->wa;
+               dev = &wa->usb_iface->dev;
+               rpipe = xfer->ep->hcpriv;
+               if (printk_ratelimit())
+                       dev_err(dev, "xfer %p#%u: data in error %d\n",
+                               xfer, seg->index, urb->status);
+               if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS,
+                           EDC_ERROR_TIMEFRAME)){
+                       dev_err(dev, "DTO: URB max acceptable errors "
+                               "exceeded, resetting device\n");
+                       wa_reset_all(wa);
+               }
+               seg->status = WA_SEG_ERROR;
+               seg->result = urb->status;
+               xfer->segs_done++;
+               rpipe_ready = rpipe_avail_inc(rpipe);
+               __wa_xfer_abort(xfer);
+               done = __wa_xfer_is_done(xfer);
+               spin_unlock_irqrestore(&xfer->lock, flags);
+               if (done)
+                       wa_xfer_completion(xfer);
+               if (rpipe_ready)
+                       wa_xfer_delayed_run(rpipe);
+       }
+       d_fnend(3, NULL, "(urb %p [%d]) = void\n", urb, urb->status);
+}
+
+/*
+ * Handle an incoming transfer result buffer
+ *
+ * Given a transfer result buffer, it completes the transfer (possibly
+ * scheduling and buffer in read) and then resubmits the DTI URB for a
+ * new transfer result read.
+ *
+ *
+ * The xfer_result DTI URB state machine
+ *
+ * States: OFF | RXR (Read-Xfer-Result) | RBI (Read-Buffer-In)
+ *
+ * We start in OFF mode, the first xfer_result notification [through
+ * wa_handle_notif_xfer()] moves us to RXR by posting the DTI-URB to
+ * read.
+ *
+ * We receive a buffer -- if it is not a xfer_result, we complain and
+ * repost the DTI-URB. If it is a xfer_result then do the xfer seg
+ * request accounting. If it is an IN segment, we move to RBI and post
+ * a BUF-IN-URB to the right buffer. The BUF-IN-URB callback will
+ * repost the DTI-URB and move to RXR state. if there was no IN
+ * segment, it will repost the DTI-URB.
+ *
+ * We go back to OFF when we detect a ENOENT or ESHUTDOWN (or too many
+ * errors) in the URBs.
+ */
+static void wa_xfer_result_cb(struct urb *urb)
+{
+       int result;
+       struct wahc *wa = urb->context;
+       struct device *dev = &wa->usb_iface->dev;
+       struct wa_xfer_result *xfer_result;
+       u32 xfer_id;
+       struct wa_xfer *xfer;
+       u8 usb_status;
+
+       d_fnstart(3, dev, "(%p)\n", wa);
+       BUG_ON(wa->dti_urb != urb);
+       switch (wa->dti_urb->status) {
+       case 0:
+               /* We have a xfer result buffer; check it */
+               d_printf(2, dev, "DTI: xfer result %d bytes at %p\n",
+                          urb->actual_length, urb->transfer_buffer);
+               d_dump(3, dev, urb->transfer_buffer, urb->actual_length);
+               if (wa->dti_urb->actual_length != sizeof(*xfer_result)) {
+                       dev_err(dev, "DTI Error: xfer result--bad size "
+                               "xfer result (%d bytes vs %zu needed)\n",
+                               urb->actual_length, sizeof(*xfer_result));
+                       break;
+               }
+               xfer_result = wa->xfer_result;
+               if (xfer_result->hdr.bLength != sizeof(*xfer_result)) {
+                       dev_err(dev, "DTI Error: xfer result--"
+                               "bad header length %u\n",
+                               xfer_result->hdr.bLength);
+                       break;
+               }
+               if (xfer_result->hdr.bNotifyType != WA_XFER_RESULT) {
+                       dev_err(dev, "DTI Error: xfer result--"
+                               "bad header type 0x%02x\n",
+                               xfer_result->hdr.bNotifyType);
+                       break;
+               }
+               usb_status = xfer_result->bTransferStatus & 0x3f;
+               if (usb_status == WA_XFER_STATUS_ABORTED
+                   || usb_status == WA_XFER_STATUS_NOT_FOUND)
+                       /* taken care of already */
+                       break;
+               xfer_id = xfer_result->dwTransferID;
+               xfer = wa_xfer_get_by_id(wa, xfer_id);
+               if (xfer == NULL) {
+                       /* FIXME: transaction might have been cancelled */
+                       dev_err(dev, "DTI Error: xfer result--"
+                               "unknown xfer 0x%08x (status 0x%02x)\n",
+                               xfer_id, usb_status);
+                       break;
+               }
+               wa_xfer_result_chew(wa, xfer);
+               wa_xfer_put(xfer);
+               break;
+       case -ENOENT:           /* (we killed the URB)...so, no broadcast */
+       case -ESHUTDOWN:        /* going away! */
+               dev_dbg(dev, "DTI: going down! %d\n", urb->status);
+               goto out;
+       default:
+               /* Unknown error */
+               if (edc_inc(&wa->dti_edc, EDC_MAX_ERRORS,
+                           EDC_ERROR_TIMEFRAME)) {
+                       dev_err(dev, "DTI: URB max acceptable errors "
+                               "exceeded, resetting device\n");
+                       wa_reset_all(wa);
+                       goto out;
+               }
+               if (printk_ratelimit())
+                       dev_err(dev, "DTI: URB error %d\n", urb->status);
+               break;
+       }
+       /* Resubmit the DTI URB */
+       result = usb_submit_urb(wa->dti_urb, GFP_ATOMIC);
+       if (result < 0) {
+               dev_err(dev, "DTI Error: Could not submit DTI URB (%d), "
+                       "resetting\n", result);
+               wa_reset_all(wa);
+       }
+out:
+       d_fnend(3, dev, "(%p) = void\n", wa);
+       return;
+}
+
+/*
+ * Transfer complete notification
+ *
+ * Called from the notif.c code. We get a notification on EP2 saying
+ * that some endpoint has some transfer result data available. We are
+ * about to read it.
+ *
+ * To speed up things, we always have a URB reading the DTI URB; we
+ * don't really set it up and start it until the first xfer complete
+ * notification arrives, which is what we do here.
+ *
+ * Follow up in wa_xfer_result_cb(), as that's where the whole state
+ * machine starts.
+ *
+ * So here we just initialize the DTI URB for reading transfer result
+ * notifications and also the buffer-in URB, for reading buffers. Then
+ * we just submit the DTI URB.
+ *
+ * @wa shall be referenced
+ */
+void wa_handle_notif_xfer(struct wahc *wa, struct wa_notif_hdr *notif_hdr)
+{
+       int result;
+       struct device *dev = &wa->usb_iface->dev;
+       struct wa_notif_xfer *notif_xfer;
+       const struct usb_endpoint_descriptor *dti_epd = wa->dti_epd;
+
+       d_fnstart(4, dev, "(%p, %p)\n", wa, notif_hdr);
+       notif_xfer = container_of(notif_hdr, struct wa_notif_xfer, hdr);
+       BUG_ON(notif_hdr->bNotifyType != WA_NOTIF_TRANSFER);
+
+       if ((0x80 | notif_xfer->bEndpoint) != dti_epd->bEndpointAddress) {
+               /* FIXME: hardcoded limitation, adapt */
+               dev_err(dev, "BUG: DTI ep is %u, not %u (hack me)\n",
+                       notif_xfer->bEndpoint, dti_epd->bEndpointAddress);
+               goto error;
+       }
+       if (wa->dti_urb != NULL)        /* DTI URB already started */
+               goto out;
+
+       wa->dti_urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (wa->dti_urb == NULL) {
+               dev_err(dev, "Can't allocate DTI URB\n");
+               goto error_dti_urb_alloc;
+       }
+       usb_fill_bulk_urb(
+               wa->dti_urb, wa->usb_dev,
+               usb_rcvbulkpipe(wa->usb_dev, 0x80 | notif_xfer->bEndpoint),
+               wa->xfer_result, wa->xfer_result_size,
+               wa_xfer_result_cb, wa);
+
+       wa->buf_in_urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (wa->buf_in_urb == NULL) {
+               dev_err(dev, "Can't allocate BUF-IN URB\n");
+               goto error_buf_in_urb_alloc;
+       }
+       usb_fill_bulk_urb(
+               wa->buf_in_urb, wa->usb_dev,
+               usb_rcvbulkpipe(wa->usb_dev, 0x80 | notif_xfer->bEndpoint),
+               NULL, 0, wa_buf_in_cb, wa);
+       result = usb_submit_urb(wa->dti_urb, GFP_KERNEL);
+       if (result < 0) {
+               dev_err(dev, "DTI Error: Could not submit DTI URB (%d), "
+                       "resetting\n", result);
+               goto error_dti_urb_submit;
+       }
+out:
+       d_fnend(4, dev, "(%p, %p) = void\n", wa, notif_hdr);
+       return;
+
+error_dti_urb_submit:
+       usb_put_urb(wa->buf_in_urb);
+error_buf_in_urb_alloc:
+       usb_put_urb(wa->dti_urb);
+       wa->dti_urb = NULL;
+error_dti_urb_alloc:
+error:
+       wa_reset_all(wa);
+       d_fnend(4, dev, "(%p, %p) = void\n", wa, notif_hdr);
+       return;
+}
diff --git a/drivers/usb/wusbcore/wusbhc.c b/drivers/usb/wusbcore/wusbhc.c
new file mode 100644 (file)
index 0000000..07c63a3
--- /dev/null
@@ -0,0 +1,418 @@
+/*
+ * Wireless USB Host Controller
+ * sysfs glue, wusbcore module support and life cycle management
+ *
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * Creation/destruction of wusbhc is split in two parts; that that
+ * doesn't require the HCD to be added (wusbhc_{create,destroy}) and
+ * the one that requires (phase B, wusbhc_b_{create,destroy}).
+ *
+ * This is so because usb_add_hcd() will start the HC, and thus, all
+ * the HC specific stuff has to be already initialiazed (like sysfs
+ * thingies).
+ */
+#include <linux/device.h>
+#include <linux/module.h>
+#include "wusbhc.h"
+
+/**
+ * Extract the wusbhc that corresponds to a USB Host Controller class device
+ *
+ * WARNING! Apply only if @dev is that of a
+ *          wusbhc.usb_hcd.self->class_dev; otherwise, you loose.
+ */
+static struct wusbhc *usbhc_dev_to_wusbhc(struct device *dev)
+{
+       struct usb_bus *usb_bus = dev_get_drvdata(dev);
+       struct usb_hcd *usb_hcd = bus_to_hcd(usb_bus);
+       return usb_hcd_to_wusbhc(usb_hcd);
+}
+
+/*
+ * Show & store the current WUSB trust timeout
+ *
+ * We don't do locking--it is an 'atomic' value.
+ *
+ * The units that we store/show are always MILLISECONDS. However, the
+ * value of trust_timeout is jiffies.
+ */
+static ssize_t wusb_trust_timeout_show(struct device *dev,
+                                      struct device_attribute *attr, char *buf)
+{
+       struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);
+
+       return scnprintf(buf, PAGE_SIZE, "%u\n", wusbhc->trust_timeout);
+}
+
+static ssize_t wusb_trust_timeout_store(struct device *dev,
+                                       struct device_attribute *attr,
+                                       const char *buf, size_t size)
+{
+       struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);
+       ssize_t result = -ENOSYS;
+       unsigned trust_timeout;
+
+       result = sscanf(buf, "%u", &trust_timeout);
+       if (result != 1) {
+               result = -EINVAL;
+               goto out;
+       }
+       /* FIXME: maybe we should check for range validity? */
+       wusbhc->trust_timeout = trust_timeout;
+       cancel_delayed_work(&wusbhc->keep_alive_timer);
+       flush_workqueue(wusbd);
+       queue_delayed_work(wusbd, &wusbhc->keep_alive_timer,
+                          (trust_timeout * CONFIG_HZ)/1000/2);
+out:
+       return result < 0 ? result : size;
+}
+static DEVICE_ATTR(wusb_trust_timeout, 0644, wusb_trust_timeout_show,
+                                            wusb_trust_timeout_store);
+
+/*
+ * Show & store the current WUSB CHID
+ */
+static ssize_t wusb_chid_show(struct device *dev,
+                             struct device_attribute *attr, char *buf)
+{
+       struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);
+       ssize_t result = 0;
+
+       if (wusbhc->wuie_host_info != NULL)
+               result += ckhdid_printf(buf, PAGE_SIZE,
+                                       &wusbhc->wuie_host_info->CHID);
+       return result;
+}
+
+/*
+ * Store a new CHID
+ *
+ * This will (FIXME) trigger many changes.
+ *
+ * - Send an all zeros CHID and it will stop the controller
+ * - Send a non-zero CHID and it will start it
+ *   (unless it was started, it will just change the CHID,
+ *   diconnecting all devices first).
+ *
+ * So first we scan the MMC we are sent and then we act on it.  We
+ * read it in the same format as we print it, an ASCII string of 16
+ * hex bytes.
+ *
+ * See wusbhc_chid_set() for more info.
+ */
+static ssize_t wusb_chid_store(struct device *dev,
+                              struct device_attribute *attr,
+                              const char *buf, size_t size)
+{
+       struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);
+       struct wusb_ckhdid chid;
+       ssize_t result;
+
+       result = sscanf(buf,
+                       "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx\n",
+                       &chid.data[0] , &chid.data[1] ,
+                       &chid.data[2] , &chid.data[3] ,
+                       &chid.data[4] , &chid.data[5] ,
+                       &chid.data[6] , &chid.data[7] ,
+                       &chid.data[8] , &chid.data[9] ,
+                       &chid.data[10], &chid.data[11],
+                       &chid.data[12], &chid.data[13],
+                       &chid.data[14], &chid.data[15]);
+       if (result != 16) {
+               dev_err(dev, "Unrecognized CHID (need 16 8-bit hex digits): "
+                       "%d\n", (int)result);
+               return -EINVAL;
+       }
+       result = wusbhc_chid_set(wusbhc, &chid);
+       return result < 0 ? result : size;
+}
+static DEVICE_ATTR(wusb_chid, 0644, wusb_chid_show, wusb_chid_store);
+
+/* Group all the WUSBHC attributes */
+static struct attribute *wusbhc_attrs[] = {
+               &dev_attr_wusb_trust_timeout.attr,
+               &dev_attr_wusb_chid.attr,
+               NULL,
+};
+
+static struct attribute_group wusbhc_attr_group = {
+       .name = NULL,   /* we want them in the same directory */
+       .attrs = wusbhc_attrs,
+};
+
+/*
+ * Create a wusbhc instance
+ *
+ * NOTEs:
+ *
+ *  - assumes *wusbhc has been zeroed and wusbhc->usb_hcd has been
+ *    initialized but not added.
+ *
+ *  - fill out ports_max, mmcies_max and mmcie_{add,rm} before calling.
+ *
+ *  - fill out wusbhc->uwb_rc and refcount it before calling
+ *  - fill out the wusbhc->sec_modes array
+ */
+int wusbhc_create(struct wusbhc *wusbhc)
+{
+       int result = 0;
+
+       wusbhc->trust_timeout = WUSB_TRUST_TIMEOUT_MS;
+       mutex_init(&wusbhc->mutex);
+       result = wusbhc_mmcie_create(wusbhc);
+       if (result < 0)
+               goto error_mmcie_create;
+       result = wusbhc_devconnect_create(wusbhc);
+       if (result < 0)
+               goto error_devconnect_create;
+       result = wusbhc_rh_create(wusbhc);
+       if (result < 0)
+               goto error_rh_create;
+       result = wusbhc_sec_create(wusbhc);
+       if (result < 0)
+               goto error_sec_create;
+       return 0;
+
+error_sec_create:
+       wusbhc_rh_destroy(wusbhc);
+error_rh_create:
+       wusbhc_devconnect_destroy(wusbhc);
+error_devconnect_create:
+       wusbhc_mmcie_destroy(wusbhc);
+error_mmcie_create:
+       return result;
+}
+EXPORT_SYMBOL_GPL(wusbhc_create);
+
+static inline struct kobject *wusbhc_kobj(struct wusbhc *wusbhc)
+{
+       return &wusbhc->usb_hcd.self.controller->kobj;
+}
+
+/*
+ * Phase B of a wusbhc instance creation
+ *
+ * Creates fields that depend on wusbhc->usb_hcd having been
+ * added. This is where we create the sysfs files in
+ * /sys/class/usb_host/usb_hostX/.
+ *
+ * NOTE: Assumes wusbhc->usb_hcd has been already added by the upper
+ *       layer (hwahc or whci)
+ */
+int wusbhc_b_create(struct wusbhc *wusbhc)
+{
+       int result = 0;
+       struct device *dev = wusbhc->usb_hcd.self.controller;
+
+       result = sysfs_create_group(wusbhc_kobj(wusbhc), &wusbhc_attr_group);
+       if (result < 0) {
+               dev_err(dev, "Cannot register WUSBHC attributes: %d\n", result);
+               goto error_create_attr_group;
+       }
+
+       result = wusbhc_pal_register(wusbhc);
+       if (result < 0)
+               goto error_pal_register;
+       return 0;
+
+error_pal_register:
+       sysfs_remove_group(wusbhc_kobj(wusbhc), &wusbhc_attr_group);
+error_create_attr_group:
+       return result;
+}
+EXPORT_SYMBOL_GPL(wusbhc_b_create);
+
+void wusbhc_b_destroy(struct wusbhc *wusbhc)
+{
+       wusbhc_pal_unregister(wusbhc);
+       sysfs_remove_group(wusbhc_kobj(wusbhc), &wusbhc_attr_group);
+}
+EXPORT_SYMBOL_GPL(wusbhc_b_destroy);
+
+void wusbhc_destroy(struct wusbhc *wusbhc)
+{
+       wusbhc_sec_destroy(wusbhc);
+       wusbhc_rh_destroy(wusbhc);
+       wusbhc_devconnect_destroy(wusbhc);
+       wusbhc_mmcie_destroy(wusbhc);
+}
+EXPORT_SYMBOL_GPL(wusbhc_destroy);
+
+struct workqueue_struct *wusbd;
+EXPORT_SYMBOL_GPL(wusbd);
+
+/*
+ * WUSB Cluster ID allocation map
+ *
+ * Each WUSB bus in a channel is identified with a Cluster Id in the
+ * unauth address pace (WUSB1.0[4.3]). We take the range 0xe0 to 0xff
+ * (that's space for 31 WUSB controllers, as 0xff can't be taken). We
+ * start taking from 0xff, 0xfe, 0xfd... (hence the += or -= 0xff).
+ *
+ * For each one we taken, we pin it in the bitap
+ */
+#define CLUSTER_IDS 32
+static DECLARE_BITMAP(wusb_cluster_id_table, CLUSTER_IDS);
+static DEFINE_SPINLOCK(wusb_cluster_ids_lock);
+
+/*
+ * Get a WUSB Cluster ID
+ *
+ * Need to release with wusb_cluster_id_put() when done w/ it.
+ */
+/* FIXME: coordinate with the choose_addres() from the USB stack */
+/* we want to leave the top of the 128 range for cluster addresses and
+ * the bottom for device addresses (as we map them one on one with
+ * ports). */
+u8 wusb_cluster_id_get(void)
+{
+       u8 id;
+       spin_lock(&wusb_cluster_ids_lock);
+       id = find_first_zero_bit(wusb_cluster_id_table, CLUSTER_IDS);
+       if (id > CLUSTER_IDS) {
+               id = 0;
+               goto out;
+       }
+       set_bit(id, wusb_cluster_id_table);
+       id = (u8) 0xff - id;
+out:
+       spin_unlock(&wusb_cluster_ids_lock);
+       return id;
+
+}
+EXPORT_SYMBOL_GPL(wusb_cluster_id_get);
+
+/*
+ * Release a WUSB Cluster ID
+ *
+ * Obtained it with wusb_cluster_id_get()
+ */
+void wusb_cluster_id_put(u8 id)
+{
+       id = 0xff - id;
+       BUG_ON(id >= CLUSTER_IDS);
+       spin_lock(&wusb_cluster_ids_lock);
+       WARN_ON(!test_bit(id, wusb_cluster_id_table));
+       clear_bit(id, wusb_cluster_id_table);
+       spin_unlock(&wusb_cluster_ids_lock);
+}
+EXPORT_SYMBOL_GPL(wusb_cluster_id_put);
+
+/**
+ * wusbhc_giveback_urb - return an URB to the USB core
+ * @wusbhc: the host controller the URB is from.
+ * @urb:    the URB.
+ * @status: the URB's status.
+ *
+ * Return an URB to the USB core doing some additional WUSB specific
+ * processing.
+ *
+ *  - After a successful transfer, update the trust timeout timestamp
+ *    for the WUSB device.
+ *
+ *  - [WUSB] sections 4.13 and 7.5.1 specifies the stop retrasmittion
+ *    condition for the WCONNECTACK_IE is that the host has observed
+ *    the associated device responding to a control transfer.
+ */
+void wusbhc_giveback_urb(struct wusbhc *wusbhc, struct urb *urb, int status)
+{
+       struct wusb_dev *wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev);
+
+       if (status == 0) {
+               wusb_dev->entry_ts = jiffies;
+
+               /* wusbhc_devconnect_acked() can't be called from from
+                  atomic context so defer it to a work queue. */
+               if (!list_empty(&wusb_dev->cack_node))
+                       queue_work(wusbd, &wusb_dev->devconnect_acked_work);
+       }
+
+       usb_hcd_giveback_urb(&wusbhc->usb_hcd, urb, status);
+}
+EXPORT_SYMBOL_GPL(wusbhc_giveback_urb);
+
+/**
+ * wusbhc_reset_all - reset the HC hardware
+ * @wusbhc: the host controller to reset.
+ *
+ * Request a full hardware reset of the chip.  This will also reset
+ * the radio controller and any other PALs.
+ */
+void wusbhc_reset_all(struct wusbhc *wusbhc)
+{
+       uwb_rc_reset_all(wusbhc->uwb_rc);
+}
+EXPORT_SYMBOL_GPL(wusbhc_reset_all);
+
+static struct notifier_block wusb_usb_notifier = {
+       .notifier_call = wusb_usb_ncb,
+       .priority = INT_MAX     /* Need to be called first of all */
+};
+
+static int __init wusbcore_init(void)
+{
+       int result;
+       result = wusb_crypto_init();
+       if (result < 0)
+               goto error_crypto_init;
+       /* WQ is singlethread because we need to serialize notifications */
+       wusbd = create_singlethread_workqueue("wusbd");
+       if (wusbd == NULL) {
+               result = -ENOMEM;
+               printk(KERN_ERR "WUSB-core: Cannot create wusbd workqueue\n");
+               goto error_wusbd_create;
+       }
+       usb_register_notify(&wusb_usb_notifier);
+       bitmap_zero(wusb_cluster_id_table, CLUSTER_IDS);
+       set_bit(0, wusb_cluster_id_table);      /* reserve Cluster ID 0xff */
+       return 0;
+
+error_wusbd_create:
+       wusb_crypto_exit();
+error_crypto_init:
+       return result;
+
+}
+module_init(wusbcore_init);
+
+static void __exit wusbcore_exit(void)
+{
+       clear_bit(0, wusb_cluster_id_table);
+       if (!bitmap_empty(wusb_cluster_id_table, CLUSTER_IDS)) {
+               char buf[256];
+               bitmap_scnprintf(buf, sizeof(buf), wusb_cluster_id_table,
+                                CLUSTER_IDS);
+               printk(KERN_ERR "BUG: WUSB Cluster IDs not released "
+                      "on exit: %s\n", buf);
+               WARN_ON(1);
+       }
+       usb_unregister_notify(&wusb_usb_notifier);
+       destroy_workqueue(wusbd);
+       wusb_crypto_exit();
+}
+module_exit(wusbcore_exit);
+
+MODULE_AUTHOR("Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>");
+MODULE_DESCRIPTION("Wireless USB core");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/wusbcore/wusbhc.h b/drivers/usb/wusbcore/wusbhc.h
new file mode 100644 (file)
index 0000000..d0c1324
--- /dev/null
@@ -0,0 +1,495 @@
+/*
+ * Wireless USB Host Controller
+ * Common infrastructure for WHCI and HWA WUSB-HC drivers
+ *
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * This driver implements parts common to all Wireless USB Host
+ * Controllers (struct wusbhc, embedding a struct usb_hcd) and is used
+ * by:
+ *
+ *   - hwahc: HWA, USB-dongle that implements a Wireless USB host
+ *     controller, (Wireless USB 1.0 Host-Wire-Adapter specification).
+ *
+ *   - whci: WHCI, a PCI card with a wireless host controller
+ *     (Wireless Host Controller Interface 1.0 specification).
+ *
+ * Check out the Design-overview.txt file in the source documentation
+ * for other details on the implementation.
+ *
+ * Main blocks:
+ *
+ *  rh         Root Hub emulation (part of the HCD glue)
+ *
+ *  devconnect Handle all the issues related to device connection,
+ *             authentication, disconnection, timeout, reseting,
+ *             keepalives, etc.
+ *
+ *  mmc        MMC IE broadcasting handling
+ *
+ * A host controller driver just initializes its stuff and as part of
+ * that, creates a 'struct wusbhc' instance that handles all the
+ * common WUSB mechanisms. Links in the function ops that are specific
+ * to it and then registers the host controller. Ready to run.
+ */
+
+#ifndef __WUSBHC_H__
+#define __WUSBHC_H__
+
+#include <linux/usb.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/kref.h>
+#include <linux/workqueue.h>
+/* FIXME: Yes, I know: BAD--it's not my fault the USB HC iface is not
+ *        public */
+#include <linux/../../drivers/usb/core/hcd.h>
+#include <linux/uwb.h>
+#include <linux/usb/wusb.h>
+
+
+/**
+ * Wireless USB device
+ *
+ * Describe a WUSB device connected to the cluster. This struct
+ * belongs to the 'struct wusb_port' it is attached to and it is
+ * responsible for putting and clearing the pointer to it.
+ *
+ * Note this "complements" the 'struct usb_device' that the usb_hcd
+ * keeps for each connected USB device. However, it extends some
+ * information that is not available (there is no hcpriv ptr in it!)
+ * *and* most importantly, it's life cycle is different. It is created
+ * as soon as we get a DN_Connect (connect request notification) from
+ * the device through the WUSB host controller; the USB stack doesn't
+ * create the device until we authenticate it. FIXME: this will
+ * change.
+ *
+ * @bos:    This is allocated when the BOS descriptors are read from
+ *          the device and freed upon the wusb_dev struct dying.
+ * @wusb_cap_descr: points into @bos, and has been verified to be size
+ *                  safe.
+ */
+struct wusb_dev {
+       struct kref refcnt;
+       struct wusbhc *wusbhc;
+       struct list_head cack_node;     /* Connect-Ack list */
+       u8 port_idx;
+       u8 addr;
+       u8 beacon_type:4;
+       struct usb_encryption_descriptor ccm1_etd;
+       struct wusb_ckhdid cdid;
+       unsigned long entry_ts;
+       struct usb_bos_descriptor *bos;
+       struct usb_wireless_cap_descriptor *wusb_cap_descr;
+       struct uwb_mas_bm availability;
+       struct work_struct devconnect_acked_work;
+       struct urb *set_gtk_urb;
+       struct usb_ctrlrequest *set_gtk_req;
+       struct usb_device *usb_dev;
+};
+
+#define WUSB_DEV_ADDR_UNAUTH 0x80
+
+static inline void wusb_dev_init(struct wusb_dev *wusb_dev)
+{
+       kref_init(&wusb_dev->refcnt);
+       /* no need to init the cack_node */
+}
+
+extern void wusb_dev_destroy(struct kref *_wusb_dev);
+
+static inline struct wusb_dev *wusb_dev_get(struct wusb_dev *wusb_dev)
+{
+       kref_get(&wusb_dev->refcnt);
+       return wusb_dev;
+}
+
+static inline void wusb_dev_put(struct wusb_dev *wusb_dev)
+{
+       kref_put(&wusb_dev->refcnt, wusb_dev_destroy);
+}
+
+/**
+ * Wireless USB Host Controlller root hub "fake" ports
+ * (state and device information)
+ *
+ * Wireless USB is wireless, so there are no ports; but we
+ * fake'em. Each RC can connect a max of devices at the same time
+ * (given in the Wireless Adapter descriptor, bNumPorts or WHCI's
+ * caps), referred to in wusbhc->ports_max.
+ *
+ * See rh.c for more information.
+ *
+ * The @status and @change use the same bits as in USB2.0[11.24.2.7],
+ * so we don't have to do much when getting the port's status.
+ *
+ * WUSB1.0[7.1], USB2.0[11.24.2.7.1,fig 11-10],
+ * include/linux/usb_ch9.h (#define USB_PORT_STAT_*)
+ */
+struct wusb_port {
+       u16 status;
+       u16 change;
+       struct wusb_dev *wusb_dev;      /* connected device's info */
+       unsigned reset_count;
+       u32 ptk_tkid;
+};
+
+/**
+ * WUSB Host Controller specifics
+ *
+ * All fields that are common to all Wireless USB controller types
+ * (HWA and WHCI) are grouped here. Host Controller
+ * functions/operations that only deal with general Wireless USB HC
+ * issues use this data type to refer to the host.
+ *
+ * @usb_hcd       Instantiation of a USB host controller
+ *                 (initialized by upper layer [HWA=HC or WHCI].
+ *
+ * @dev                   Device that implements this; initialized by the
+ *                 upper layer (HWA-HC, WHCI...); this device should
+ *                 have a refcount.
+ *
+ * @trust_timeout  After this time without hearing for device
+ *                 activity, we consider the device gone and we have to
+ *                 re-authenticate.
+ *
+ *                 Can be accessed w/o locking--however, read to a
+ *                 local variable then use.
+ *
+ * @chid           WUSB Cluster Host ID: this is supposed to be a
+ *                 unique value that doesn't change across reboots (so
+ *                 that your devices do not require re-association).
+ *
+ *                 Read/Write protected by @mutex
+ *
+ * @dev_info       This array has ports_max elements. It is used to
+ *                 give the HC information about the WUSB devices (see
+ *                 'struct wusb_dev_info').
+ *
+ *                For HWA we need to allocate it in heap; for WHCI it
+ *                 needs to be permanently mapped, so we keep it for
+ *                 both and make it easy. Call wusbhc->dev_info_set()
+ *                 to update an entry.
+ *
+ * @ports_max     Number of simultaneous device connections (fake
+ *                 ports) this HC will take. Read-only.
+ *
+ * @port          Array of port status for each fake root port. Guaranteed to
+ *                 always be the same lenght during device existence
+ *                 [this allows for some unlocked but referenced reading].
+ *
+ * @mmcies_max    Max number of Information Elements this HC can send
+ *                 in its MMC. Read-only.
+ *
+ * @mmcie_add     HC specific operation (WHCI or HWA) for adding an
+ *                 MMCIE.
+ *
+ * @mmcie_rm      HC specific operation (WHCI or HWA) for removing an
+ *                 MMCIE.
+ *
+ * @enc_types     Array which describes the encryptions methods
+ *                 supported by the host as described in WUSB1.0 --
+ *                 one entry per supported method. As of WUSB1.0 there
+ *                 is only four methods, we make space for eight just in
+ *                 case they decide to add some more (and pray they do
+ *                 it in sequential order). if 'enc_types[enc_method]
+ *                 != 0', then it is supported by the host. enc_method
+ *                 is USB_ENC_TYPE*.
+ *
+ * @set_ptk:       Set the PTK and enable encryption for a device. Or, if
+ *                 the supplied key is NULL, disable encryption for that
+ *                 device.
+ *
+ * @set_gtk:       Set the GTK to be used for all future broadcast packets
+ *                 (i.e., MMCs).  With some hardware, setting the GTK may start
+ *                 MMC transmission.
+ *
+ * NOTE:
+ *
+ *  - If wusb_dev->usb_dev is not NULL, then usb_dev is valid
+ *    (wusb_dev has a refcount on it). Likewise, if usb_dev->wusb_dev
+ *    is not NULL, usb_dev->wusb_dev is valid (usb_dev keeps a
+ *    refcount on it).
+ *
+ *    Most of the times when you need to use it, it will be non-NULL,
+ *    so there is no real need to check for it (wusb_dev will
+ *    dissapear before usb_dev).
+ *
+ *  - The following fields need to be filled out before calling
+ *    wusbhc_create(): ports_max, mmcies_max, mmcie_{add,rm}.
+ *
+ *  - there is no wusbhc_init() method, we do everything in
+ *    wusbhc_create().
+ *
+ *  - Creation is done in two phases, wusbhc_create() and
+ *    wusbhc_create_b(); b are the parts that need to be called after
+ *    calling usb_hcd_add(&wusbhc->usb_hcd).
+ */
+struct wusbhc {
+       struct usb_hcd usb_hcd;         /* HAS TO BE 1st */
+       struct device *dev;
+       struct uwb_rc *uwb_rc;
+       struct uwb_pal pal;
+
+       unsigned trust_timeout;                 /* in jiffies */
+       struct wuie_host_info *wuie_host_info;  /* Includes CHID */
+
+       struct mutex mutex;                     /* locks everything else */
+       u16 cluster_id;                         /* Wireless USB Cluster ID */
+       struct wusb_port *port;                 /* Fake port status handling */
+       struct wusb_dev_info *dev_info;         /* for Set Device Info mgmt */
+       u8 ports_max;
+       unsigned active:1;                      /* currently xmit'ing MMCs */
+       struct wuie_keep_alive keep_alive_ie;   /* protected by mutex */
+       struct delayed_work keep_alive_timer;
+       struct list_head cack_list;             /* Connect acknowledging */
+       size_t cack_count;                      /* protected by 'mutex' */
+       struct wuie_connect_ack cack_ie;
+       struct uwb_rsv *rsv;            /* cluster bandwidth reservation */
+
+       struct mutex mmcie_mutex;               /* MMC WUIE handling */
+       struct wuie_hdr **mmcie;                /* WUIE array */
+       u8 mmcies_max;
+       /* FIXME: make wusbhc_ops? */
+       int (*start)(struct wusbhc *wusbhc);
+       void (*stop)(struct wusbhc *wusbhc);
+       int (*mmcie_add)(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt,
+                        u8 handle, struct wuie_hdr *wuie);
+       int (*mmcie_rm)(struct wusbhc *wusbhc, u8 handle);
+       int (*dev_info_set)(struct wusbhc *, struct wusb_dev *wusb_dev);
+       int (*bwa_set)(struct wusbhc *wusbhc, s8 stream_index,
+                      const struct uwb_mas_bm *);
+       int (*set_ptk)(struct wusbhc *wusbhc, u8 port_idx,
+                      u32 tkid, const void *key, size_t key_size);
+       int (*set_gtk)(struct wusbhc *wusbhc,
+                      u32 tkid, const void *key, size_t key_size);
+       int (*set_num_dnts)(struct wusbhc *wusbhc, u8 interval, u8 slots);
+
+       struct {
+               struct usb_key_descriptor descr;
+               u8 data[16];                            /* GTK key data */
+       } __attribute__((packed)) gtk;
+       u8 gtk_index;
+       u32 gtk_tkid;
+       struct work_struct gtk_rekey_done_work;
+       int pending_set_gtks;
+
+       struct usb_encryption_descriptor *ccm1_etd;
+};
+
+#define usb_hcd_to_wusbhc(u) container_of((u), struct wusbhc, usb_hcd)
+
+
+extern int wusbhc_create(struct wusbhc *);
+extern int wusbhc_b_create(struct wusbhc *);
+extern void wusbhc_b_destroy(struct wusbhc *);
+extern void wusbhc_destroy(struct wusbhc *);
+extern int wusb_dev_sysfs_add(struct wusbhc *, struct usb_device *,
+                             struct wusb_dev *);
+extern void wusb_dev_sysfs_rm(struct wusb_dev *);
+extern int wusbhc_sec_create(struct wusbhc *);
+extern int wusbhc_sec_start(struct wusbhc *);
+extern void wusbhc_sec_stop(struct wusbhc *);
+extern void wusbhc_sec_destroy(struct wusbhc *);
+extern void wusbhc_giveback_urb(struct wusbhc *wusbhc, struct urb *urb,
+                               int status);
+void wusbhc_reset_all(struct wusbhc *wusbhc);
+
+int wusbhc_pal_register(struct wusbhc *wusbhc);
+void wusbhc_pal_unregister(struct wusbhc *wusbhc);
+
+/*
+ * Return @usb_dev's @usb_hcd (properly referenced) or NULL if gone
+ *
+ * @usb_dev: USB device, UNLOCKED and referenced (or otherwise, safe ptr)
+ *
+ * This is a safe assumption as @usb_dev->bus is referenced all the
+ * time during the @usb_dev life cycle.
+ */
+static inline struct usb_hcd *usb_hcd_get_by_usb_dev(struct usb_device *usb_dev)
+{
+       struct usb_hcd *usb_hcd;
+       usb_hcd = container_of(usb_dev->bus, struct usb_hcd, self);
+       return usb_get_hcd(usb_hcd);
+}
+
+/*
+ * Increment the reference count on a wusbhc.
+ *
+ * @wusbhc's life cycle is identical to that of the underlying usb_hcd.
+ */
+static inline struct wusbhc *wusbhc_get(struct wusbhc *wusbhc)
+{
+       return usb_get_hcd(&wusbhc->usb_hcd) ? wusbhc : NULL;
+}
+
+/*
+ * Return the wusbhc associated to a @usb_dev
+ *
+ * @usb_dev: USB device, UNLOCKED and referenced (or otherwise, safe ptr)
+ *
+ * @returns: wusbhc for @usb_dev; NULL if the @usb_dev is being torn down.
+ *           WARNING: referenced at the usb_hcd level, unlocked
+ *
+ * FIXME: move offline
+ */
+static inline struct wusbhc *wusbhc_get_by_usb_dev(struct usb_device *usb_dev)
+{
+       struct wusbhc *wusbhc = NULL;
+       struct usb_hcd *usb_hcd;
+       if (usb_dev->devnum > 1 && !usb_dev->wusb) {
+               /* but root hubs */
+               dev_err(&usb_dev->dev, "devnum %d wusb %d\n", usb_dev->devnum,
+                       usb_dev->wusb);
+               BUG_ON(usb_dev->devnum > 1 && !usb_dev->wusb);
+       }
+       usb_hcd = usb_hcd_get_by_usb_dev(usb_dev);
+       if (usb_hcd == NULL)
+               return NULL;
+       BUG_ON(usb_hcd->wireless == 0);
+       return wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+}
+
+
+static inline void wusbhc_put(struct wusbhc *wusbhc)
+{
+       usb_put_hcd(&wusbhc->usb_hcd);
+}
+
+int wusbhc_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid);
+void wusbhc_stop(struct wusbhc *wusbhc);
+extern int wusbhc_chid_set(struct wusbhc *, const struct wusb_ckhdid *);
+
+/* Device connect handling */
+extern int wusbhc_devconnect_create(struct wusbhc *);
+extern void wusbhc_devconnect_destroy(struct wusbhc *);
+extern int wusbhc_devconnect_start(struct wusbhc *wusbhc,
+                                  const struct wusb_ckhdid *chid);
+extern void wusbhc_devconnect_stop(struct wusbhc *wusbhc);
+extern int wusbhc_devconnect_auth(struct wusbhc *, u8);
+extern void wusbhc_handle_dn(struct wusbhc *, u8 srcaddr,
+                            struct wusb_dn_hdr *dn_hdr, size_t size);
+extern int wusbhc_dev_reset(struct wusbhc *wusbhc, u8 port);
+extern void __wusbhc_dev_disable(struct wusbhc *wusbhc, u8 port);
+extern int wusb_usb_ncb(struct notifier_block *nb, unsigned long val,
+                       void *priv);
+extern int wusb_set_dev_addr(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev,
+                            u8 addr);
+
+/* Wireless USB fake Root Hub methods */
+extern int wusbhc_rh_create(struct wusbhc *);
+extern void wusbhc_rh_destroy(struct wusbhc *);
+
+extern int wusbhc_rh_status_data(struct usb_hcd *, char *);
+extern int wusbhc_rh_control(struct usb_hcd *, u16, u16, u16, char *, u16);
+extern int wusbhc_rh_suspend(struct usb_hcd *);
+extern int wusbhc_rh_resume(struct usb_hcd *);
+extern int wusbhc_rh_start_port_reset(struct usb_hcd *, unsigned);
+
+/* MMC handling */
+extern int wusbhc_mmcie_create(struct wusbhc *);
+extern void wusbhc_mmcie_destroy(struct wusbhc *);
+extern int wusbhc_mmcie_set(struct wusbhc *, u8 interval, u8 repeat_cnt,
+                           struct wuie_hdr *);
+extern void wusbhc_mmcie_rm(struct wusbhc *, struct wuie_hdr *);
+
+/* Bandwidth reservation */
+int wusbhc_rsv_establish(struct wusbhc *wusbhc);
+void wusbhc_rsv_terminate(struct wusbhc *wusbhc);
+
+/*
+ * I've always said
+ * I wanted a wedding in a church...
+ *
+ * but lately I've been thinking about
+ * the Botanical Gardens.
+ *
+ * We could do it by the tulips.
+ * It'll be beautiful
+ *
+ * --Security!
+ */
+extern int wusb_dev_sec_add(struct wusbhc *, struct usb_device *,
+                               struct wusb_dev *);
+extern void wusb_dev_sec_rm(struct wusb_dev *) ;
+extern int wusb_dev_4way_handshake(struct wusbhc *, struct wusb_dev *,
+                                  struct wusb_ckhdid *ck);
+void wusbhc_gtk_rekey(struct wusbhc *wusbhc);
+
+
+/* WUSB Cluster ID handling */
+extern u8 wusb_cluster_id_get(void);
+extern void wusb_cluster_id_put(u8);
+
+/*
+ * wusb_port_by_idx - return the port associated to a zero-based port index
+ *
+ * NOTE: valid without locking as long as wusbhc is referenced (as the
+ *       number of ports doesn't change). The data pointed to has to
+ *       be verified though :)
+ */
+static inline struct wusb_port *wusb_port_by_idx(struct wusbhc *wusbhc,
+                                                u8 port_idx)
+{
+       return &wusbhc->port[port_idx];
+}
+
+/*
+ * wusb_port_no_to_idx - Convert port number (per usb_dev->portnum) to
+ * a port_idx.
+ *
+ * USB stack USB ports are 1 based!!
+ *
+ * NOTE: only valid for WUSB devices!!!
+ */
+static inline u8 wusb_port_no_to_idx(u8 port_no)
+{
+       return port_no - 1;
+}
+
+extern struct wusb_dev *__wusb_dev_get_by_usb_dev(struct wusbhc *,
+                                                 struct usb_device *);
+
+/*
+ * Return a referenced wusb_dev given a @usb_dev
+ *
+ * Returns NULL if the usb_dev is being torn down.
+ *
+ * FIXME: move offline
+ */
+static inline
+struct wusb_dev *wusb_dev_get_by_usb_dev(struct usb_device *usb_dev)
+{
+       struct wusbhc *wusbhc;
+       struct wusb_dev *wusb_dev;
+       wusbhc = wusbhc_get_by_usb_dev(usb_dev);
+       if (wusbhc == NULL)
+               return NULL;
+       mutex_lock(&wusbhc->mutex);
+       wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, usb_dev);
+       mutex_unlock(&wusbhc->mutex);
+       wusbhc_put(wusbhc);
+       return wusb_dev;
+}
+
+/* Misc */
+
+extern struct workqueue_struct *wusbd;
+#endif /* #ifndef __WUSBHC_H__ */
diff --git a/drivers/uwb/Kconfig b/drivers/uwb/Kconfig
new file mode 100644 (file)
index 0000000..ca78312
--- /dev/null
@@ -0,0 +1,90 @@
+#
+# UWB device configuration
+#
+
+menuconfig UWB
+       tristate "Ultra Wideband devices (EXPERIMENTAL)"
+       depends on EXPERIMENTAL
+       depends on PCI
+       default n
+       help
+         UWB is a high-bandwidth, low-power, point-to-point radio
+         technology using a wide spectrum (3.1-10.6GHz). It is
+         optimized for in-room use (480Mbps at 2 meters, 110Mbps at
+         10m). It serves as the transport layer for other protocols,
+         such as Wireless USB (WUSB), IP (WLP) and upcoming
+         Bluetooth and 1394
+
+         The topology is peer to peer; however, higher level
+         protocols (such as WUSB) might impose a master/slave
+         relationship.
+
+         Say Y here if your computer has UWB radio controllers (USB or PCI)
+         based. You will need to enable the radio controllers
+         below.  It is ok to select all of them, no harm done.
+
+         For more help check the UWB and WUSB related files in
+         <file:Documentation/usb/>.
+
+         To compile the UWB stack as a module, choose M here.
+
+if UWB
+
+config UWB_HWA
+       tristate "UWB Radio Control driver for WUSB-compliant USB dongles (HWA)"
+       depends on USB
+       help
+         This driver enables the radio controller for HWA USB
+         devices. HWA stands for Host Wire Adapter, and it is a UWB
+         Radio Controller connected to your system via USB. Most of
+         them come with a Wireless USB host controller also.
+
+         To compile this driver select Y (built in) or M (module). It
+         is safe to select any even if you do not have the hardware.
+
+config UWB_WHCI
+        tristate "UWB Radio Control driver for WHCI-compliant cards"
+        depends on PCI
+        help
+          This driver enables the radio controller for WHCI cards.
+
+          WHCI is an specification developed by Intel
+          (http://www.intel.com/technology/comms/wusb/whci.htm) much
+          in the spirit of USB's EHCI, but for UWB and Wireless USB
+          radio/host controllers connected via memmory mapping (eg:
+          PCI). Most of these cards come also with a Wireless USB host
+          controller.
+
+          To compile this driver select Y (built in) or M (module). It
+          is safe to select any even if you do not have the hardware.
+
+config UWB_WLP
+       tristate "Support WiMedia Link Protocol (Ethernet/IP over UWB)"
+       depends on UWB && NET
+       help
+         This is a common library for drivers that implement
+         networking over UWB.
+
+config UWB_I1480U
+        tristate "Support for Intel Wireless UWB Link 1480 HWA"
+        depends on UWB_HWA
+        select FW_LOADER
+        help
+         This driver enables support for the i1480 when connected via
+         USB. It consists of a firmware uploader that will enable it
+         to behave as an HWA device.
+
+         To compile this driver select Y (built in) or M (module). It
+         is safe to select any even if you do not have the hardware.
+
+config UWB_I1480U_WLP
+        tristate "Support for Intel Wireless UWB Link 1480 HWA's WLP interface"
+        depends on UWB_I1480U &&  UWB_WLP && NET
+        help
+         This driver enables WLP support for the i1480 when connected via
+         USB. WLP is the WiMedia Link Protocol, or IP over UWB.
+
+         To compile this driver select Y (built in) or M (module). It
+         is safe to select any even if you don't have the hardware.
+
+endif # UWB
diff --git a/drivers/uwb/Makefile b/drivers/uwb/Makefile
new file mode 100644 (file)
index 0000000..257e690
--- /dev/null
@@ -0,0 +1,29 @@
+obj-$(CONFIG_UWB)              += uwb.o
+obj-$(CONFIG_UWB_WLP)          += wlp/
+obj-$(CONFIG_UWB_WHCI)         += umc.o whci.o whc-rc.o
+obj-$(CONFIG_UWB_HWA)          += hwa-rc.o
+obj-$(CONFIG_UWB_I1480U)       += i1480/
+
+uwb-objs :=            \
+       address.o       \
+       beacon.o        \
+       driver.o        \
+       drp.o           \
+       drp-avail.o     \
+       drp-ie.o        \
+       est.o           \
+       ie.o            \
+       lc-dev.o        \
+       lc-rc.o         \
+       neh.o           \
+       pal.o           \
+       reset.o         \
+       rsv.o           \
+       scan.o          \
+       uwb-debug.o     \
+       uwbd.o
+
+umc-objs :=            \
+       umc-bus.o       \
+       umc-dev.o       \
+       umc-drv.o
diff --git a/drivers/uwb/address.c b/drivers/uwb/address.c
new file mode 100644 (file)
index 0000000..1664ae5
--- /dev/null
@@ -0,0 +1,374 @@
+/*
+ * Ultra Wide Band
+ * Address management
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/random.h>
+#include <linux/etherdevice.h>
+#include <linux/uwb/debug.h>
+#include "uwb-internal.h"
+
+
+/** Device Address Management command */
+struct uwb_rc_cmd_dev_addr_mgmt {
+       struct uwb_rccb rccb;
+       u8 bmOperationType;
+       u8 baAddr[6];
+} __attribute__((packed));
+
+
+/**
+ * Low level command for setting/getting UWB radio's addresses
+ *
+ * @hwarc:     HWA Radio Control interface instance
+ * @bmOperationType:
+ *             Set/get, MAC/DEV (see WUSB1.0[8.6.2.2])
+ * @baAddr:    address buffer--assumed to have enough data to hold
+ *              the address type requested.
+ * @reply:     Pointer to reply buffer (can be stack allocated)
+ * @returns:   0 if ok, < 0 errno code on error.
+ *
+ * @cmd has to be allocated because USB cannot grok USB or vmalloc
+ * buffers depending on your combination of host architecture.
+ */
+static
+int uwb_rc_dev_addr_mgmt(struct uwb_rc *rc,
+                        u8 bmOperationType, const u8 *baAddr,
+                        struct uwb_rc_evt_dev_addr_mgmt *reply)
+{
+       int result;
+       struct uwb_rc_cmd_dev_addr_mgmt *cmd;
+
+       result = -ENOMEM;
+       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+       if (cmd == NULL)
+               goto error_kzalloc;
+       cmd->rccb.bCommandType = UWB_RC_CET_GENERAL;
+       cmd->rccb.wCommand = cpu_to_le16(UWB_RC_CMD_DEV_ADDR_MGMT);
+       cmd->bmOperationType = bmOperationType;
+       if (baAddr) {
+               size_t size = 0;
+               switch (bmOperationType >> 1) {
+               case 0: size = 2; break;
+               case 1: size = 6; break;
+               default: BUG();
+               }
+               memcpy(cmd->baAddr, baAddr, size);
+       }
+       reply->rceb.bEventType = UWB_RC_CET_GENERAL;
+       reply->rceb.wEvent = UWB_RC_CMD_DEV_ADDR_MGMT;
+       result = uwb_rc_cmd(rc, "DEV-ADDR-MGMT",
+                           &cmd->rccb, sizeof(*cmd),
+                           &reply->rceb, sizeof(*reply));
+       if (result < 0)
+               goto error_cmd;
+       if (result < sizeof(*reply)) {
+               dev_err(&rc->uwb_dev.dev,
+                       "DEV-ADDR-MGMT: not enough data replied: "
+                       "%d vs %zu bytes needed\n", result, sizeof(*reply));
+               result = -ENOMSG;
+       } else if (reply->bResultCode != UWB_RC_RES_SUCCESS) {
+               dev_err(&rc->uwb_dev.dev,
+                       "DEV-ADDR-MGMT: command execution failed: %s (%d)\n",
+                       uwb_rc_strerror(reply->bResultCode),
+                       reply->bResultCode);
+               result = -EIO;
+       } else
+               result = 0;
+error_cmd:
+       kfree(cmd);
+error_kzalloc:
+       return result;
+}
+
+
+/**
+ * Set the UWB RC MAC or device address.
+ *
+ * @rc:      UWB Radio Controller
+ * @_addr:   Pointer to address to write [assumed to be either a
+ *           'struct uwb_mac_addr *' or a 'struct uwb_dev_addr *'].
+ * @type:    Type of address to set (UWB_ADDR_DEV or UWB_ADDR_MAC).
+ * @returns: 0 if ok, < 0 errno code on error.
+ *
+ * Some anal retentivity here: even if both 'struct
+ * uwb_{dev,mac}_addr' have the actual byte array in the same offset
+ * and I could just pass _addr to hwarc_cmd_dev_addr_mgmt(), I prefer
+ * to use some syntatic sugar in case someday we decide to change the
+ * format of the structs. The compiler will optimize it out anyway.
+ */
+static int uwb_rc_addr_set(struct uwb_rc *rc,
+                   const void *_addr, enum uwb_addr_type type)
+{
+       int result;
+       u8 bmOperationType = 0x1;               /* Set address */
+       const struct uwb_dev_addr *dev_addr = _addr;
+       const struct uwb_mac_addr *mac_addr = _addr;
+       struct uwb_rc_evt_dev_addr_mgmt reply;
+       const u8 *baAddr;
+
+       result = -EINVAL;
+       switch (type) {
+       case UWB_ADDR_DEV:
+               baAddr = dev_addr->data;
+               break;
+       case UWB_ADDR_MAC:
+               baAddr = mac_addr->data;
+               bmOperationType |= 0x2;
+               break;
+       default:
+               return result;
+       }
+       return uwb_rc_dev_addr_mgmt(rc, bmOperationType, baAddr, &reply);
+}
+
+
+/**
+ * Get the UWB radio's MAC or device address.
+ *
+ * @rc:      UWB Radio Controller
+ * @_addr:   Where to write the address data [assumed to be either a
+ *           'struct uwb_mac_addr *' or a 'struct uwb_dev_addr *'].
+ * @type:    Type of address to get (UWB_ADDR_DEV or UWB_ADDR_MAC).
+ * @returns: 0 if ok (and *_addr set), < 0 errno code on error.
+ *
+ * See comment in uwb_rc_addr_set() about anal retentivity in the
+ * type handling of the address variables.
+ */
+static int uwb_rc_addr_get(struct uwb_rc *rc,
+                   void *_addr, enum uwb_addr_type type)
+{
+       int result;
+       u8 bmOperationType = 0x0;               /* Get address */
+       struct uwb_rc_evt_dev_addr_mgmt evt;
+       struct uwb_dev_addr *dev_addr = _addr;
+       struct uwb_mac_addr *mac_addr = _addr;
+       u8 *baAddr;
+
+       result = -EINVAL;
+       switch (type) {
+       case UWB_ADDR_DEV:
+               baAddr = dev_addr->data;
+               break;
+       case UWB_ADDR_MAC:
+               bmOperationType |= 0x2;
+               baAddr = mac_addr->data;
+               break;
+       default:
+               return result;
+       }
+       result = uwb_rc_dev_addr_mgmt(rc, bmOperationType, baAddr, &evt);
+       if (result == 0)
+               switch (type) {
+               case UWB_ADDR_DEV:
+                       memcpy(&dev_addr->data, evt.baAddr,
+                              sizeof(dev_addr->data));
+                       break;
+               case UWB_ADDR_MAC:
+                       memcpy(&mac_addr->data, evt.baAddr,
+                              sizeof(mac_addr->data));
+                       break;
+               default:                /* shut gcc up */
+                       BUG();
+               }
+       return result;
+}
+
+
+/** Get @rc's MAC address to @addr */
+int uwb_rc_mac_addr_get(struct uwb_rc *rc,
+                       struct uwb_mac_addr *addr) {
+       return uwb_rc_addr_get(rc, addr, UWB_ADDR_MAC);
+}
+EXPORT_SYMBOL_GPL(uwb_rc_mac_addr_get);
+
+
+/** Get @rc's device address to @addr */
+int uwb_rc_dev_addr_get(struct uwb_rc *rc,
+                       struct uwb_dev_addr *addr) {
+       return uwb_rc_addr_get(rc, addr, UWB_ADDR_DEV);
+}
+EXPORT_SYMBOL_GPL(uwb_rc_dev_addr_get);
+
+
+/** Set @rc's address to @addr */
+int uwb_rc_mac_addr_set(struct uwb_rc *rc,
+                       const struct uwb_mac_addr *addr)
+{
+       int result = -EINVAL;
+       mutex_lock(&rc->uwb_dev.mutex);
+       result = uwb_rc_addr_set(rc, addr, UWB_ADDR_MAC);
+       mutex_unlock(&rc->uwb_dev.mutex);
+       return result;
+}
+
+
+/** Set @rc's address to @addr */
+int uwb_rc_dev_addr_set(struct uwb_rc *rc,
+                       const struct uwb_dev_addr *addr)
+{
+       int result = -EINVAL;
+       mutex_lock(&rc->uwb_dev.mutex);
+       result = uwb_rc_addr_set(rc, addr, UWB_ADDR_DEV);
+       rc->uwb_dev.dev_addr = *addr;
+       mutex_unlock(&rc->uwb_dev.mutex);
+       return result;
+}
+
+/* Returns !0 if given address is already assigned to device. */
+int __uwb_mac_addr_assigned_check(struct device *dev, void *_addr)
+{
+       struct uwb_dev *uwb_dev = to_uwb_dev(dev);
+       struct uwb_mac_addr *addr = _addr;
+
+       if (!uwb_mac_addr_cmp(addr, &uwb_dev->mac_addr))
+               return !0;
+       return 0;
+}
+
+/* Returns !0 if given address is already assigned to device. */
+int __uwb_dev_addr_assigned_check(struct device *dev, void *_addr)
+{
+       struct uwb_dev *uwb_dev = to_uwb_dev(dev);
+       struct uwb_dev_addr *addr = _addr;
+       if (!uwb_dev_addr_cmp(addr, &uwb_dev->dev_addr))
+               return !0;
+       return 0;
+}
+
+/**
+ * uwb_dev_addr_assign - assigned a generated DevAddr to a radio controller
+ * @rc:      the (local) radio controller device requiring a new DevAddr
+ *
+ * A new DevAddr is required when:
+ *    - first setting up a radio controller
+ *    - if the hardware reports a DevAddr conflict
+ *
+ * The DevAddr is randomly generated in the generated DevAddr range
+ * [0x100, 0xfeff]. The number of devices in a beacon group is limited
+ * by mMaxBPLength (96) so this address space will never be exhausted.
+ *
+ * [ECMA-368] 17.1.1, 17.16.
+ */
+int uwb_rc_dev_addr_assign(struct uwb_rc *rc)
+{
+       struct uwb_dev_addr new_addr;
+
+       do {
+               get_random_bytes(new_addr.data, sizeof(new_addr.data));
+       } while (new_addr.data[0] == 0x00 || new_addr.data[0] == 0xff
+                || __uwb_dev_addr_assigned(rc, &new_addr));
+
+       return uwb_rc_dev_addr_set(rc, &new_addr);
+}
+
+/**
+ * uwbd_evt_handle_rc_dev_addr_conflict - handle a DEV_ADDR_CONFLICT event
+ * @evt: the DEV_ADDR_CONFLICT notification from the radio controller
+ *
+ * A new (non-conflicting) DevAddr is assigned to the radio controller.
+ *
+ * [ECMA-368] 17.1.1.1.
+ */
+int uwbd_evt_handle_rc_dev_addr_conflict(struct uwb_event *evt)
+{
+       struct uwb_rc *rc = evt->rc;
+
+       return uwb_rc_dev_addr_assign(rc);
+}
+
+/*
+ * Print the 48-bit EUI MAC address of the radio controller when
+ * reading /sys/class/uwb_rc/XX/mac_address
+ */
+static ssize_t uwb_rc_mac_addr_show(struct device *dev,
+                                   struct device_attribute *attr, char *buf)
+{
+       struct uwb_dev *uwb_dev = to_uwb_dev(dev);
+       struct uwb_rc *rc = uwb_dev->rc;
+       struct uwb_mac_addr addr;
+       ssize_t result;
+
+       mutex_lock(&rc->uwb_dev.mutex);
+       result = uwb_rc_addr_get(rc, &addr, UWB_ADDR_MAC);
+       mutex_unlock(&rc->uwb_dev.mutex);
+       if (result >= 0) {
+               result = uwb_mac_addr_print(buf, UWB_ADDR_STRSIZE, &addr);
+               buf[result++] = '\n';
+       }
+       return result;
+}
+
+/*
+ * Parse a 48 bit address written to /sys/class/uwb_rc/XX/mac_address
+ * and if correct, set it.
+ */
+static ssize_t uwb_rc_mac_addr_store(struct device *dev,
+                                    struct device_attribute *attr,
+                                    const char *buf, size_t size)
+{
+       struct uwb_dev *uwb_dev = to_uwb_dev(dev);
+       struct uwb_rc *rc = uwb_dev->rc;
+       struct uwb_mac_addr addr;
+       ssize_t result;
+
+       result = sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\n",
+                       &addr.data[0], &addr.data[1], &addr.data[2],
+                       &addr.data[3], &addr.data[4], &addr.data[5]);
+       if (result != 6) {
+               result = -EINVAL;
+               goto out;
+       }
+       if (is_multicast_ether_addr(addr.data)) {
+               dev_err(&rc->uwb_dev.dev, "refusing to set multicast "
+                       "MAC address %s\n", buf);
+               result = -EINVAL;
+               goto out;
+       }
+       result = uwb_rc_mac_addr_set(rc, &addr);
+       if (result == 0)
+               rc->uwb_dev.mac_addr = addr;
+out:
+       return result < 0 ? result : size;
+}
+DEVICE_ATTR(mac_address, S_IRUGO | S_IWUSR, uwb_rc_mac_addr_show, uwb_rc_mac_addr_store);
+
+/** Print @addr to @buf, @return bytes written */
+size_t __uwb_addr_print(char *buf, size_t buf_size, const unsigned char *addr,
+                       int type)
+{
+       size_t result;
+       if (type)
+               result = scnprintf(buf, buf_size,
+                                 "%02x:%02x:%02x:%02x:%02x:%02x",
+                                 addr[0], addr[1], addr[2],
+                                 addr[3], addr[4], addr[5]);
+       else
+               result = scnprintf(buf, buf_size, "%02x:%02x",
+                                 addr[1], addr[0]);
+       return result;
+}
+EXPORT_SYMBOL_GPL(__uwb_addr_print);
diff --git a/drivers/uwb/beacon.c b/drivers/uwb/beacon.c
new file mode 100644 (file)
index 0000000..46b18ee
--- /dev/null
@@ -0,0 +1,642 @@
+/*
+ * Ultra Wide Band
+ * Beacon management
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/kdev_t.h>
+#include "uwb-internal.h"
+
+#define D_LOCAL 0
+#include <linux/uwb/debug.h>
+
+/** Start Beaconing command structure */
+struct uwb_rc_cmd_start_beacon {
+       struct uwb_rccb rccb;
+       __le16 wBPSTOffset;
+       u8 bChannelNumber;
+} __attribute__((packed));
+
+
+static int uwb_rc_start_beacon(struct uwb_rc *rc, u16 bpst_offset, u8 channel)
+{
+       int result;
+       struct uwb_rc_cmd_start_beacon *cmd;
+       struct uwb_rc_evt_confirm reply;
+
+       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+       if (cmd == NULL)
+               return -ENOMEM;
+       cmd->rccb.bCommandType = UWB_RC_CET_GENERAL;
+       cmd->rccb.wCommand = cpu_to_le16(UWB_RC_CMD_START_BEACON);
+       cmd->wBPSTOffset = cpu_to_le16(bpst_offset);
+       cmd->bChannelNumber = channel;
+       reply.rceb.bEventType = UWB_RC_CET_GENERAL;
+       reply.rceb.wEvent = UWB_RC_CMD_START_BEACON;
+       result = uwb_rc_cmd(rc, "START-BEACON", &cmd->rccb, sizeof(*cmd),
+                           &reply.rceb, sizeof(reply));
+       if (result < 0)
+               goto error_cmd;
+       if (reply.bResultCode != UWB_RC_RES_SUCCESS) {
+               dev_err(&rc->uwb_dev.dev,
+                       "START-BEACON: command execution failed: %s (%d)\n",
+                       uwb_rc_strerror(reply.bResultCode), reply.bResultCode);
+               result = -EIO;
+       }
+error_cmd:
+       kfree(cmd);
+       return result;
+}
+
+static int uwb_rc_stop_beacon(struct uwb_rc *rc)
+{
+       int result;
+       struct uwb_rccb *cmd;
+       struct uwb_rc_evt_confirm reply;
+
+       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+       if (cmd == NULL)
+               return -ENOMEM;
+       cmd->bCommandType = UWB_RC_CET_GENERAL;
+       cmd->wCommand = cpu_to_le16(UWB_RC_CMD_STOP_BEACON);
+       reply.rceb.bEventType = UWB_RC_CET_GENERAL;
+       reply.rceb.wEvent = UWB_RC_CMD_STOP_BEACON;
+       result = uwb_rc_cmd(rc, "STOP-BEACON", cmd, sizeof(*cmd),
+                           &reply.rceb, sizeof(reply));
+       if (result < 0)
+               goto error_cmd;
+       if (reply.bResultCode != UWB_RC_RES_SUCCESS) {
+               dev_err(&rc->uwb_dev.dev,
+                       "STOP-BEACON: command execution failed: %s (%d)\n",
+                       uwb_rc_strerror(reply.bResultCode), reply.bResultCode);
+               result = -EIO;
+       }
+error_cmd:
+       kfree(cmd);
+       return result;
+}
+
+/*
+ * Start/stop beacons
+ *
+ * @rc:          UWB Radio Controller to operate on
+ * @channel:     UWB channel on which to beacon (WUSB[table
+ *               5-12]). If -1, stop beaconing.
+ * @bpst_offset: Beacon Period Start Time offset; FIXME-do zero
+ *
+ * According to WHCI 0.95 [4.13.6] the driver will only receive the RCEB
+ * of a SET IE command after the device sent the first beacon that includes
+ * the IEs specified in the SET IE command. So, after we start beaconing we
+ * check if there is anything in the IE cache and call the SET IE command
+ * if needed.
+ */
+int uwb_rc_beacon(struct uwb_rc *rc, int channel, unsigned bpst_offset)
+{
+       int result;
+       struct device *dev = &rc->uwb_dev.dev;
+
+       mutex_lock(&rc->uwb_dev.mutex);
+       if (channel < 0)
+               channel = -1;
+       if (channel == -1)
+               result = uwb_rc_stop_beacon(rc);
+       else {
+               /* channel >= 0...dah */
+               result = uwb_rc_start_beacon(rc, bpst_offset, channel);
+               if (result < 0)
+                       goto out_up;
+               if (le16_to_cpu(rc->ies->wIELength) > 0) {
+                       result = uwb_rc_set_ie(rc, rc->ies);
+                       if (result < 0) {
+                               dev_err(dev, "Cannot set new IE on device: "
+                                       "%d\n", result);
+                               result = uwb_rc_stop_beacon(rc);
+                               channel = -1;
+                               bpst_offset = 0;
+                       } else
+                               result = 0;
+               }
+       }
+
+       if (result < 0)
+               goto out_up;
+       rc->beaconing = channel;
+
+       uwb_notify(rc, NULL, uwb_bg_joined(rc) ? UWB_NOTIF_BG_JOIN : UWB_NOTIF_BG_LEAVE);
+
+out_up:
+       mutex_unlock(&rc->uwb_dev.mutex);
+       return result;
+}
+
+/*
+ * Beacon cache
+ *
+ * The purpose of this is to speed up the lookup of becon information
+ * when a new beacon arrives. The UWB Daemon uses it also to keep a
+ * tab of which devices are in radio distance and which not. When a
+ * device's beacon stays present for more than a certain amount of
+ * time, it is considered a new, usable device. When a beacon ceases
+ * to be received for a certain amount of time, it is considered that
+ * the device is gone.
+ *
+ * FIXME: use an allocator for the entries
+ * FIXME: use something faster for search than a list
+ */
+
+struct uwb_beca uwb_beca = {
+       .list = LIST_HEAD_INIT(uwb_beca.list),
+       .mutex = __MUTEX_INITIALIZER(uwb_beca.mutex)
+};
+
+
+void uwb_bce_kfree(struct kref *_bce)
+{
+       struct uwb_beca_e *bce = container_of(_bce, struct uwb_beca_e, refcnt);
+
+       kfree(bce->be);
+       kfree(bce);
+}
+
+
+/* Find a beacon by dev addr in the cache */
+static
+struct uwb_beca_e *__uwb_beca_find_bydev(const struct uwb_dev_addr *dev_addr)
+{
+       struct uwb_beca_e *bce, *next;
+       list_for_each_entry_safe(bce, next, &uwb_beca.list, node) {
+               d_printf(6, NULL, "looking for addr %02x:%02x in %02x:%02x\n",
+                        dev_addr->data[0], dev_addr->data[1],
+                        bce->dev_addr.data[0], bce->dev_addr.data[1]);
+               if (!memcmp(&bce->dev_addr, dev_addr, sizeof(bce->dev_addr)))
+                       goto out;
+       }
+       bce = NULL;
+out:
+       return bce;
+}
+
+/* Find a beacon by dev addr in the cache */
+static
+struct uwb_beca_e *__uwb_beca_find_bymac(const struct uwb_mac_addr *mac_addr)
+{
+       struct uwb_beca_e *bce, *next;
+       list_for_each_entry_safe(bce, next, &uwb_beca.list, node) {
+               if (!memcmp(bce->mac_addr, mac_addr->data,
+                           sizeof(struct uwb_mac_addr)))
+                       goto out;
+       }
+       bce = NULL;
+out:
+       return bce;
+}
+
+/**
+ * uwb_dev_get_by_devaddr - get a UWB device with a specific DevAddr
+ * @rc:      the radio controller that saw the device
+ * @devaddr: DevAddr of the UWB device to find
+ *
+ * There may be more than one matching device (in the case of a
+ * DevAddr conflict), but only the first one is returned.
+ */
+struct uwb_dev *uwb_dev_get_by_devaddr(struct uwb_rc *rc,
+                                      const struct uwb_dev_addr *devaddr)
+{
+       struct uwb_dev *found = NULL;
+       struct uwb_beca_e *bce;
+
+       mutex_lock(&uwb_beca.mutex);
+       bce = __uwb_beca_find_bydev(devaddr);
+       if (bce)
+               found = uwb_dev_try_get(rc, bce->uwb_dev);
+       mutex_unlock(&uwb_beca.mutex);
+
+       return found;
+}
+
+/**
+ * uwb_dev_get_by_macaddr - get a UWB device with a specific EUI-48
+ * @rc:      the radio controller that saw the device
+ * @devaddr: EUI-48 of the UWB device to find
+ */
+struct uwb_dev *uwb_dev_get_by_macaddr(struct uwb_rc *rc,
+                                      const struct uwb_mac_addr *macaddr)
+{
+       struct uwb_dev *found = NULL;
+       struct uwb_beca_e *bce;
+
+       mutex_lock(&uwb_beca.mutex);
+       bce = __uwb_beca_find_bymac(macaddr);
+       if (bce)
+               found = uwb_dev_try_get(rc, bce->uwb_dev);
+       mutex_unlock(&uwb_beca.mutex);
+
+       return found;
+}
+
+/* Initialize a beacon cache entry */
+static void uwb_beca_e_init(struct uwb_beca_e *bce)
+{
+       mutex_init(&bce->mutex);
+       kref_init(&bce->refcnt);
+       stats_init(&bce->lqe_stats);
+       stats_init(&bce->rssi_stats);
+}
+
+/*
+ * Add a beacon to the cache
+ *
+ * @be:         Beacon event information
+ * @bf:         Beacon frame (part of b, really)
+ * @ts_jiffies: Timestamp (in jiffies) when the beacon was received
+ */
+struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *be,
+                                 struct uwb_beacon_frame *bf,
+                                 unsigned long ts_jiffies)
+{
+       struct uwb_beca_e *bce;
+
+       bce = kzalloc(sizeof(*bce), GFP_KERNEL);
+       if (bce == NULL)
+               return NULL;
+       uwb_beca_e_init(bce);
+       bce->ts_jiffies = ts_jiffies;
+       bce->uwb_dev = NULL;
+       list_add(&bce->node, &uwb_beca.list);
+       return bce;
+}
+
+/*
+ * Wipe out beacon entries that became stale
+ *
+ * Remove associated devicest too.
+ */
+void uwb_beca_purge(void)
+{
+       struct uwb_beca_e *bce, *next;
+       unsigned long expires;
+
+       mutex_lock(&uwb_beca.mutex);
+       list_for_each_entry_safe(bce, next, &uwb_beca.list, node) {
+               expires = bce->ts_jiffies + msecs_to_jiffies(beacon_timeout_ms);
+               if (time_after(jiffies, expires)) {
+                       uwbd_dev_offair(bce);
+                       list_del(&bce->node);
+                       uwb_bce_put(bce);
+               }
+       }
+       mutex_unlock(&uwb_beca.mutex);
+}
+
+/* Clean up the whole beacon cache. Called on shutdown */
+void uwb_beca_release(void)
+{
+       struct uwb_beca_e *bce, *next;
+       mutex_lock(&uwb_beca.mutex);
+       list_for_each_entry_safe(bce, next, &uwb_beca.list, node) {
+               list_del(&bce->node);
+               uwb_bce_put(bce);
+       }
+       mutex_unlock(&uwb_beca.mutex);
+}
+
+static void uwb_beacon_print(struct uwb_rc *rc, struct uwb_rc_evt_beacon *be,
+                            struct uwb_beacon_frame *bf)
+{
+       char macbuf[UWB_ADDR_STRSIZE];
+       char devbuf[UWB_ADDR_STRSIZE];
+       char dstbuf[UWB_ADDR_STRSIZE];
+
+       uwb_mac_addr_print(macbuf, sizeof(macbuf), &bf->Device_Identifier);
+       uwb_dev_addr_print(devbuf, sizeof(devbuf), &bf->hdr.SrcAddr);
+       uwb_dev_addr_print(dstbuf, sizeof(dstbuf), &bf->hdr.DestAddr);
+       dev_info(&rc->uwb_dev.dev,
+                "BEACON from %s to %s (ch%u offset %u slot %u MAC %s)\n",
+                devbuf, dstbuf, be->bChannelNumber, be->wBPSTOffset,
+                bf->Beacon_Slot_Number, macbuf);
+}
+
+/*
+ * @bce: beacon cache entry, referenced
+ */
+ssize_t uwb_bce_print_IEs(struct uwb_dev *uwb_dev, struct uwb_beca_e *bce,
+                         char *buf, size_t size)
+{
+       ssize_t result = 0;
+       struct uwb_rc_evt_beacon *be;
+       struct uwb_beacon_frame *bf;
+       struct uwb_buf_ctx ctx = {
+               .buf = buf,
+               .bytes = 0,
+               .size = size
+       };
+
+       mutex_lock(&bce->mutex);
+       be = bce->be;
+       if (be == NULL)
+               goto out;
+       bf = (void *) be->BeaconInfo;
+       uwb_ie_for_each(uwb_dev, uwb_ie_dump_hex, &ctx,
+                       bf->IEData, be->wBeaconInfoLength - sizeof(*bf));
+       result = ctx.bytes;
+out:
+       mutex_unlock(&bce->mutex);
+       return result;
+}
+
+/*
+ * Verify that the beacon event, frame and IEs are ok
+ */
+static int uwb_verify_beacon(struct uwb_rc *rc, struct uwb_event *evt,
+                            struct uwb_rc_evt_beacon *be)
+{
+       int result = -EINVAL;
+       struct uwb_beacon_frame *bf;
+       struct device *dev = &rc->uwb_dev.dev;
+
+       /* Is there enough data to decode a beacon frame? */
+       if (evt->notif.size < sizeof(*be) + sizeof(*bf)) {
+               dev_err(dev, "BEACON event: Not enough data to decode "
+                       "(%zu vs %zu bytes needed)\n", evt->notif.size,
+                       sizeof(*be) + sizeof(*bf));
+               goto error;
+       }
+       /* FIXME: make sure beacon frame IEs are fine and that the whole thing
+        * is consistent */
+       result = 0;
+error:
+       return result;
+}
+
+/*
+ * Handle UWB_RC_EVT_BEACON events
+ *
+ * We check the beacon cache to see how the received beacon fares. If
+ * is there already we refresh the timestamp. If not we create a new
+ * entry.
+ *
+ * According to the WHCI and WUSB specs, only one beacon frame is
+ * allowed per notification block, so we don't bother about scanning
+ * for more.
+ */
+int uwbd_evt_handle_rc_beacon(struct uwb_event *evt)
+{
+       int result = -EINVAL;
+       struct uwb_rc *rc;
+       struct uwb_rc_evt_beacon *be;
+       struct uwb_beacon_frame *bf;
+       struct uwb_beca_e *bce;
+       unsigned long last_ts;
+
+       rc = evt->rc;
+       be = container_of(evt->notif.rceb, struct uwb_rc_evt_beacon, rceb);
+       result = uwb_verify_beacon(rc, evt, be);
+       if (result < 0)
+               return result;
+
+       /* FIXME: handle alien beacons. */
+       if (be->bBeaconType == UWB_RC_BEACON_TYPE_OL_ALIEN ||
+           be->bBeaconType == UWB_RC_BEACON_TYPE_NOL_ALIEN) {
+               return -ENOSYS;
+       }
+
+       bf = (struct uwb_beacon_frame *) be->BeaconInfo;
+
+       /*
+        * Drop beacons from devices with a NULL EUI-48 -- they cannot
+        * be uniquely identified.
+        *
+        * It's expected that these will all be WUSB devices and they
+        * have a WUSB specific connection method so ignoring them
+        * here shouldn't be a problem.
+        */
+       if (uwb_mac_addr_bcast(&bf->Device_Identifier))
+               return 0;
+
+       mutex_lock(&uwb_beca.mutex);
+       bce = __uwb_beca_find_bymac(&bf->Device_Identifier);
+       if (bce == NULL) {
+               /* Not in there, a new device is pinging */
+               uwb_beacon_print(evt->rc, be, bf);
+               bce = __uwb_beca_add(be, bf, evt->ts_jiffies);
+               if (bce == NULL) {
+                       mutex_unlock(&uwb_beca.mutex);
+                       return -ENOMEM;
+               }
+       }
+       mutex_unlock(&uwb_beca.mutex);
+
+       mutex_lock(&bce->mutex);
+       /* purge old beacon data */
+       kfree(bce->be);
+
+       last_ts = bce->ts_jiffies;
+
+       /* Update commonly used fields */
+       bce->ts_jiffies = evt->ts_jiffies;
+       bce->be = be;
+       bce->dev_addr = bf->hdr.SrcAddr;
+       bce->mac_addr = &bf->Device_Identifier;
+       be->wBPSTOffset = le16_to_cpu(be->wBPSTOffset);
+       be->wBeaconInfoLength = le16_to_cpu(be->wBeaconInfoLength);
+       stats_add_sample(&bce->lqe_stats, be->bLQI - 7);
+       stats_add_sample(&bce->rssi_stats, be->bRSSI + 18);
+
+       /*
+        * This might be a beacon from a new device.
+        */
+       if (bce->uwb_dev == NULL)
+               uwbd_dev_onair(evt->rc, bce);
+
+       mutex_unlock(&bce->mutex);
+
+       return 1; /* we keep the event data */
+}
+
+/*
+ * Handle UWB_RC_EVT_BEACON_SIZE events
+ *
+ * XXXXX
+ */
+int uwbd_evt_handle_rc_beacon_size(struct uwb_event *evt)
+{
+       int result = -EINVAL;
+       struct device *dev = &evt->rc->uwb_dev.dev;
+       struct uwb_rc_evt_beacon_size *bs;
+
+       /* Is there enough data to decode the event? */
+       if (evt->notif.size < sizeof(*bs)) {
+               dev_err(dev, "BEACON SIZE notification: Not enough data to "
+                       "decode (%zu vs %zu bytes needed)\n",
+                       evt->notif.size, sizeof(*bs));
+               goto error;
+       }
+       bs = container_of(evt->notif.rceb, struct uwb_rc_evt_beacon_size, rceb);
+       if (0)
+               dev_info(dev, "Beacon size changed to %u bytes "
+                       "(FIXME: action?)\n", le16_to_cpu(bs->wNewBeaconSize));
+       else {
+               /* temporary hack until we do something with this message... */
+               static unsigned count;
+               if (++count % 1000 == 0)
+                       dev_info(dev, "Beacon size changed %u times "
+                               "(FIXME: action?)\n", count);
+       }
+       result = 0;
+error:
+       return result;
+}
+
+/**
+ * uwbd_evt_handle_rc_bp_slot_change - handle a BP_SLOT_CHANGE event
+ * @evt: the BP_SLOT_CHANGE notification from the radio controller
+ *
+ * If the event indicates that no beacon period slots were available
+ * then radio controller has transitioned to a non-beaconing state.
+ * Otherwise, simply save the current beacon slot.
+ */
+int uwbd_evt_handle_rc_bp_slot_change(struct uwb_event *evt)
+{
+       struct uwb_rc *rc = evt->rc;
+       struct device *dev = &rc->uwb_dev.dev;
+       struct uwb_rc_evt_bp_slot_change *bpsc;
+
+       if (evt->notif.size < sizeof(*bpsc)) {
+               dev_err(dev, "BP SLOT CHANGE event: Not enough data\n");
+               return -EINVAL;
+       }
+       bpsc = container_of(evt->notif.rceb, struct uwb_rc_evt_bp_slot_change, rceb);
+
+       mutex_lock(&rc->uwb_dev.mutex);
+       if (uwb_rc_evt_bp_slot_change_no_slot(bpsc)) {
+               dev_info(dev, "stopped beaconing: No free slots in BP\n");
+               rc->beaconing = -1;
+       } else
+               rc->uwb_dev.beacon_slot = uwb_rc_evt_bp_slot_change_slot_num(bpsc);
+       mutex_unlock(&rc->uwb_dev.mutex);
+
+       return 0;
+}
+
+/**
+ * Handle UWB_RC_EVT_BPOIE_CHANGE events
+ *
+ * XXXXX
+ */
+struct uwb_ie_bpo {
+       struct uwb_ie_hdr hdr;
+       u8                bp_length;
+       u8                data[];
+} __attribute__((packed));
+
+int uwbd_evt_handle_rc_bpoie_change(struct uwb_event *evt)
+{
+       int result = -EINVAL;
+       struct device *dev = &evt->rc->uwb_dev.dev;
+       struct uwb_rc_evt_bpoie_change *bpoiec;
+       struct uwb_ie_bpo *bpoie;
+       static unsigned count;  /* FIXME: this is a temp hack */
+       size_t iesize;
+
+       /* Is there enough data to decode it? */
+       if (evt->notif.size < sizeof(*bpoiec)) {
+               dev_err(dev, "BPOIEC notification: Not enough data to "
+                       "decode (%zu vs %zu bytes needed)\n",
+                       evt->notif.size, sizeof(*bpoiec));
+               goto error;
+       }
+       bpoiec = container_of(evt->notif.rceb, struct uwb_rc_evt_bpoie_change, rceb);
+       iesize = le16_to_cpu(bpoiec->wBPOIELength);
+       if (iesize < sizeof(*bpoie)) {
+               dev_err(dev, "BPOIEC notification: Not enough IE data to "
+                       "decode (%zu vs %zu bytes needed)\n",
+                       iesize, sizeof(*bpoie));
+               goto error;
+       }
+       if (++count % 1000 == 0)        /* Lame placeholder */
+               dev_info(dev, "BPOIE: %u changes received\n", count);
+       /*
+        * FIXME: At this point we should go over all the IEs in the
+        *        bpoiec->BPOIE array and act on each.
+        */
+       result = 0;
+error:
+       return result;
+}
+
+/**
+ * uwb_bg_joined - is the RC in a beacon group?
+ * @rc: the radio controller
+ *
+ * Returns true if the radio controller is in a beacon group (even if
+ * it's the sole member).
+ */
+int uwb_bg_joined(struct uwb_rc *rc)
+{
+       return rc->beaconing != -1;
+}
+EXPORT_SYMBOL_GPL(uwb_bg_joined);
+
+/*
+ * Print beaconing state.
+ */
+static ssize_t uwb_rc_beacon_show(struct device *dev,
+                                 struct device_attribute *attr, char *buf)
+{
+       struct uwb_dev *uwb_dev = to_uwb_dev(dev);
+       struct uwb_rc *rc = uwb_dev->rc;
+       ssize_t result;
+
+       mutex_lock(&rc->uwb_dev.mutex);
+       result = sprintf(buf, "%d\n", rc->beaconing);
+       mutex_unlock(&rc->uwb_dev.mutex);
+       return result;
+}
+
+/*
+ * Start beaconing on the specified channel, or stop beaconing.
+ *
+ * The BPST offset of when to start searching for a beacon group to
+ * join may be specified.
+ */
+static ssize_t uwb_rc_beacon_store(struct device *dev,
+                                  struct device_attribute *attr,
+                                  const char *buf, size_t size)
+{
+       struct uwb_dev *uwb_dev = to_uwb_dev(dev);
+       struct uwb_rc *rc = uwb_dev->rc;
+       int channel;
+       unsigned bpst_offset = 0;
+       ssize_t result = -EINVAL;
+
+       result = sscanf(buf, "%d %u\n", &channel, &bpst_offset);
+       if (result >= 1)
+               result = uwb_rc_beacon(rc, channel, bpst_offset);
+
+       return result < 0 ? result : size;
+}
+DEVICE_ATTR(beacon, S_IRUGO | S_IWUSR, uwb_rc_beacon_show, uwb_rc_beacon_store);
diff --git a/drivers/uwb/driver.c b/drivers/uwb/driver.c
new file mode 100644 (file)
index 0000000..521cdeb
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Ultra Wide Band
+ * Driver initialization, etc
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ *
+ * Life cycle: FIXME: explain
+ *
+ *  UWB radio controller:
+ *
+ *    1. alloc a uwb_rc, zero it
+ *    2. call uwb_rc_init() on it to set it up + ops (won't do any
+ *       kind of allocation)
+ *    3. register (now it is owned by the UWB stack--deregister before
+ *       freeing/destroying).
+ *    4. It lives on it's own now (UWB stack handles)--when it
+ *       disconnects, call unregister()
+ *    5. free it.
+ *
+ *    Make sure you have a reference to the uwb_rc before calling
+ *    any of the UWB API functions.
+ *
+ * TODO:
+ *
+ * 1. Locking and life cycle management is crappy still. All entry
+ *    points to the UWB HCD API assume you have a reference on the
+ *    uwb_rc structure and that it won't go away. They mutex lock it
+ *    before doing anything.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/kdev_t.h>
+#include <linux/random.h>
+#include <linux/uwb/debug.h>
+#include "uwb-internal.h"
+
+
+/* UWB stack attributes (or 'global' constants) */
+
+
+/**
+ * If a beacon dissapears for longer than this, then we consider the
+ * device who was represented by that beacon to be gone.
+ *
+ * ECMA-368[17.2.3, last para] establishes that a device must not
+ * consider a device to be its neighbour if he doesn't receive a beacon
+ * for more than mMaxLostBeacons. mMaxLostBeacons is defined in
+ * ECMA-368[17.16] as 3; because we can get only one beacon per
+ * superframe, that'd be 3 * 65ms = 195 ~ 200 ms. Let's give it time
+ * for jitter and stuff and make it 500 ms.
+ */
+unsigned long beacon_timeout_ms = 500;
+
+static
+ssize_t beacon_timeout_ms_show(struct class *class, char *buf)
+{
+       return scnprintf(buf, PAGE_SIZE, "%lu\n", beacon_timeout_ms);
+}
+
+static
+ssize_t beacon_timeout_ms_store(struct class *class,
+                               const char *buf, size_t size)
+{
+       unsigned long bt;
+       ssize_t result;
+       result = sscanf(buf, "%lu", &bt);
+       if (result != 1)
+               return -EINVAL;
+       beacon_timeout_ms = bt;
+       return size;
+}
+
+static struct class_attribute uwb_class_attrs[] = {
+       __ATTR(beacon_timeout_ms, S_IWUSR | S_IRUGO,
+              beacon_timeout_ms_show, beacon_timeout_ms_store),
+       __ATTR_NULL,
+};
+
+/** Device model classes */
+struct class uwb_rc_class = {
+       .name        = "uwb_rc",
+       .class_attrs = uwb_class_attrs,
+};
+
+
+static int __init uwb_subsys_init(void)
+{
+       int result = 0;
+
+       result = uwb_est_create();
+       if (result < 0) {
+               printk(KERN_ERR "uwb: Can't initialize EST subsystem\n");
+               goto error_est_init;
+       }
+
+       result = class_register(&uwb_rc_class);
+       if (result < 0)
+               goto error_uwb_rc_class_register;
+       uwbd_start();
+       uwb_dbg_init();
+       return 0;
+
+error_uwb_rc_class_register:
+       uwb_est_destroy();
+error_est_init:
+       return result;
+}
+module_init(uwb_subsys_init);
+
+static void __exit uwb_subsys_exit(void)
+{
+       uwb_dbg_exit();
+       uwbd_stop();
+       class_unregister(&uwb_rc_class);
+       uwb_est_destroy();
+       return;
+}
+module_exit(uwb_subsys_exit);
+
+MODULE_AUTHOR("Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>");
+MODULE_DESCRIPTION("Ultra Wide Band core");
+MODULE_LICENSE("GPL");
diff --git a/drivers/uwb/drp-avail.c b/drivers/uwb/drp-avail.c
new file mode 100644 (file)
index 0000000..3febd85
--- /dev/null
@@ -0,0 +1,288 @@
+/*
+ * Ultra Wide Band
+ * DRP availability management
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Reinette Chatre <reinette.chatre@intel.com>
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * Manage DRP Availability (the MAS available for DRP
+ * reservations). Thus:
+ *
+ * - Handle DRP Availability Change notifications
+ *
+ * - Allow the reservation manager to indicate MAS reserved/released
+ *   by local (owned by/targeted at the radio controller)
+ *   reservations.
+ *
+ * - Based on the two sources above, generate a DRP Availability IE to
+ *   be included in the beacon.
+ *
+ * See also the documentation for struct uwb_drp_avail.
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/bitmap.h>
+#include "uwb-internal.h"
+
+/**
+ * uwb_drp_avail_init - initialize an RC's MAS availability
+ *
+ * All MAS are available initially.  The RC will inform use which
+ * slots are used for the BP (it may change in size).
+ */
+void uwb_drp_avail_init(struct uwb_rc *rc)
+{
+       bitmap_fill(rc->drp_avail.global, UWB_NUM_MAS);
+       bitmap_fill(rc->drp_avail.local, UWB_NUM_MAS);
+       bitmap_fill(rc->drp_avail.pending, UWB_NUM_MAS);
+}
+
+/*
+ * Determine MAS available for new local reservations.
+ *
+ * avail = global & local & pending
+ */
+static void uwb_drp_available(struct uwb_rc *rc, struct uwb_mas_bm *avail)
+{
+       bitmap_and(avail->bm, rc->drp_avail.global, rc->drp_avail.local, UWB_NUM_MAS);
+       bitmap_and(avail->bm, avail->bm, rc->drp_avail.pending, UWB_NUM_MAS);
+}
+
+/**
+ * uwb_drp_avail_reserve_pending - reserve MAS for a new reservation
+ * @rc: the radio controller
+ * @mas: the MAS to reserve
+ *
+ * Returns 0 on success, or -EBUSY if the MAS requested aren't available.
+ */
+int uwb_drp_avail_reserve_pending(struct uwb_rc *rc, struct uwb_mas_bm *mas)
+{
+       struct uwb_mas_bm avail;
+
+       uwb_drp_available(rc, &avail);
+       if (!bitmap_subset(mas->bm, avail.bm, UWB_NUM_MAS))
+               return -EBUSY;
+
+       bitmap_andnot(rc->drp_avail.pending, rc->drp_avail.pending, mas->bm, UWB_NUM_MAS);
+       return 0;
+}
+
+/**
+ * uwb_drp_avail_reserve - reserve MAS for an established reservation
+ * @rc: the radio controller
+ * @mas: the MAS to reserve
+ */
+void uwb_drp_avail_reserve(struct uwb_rc *rc, struct uwb_mas_bm *mas)
+{
+       bitmap_or(rc->drp_avail.pending, rc->drp_avail.pending, mas->bm, UWB_NUM_MAS);
+       bitmap_andnot(rc->drp_avail.local, rc->drp_avail.local, mas->bm, UWB_NUM_MAS);
+       rc->drp_avail.ie_valid = false;
+}
+
+/**
+ * uwb_drp_avail_release - release MAS from a pending or established reservation
+ * @rc: the radio controller
+ * @mas: the MAS to release
+ */
+void uwb_drp_avail_release(struct uwb_rc *rc, struct uwb_mas_bm *mas)
+{
+       bitmap_or(rc->drp_avail.local, rc->drp_avail.local, mas->bm, UWB_NUM_MAS);
+       bitmap_or(rc->drp_avail.pending, rc->drp_avail.pending, mas->bm, UWB_NUM_MAS);
+       rc->drp_avail.ie_valid = false;
+}
+
+/**
+ * uwb_drp_avail_ie_update - update the DRP Availability IE
+ * @rc: the radio controller
+ *
+ * avail = global & local
+ */
+void uwb_drp_avail_ie_update(struct uwb_rc *rc)
+{
+       struct uwb_mas_bm avail;
+
+       bitmap_and(avail.bm, rc->drp_avail.global, rc->drp_avail.local, UWB_NUM_MAS);
+
+       rc->drp_avail.ie.hdr.element_id = UWB_IE_DRP_AVAILABILITY;
+       rc->drp_avail.ie.hdr.length = UWB_NUM_MAS / 8;
+       uwb_mas_bm_copy_le(rc->drp_avail.ie.bmp, &avail);
+       rc->drp_avail.ie_valid = true;
+}
+
+/**
+ * Create an unsigned long from a buffer containing a byte stream.
+ *
+ * @array: pointer to buffer
+ * @itr:   index of buffer from where we start
+ * @len:   the buffer's remaining size may not be exact multiple of
+ *         sizeof(unsigned long), @len is the length of buffer that needs
+ *         to be converted. This will be sizeof(unsigned long) or smaller
+ *         (BUG if not). If it is smaller then we will pad the remaining
+ *         space of the result with zeroes.
+ */
+static
+unsigned long get_val(u8 *array, size_t itr, size_t len)
+{
+       unsigned long val = 0;
+       size_t top = itr + len;
+
+       BUG_ON(len > sizeof(val));
+
+       while (itr < top) {
+               val <<= 8;
+               val |= array[top - 1];
+               top--;
+       }
+       val <<= 8 * (sizeof(val) - len); /* padding */
+       return val;
+}
+
+/**
+ * Initialize bitmap from data buffer.
+ *
+ * The bitmap to be converted could come from a IE, for example a
+ * DRP Availability IE.
+ * From ECMA-368 1.0 [16.8.7]: "
+ * octets: 1            1               N * (0 to 32)
+ *         Element ID   Length (=N)     DRP Availability Bitmap
+ *
+ * The DRP Availability Bitmap field is up to 256 bits long, one
+ * bit for each MAS in the superframe, where the least-significant
+ * bit of the field corresponds to the first MAS in the superframe
+ * and successive bits correspond to successive MASs."
+ *
+ * The DRP Availability bitmap is in octets from 0 to 32, so octet
+ * 32 contains bits for MAS 1-8, etc. If the bitmap is smaller than 32
+ * octets, the bits in octets not included at the end of the bitmap are
+ * treated as zero. In this case (when the bitmap is smaller than 32
+ * octets) the MAS represented range from MAS 1 to MAS (size of bitmap)
+ * with the last octet still containing bits for MAS 1-8, etc.
+ *
+ * For example:
+ * F00F0102 03040506 0708090A 0B0C0D0E 0F010203
+ * ^^^^
+ * ||||
+ * ||||
+ * |||\LSB of byte is MAS 9
+ * ||\MSB of byte is MAS 16
+ * |\LSB of first byte is MAS 1
+ * \ MSB of byte is MAS 8
+ *
+ * An example of this encoding can be found in ECMA-368 Annex-D [Table D.11]
+ *
+ * The resulting bitmap will have the following mapping:
+ *     bit position 0 == MAS 1
+ *     bit position 1 == MAS 2
+ *     ...
+ *     bit position (UWB_NUM_MAS - 1) == MAS UWB_NUM_MAS
+ *
+ * @bmp_itr:   pointer to bitmap (can be declared with DECLARE_BITMAP)
+ * @buffer:    pointer to buffer containing bitmap data in big endian
+ *              format (MSB first)
+ * @buffer_size:number of bytes with which bitmap should be initialized
+ */
+static
+void buffer_to_bmp(unsigned long *bmp_itr, void *_buffer,
+                  size_t buffer_size)
+{
+       u8 *buffer = _buffer;
+       size_t itr, len;
+       unsigned long val;
+
+       itr = 0;
+       while (itr < buffer_size) {
+               len = buffer_size - itr >= sizeof(val) ?
+                       sizeof(val) : buffer_size - itr;
+               val = get_val(buffer, itr, len);
+               bmp_itr[itr / sizeof(val)] = val;
+               itr += sizeof(val);
+       }
+}
+
+
+/**
+ * Extract DRP Availability bitmap from the notification.
+ *
+ * The notification that comes in contains a bitmap of (UWB_NUM_MAS / 8) bytes
+ * We convert that to our internal representation.
+ */
+static
+int uwbd_evt_get_drp_avail(struct uwb_event *evt, unsigned long *bmp)
+{
+       struct device *dev = &evt->rc->uwb_dev.dev;
+       struct uwb_rc_evt_drp_avail *drp_evt;
+       int result = -EINVAL;
+
+       /* Is there enough data to decode the event? */
+       if (evt->notif.size < sizeof(*drp_evt)) {
+               dev_err(dev, "DRP Availability Change: Not enough "
+                       "data to decode event [%zu bytes, %zu "
+                       "needed]\n", evt->notif.size, sizeof(*drp_evt));
+               goto error;
+       }
+       drp_evt = container_of(evt->notif.rceb, struct uwb_rc_evt_drp_avail, rceb);
+       buffer_to_bmp(bmp, drp_evt->bmp, UWB_NUM_MAS/8);
+       result = 0;
+error:
+       return result;
+}
+
+
+/**
+ * Process an incoming DRP Availability notification.
+ *
+ * @evt:       Event information (packs the actual event data, which
+ *              radio controller it came to, etc).
+ *
+ * @returns:    0 on success (so uwbd() frees the event buffer), < 0
+ *              on error.
+ *
+ * According to ECMA-368 1.0 [16.8.7], bits set to ONE indicate that
+ * the MAS slot is available, bits set to ZERO indicate that the slot
+ * is busy.
+ *
+ * So we clear available slots, we set used slots :)
+ *
+ * The notification only marks non-availability based on the BP and
+ * received DRP IEs that are not for this radio controller.  A copy of
+ * this bitmap is needed to generate the real availability (which
+ * includes local and pending reservations).
+ *
+ * The DRP Availability IE that this radio controller emits will need
+ * to be updated.
+ */
+int uwbd_evt_handle_rc_drp_avail(struct uwb_event *evt)
+{
+       int result;
+       struct uwb_rc *rc = evt->rc;
+       DECLARE_BITMAP(bmp, UWB_NUM_MAS);
+
+       result = uwbd_evt_get_drp_avail(evt, bmp);
+       if (result < 0)
+               return result;
+
+       mutex_lock(&rc->rsvs_mutex);
+       bitmap_copy(rc->drp_avail.global, bmp, UWB_NUM_MAS);
+       rc->drp_avail.ie_valid = false;
+       mutex_unlock(&rc->rsvs_mutex);
+
+       uwb_rsv_sched_update(rc);
+
+       return 0;
+}
diff --git a/drivers/uwb/drp-ie.c b/drivers/uwb/drp-ie.c
new file mode 100644 (file)
index 0000000..882724c
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * UWB DRP IE management.
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/random.h>
+#include <linux/uwb.h>
+
+#include "uwb-internal.h"
+
+/*
+ * Allocate a DRP IE.
+ *
+ * To save having to free/allocate a DRP IE when its MAS changes,
+ * enough memory is allocated for the maxiumum number of DRP
+ * allocation fields.  This gives an overhead per reservation of up to
+ * (UWB_NUM_ZONES - 1) * 4 = 60 octets.
+ */
+static struct uwb_ie_drp *uwb_drp_ie_alloc(void)
+{
+       struct uwb_ie_drp *drp_ie;
+       unsigned tiebreaker;
+
+       drp_ie = kzalloc(sizeof(struct uwb_ie_drp) +
+                       UWB_NUM_ZONES * sizeof(struct uwb_drp_alloc),
+                       GFP_KERNEL);
+       if (drp_ie) {
+               drp_ie->hdr.element_id = UWB_IE_DRP;
+
+               get_random_bytes(&tiebreaker, sizeof(unsigned));
+               uwb_ie_drp_set_tiebreaker(drp_ie, tiebreaker & 1);
+       }
+       return drp_ie;
+}
+
+
+/*
+ * Fill a DRP IE's allocation fields from a MAS bitmap.
+ */
+static void uwb_drp_ie_from_bm(struct uwb_ie_drp *drp_ie,
+                              struct uwb_mas_bm *mas)
+{
+       int z, i, num_fields = 0, next = 0;
+       struct uwb_drp_alloc *zones;
+       __le16 current_bmp;
+       DECLARE_BITMAP(tmp_bmp, UWB_NUM_MAS);
+       DECLARE_BITMAP(tmp_mas_bm, UWB_MAS_PER_ZONE);
+
+       zones = drp_ie->allocs;
+
+       bitmap_copy(tmp_bmp, mas->bm, UWB_NUM_MAS);
+
+       /* Determine unique MAS bitmaps in zones from bitmap. */
+       for (z = 0; z < UWB_NUM_ZONES; z++) {
+               bitmap_copy(tmp_mas_bm, tmp_bmp, UWB_MAS_PER_ZONE);
+               if (bitmap_weight(tmp_mas_bm, UWB_MAS_PER_ZONE) > 0) {
+                       bool found = false;
+                       current_bmp = (__le16) *tmp_mas_bm;
+                       for (i = 0; i < next; i++) {
+                               if (current_bmp == zones[i].mas_bm) {
+                                       zones[i].zone_bm |= 1 << z;
+                                       found = true;
+                                       break;
+                               }
+                       }
+                       if (!found)  {
+                               num_fields++;
+                               zones[next].zone_bm = 1 << z;
+                               zones[next].mas_bm = current_bmp;
+                               next++;
+                       }
+               }
+               bitmap_shift_right(tmp_bmp, tmp_bmp, UWB_MAS_PER_ZONE, UWB_NUM_MAS);
+       }
+
+       /* Store in format ready for transmission (le16). */
+       for (i = 0; i < num_fields; i++) {
+               drp_ie->allocs[i].zone_bm = cpu_to_le16(zones[i].zone_bm);
+               drp_ie->allocs[i].mas_bm = cpu_to_le16(zones[i].mas_bm);
+       }
+
+       drp_ie->hdr.length = sizeof(struct uwb_ie_drp) - sizeof(struct uwb_ie_hdr)
+               + num_fields * sizeof(struct uwb_drp_alloc);
+}
+
+/**
+ * uwb_drp_ie_update - update a reservation's DRP IE
+ * @rsv: the reservation
+ */
+int uwb_drp_ie_update(struct uwb_rsv *rsv)
+{
+       struct device *dev = &rsv->rc->uwb_dev.dev;
+       struct uwb_ie_drp *drp_ie;
+       int reason_code, status;
+
+       switch (rsv->state) {
+       case UWB_RSV_STATE_NONE:
+               kfree(rsv->drp_ie);
+               rsv->drp_ie = NULL;
+               return 0;
+       case UWB_RSV_STATE_O_INITIATED:
+               reason_code = UWB_DRP_REASON_ACCEPTED;
+               status = 0;
+               break;
+       case UWB_RSV_STATE_O_PENDING:
+               reason_code = UWB_DRP_REASON_ACCEPTED;
+               status = 0;
+               break;
+       case UWB_RSV_STATE_O_MODIFIED:
+               reason_code = UWB_DRP_REASON_MODIFIED;
+               status = 1;
+               break;
+       case UWB_RSV_STATE_O_ESTABLISHED:
+               reason_code = UWB_DRP_REASON_ACCEPTED;
+               status = 1;
+               break;
+       case UWB_RSV_STATE_T_ACCEPTED:
+               reason_code = UWB_DRP_REASON_ACCEPTED;
+               status = 1;
+               break;
+       case UWB_RSV_STATE_T_DENIED:
+               reason_code = UWB_DRP_REASON_DENIED;
+               status = 0;
+               break;
+       default:
+               dev_dbg(dev, "rsv with unhandled state (%d)\n", rsv->state);
+               return -EINVAL;
+       }
+
+       if (rsv->drp_ie == NULL) {
+               rsv->drp_ie = uwb_drp_ie_alloc();
+               if (rsv->drp_ie == NULL)
+                       return -ENOMEM;
+       }
+       drp_ie = rsv->drp_ie;
+
+       uwb_ie_drp_set_owner(drp_ie,        uwb_rsv_is_owner(rsv));
+       uwb_ie_drp_set_status(drp_ie,       status);
+       uwb_ie_drp_set_reason_code(drp_ie,  reason_code);
+       uwb_ie_drp_set_stream_index(drp_ie, rsv->stream);
+       uwb_ie_drp_set_type(drp_ie,         rsv->type);
+
+       if (uwb_rsv_is_owner(rsv)) {
+               switch (rsv->target.type) {
+               case UWB_RSV_TARGET_DEV:
+                       drp_ie->dev_addr = rsv->target.dev->dev_addr;
+                       break;
+               case UWB_RSV_TARGET_DEVADDR:
+                       drp_ie->dev_addr = rsv->target.devaddr;
+                       break;
+               }
+       } else
+               drp_ie->dev_addr = rsv->owner->dev_addr;
+
+       uwb_drp_ie_from_bm(drp_ie, &rsv->mas);
+
+       rsv->ie_valid = true;
+       return 0;
+}
+
+/*
+ * Set MAS bits from given MAS bitmap in a single zone of large bitmap.
+ *
+ * We are given a zone id and the MAS bitmap of bits that need to be set in
+ * this zone. Note that this zone may already have bits set and this only
+ * adds settings - we cannot simply assign the MAS bitmap contents to the
+ * zone contents. We iterate over the the bits (MAS) in the zone and set the
+ * bits that are set in the given MAS bitmap.
+ */
+static
+void uwb_drp_ie_single_zone_to_bm(struct uwb_mas_bm *bm, u8 zone, u16 mas_bm)
+{
+       int mas;
+       u16 mas_mask;
+
+       for (mas = 0; mas < UWB_MAS_PER_ZONE; mas++) {
+               mas_mask = 1 << mas;
+               if (mas_bm & mas_mask)
+                       set_bit(zone * UWB_NUM_ZONES + mas, bm->bm);
+       }
+}
+
+/**
+ * uwb_drp_ie_zones_to_bm - convert DRP allocation fields to a bitmap
+ * @mas:    MAS bitmap that will be populated to correspond to the
+ *          allocation fields in the DRP IE
+ * @drp_ie: the DRP IE that contains the allocation fields.
+ *
+ * The input format is an array of MAS allocation fields (16 bit Zone
+ * bitmap, 16 bit MAS bitmap) as described in [ECMA-368] section
+ * 16.8.6. The output is a full 256 bit MAS bitmap.
+ *
+ * We go over all the allocation fields, for each allocation field we
+ * know which zones are impacted. We iterate over all the zones
+ * impacted and call a function that will set the correct MAS bits in
+ * each zone.
+ */
+void uwb_drp_ie_to_bm(struct uwb_mas_bm *bm, const struct uwb_ie_drp *drp_ie)
+{
+       int numallocs = (drp_ie->hdr.length - 4) / 4;
+       const struct uwb_drp_alloc *alloc;
+       int cnt;
+       u16 zone_bm, mas_bm;
+       u8 zone;
+       u16 zone_mask;
+
+       for (cnt = 0; cnt < numallocs; cnt++) {
+               alloc = &drp_ie->allocs[cnt];
+               zone_bm = le16_to_cpu(alloc->zone_bm);
+               mas_bm = le16_to_cpu(alloc->mas_bm);
+               for (zone = 0; zone < UWB_NUM_ZONES; zone++)   {
+                       zone_mask = 1 << zone;
+                       if (zone_bm & zone_mask)
+                               uwb_drp_ie_single_zone_to_bm(bm, zone, mas_bm);
+               }
+       }
+}
diff --git a/drivers/uwb/drp.c b/drivers/uwb/drp.c
new file mode 100644 (file)
index 0000000..c0b1e5e
--- /dev/null
@@ -0,0 +1,461 @@
+/*
+ * Ultra Wide Band
+ * Dynamic Reservation Protocol handling
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <linux/delay.h>
+#include "uwb-internal.h"
+
+/**
+ * Construct and send the SET DRP IE
+ *
+ * @rc:         UWB Host controller
+ * @returns:    >= 0 number of bytes still available in the beacon
+ *              < 0 errno code on error.
+ *
+ * See WUSB[8.6.2.7]: The host must set all the DRP IEs that it wants the
+ * device to include in its beacon at the same time. We thus have to
+ * traverse all reservations and include the DRP IEs of all PENDING
+ * and NEGOTIATED reservations in a SET DRP command for transmission.
+ *
+ * A DRP Availability IE is appended.
+ *
+ * rc->uwb_dev.mutex is held
+ *
+ * FIXME We currently ignore the returned value indicating the remaining space
+ * in beacon. This could be used to deny reservation requests earlier if
+ * determined that they would cause the beacon space to be exceeded.
+ */
+static
+int uwb_rc_gen_send_drp_ie(struct uwb_rc *rc)
+{
+       int result;
+       struct device *dev = &rc->uwb_dev.dev;
+       struct uwb_rc_cmd_set_drp_ie *cmd;
+       struct uwb_rc_evt_set_drp_ie reply;
+       struct uwb_rsv *rsv;
+       int num_bytes = 0;
+       u8 *IEDataptr;
+
+       result = -ENOMEM;
+       /* First traverse all reservations to determine memory needed. */
+       list_for_each_entry(rsv, &rc->reservations, rc_node) {
+               if (rsv->drp_ie != NULL)
+                       num_bytes += rsv->drp_ie->hdr.length + 2;
+       }
+       num_bytes += sizeof(rc->drp_avail.ie);
+       cmd = kzalloc(sizeof(*cmd) + num_bytes, GFP_KERNEL);
+       if (cmd == NULL)
+               goto error;
+       cmd->rccb.bCommandType = UWB_RC_CET_GENERAL;
+       cmd->rccb.wCommand = cpu_to_le16(UWB_RC_CMD_SET_DRP_IE);
+       cmd->wIELength = num_bytes;
+       IEDataptr = (u8 *)&cmd->IEData[0];
+
+       /* Next traverse all reservations to place IEs in allocated memory. */
+       list_for_each_entry(rsv, &rc->reservations, rc_node) {
+               if (rsv->drp_ie != NULL) {
+                       memcpy(IEDataptr, rsv->drp_ie,
+                              rsv->drp_ie->hdr.length + 2);
+                       IEDataptr += rsv->drp_ie->hdr.length + 2;
+               }
+       }
+       memcpy(IEDataptr, &rc->drp_avail.ie, sizeof(rc->drp_avail.ie));
+
+       reply.rceb.bEventType = UWB_RC_CET_GENERAL;
+       reply.rceb.wEvent = UWB_RC_CMD_SET_DRP_IE;
+       result = uwb_rc_cmd(rc, "SET-DRP-IE", &cmd->rccb,
+                       sizeof(*cmd) + num_bytes, &reply.rceb,
+                       sizeof(reply));
+       if (result < 0)
+               goto error_cmd;
+       result = le16_to_cpu(reply.wRemainingSpace);
+       if (reply.bResultCode != UWB_RC_RES_SUCCESS) {
+               dev_err(&rc->uwb_dev.dev, "SET-DRP-IE: command execution "
+                               "failed: %s (%d). RemainingSpace in beacon "
+                               "= %d\n", uwb_rc_strerror(reply.bResultCode),
+                               reply.bResultCode, result);
+               result = -EIO;
+       } else {
+               dev_dbg(dev, "SET-DRP-IE sent. RemainingSpace in beacon "
+                            "= %d.\n", result);
+               result = 0;
+       }
+error_cmd:
+       kfree(cmd);
+error:
+       return result;
+
+}
+/**
+ * Send all DRP IEs associated with this host
+ *
+ * @returns:    >= 0 number of bytes still available in the beacon
+ *              < 0 errno code on error.
+ *
+ * As per the protocol we obtain the host controller device lock to access
+ * bandwidth structures.
+ */
+int uwb_rc_send_all_drp_ie(struct uwb_rc *rc)
+{
+       int result;
+
+       mutex_lock(&rc->uwb_dev.mutex);
+       result = uwb_rc_gen_send_drp_ie(rc);
+       mutex_unlock(&rc->uwb_dev.mutex);
+       return result;
+}
+
+void uwb_drp_handle_timeout(struct uwb_rsv *rsv)
+{
+       struct device *dev = &rsv->rc->uwb_dev.dev;
+
+       dev_dbg(dev, "reservation timeout in state %s (%d)\n",
+               uwb_rsv_state_str(rsv->state), rsv->state);
+
+       switch (rsv->state) {
+       case UWB_RSV_STATE_O_INITIATED:
+               if (rsv->is_multicast) {
+                       uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_ESTABLISHED);
+                       return;
+               }
+               break;
+       case UWB_RSV_STATE_O_ESTABLISHED:
+               if (rsv->is_multicast)
+                       return;
+               break;
+       default:
+               break;
+       }
+       uwb_rsv_remove(rsv);
+}
+
+/*
+ * Based on the DRP IE, transition a target reservation to a new
+ * state.
+ */
+static void uwb_drp_process_target(struct uwb_rc *rc, struct uwb_rsv *rsv,
+                                  struct uwb_ie_drp *drp_ie)
+{
+       struct device *dev = &rc->uwb_dev.dev;
+       int status;
+       enum uwb_drp_reason reason_code;
+
+       status = uwb_ie_drp_status(drp_ie);
+       reason_code = uwb_ie_drp_reason_code(drp_ie);
+
+       if (status) {
+               switch (reason_code) {
+               case UWB_DRP_REASON_ACCEPTED:
+                       uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_ACCEPTED);
+                       break;
+               case UWB_DRP_REASON_MODIFIED:
+                       dev_err(dev, "FIXME: unhandled reason code (%d/%d)\n",
+                               reason_code, status);
+                       break;
+               default:
+                       dev_warn(dev, "ignoring invalid DRP IE state (%d/%d)\n",
+                                reason_code, status);
+               }
+       } else {
+               switch (reason_code) {
+               case UWB_DRP_REASON_ACCEPTED:
+                       /* New reservations are handled in uwb_rsv_find(). */
+                       break;
+               case UWB_DRP_REASON_DENIED:
+                       uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE);
+                       break;
+               case UWB_DRP_REASON_CONFLICT:
+               case UWB_DRP_REASON_MODIFIED:
+                       dev_err(dev, "FIXME: unhandled reason code (%d/%d)\n",
+                               reason_code, status);
+                       break;
+               default:
+                       dev_warn(dev, "ignoring invalid DRP IE state (%d/%d)\n",
+                                reason_code, status);
+               }
+       }
+}
+
+/*
+ * Based on the DRP IE, transition an owner reservation to a new
+ * state.
+ */
+static void uwb_drp_process_owner(struct uwb_rc *rc, struct uwb_rsv *rsv,
+                                 struct uwb_ie_drp *drp_ie)
+{
+       struct device *dev = &rc->uwb_dev.dev;
+       int status;
+       enum uwb_drp_reason reason_code;
+
+       status = uwb_ie_drp_status(drp_ie);
+       reason_code = uwb_ie_drp_reason_code(drp_ie);
+
+       if (status) {
+               switch (reason_code) {
+               case UWB_DRP_REASON_ACCEPTED:
+                       uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_ESTABLISHED);
+                       break;
+               case UWB_DRP_REASON_MODIFIED:
+                       dev_err(dev, "FIXME: unhandled reason code (%d/%d)\n",
+                               reason_code, status);
+                       break;
+               default:
+                       dev_warn(dev, "ignoring invalid DRP IE state (%d/%d)\n",
+                                reason_code, status);
+               }
+       } else {
+               switch (reason_code) {
+               case UWB_DRP_REASON_PENDING:
+                       uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_PENDING);
+                       break;
+               case UWB_DRP_REASON_DENIED:
+                       uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE);
+                       break;
+               case UWB_DRP_REASON_CONFLICT:
+               case UWB_DRP_REASON_MODIFIED:
+                       dev_err(dev, "FIXME: unhandled reason code (%d/%d)\n",
+                               reason_code, status);
+                       break;
+               default:
+                       dev_warn(dev, "ignoring invalid DRP IE state (%d/%d)\n",
+                                reason_code, status);
+               }
+       }
+}
+
+/*
+ * Process a received DRP IE, it's either for a reservation owned by
+ * the RC or targeted at it (or it's for a WUSB cluster reservation).
+ */
+static void uwb_drp_process(struct uwb_rc *rc, struct uwb_dev *src,
+                    struct uwb_ie_drp *drp_ie)
+{
+       struct uwb_rsv *rsv;
+
+       rsv = uwb_rsv_find(rc, src, drp_ie);
+       if (!rsv) {
+               /*
+                * No reservation? It's either for a recently
+                * terminated reservation; or the DRP IE couldn't be
+                * processed (e.g., an invalid IE or out of memory).
+                */
+               return;
+       }
+
+       /*
+        * Do nothing with DRP IEs for reservations that have been
+        * terminated.
+        */
+       if (rsv->state == UWB_RSV_STATE_NONE) {
+               uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE);
+               return;
+       }
+
+       if (uwb_ie_drp_owner(drp_ie))
+               uwb_drp_process_target(rc, rsv, drp_ie);
+       else
+               uwb_drp_process_owner(rc, rsv, drp_ie);
+}
+
+
+/*
+ * Process all the DRP IEs (both DRP IEs and the DRP Availability IE)
+ * from a device.
+ */
+static
+void uwb_drp_process_all(struct uwb_rc *rc, struct uwb_rc_evt_drp *drp_evt,
+                        size_t ielen, struct uwb_dev *src_dev)
+{
+       struct device *dev = &rc->uwb_dev.dev;
+       struct uwb_ie_hdr *ie_hdr;
+       void *ptr;
+
+       ptr = drp_evt->ie_data;
+       for (;;) {
+               ie_hdr = uwb_ie_next(&ptr, &ielen);
+               if (!ie_hdr)
+                       break;
+
+               switch (ie_hdr->element_id) {
+               case UWB_IE_DRP_AVAILABILITY:
+                       /* FIXME: does something need to be done with this? */
+                       break;
+               case UWB_IE_DRP:
+                       uwb_drp_process(rc, src_dev, (struct uwb_ie_drp *)ie_hdr);
+                       break;
+               default:
+                       dev_warn(dev, "unexpected IE in DRP notification\n");
+                       break;
+               }
+       }
+
+       if (ielen > 0)
+               dev_warn(dev, "%d octets remaining in DRP notification\n",
+                        (int)ielen);
+}
+
+
+/*
+ * Go through all the DRP IEs and find the ones that conflict with our
+ * reservations.
+ *
+ * FIXME: must resolve the conflict according the the rules in
+ * [ECMA-368].
+ */
+static
+void uwb_drp_process_conflict_all(struct uwb_rc *rc, struct uwb_rc_evt_drp *drp_evt,
+                                 size_t ielen, struct uwb_dev *src_dev)
+{
+       struct device *dev = &rc->uwb_dev.dev;
+       struct uwb_ie_hdr *ie_hdr;
+       struct uwb_ie_drp *drp_ie;
+       void *ptr;
+
+       ptr = drp_evt->ie_data;
+       for (;;) {
+               ie_hdr = uwb_ie_next(&ptr, &ielen);
+               if (!ie_hdr)
+                       break;
+
+               drp_ie = container_of(ie_hdr, struct uwb_ie_drp, hdr);
+
+               /* FIXME: check if this DRP IE conflicts. */
+       }
+
+       if (ielen > 0)
+               dev_warn(dev, "%d octets remaining in DRP notification\n",
+                        (int)ielen);
+}
+
+
+/*
+ * Terminate all reservations owned by, or targeted at, 'uwb_dev'.
+ */
+static void uwb_drp_terminate_all(struct uwb_rc *rc, struct uwb_dev *uwb_dev)
+{
+       struct uwb_rsv *rsv;
+
+       list_for_each_entry(rsv, &rc->reservations, rc_node) {
+               if (rsv->owner == uwb_dev
+                   || (rsv->target.type == UWB_RSV_TARGET_DEV && rsv->target.dev == uwb_dev))
+                       uwb_rsv_remove(rsv);
+       }
+}
+
+
+/**
+ * uwbd_evt_handle_rc_drp - handle a DRP_IE event
+ * @evt: the DRP_IE event from the radio controller
+ *
+ * This processes DRP notifications from the radio controller, either
+ * initiating a new reservation or transitioning an existing
+ * reservation into a different state.
+ *
+ * DRP notifications can occur for three different reasons:
+ *
+ * - UWB_DRP_NOTIF_DRP_IE_RECVD: one or more DRP IEs with the RC as
+ *   the target or source have been recieved.
+ *
+ *   These DRP IEs could be new or for an existing reservation.
+ *
+ *   If the DRP IE for an existing reservation ceases to be to
+ *   recieved for at least mMaxLostBeacons, the reservation should be
+ *   considered to be terminated.  Note that the TERMINATE reason (see
+ *   below) may not always be signalled (e.g., the remote device has
+ *   two or more reservations established with the RC).
+ *
+ * - UWB_DRP_NOTIF_CONFLICT: DRP IEs from any device in the beacon
+ *   group conflict with the RC's reservations.
+ *
+ * - UWB_DRP_NOTIF_TERMINATE: DRP IEs are no longer being received
+ *   from a device (i.e., it's terminated all reservations).
+ *
+ * Only the software state of the reservations is changed; the setting
+ * of the radio controller's DRP IEs is done after all the events in
+ * an event buffer are processed.  This saves waiting multiple times
+ * for the SET_DRP_IE command to complete.
+ */
+int uwbd_evt_handle_rc_drp(struct uwb_event *evt)
+{
+       struct device *dev = &evt->rc->uwb_dev.dev;
+       struct uwb_rc *rc = evt->rc;
+       struct uwb_rc_evt_drp *drp_evt;
+       size_t ielength, bytes_left;
+       struct uwb_dev_addr src_addr;
+       struct uwb_dev *src_dev;
+       int reason;
+
+       /* Is there enough data to decode the event (and any IEs in
+          its payload)? */
+       if (evt->notif.size < sizeof(*drp_evt)) {
+               dev_err(dev, "DRP event: Not enough data to decode event "
+                       "[%zu bytes left, %zu needed]\n",
+                       evt->notif.size, sizeof(*drp_evt));
+               return 0;
+       }
+       bytes_left = evt->notif.size - sizeof(*drp_evt);
+       drp_evt = container_of(evt->notif.rceb, struct uwb_rc_evt_drp, rceb);
+       ielength = le16_to_cpu(drp_evt->ie_length);
+       if (bytes_left != ielength) {
+               dev_err(dev, "DRP event: Not enough data in payload [%zu"
+                       "bytes left, %zu declared in the event]\n",
+                       bytes_left, ielength);
+               return 0;
+       }
+
+       memcpy(src_addr.data, &drp_evt->src_addr, sizeof(src_addr));
+       src_dev = uwb_dev_get_by_devaddr(rc, &src_addr);
+       if (!src_dev) {
+               /*
+                * A DRP notification from an unrecognized device.
+                *
+                * This is probably from a WUSB device that doesn't
+                * have an EUI-48 and therefore doesn't show up in the
+                * UWB device database.  It's safe to simply ignore
+                * these.
+                */
+               return 0;
+       }
+
+       mutex_lock(&rc->rsvs_mutex);
+
+       reason = uwb_rc_evt_drp_reason(drp_evt);
+
+       switch (reason) {
+       case UWB_DRP_NOTIF_DRP_IE_RCVD:
+               uwb_drp_process_all(rc, drp_evt, ielength, src_dev);
+               break;
+       case UWB_DRP_NOTIF_CONFLICT:
+               uwb_drp_process_conflict_all(rc, drp_evt, ielength, src_dev);
+               break;
+       case UWB_DRP_NOTIF_TERMINATE:
+               uwb_drp_terminate_all(rc, src_dev);
+               break;
+       default:
+               dev_warn(dev, "ignored DRP event with reason code: %d\n", reason);
+               break;
+       }
+
+       mutex_unlock(&rc->rsvs_mutex);
+
+       uwb_dev_put(src_dev);
+       return 0;
+}
diff --git a/drivers/uwb/est.c b/drivers/uwb/est.c
new file mode 100644 (file)
index 0000000..5fe566b
--- /dev/null
@@ -0,0 +1,477 @@
+/*
+ * Ultra Wide Band Radio Control
+ * Event Size Tables management
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ *
+ * Infrastructure, code and data tables for guessing the size of
+ * events received on the notification endpoints of UWB radio
+ * controllers.
+ *
+ * You define a table of events and for each, its size and how to get
+ * the extra size.
+ *
+ * ENTRY POINTS:
+ *
+ * uwb_est_{init/destroy}(): To initialize/release the EST subsystem.
+ *
+ * uwb_est_[u]register(): To un/register event size tables
+ *   uwb_est_grow()
+ *
+ * uwb_est_find_size(): Get the size of an event
+ *   uwb_est_get_size()
+ */
+#include <linux/spinlock.h>
+#define D_LOCAL 0
+#include <linux/uwb/debug.h>
+#include "uwb-internal.h"
+
+
+struct uwb_est {
+       u16 type_event_high;
+       u16 vendor, product;
+       u8 entries;
+       const struct uwb_est_entry *entry;
+};
+
+
+static struct uwb_est *uwb_est;
+static u8 uwb_est_size;
+static u8 uwb_est_used;
+static DEFINE_RWLOCK(uwb_est_lock);
+
+/**
+ * WUSB Standard Event Size Table, HWA-RC interface
+ *
+ * Sizes for events and notifications type 0 (general), high nibble 0.
+ */
+static
+struct uwb_est_entry uwb_est_00_00xx[] = {
+       [UWB_RC_EVT_IE_RCV] = {
+               .size = sizeof(struct uwb_rc_evt_ie_rcv),
+               .offset = 1 + offsetof(struct uwb_rc_evt_ie_rcv, wIELength),
+       },
+       [UWB_RC_EVT_BEACON] = {
+               .size = sizeof(struct uwb_rc_evt_beacon),
+               .offset = 1 + offsetof(struct uwb_rc_evt_beacon, wBeaconInfoLength),
+       },
+       [UWB_RC_EVT_BEACON_SIZE] = {
+               .size = sizeof(struct uwb_rc_evt_beacon_size),
+       },
+       [UWB_RC_EVT_BPOIE_CHANGE] = {
+               .size = sizeof(struct uwb_rc_evt_bpoie_change),
+               .offset = 1 + offsetof(struct uwb_rc_evt_bpoie_change,
+                                      wBPOIELength),
+       },
+       [UWB_RC_EVT_BP_SLOT_CHANGE] = {
+               .size = sizeof(struct uwb_rc_evt_bp_slot_change),
+       },
+       [UWB_RC_EVT_BP_SWITCH_IE_RCV] = {
+               .size = sizeof(struct uwb_rc_evt_bp_switch_ie_rcv),
+               .offset = 1 + offsetof(struct uwb_rc_evt_bp_switch_ie_rcv, wIELength),
+       },
+       [UWB_RC_EVT_DEV_ADDR_CONFLICT] = {
+               .size = sizeof(struct uwb_rc_evt_dev_addr_conflict),
+       },
+       [UWB_RC_EVT_DRP_AVAIL] = {
+               .size = sizeof(struct uwb_rc_evt_drp_avail)
+       },
+       [UWB_RC_EVT_DRP] = {
+               .size = sizeof(struct uwb_rc_evt_drp),
+               .offset = 1 + offsetof(struct uwb_rc_evt_drp, ie_length),
+       },
+       [UWB_RC_EVT_BP_SWITCH_STATUS] = {
+               .size = sizeof(struct uwb_rc_evt_bp_switch_status),
+       },
+       [UWB_RC_EVT_CMD_FRAME_RCV] = {
+               .size = sizeof(struct uwb_rc_evt_cmd_frame_rcv),
+               .offset = 1 + offsetof(struct uwb_rc_evt_cmd_frame_rcv, dataLength),
+       },
+       [UWB_RC_EVT_CHANNEL_CHANGE_IE_RCV] = {
+               .size = sizeof(struct uwb_rc_evt_channel_change_ie_rcv),
+               .offset = 1 + offsetof(struct uwb_rc_evt_channel_change_ie_rcv, wIELength),
+       },
+       [UWB_RC_CMD_CHANNEL_CHANGE] = {
+               .size = sizeof(struct uwb_rc_evt_confirm),
+       },
+       [UWB_RC_CMD_DEV_ADDR_MGMT] = {
+               .size = sizeof(struct uwb_rc_evt_dev_addr_mgmt) },
+       [UWB_RC_CMD_GET_IE] = {
+               .size = sizeof(struct uwb_rc_evt_get_ie),
+               .offset = 1 + offsetof(struct uwb_rc_evt_get_ie, wIELength),
+       },
+       [UWB_RC_CMD_RESET] = {
+               .size = sizeof(struct uwb_rc_evt_confirm),
+       },
+       [UWB_RC_CMD_SCAN] = {
+               .size = sizeof(struct uwb_rc_evt_confirm),
+       },
+       [UWB_RC_CMD_SET_BEACON_FILTER] = {
+               .size = sizeof(struct uwb_rc_evt_confirm),
+       },
+       [UWB_RC_CMD_SET_DRP_IE] = {
+               .size = sizeof(struct uwb_rc_evt_set_drp_ie),
+       },
+       [UWB_RC_CMD_SET_IE] = {
+               .size = sizeof(struct uwb_rc_evt_set_ie),
+       },
+       [UWB_RC_CMD_SET_NOTIFICATION_FILTER] = {
+               .size = sizeof(struct uwb_rc_evt_confirm),
+       },
+       [UWB_RC_CMD_SET_TX_POWER] = {
+               .size = sizeof(struct uwb_rc_evt_confirm),
+       },
+       [UWB_RC_CMD_SLEEP] = {
+               .size = sizeof(struct uwb_rc_evt_confirm),
+       },
+       [UWB_RC_CMD_START_BEACON] = {
+               .size = sizeof(struct uwb_rc_evt_confirm),
+       },
+       [UWB_RC_CMD_STOP_BEACON] = {
+               .size = sizeof(struct uwb_rc_evt_confirm),
+       },
+       [UWB_RC_CMD_BP_MERGE] = {
+               .size = sizeof(struct uwb_rc_evt_confirm),
+       },
+       [UWB_RC_CMD_SEND_COMMAND_FRAME] = {
+               .size = sizeof(struct uwb_rc_evt_confirm),
+       },
+       [UWB_RC_CMD_SET_ASIE_NOTIF] = {
+               .size = sizeof(struct uwb_rc_evt_confirm),
+       },
+};
+
+static
+struct uwb_est_entry uwb_est_01_00xx[] = {
+       [UWB_RC_DAA_ENERGY_DETECTED] = {
+               .size = sizeof(struct uwb_rc_evt_daa_energy_detected),
+       },
+       [UWB_RC_SET_DAA_ENERGY_MASK] = {
+               .size = sizeof(struct uwb_rc_evt_set_daa_energy_mask),
+       },
+       [UWB_RC_SET_NOTIFICATION_FILTER_EX] = {
+               .size = sizeof(struct uwb_rc_evt_set_notification_filter_ex),
+       },
+};
+
+/**
+ * Initialize the EST subsystem
+ *
+ * Register the standard tables also.
+ *
+ * FIXME: tag init
+ */
+int uwb_est_create(void)
+{
+       int result;
+
+       uwb_est_size = 2;
+       uwb_est_used = 0;
+       uwb_est = kzalloc(uwb_est_size * sizeof(uwb_est[0]), GFP_KERNEL);
+       if (uwb_est == NULL)
+               return -ENOMEM;
+
+       result = uwb_est_register(UWB_RC_CET_GENERAL, 0, 0xffff, 0xffff,
+                                 uwb_est_00_00xx, ARRAY_SIZE(uwb_est_00_00xx));
+       if (result < 0)
+               goto out;
+       result = uwb_est_register(UWB_RC_CET_EX_TYPE_1, 0, 0xffff, 0xffff,
+                                 uwb_est_01_00xx, ARRAY_SIZE(uwb_est_01_00xx));
+out:
+       return result;
+}
+
+
+/** Clean it up */
+void uwb_est_destroy(void)
+{
+       kfree(uwb_est);
+       uwb_est = NULL;
+       uwb_est_size = uwb_est_used = 0;
+}
+
+
+/**
+ * Double the capacity of the EST table
+ *
+ * @returns 0 if ok, < 0 errno no error.
+ */
+static
+int uwb_est_grow(void)
+{
+       size_t actual_size = uwb_est_size * sizeof(uwb_est[0]);
+       void *new = kmalloc(2 * actual_size, GFP_ATOMIC);
+       if (new == NULL)
+               return -ENOMEM;
+       memcpy(new, uwb_est, actual_size);
+       memset(new + actual_size, 0, actual_size);
+       kfree(uwb_est);
+       uwb_est = new;
+       uwb_est_size *= 2;
+       return 0;
+}
+
+
+/**
+ * Register an event size table
+ *
+ * Makes room for it if the table is full, and then inserts  it in the
+ * right position (entries are sorted by type, event_high, vendor and
+ * then product).
+ *
+ * @vendor:  vendor code for matching against the device (0x0000 and
+ *           0xffff mean any); use 0x0000 to force all to match without
+ *           checking possible vendor specific ones, 0xfffff to match
+ *           after checking vendor specific ones.
+ *
+ * @product: product code from that vendor; same matching rules, use
+ *           0x0000 for not allowing vendor specific matches, 0xffff
+ *           for allowing.
+ *
+ * This arragement just makes the tables sort differenty. Because the
+ * table is sorted by growing type-event_high-vendor-product, a zero
+ * vendor will match before than a 0x456a vendor, that will match
+ * before a 0xfffff vendor.
+ *
+ * @returns 0 if ok, < 0 errno on error (-ENOENT if not found).
+ */
+/* FIXME: add bus type to vendor/product code */
+int uwb_est_register(u8 type, u8 event_high, u16 vendor, u16 product,
+                    const struct uwb_est_entry *entry, size_t entries)
+{
+       unsigned long flags;
+       unsigned itr;
+       u16 type_event_high;
+       int result = 0;
+
+       write_lock_irqsave(&uwb_est_lock, flags);
+       if (uwb_est_used == uwb_est_size) {
+               result = uwb_est_grow();
+               if (result < 0)
+                       goto out;
+       }
+       /* Find the right spot to insert it in */
+       type_event_high = type << 8 | event_high;
+       for (itr = 0; itr < uwb_est_used; itr++)
+               if (uwb_est[itr].type_event_high < type
+                   && uwb_est[itr].vendor < vendor
+                   && uwb_est[itr].product < product)
+                       break;
+
+       /* Shift others to make room for the new one? */
+       if (itr < uwb_est_used)
+               memmove(&uwb_est[itr+1], &uwb_est[itr], uwb_est_used - itr);
+       uwb_est[itr].type_event_high = type << 8 | event_high;
+       uwb_est[itr].vendor = vendor;
+       uwb_est[itr].product = product;
+       uwb_est[itr].entry = entry;
+       uwb_est[itr].entries = entries;
+       uwb_est_used++;
+out:
+       write_unlock_irqrestore(&uwb_est_lock, flags);
+       return result;
+}
+EXPORT_SYMBOL_GPL(uwb_est_register);
+
+
+/**
+ * Unregister an event size table
+ *
+ * This just removes the specified entry and moves the ones after it
+ * to fill in the gap. This is needed to keep the list sorted; no
+ * reallocation is done to reduce the size of the table.
+ *
+ * We unregister by all the data we used to register instead of by
+ * pointer to the @entry array because we might have used the same
+ * table for a bunch of IDs (for example).
+ *
+ * @returns 0 if ok, < 0 errno on error (-ENOENT if not found).
+ */
+int uwb_est_unregister(u8 type, u8 event_high, u16 vendor, u16 product,
+                      const struct uwb_est_entry *entry, size_t entries)
+{
+       unsigned long flags;
+       unsigned itr;
+       struct uwb_est est_cmp = {
+               .type_event_high = type << 8 | event_high,
+               .vendor = vendor,
+               .product = product,
+               .entry = entry,
+               .entries = entries
+       };
+       write_lock_irqsave(&uwb_est_lock, flags);
+       for (itr = 0; itr < uwb_est_used; itr++)
+               if (!memcmp(&uwb_est[itr], &est_cmp, sizeof(est_cmp)))
+                       goto found;
+       write_unlock_irqrestore(&uwb_est_lock, flags);
+       return -ENOENT;
+
+found:
+       if (itr < uwb_est_used - 1)     /* Not last one? move ones above */
+               memmove(&uwb_est[itr], &uwb_est[itr+1], uwb_est_used - itr - 1);
+       uwb_est_used--;
+       write_unlock_irqrestore(&uwb_est_lock, flags);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(uwb_est_unregister);
+
+
+/**
+ * Get the size of an event from a table
+ *
+ * @rceb: pointer to the buffer with the event
+ * @rceb_size: size of the area pointed to by @rceb in bytes.
+ * @returns: > 0      Size of the event
+ *          -ENOSPC  An area big enough was not provided to look
+ *                   ahead into the event's guts and guess the size.
+ *          -EINVAL  Unknown event code (wEvent).
+ *
+ * This will look at the received RCEB and guess what is the total
+ * size. For variable sized events, it will look further ahead into
+ * their length field to see how much data should be read.
+ *
+ * Note this size is *not* final--the neh (Notification/Event Handle)
+ * might specificy an extra size to add.
+ */
+static
+ssize_t uwb_est_get_size(struct uwb_rc *uwb_rc, struct uwb_est *est,
+                        u8 event_low, const struct uwb_rceb *rceb,
+                        size_t rceb_size)
+{
+       unsigned offset;
+       ssize_t size;
+       struct device *dev = &uwb_rc->uwb_dev.dev;
+       const struct uwb_est_entry *entry;
+
+       size = -ENOENT;
+       if (event_low >= est->entries) {        /* in range? */
+               dev_err(dev, "EST %p 0x%04x/%04x/%04x[%u]: event %u out of range\n",
+                       est, est->type_event_high, est->vendor, est->product,
+                       est->entries, event_low);
+               goto out;
+       }
+       size = -ENOENT;
+       entry = &est->entry[event_low];
+       if (entry->size == 0 && entry->offset == 0) {   /* unknown? */
+               dev_err(dev, "EST %p 0x%04x/%04x/%04x[%u]: event %u unknown\n",
+                       est, est->type_event_high, est->vendor, est->product,
+                       est->entries, event_low);
+               goto out;
+       }
+       offset = entry->offset; /* extra fries with that? */
+       if (offset == 0)
+               size = entry->size;
+       else {
+               /* Ops, got an extra size field at 'offset'--read it */
+               const void *ptr = rceb;
+               size_t type_size = 0;
+               offset--;
+               size = -ENOSPC;                 /* enough data for more? */
+               switch (entry->type) {
+               case UWB_EST_16:  type_size = sizeof(__le16); break;
+               case UWB_EST_8:   type_size = sizeof(u8);     break;
+               default:         BUG();
+               }
+               if (offset + type_size > rceb_size) {
+                       dev_err(dev, "EST %p 0x%04x/%04x/%04x[%u]: "
+                               "not enough data to read extra size\n",
+                               est, est->type_event_high, est->vendor,
+                               est->product, est->entries);
+                       goto out;
+               }
+               size = entry->size;
+               ptr += offset;
+               switch (entry->type) {
+               case UWB_EST_16:  size += le16_to_cpu(*(__le16 *)ptr); break;
+               case UWB_EST_8:   size += *(u8 *)ptr;                  break;
+               default:         BUG();
+               }
+       }
+out:
+       return size;
+}
+
+
+/**
+ * Guesses the size of a WA event
+ *
+ * @rceb: pointer to the buffer with the event
+ * @rceb_size: size of the area pointed to by @rceb in bytes.
+ * @returns: > 0      Size of the event
+ *          -ENOSPC  An area big enough was not provided to look
+ *                   ahead into the event's guts and guess the size.
+ *          -EINVAL  Unknown event code (wEvent).
+ *
+ * This will look at the received RCEB and guess what is the total
+ * size by checking all the tables registered with
+ * uwb_est_register(). For variable sized events, it will look further
+ * ahead into their length field to see how much data should be read.
+ *
+ * Note this size is *not* final--the neh (Notification/Event Handle)
+ * might specificy an extra size to add or replace.
+ */
+ssize_t uwb_est_find_size(struct uwb_rc *rc, const struct uwb_rceb *rceb,
+                         size_t rceb_size)
+{
+       /* FIXME: add vendor/product data */
+       ssize_t size;
+       struct device *dev = &rc->uwb_dev.dev;
+       unsigned long flags;
+       unsigned itr;
+       u16 type_event_high, event;
+       u8 *ptr = (u8 *) rceb;
+
+       read_lock_irqsave(&uwb_est_lock, flags);
+       d_printf(2, dev, "Size query for event 0x%02x/%04x/%02x,"
+                " buffer size %ld\n",
+                (unsigned) rceb->bEventType,
+                (unsigned) le16_to_cpu(rceb->wEvent),
+                (unsigned) rceb->bEventContext,
+                (long) rceb_size);
+       size = -ENOSPC;
+       if (rceb_size < sizeof(*rceb))
+               goto out;
+       event = le16_to_cpu(rceb->wEvent);
+       type_event_high = rceb->bEventType << 8 | (event & 0xff00) >> 8;
+       for (itr = 0; itr < uwb_est_used; itr++) {
+               d_printf(3, dev, "Checking EST 0x%04x/%04x/%04x\n",
+                       uwb_est[itr].type_event_high, uwb_est[itr].vendor,
+                       uwb_est[itr].product);
+               if (uwb_est[itr].type_event_high != type_event_high)
+                       continue;
+               size = uwb_est_get_size(rc, &uwb_est[itr],
+                                       event & 0x00ff, rceb, rceb_size);
+               /* try more tables that might handle the same type */
+               if (size != -ENOENT)
+                       goto out;
+       }
+       dev_dbg(dev, "event 0x%02x/%04x/%02x: no handlers available; "
+               "RCEB %02x %02x %02x %02x\n",
+               (unsigned) rceb->bEventType,
+               (unsigned) le16_to_cpu(rceb->wEvent),
+               (unsigned) rceb->bEventContext,
+               ptr[0], ptr[1], ptr[2], ptr[3]);
+       size = -ENOENT;
+out:
+       read_unlock_irqrestore(&uwb_est_lock, flags);
+       return size;
+}
+EXPORT_SYMBOL_GPL(uwb_est_find_size);
diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c
new file mode 100644 (file)
index 0000000..3d26fa0
--- /dev/null
@@ -0,0 +1,926 @@
+/*
+ * WUSB Host Wire Adapter: Radio Control Interface (WUSB[8.6])
+ * Radio Control command/event transport
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * Initialize the Radio Control interface Driver.
+ *
+ * For each device probed, creates an 'struct hwarc' which contains
+ * just the representation of the UWB Radio Controller, and the logic
+ * for reading notifications and passing them to the UWB Core.
+ *
+ * So we initialize all of those, register the UWB Radio Controller
+ * and setup the notification/event handle to pipe the notifications
+ * to the UWB management Daemon.
+ *
+ * Command and event filtering.
+ *
+ * This is the driver for the Radio Control Interface described in WUSB
+ * 1.0. The core UWB module assumes that all drivers are compliant to the
+ * WHCI 0.95 specification. We thus create a filter that parses all
+ * incoming messages from the (WUSB 1.0) device and manipulate them to
+ * conform to the WHCI 0.95 specification. Similarly, outgoing messages
+ * are parsed and manipulated to conform to the WUSB 1.0 compliant messages
+ * that the device expects. Only a few messages are affected:
+ * Affected events:
+ *    UWB_RC_EVT_BEACON
+ *    UWB_RC_EVT_BP_SLOT_CHANGE
+ *    UWB_RC_EVT_DRP_AVAIL
+ *    UWB_RC_EVT_DRP
+ * Affected commands:
+ *    UWB_RC_CMD_SCAN
+ *    UWB_RC_CMD_SET_DRP_IE
+ *
+ *
+ *
+ */
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/wusb.h>
+#include <linux/usb/wusb-wa.h>
+#include <linux/uwb.h>
+#include "uwb-internal.h"
+#define D_LOCAL 1
+#include <linux/uwb/debug.h>
+
+/* The device uses commands and events from the WHCI specification, although
+ * reporting itself as WUSB compliant. */
+#define WUSB_QUIRK_WHCI_CMD_EVT                0x01
+
+/**
+ * Descriptor for an instance of the UWB Radio Control Driver that
+ * attaches to the RCI interface of the Host Wired Adapter.
+ *
+ * Unless there is a lock specific to the 'data members', all access
+ * is protected by uwb_rc->mutex.
+ *
+ * The NEEP (Notification/Event EndPoint) URB (@neep_urb) writes to
+ * @rd_buffer. Note there is no locking because it is perfectly (heh!)
+ * serialized--probe() submits an URB, callback is called, processes
+ * the data (synchronously), submits another URB, and so on. There is
+ * no concurrent access to the buffer.
+ */
+struct hwarc {
+       struct usb_device *usb_dev;
+       struct usb_interface *usb_iface;
+       struct uwb_rc *uwb_rc;          /* UWB host controller */
+       struct urb *neep_urb;           /* Notification endpoint handling */
+       struct edc neep_edc;
+       void *rd_buffer;                /* NEEP read buffer */
+};
+
+
+/* Beacon received notification (WUSB 1.0 [8.6.3.2]) */
+struct uwb_rc_evt_beacon_WUSB_0100 {
+       struct uwb_rceb rceb;
+       u8      bChannelNumber;
+       __le16  wBPSTOffset;
+       u8      bLQI;
+       u8      bRSSI;
+       __le16  wBeaconInfoLength;
+       u8      BeaconInfo[];
+} __attribute__((packed));
+
+/**
+ * Filter WUSB 1.0 BEACON RCV notification to be WHCI 0.95
+ *
+ * @header: the incoming event
+ * @buf_size: size of buffer containing incoming event
+ * @new_size: size of event after filtering completed
+ *
+ * The WHCI 0.95 spec has a "Beacon Type" field. This value is unknown at
+ * the time we receive the beacon from WUSB so we just set it to
+ * UWB_RC_BEACON_TYPE_NEIGHBOR as a default.
+ * The solution below allocates memory upon receipt of every beacon from a
+ * WUSB device. This will deteriorate performance. What is the right way to
+ * do this?
+ */
+static
+int hwarc_filter_evt_beacon_WUSB_0100(struct uwb_rc *rc,
+                                     struct uwb_rceb **header,
+                                     const size_t buf_size,
+                                     size_t *new_size)
+{
+       struct uwb_rc_evt_beacon_WUSB_0100 *be;
+       struct uwb_rc_evt_beacon *newbe;
+       size_t bytes_left, ielength;
+       struct device *dev = &rc->uwb_dev.dev;
+
+       be = container_of(*header, struct uwb_rc_evt_beacon_WUSB_0100, rceb);
+       bytes_left = buf_size;
+       if (bytes_left < sizeof(*be)) {
+               dev_err(dev, "Beacon Received Notification: Not enough data "
+                       "to decode for filtering (%zu vs %zu bytes needed)\n",
+                       bytes_left, sizeof(*be));
+               return -EINVAL;
+       }
+       bytes_left -= sizeof(*be);
+       ielength = le16_to_cpu(be->wBeaconInfoLength);
+       if (bytes_left < ielength) {
+               dev_err(dev, "Beacon Received Notification: Not enough data "
+                       "to decode IEs (%zu vs %zu bytes needed)\n",
+                       bytes_left, ielength);
+               return -EINVAL;
+       }
+       newbe = kzalloc(sizeof(*newbe) + ielength, GFP_ATOMIC);
+       if (newbe == NULL)
+               return -ENOMEM;
+       newbe->rceb = be->rceb;
+       newbe->bChannelNumber = be->bChannelNumber;
+       newbe->bBeaconType = UWB_RC_BEACON_TYPE_NEIGHBOR;
+       newbe->wBPSTOffset = be->wBPSTOffset;
+       newbe->bLQI = be->bLQI;
+       newbe->bRSSI = be->bRSSI;
+       newbe->wBeaconInfoLength = be->wBeaconInfoLength;
+       memcpy(newbe->BeaconInfo, be->BeaconInfo, ielength);
+       *header = &newbe->rceb;
+       *new_size = sizeof(*newbe) + ielength;
+       return 1;  /* calling function will free memory */
+}
+
+
+/* DRP Availability change notification (WUSB 1.0 [8.6.3.8]) */
+struct uwb_rc_evt_drp_avail_WUSB_0100 {
+       struct uwb_rceb rceb;
+       __le16 wIELength;
+       u8 IEData[];
+} __attribute__((packed));
+
+/**
+ * Filter WUSB 1.0 DRP AVAILABILITY CHANGE notification to be WHCI 0.95
+ *
+ * @header: the incoming event
+ * @buf_size: size of buffer containing incoming event
+ * @new_size: size of event after filtering completed
+ */
+static
+int hwarc_filter_evt_drp_avail_WUSB_0100(struct uwb_rc *rc,
+                                        struct uwb_rceb **header,
+                                        const size_t buf_size,
+                                        size_t *new_size)
+{
+       struct uwb_rc_evt_drp_avail_WUSB_0100 *da;
+       struct uwb_rc_evt_drp_avail *newda;
+       struct uwb_ie_hdr *ie_hdr;
+       size_t bytes_left, ielength;
+       struct device *dev = &rc->uwb_dev.dev;
+
+
+       da = container_of(*header, struct uwb_rc_evt_drp_avail_WUSB_0100, rceb);
+       bytes_left = buf_size;
+       if (bytes_left < sizeof(*da)) {
+               dev_err(dev, "Not enough data to decode DRP Avail "
+                       "Notification for filtering. Expected %zu, "
+                       "received %zu.\n", (size_t)sizeof(*da), bytes_left);
+               return -EINVAL;
+       }
+       bytes_left -= sizeof(*da);
+       ielength = le16_to_cpu(da->wIELength);
+       if (bytes_left < ielength) {
+               dev_err(dev, "DRP Avail Notification filter: IE length "
+                       "[%zu bytes] does not match actual length "
+                       "[%zu bytes].\n", ielength, bytes_left);
+               return -EINVAL;
+       }
+       if (ielength < sizeof(*ie_hdr)) {
+               dev_err(dev, "DRP Avail Notification filter: Not enough "
+                       "data to decode IE [%zu bytes, %zu needed]\n",
+                       ielength, sizeof(*ie_hdr));
+               return -EINVAL;
+       }
+       ie_hdr = (void *) da->IEData;
+       if (ie_hdr->length > 32) {
+               dev_err(dev, "DRP Availability Change event has unexpected "
+                       "length for filtering. Expected < 32 bytes, "
+                       "got %zu bytes.\n", (size_t)ie_hdr->length);
+               return -EINVAL;
+       }
+       newda = kzalloc(sizeof(*newda), GFP_ATOMIC);
+       if (newda == NULL)
+               return -ENOMEM;
+       newda->rceb = da->rceb;
+       memcpy(newda->bmp, (u8 *) ie_hdr + sizeof(*ie_hdr), ie_hdr->length);
+       *header = &newda->rceb;
+       *new_size = sizeof(*newda);
+       return 1; /* calling function will free memory */
+}
+
+
+/* DRP notification (WUSB 1.0 [8.6.3.9]) */
+struct uwb_rc_evt_drp_WUSB_0100 {
+       struct uwb_rceb rceb;
+       struct uwb_dev_addr wSrcAddr;
+       u8 bExplicit;
+       __le16 wIELength;
+       u8 IEData[];
+} __attribute__((packed));
+
+/**
+ * Filter WUSB 1.0 DRP Notification to be WHCI 0.95
+ *
+ * @header: the incoming event
+ * @buf_size: size of buffer containing incoming event
+ * @new_size: size of event after filtering completed
+ *
+ * It is hard to manage DRP reservations without having a Reason code.
+ * Unfortunately there is none in the WUSB spec. We just set the default to
+ * DRP IE RECEIVED.
+ * We do not currently use the bBeaconSlotNumber value, so we set this to
+ * zero for now.
+ */
+static
+int hwarc_filter_evt_drp_WUSB_0100(struct uwb_rc *rc,
+                                  struct uwb_rceb **header,
+                                  const size_t buf_size,
+                                  size_t *new_size)
+{
+       struct uwb_rc_evt_drp_WUSB_0100 *drpev;
+       struct uwb_rc_evt_drp *newdrpev;
+       size_t bytes_left, ielength;
+       struct device *dev = &rc->uwb_dev.dev;
+
+       drpev = container_of(*header, struct uwb_rc_evt_drp_WUSB_0100, rceb);
+       bytes_left = buf_size;
+       if (bytes_left < sizeof(*drpev)) {
+               dev_err(dev, "Not enough data to decode DRP Notification "
+                       "for filtering. Expected %zu, received %zu.\n",
+                       (size_t)sizeof(*drpev), bytes_left);
+               return -EINVAL;
+       }
+       ielength = le16_to_cpu(drpev->wIELength);
+       bytes_left -= sizeof(*drpev);
+       if (bytes_left < ielength) {
+               dev_err(dev, "DRP Notification filter: header length [%zu "
+                       "bytes] does not match actual length [%zu "
+                       "bytes].\n", ielength, bytes_left);
+               return -EINVAL;
+       }
+       newdrpev = kzalloc(sizeof(*newdrpev) + ielength, GFP_ATOMIC);
+       if (newdrpev == NULL)
+               return -ENOMEM;
+       newdrpev->rceb = drpev->rceb;
+       newdrpev->src_addr = drpev->wSrcAddr;
+       newdrpev->reason = UWB_DRP_NOTIF_DRP_IE_RCVD;
+       newdrpev->beacon_slot_number = 0;
+       newdrpev->ie_length = drpev->wIELength;
+       memcpy(newdrpev->ie_data, drpev->IEData, ielength);
+       *header = &newdrpev->rceb;
+       *new_size = sizeof(*newdrpev) + ielength;
+       return 1; /* calling function will free memory */
+}
+
+
+/* Scan Command (WUSB 1.0 [8.6.2.5]) */
+struct uwb_rc_cmd_scan_WUSB_0100 {
+       struct uwb_rccb rccb;
+       u8 bChannelNumber;
+       u8 bScanState;
+} __attribute__((packed));
+
+/**
+ * Filter WHCI 0.95 SCAN command to be WUSB 1.0 SCAN command
+ *
+ * @header:   command sent to device (compliant to WHCI 0.95)
+ * @size:     size of command sent to device
+ *
+ * We only reduce the size by two bytes because the WUSB 1.0 scan command
+ * does not have the last field (wStarttime). Also, make sure we don't send
+ * the device an unexpected scan type.
+ */
+static
+int hwarc_filter_cmd_scan_WUSB_0100(struct uwb_rc *rc,
+                                   struct uwb_rccb **header,
+                                   size_t *size)
+{
+       struct uwb_rc_cmd_scan *sc;
+
+       sc = container_of(*header, struct uwb_rc_cmd_scan, rccb);
+
+       if (sc->bScanState == UWB_SCAN_ONLY_STARTTIME)
+               sc->bScanState = UWB_SCAN_ONLY;
+       /* Don't send the last two bytes. */
+       *size -= 2;
+       return 0;
+}
+
+
+/* SET DRP IE command (WUSB 1.0 [8.6.2.7]) */
+struct uwb_rc_cmd_set_drp_ie_WUSB_0100 {
+       struct uwb_rccb rccb;
+       u8 bExplicit;
+       __le16 wIELength;
+       struct uwb_ie_drp IEData[];
+} __attribute__((packed));
+
+/**
+ * Filter WHCI 0.95 SET DRP IE command to be WUSB 1.0 SET DRP IE command
+ *
+ * @header:   command sent to device (compliant to WHCI 0.95)
+ * @size:     size of command sent to device
+ *
+ * WUSB has an extra bExplicit field - we assume always explicit
+ * negotiation so this field is set. The command expected by the device is
+ * thus larger than the one prepared by the driver so we need to
+ * reallocate memory to accommodate this.
+ * We trust the driver to send us the correct data so no checking is done
+ * on incoming data - evn though it is variable length.
+ */
+static
+int hwarc_filter_cmd_set_drp_ie_WUSB_0100(struct uwb_rc *rc,
+                                         struct uwb_rccb **header,
+                                         size_t *size)
+{
+       struct uwb_rc_cmd_set_drp_ie *orgcmd;
+       struct uwb_rc_cmd_set_drp_ie_WUSB_0100 *cmd;
+       size_t ielength;
+
+       orgcmd = container_of(*header, struct uwb_rc_cmd_set_drp_ie, rccb);
+       ielength = le16_to_cpu(orgcmd->wIELength);
+       cmd = kzalloc(sizeof(*cmd) + ielength, GFP_KERNEL);
+       if (cmd == NULL)
+               return -ENOMEM;
+       cmd->rccb = orgcmd->rccb;
+       cmd->bExplicit = 0;
+       cmd->wIELength = orgcmd->wIELength;
+       memcpy(cmd->IEData, orgcmd->IEData, ielength);
+       *header = &cmd->rccb;
+       *size = sizeof(*cmd) + ielength;
+       return 1; /* calling function will free memory */
+}
+
+
+/**
+ * Filter data from WHCI driver to WUSB device
+ *
+ * @header: WHCI 0.95 compliant command from driver
+ * @size:   length of command
+ *
+ * The routine managing commands to the device (uwb_rc_cmd()) will call the
+ * filtering function pointer (if it exists) before it passes any data to
+ * the device. At this time the command has been formatted according to
+ * WHCI 0.95 and is ready to be sent to the device.
+ *
+ * The filter function will be provided with the current command and its
+ * length. The function will manipulate the command if necessary and
+ * potentially reallocate memory for a command that needed more memory that
+ * the given command. If new memory was created the function will return 1
+ * to indicate to the calling function that the memory need to be freed
+ * when not needed any more. The size will contain the new length of the
+ * command.
+ * If memory has not been allocated we rely on the original mechanisms to
+ * free the memory of the command - even when we reduce the value of size.
+ */
+static
+int hwarc_filter_cmd_WUSB_0100(struct uwb_rc *rc, struct uwb_rccb **header,
+                              size_t *size)
+{
+       int result;
+       struct uwb_rccb *rccb = *header;
+       int cmd = le16_to_cpu(rccb->wCommand);
+       switch (cmd) {
+       case UWB_RC_CMD_SCAN:
+               result = hwarc_filter_cmd_scan_WUSB_0100(rc, header, size);
+               break;
+       case UWB_RC_CMD_SET_DRP_IE:
+               result = hwarc_filter_cmd_set_drp_ie_WUSB_0100(rc, header, size);
+               break;
+       default:
+               result = -ENOANO;
+               break;
+       }
+       return result;
+}
+
+
+/**
+ * Filter data from WHCI driver to WUSB device
+ *
+ * @header: WHCI 0.95 compliant command from driver
+ * @size:   length of command
+ *
+ * Filter commands based on which protocol the device supports. The WUSB
+ * errata should be the same as WHCI 0.95 so we do not filter that here -
+ * only WUSB 1.0.
+ */
+static
+int hwarc_filter_cmd(struct uwb_rc *rc, struct uwb_rccb **header,
+                    size_t *size)
+{
+       int result = -ENOANO;
+       if (rc->version == 0x0100)
+               result = hwarc_filter_cmd_WUSB_0100(rc, header, size);
+       return result;
+}
+
+
+/**
+ * Compute return value as sum of incoming value and value at given offset
+ *
+ * @rceb:      event for which we compute the size, it contains a variable
+ *            length field.
+ * @core_size: size of the "non variable" part of the event
+ * @offset:    place in event where the length of the variable part is stored
+ * @buf_size: total length of buffer in which event arrived - we need to make
+ *            sure we read the offset in memory that is still part of the event
+ */
+static
+ssize_t hwarc_get_event_size(struct uwb_rc *rc, const struct uwb_rceb *rceb,
+                            size_t core_size, size_t offset,
+                            const size_t buf_size)
+{
+       ssize_t size = -ENOSPC;
+       const void *ptr = rceb;
+       size_t type_size = sizeof(__le16);
+       struct device *dev = &rc->uwb_dev.dev;
+
+       if (offset + type_size >= buf_size) {
+               dev_err(dev, "Not enough data to read extra size of event "
+                       "0x%02x/%04x/%02x, only got %zu bytes.\n",
+                       rceb->bEventType, le16_to_cpu(rceb->wEvent),
+                       rceb->bEventContext, buf_size);
+               goto out;
+       }
+       ptr += offset;
+       size = core_size + le16_to_cpu(*(__le16 *)ptr);
+out:
+       return size;
+}
+
+
+/* Beacon slot change notification (WUSB 1.0 [8.6.3.5]) */
+struct uwb_rc_evt_bp_slot_change_WUSB_0100 {
+       struct uwb_rceb rceb;
+       u8 bSlotNumber;
+} __attribute__((packed));
+
+
+/**
+ * Filter data from WUSB device to WHCI driver
+ *
+ * @header:     incoming event
+ * @buf_size:   size of buffer in which event arrived
+ * @_event_size: actual size of event in the buffer
+ * @new_size:   size of event after filtered
+ *
+ * We don't know how the buffer is constructed - there may be more than one
+ * event in it so buffer length does not determine event length. We first
+ * determine the expected size of the incoming event. This value is passed
+ * back only if the actual filtering succeeded (so we know the computed
+ * expected size is correct). This value will be zero if
+ * the event did not need any filtering.
+ *
+ * WHCI interprets the BP Slot Change event's data differently than
+ * WUSB. The event sizes are exactly the same. The data field
+ * indicates the new beacon slot in which a RC is transmitting its
+ * beacon. The maximum value of this is 96 (wMacBPLength ECMA-368
+ * 17.16 (Table 117)). We thus know that the WUSB value will not set
+ * the bit bNoSlot, so we don't really do anything (placeholder).
+ */
+static
+int hwarc_filter_event_WUSB_0100(struct uwb_rc *rc, struct uwb_rceb **header,
+                                const size_t buf_size, size_t *_real_size,
+                                size_t *_new_size)
+{
+       int result = -ENOANO;
+       struct uwb_rceb *rceb = *header;
+       int event = le16_to_cpu(rceb->wEvent);
+       size_t event_size;
+       size_t core_size, offset;
+
+       if (rceb->bEventType != UWB_RC_CET_GENERAL)
+               goto out;
+       switch (event) {
+       case UWB_RC_EVT_BEACON:
+               core_size = sizeof(struct uwb_rc_evt_beacon_WUSB_0100);
+               offset = offsetof(struct uwb_rc_evt_beacon_WUSB_0100,
+                                 wBeaconInfoLength);
+               event_size = hwarc_get_event_size(rc, rceb, core_size,
+                                                 offset, buf_size);
+               if (event_size < 0)
+                       goto out;
+               *_real_size = event_size;
+               result = hwarc_filter_evt_beacon_WUSB_0100(rc, header,
+                                                          buf_size, _new_size);
+               break;
+       case UWB_RC_EVT_BP_SLOT_CHANGE:
+               *_new_size = *_real_size =
+                       sizeof(struct uwb_rc_evt_bp_slot_change_WUSB_0100);
+               result = 0;
+               break;
+
+       case UWB_RC_EVT_DRP_AVAIL:
+               core_size = sizeof(struct uwb_rc_evt_drp_avail_WUSB_0100);
+               offset = offsetof(struct uwb_rc_evt_drp_avail_WUSB_0100,
+                                 wIELength);
+               event_size = hwarc_get_event_size(rc, rceb, core_size,
+                                                 offset, buf_size);
+               if (event_size < 0)
+                       goto out;
+               *_real_size = event_size;
+               result = hwarc_filter_evt_drp_avail_WUSB_0100(
+                       rc, header, buf_size, _new_size);
+               break;
+
+       case UWB_RC_EVT_DRP:
+               core_size = sizeof(struct uwb_rc_evt_drp_WUSB_0100);
+               offset = offsetof(struct uwb_rc_evt_drp_WUSB_0100, wIELength);
+               event_size = hwarc_get_event_size(rc, rceb, core_size,
+                                                 offset, buf_size);
+               if (event_size < 0)
+                       goto out;
+               *_real_size = event_size;
+               result = hwarc_filter_evt_drp_WUSB_0100(rc, header,
+                                                       buf_size, _new_size);
+               break;
+
+       default:
+               break;
+       }
+out:
+       return result;
+}
+
+/**
+ * Filter data from WUSB device to WHCI driver
+ *
+ * @header:     incoming event
+ * @buf_size:   size of buffer in which event arrived
+ * @_event_size: actual size of event in the buffer
+ * @_new_size:  size of event after filtered
+ *
+ * Filter events based on which protocol the device supports. The WUSB
+ * errata should be the same as WHCI 0.95 so we do not filter that here -
+ * only WUSB 1.0.
+ *
+ * If we don't handle it, we return -ENOANO (why the weird error code?
+ * well, so if I get it, I can pinpoint in the code that raised
+ * it...after all, not too many places use the higher error codes).
+ */
+static
+int hwarc_filter_event(struct uwb_rc *rc, struct uwb_rceb **header,
+                      const size_t buf_size, size_t *_real_size,
+                      size_t *_new_size)
+{
+       int result = -ENOANO;
+       if (rc->version == 0x0100)
+               result =  hwarc_filter_event_WUSB_0100(
+                       rc, header, buf_size, _real_size, _new_size);
+       return result;
+}
+
+
+/**
+ * Execute an UWB RC command on HWA
+ *
+ * @rc:              Instance of a Radio Controller that is a HWA
+ * @cmd:      Buffer containing the RCCB and payload to execute
+ * @cmd_size: Size of the command buffer.
+ *
+ * NOTE: rc's mutex has to be locked
+ */
+static
+int hwarc_cmd(struct uwb_rc *uwb_rc, const struct uwb_rccb *cmd, size_t cmd_size)
+{
+       struct hwarc *hwarc = uwb_rc->priv;
+       return usb_control_msg(
+               hwarc->usb_dev, usb_sndctrlpipe(hwarc->usb_dev, 0),
+               WA_EXEC_RC_CMD, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+               0, hwarc->usb_iface->cur_altsetting->desc.bInterfaceNumber,
+               (void *) cmd, cmd_size, 100 /* FIXME: this is totally arbitrary */);
+}
+
+static
+int hwarc_reset(struct uwb_rc *uwb_rc)
+{
+       struct hwarc *hwarc = uwb_rc->priv;
+       return usb_reset_device(hwarc->usb_dev);
+}
+
+/**
+ * Callback for the notification and event endpoint
+ *
+ * Check's that everything is fine and then passes the read data to
+ * the notification/event handling mechanism (neh).
+ */
+static
+void hwarc_neep_cb(struct urb *urb)
+{
+       struct hwarc *hwarc = urb->context;
+       struct usb_interface *usb_iface = hwarc->usb_iface;
+       struct device *dev = &usb_iface->dev;
+       int result;
+
+       switch (result = urb->status) {
+       case 0:
+               d_printf(3, dev, "NEEP: receive stat %d, %zu bytes\n",
+                        urb->status, (size_t)urb->actual_length);
+               uwb_rc_neh_grok(hwarc->uwb_rc, urb->transfer_buffer,
+                               urb->actual_length);
+               break;
+       case -ECONNRESET:       /* Not an error, but a controlled situation; */
+       case -ENOENT:           /* (we killed the URB)...so, no broadcast */
+               d_printf(2, dev, "NEEP: URB reset/noent %d\n", urb->status);
+               goto out;
+       case -ESHUTDOWN:        /* going away! */
+               d_printf(2, dev, "NEEP: URB down %d\n", urb->status);
+               goto out;
+       default:                /* On general errors, retry unless it gets ugly */
+               if (edc_inc(&hwarc->neep_edc, EDC_MAX_ERRORS,
+                           EDC_ERROR_TIMEFRAME))
+                       goto error_exceeded;
+               dev_err(dev, "NEEP: URB error %d\n", urb->status);
+       }
+       result = usb_submit_urb(urb, GFP_ATOMIC);
+       d_printf(3, dev, "NEEP: submit %d\n", result);
+       if (result < 0) {
+               dev_err(dev, "NEEP: Can't resubmit URB (%d) resetting device\n",
+                       result);
+               goto error;
+       }
+out:
+       return;
+
+error_exceeded:
+       dev_err(dev, "NEEP: URB max acceptable errors "
+               "exceeded, resetting device\n");
+error:
+       uwb_rc_neh_error(hwarc->uwb_rc, result);
+       uwb_rc_reset_all(hwarc->uwb_rc);
+       return;
+}
+
+static void hwarc_init(struct hwarc *hwarc)
+{
+       edc_init(&hwarc->neep_edc);
+}
+
+/**
+ * Initialize the notification/event endpoint stuff
+ *
+ * Note this is effectively a parallel thread; it knows that
+ * hwarc->uwb_rc always exists because the existence of a 'hwarc'
+ * means that there is a reverence on the hwarc->uwb_rc (see
+ * _probe()), and thus _neep_cb() can execute safely.
+ */
+static int hwarc_neep_init(struct uwb_rc *rc)
+{
+       struct hwarc *hwarc = rc->priv;
+       struct usb_interface *iface = hwarc->usb_iface;
+       struct usb_device *usb_dev = interface_to_usbdev(iface);
+       struct device *dev = &iface->dev;
+       int result;
+       struct usb_endpoint_descriptor *epd;
+
+       epd = &iface->cur_altsetting->endpoint[0].desc;
+       hwarc->rd_buffer = (void *) __get_free_page(GFP_KERNEL);
+       if (hwarc->rd_buffer == NULL) {
+               dev_err(dev, "Unable to allocate notification's read buffer\n");
+               goto error_rd_buffer;
+       }
+       hwarc->neep_urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (hwarc->neep_urb == NULL) {
+               dev_err(dev, "Unable to allocate notification URB\n");
+               goto error_urb_alloc;
+       }
+       usb_fill_int_urb(hwarc->neep_urb, usb_dev,
+                        usb_rcvintpipe(usb_dev, epd->bEndpointAddress),
+                        hwarc->rd_buffer, PAGE_SIZE,
+                        hwarc_neep_cb, hwarc, epd->bInterval);
+       result = usb_submit_urb(hwarc->neep_urb, GFP_ATOMIC);
+       if (result < 0) {
+               dev_err(dev, "Cannot submit notification URB: %d\n", result);
+               goto error_neep_submit;
+       }
+       return 0;
+
+error_neep_submit:
+       usb_free_urb(hwarc->neep_urb);
+error_urb_alloc:
+       free_page((unsigned long)hwarc->rd_buffer);
+error_rd_buffer:
+       return -ENOMEM;
+}
+
+
+/** Clean up all the notification endpoint resources */
+static void hwarc_neep_release(struct uwb_rc *rc)
+{
+       struct hwarc *hwarc = rc->priv;
+
+       usb_kill_urb(hwarc->neep_urb);
+       usb_free_urb(hwarc->neep_urb);
+       free_page((unsigned long)hwarc->rd_buffer);
+}
+
+/**
+ * Get the version from class-specific descriptor
+ *
+ * NOTE: this descriptor comes with the big bundled configuration
+ *      descriptor that includes the interfaces' and endpoints', so
+ *      we just look for it in the cached copy kept by the USB stack.
+ *
+ * NOTE2: We convert LE fields to CPU order.
+ */
+static int hwarc_get_version(struct uwb_rc *rc)
+{
+       int result;
+
+       struct hwarc *hwarc = rc->priv;
+       struct uwb_rc_control_intf_class_desc *descr;
+       struct device *dev = &rc->uwb_dev.dev;
+       struct usb_device *usb_dev = hwarc->usb_dev;
+       char *itr;
+       struct usb_descriptor_header *hdr;
+       size_t itr_size, actconfig_idx;
+       u16 version;
+
+       actconfig_idx = (usb_dev->actconfig - usb_dev->config) /
+               sizeof(usb_dev->config[0]);
+       itr = usb_dev->rawdescriptors[actconfig_idx];
+       itr_size = le16_to_cpu(usb_dev->actconfig->desc.wTotalLength);
+       while (itr_size >= sizeof(*hdr)) {
+               hdr = (struct usb_descriptor_header *) itr;
+               d_printf(3, dev, "Extra device descriptor: "
+                        "type %02x/%u bytes @ %zu (%zu left)\n",
+                        hdr->bDescriptorType, hdr->bLength,
+                        (itr - usb_dev->rawdescriptors[actconfig_idx]),
+                        itr_size);
+               if (hdr->bDescriptorType == USB_DT_CS_RADIO_CONTROL)
+                       goto found;
+               itr += hdr->bLength;
+               itr_size -= hdr->bLength;
+       }
+       dev_err(dev, "cannot find Radio Control Interface Class descriptor\n");
+       return -ENODEV;
+
+found:
+       result = -EINVAL;
+       if (hdr->bLength > itr_size) {  /* is it available? */
+               dev_err(dev, "incomplete Radio Control Interface Class "
+                       "descriptor (%zu bytes left, %u needed)\n",
+                       itr_size, hdr->bLength);
+               goto error;
+       }
+       if (hdr->bLength < sizeof(*descr)) {
+               dev_err(dev, "short Radio Control Interface Class "
+                       "descriptor\n");
+               goto error;
+       }
+       descr = (struct uwb_rc_control_intf_class_desc *) hdr;
+       /* Make LE fields CPU order */
+       version = __le16_to_cpu(descr->bcdRCIVersion);
+       if (version != 0x0100) {
+               dev_err(dev, "Device reports protocol version 0x%04x. We "
+                       "do not support that. \n", version);
+               result = -EINVAL;
+               goto error;
+       }
+       rc->version = version;
+       d_printf(3, dev, "Device supports WUSB protocol version 0x%04x \n",
+                rc->version);
+       result = 0;
+error:
+       return result;
+}
+
+/*
+ * By creating a 'uwb_rc', we have a reference on it -- that reference
+ * is the one we drop when we disconnect.
+ *
+ * No need to switch altsettings; according to WUSB1.0[8.6.1.1], there
+ * is only one altsetting allowed.
+ */
+static int hwarc_probe(struct usb_interface *iface,
+                      const struct usb_device_id *id)
+{
+       int result;
+       struct uwb_rc *uwb_rc;
+       struct hwarc *hwarc;
+       struct device *dev = &iface->dev;
+
+       result = -ENOMEM;
+       uwb_rc = uwb_rc_alloc();
+       if (uwb_rc == NULL) {
+               dev_err(dev, "unable to allocate RC instance\n");
+               goto error_rc_alloc;
+       }
+       hwarc = kzalloc(sizeof(*hwarc), GFP_KERNEL);
+       if (hwarc == NULL) {
+               dev_err(dev, "unable to allocate HWA RC instance\n");
+               goto error_alloc;
+       }
+       hwarc_init(hwarc);
+       hwarc->usb_dev = usb_get_dev(interface_to_usbdev(iface));
+       hwarc->usb_iface = usb_get_intf(iface);
+       hwarc->uwb_rc = uwb_rc;
+
+       uwb_rc->owner = THIS_MODULE;
+       uwb_rc->start = hwarc_neep_init;
+       uwb_rc->stop  = hwarc_neep_release;
+       uwb_rc->cmd   = hwarc_cmd;
+       uwb_rc->reset = hwarc_reset;
+       if (id->driver_info & WUSB_QUIRK_WHCI_CMD_EVT) {
+               uwb_rc->filter_cmd   = NULL;
+               uwb_rc->filter_event = NULL;
+       } else {
+               uwb_rc->filter_cmd   = hwarc_filter_cmd;
+               uwb_rc->filter_event = hwarc_filter_event;
+       }
+
+       result = uwb_rc_add(uwb_rc, dev, hwarc);
+       if (result < 0)
+               goto error_rc_add;
+       result = hwarc_get_version(uwb_rc);
+       if (result < 0) {
+               dev_err(dev, "cannot retrieve version of RC \n");
+               goto error_get_version;
+       }
+       usb_set_intfdata(iface, hwarc);
+       return 0;
+
+error_get_version:
+       uwb_rc_rm(uwb_rc);
+error_rc_add:
+       usb_put_intf(iface);
+       usb_put_dev(hwarc->usb_dev);
+error_alloc:
+       uwb_rc_put(uwb_rc);
+error_rc_alloc:
+       return result;
+}
+
+static void hwarc_disconnect(struct usb_interface *iface)
+{
+       struct hwarc *hwarc = usb_get_intfdata(iface);
+       struct uwb_rc *uwb_rc = hwarc->uwb_rc;
+
+       usb_set_intfdata(hwarc->usb_iface, NULL);
+       uwb_rc_rm(uwb_rc);
+       usb_put_intf(hwarc->usb_iface);
+       usb_put_dev(hwarc->usb_dev);
+       d_printf(1, &hwarc->usb_iface->dev, "freed hwarc %p\n", hwarc);
+       kfree(hwarc);
+       uwb_rc_put(uwb_rc);     /* when creating the device, refcount = 1 */
+}
+
+/** USB device ID's that we handle */
+static 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 },
+       /* Intel i1480 (using firmware 1.3PA2-20070828) */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x8086, 0x0c3b, 0xe0, 0x01, 0x02),
+         .driver_info = WUSB_QUIRK_WHCI_CMD_EVT },
+       /* Generic match for the Radio Control interface */
+       { USB_INTERFACE_INFO(0xe0, 0x01, 0x02), },
+       { },
+};
+MODULE_DEVICE_TABLE(usb, hwarc_id_table);
+
+static struct usb_driver hwarc_driver = {
+       .name =         "hwa-rc",
+       .probe =        hwarc_probe,
+       .disconnect =   hwarc_disconnect,
+       .id_table =     hwarc_id_table,
+};
+
+static int __init hwarc_driver_init(void)
+{
+       int result;
+       result = usb_register(&hwarc_driver);
+       if (result < 0)
+               printk(KERN_ERR "HWA-RC: Cannot register USB driver: %d\n",
+                      result);
+       return result;
+
+}
+module_init(hwarc_driver_init);
+
+static void __exit hwarc_driver_exit(void)
+{
+       usb_deregister(&hwarc_driver);
+}
+module_exit(hwarc_driver_exit);
+
+MODULE_AUTHOR("Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>");
+MODULE_DESCRIPTION("Host Wireless Adapter Radio Control Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/uwb/i1480/Makefile b/drivers/uwb/i1480/Makefile
new file mode 100644 (file)
index 0000000..212bbc7
--- /dev/null
@@ -0,0 +1,2 @@
+obj-$(CONFIG_UWB_I1480U)       += dfu/ i1480-est.o
+obj-$(CONFIG_UWB_I1480U_WLP)   += i1480u-wlp/
diff --git a/drivers/uwb/i1480/dfu/Makefile b/drivers/uwb/i1480/dfu/Makefile
new file mode 100644 (file)
index 0000000..bd1b9f2
--- /dev/null
@@ -0,0 +1,9 @@
+obj-$(CONFIG_UWB_I1480U)       += i1480-dfu-usb.o
+
+i1480-dfu-usb-objs := \
+       dfu.o   \
+       mac.o   \
+       phy.o   \
+       usb.o
+
+
diff --git a/drivers/uwb/i1480/dfu/dfu.c b/drivers/uwb/i1480/dfu/dfu.c
new file mode 100644 (file)
index 0000000..9097b3b
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * Intel Wireless UWB Link 1480
+ * Main driver
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * Common code for firmware upload used by the USB and PCI version;
+ * i1480_fw_upload() takes a device descriptor and uses the function
+ * pointers it provides to upload firmware and prepare the PHY.
+ *
+ * As well, provides common functions used by the rest of the code.
+ */
+#include "i1480-dfu.h"
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/device.h>
+#include <linux/uwb.h>
+#include <linux/random.h>
+
+#define D_LOCAL 0
+#include <linux/uwb/debug.h>
+
+/**
+ * i1480_rceb_check - Check RCEB for expected field values
+ * @i1480: pointer to device for which RCEB is being checked
+ * @rceb: RCEB being checked
+ * @cmd: which command the RCEB is related to
+ * @context: expected context
+ * @expected_type: expected event type
+ * @expected_event: expected event
+ *
+ * If @cmd is NULL, do not print error messages, but still return an error
+ * code.
+ *
+ * Return 0 if @rceb matches the expected values, -EINVAL otherwise.
+ */
+int i1480_rceb_check(const struct i1480 *i1480, const struct uwb_rceb *rceb,
+                    const char *cmd, u8 context, u8 expected_type,
+                    unsigned expected_event)
+{
+       int result = 0;
+       struct device *dev = i1480->dev;
+       if (rceb->bEventContext != context) {
+               if (cmd)
+                       dev_err(dev, "%s: unexpected context id 0x%02x "
+                               "(expected 0x%02x)\n", cmd,
+                               rceb->bEventContext, context);
+               result = -EINVAL;
+       }
+       if (rceb->bEventType != expected_type) {
+               if (cmd)
+                       dev_err(dev, "%s: unexpected event type 0x%02x "
+                               "(expected 0x%02x)\n", cmd,
+                               rceb->bEventType, expected_type);
+               result = -EINVAL;
+       }
+       if (le16_to_cpu(rceb->wEvent) != expected_event) {
+               if (cmd)
+                       dev_err(dev, "%s: unexpected event 0x%04x "
+                               "(expected 0x%04x)\n", cmd,
+                               le16_to_cpu(rceb->wEvent), expected_event);
+               result = -EINVAL;
+       }
+       return result;
+}
+EXPORT_SYMBOL_GPL(i1480_rceb_check);
+
+
+/**
+ * Execute a Radio Control Command
+ *
+ * Command data has to be in i1480->cmd_buf.
+ *
+ * @returns size of the reply data filled in i1480->evt_buf or < 0 errno
+ *          code on error.
+ */
+ssize_t i1480_cmd(struct i1480 *i1480, const char *cmd_name, size_t cmd_size,
+                 size_t reply_size)
+{
+       ssize_t result;
+       struct uwb_rceb *reply = i1480->evt_buf;
+       struct uwb_rccb *cmd = i1480->cmd_buf;
+       u16 expected_event = reply->wEvent;
+       u8 expected_type = reply->bEventType;
+       u8 context;
+
+       d_fnstart(3, i1480->dev, "(%p, %s, %zu)\n", i1480, cmd_name, cmd_size);
+       init_completion(&i1480->evt_complete);
+       i1480->evt_result = -EINPROGRESS;
+       do {
+               get_random_bytes(&context, 1);
+       } while (context == 0x00 || context == 0xff);
+       cmd->bCommandContext = context;
+       result = i1480->cmd(i1480, cmd_name, cmd_size);
+       if (result < 0)
+               goto error;
+       /* wait for the callback to report a event was received */
+       result = wait_for_completion_interruptible_timeout(
+               &i1480->evt_complete, HZ);
+       if (result == 0) {
+               result = -ETIMEDOUT;
+               goto error;
+       }
+       if (result < 0)
+               goto error;
+       result = i1480->evt_result;
+       if (result < 0) {
+               dev_err(i1480->dev, "%s: command reply reception failed: %zd\n",
+                       cmd_name, result);
+               goto error;
+       }
+       /*
+        * Firmware versions >= 1.4.12224 for IOGear GUWA100U generate a
+        * spurious notification after firmware is downloaded. So check whether
+        * the receibed RCEB is such notification before assuming that the
+        * command has failed.
+        */
+       if (i1480_rceb_check(i1480, i1480->evt_buf, NULL,
+                            0, 0xfd, 0x0022) == 0) {
+               /* Now wait for the actual RCEB for this command. */
+               result = i1480->wait_init_done(i1480);
+               if (result < 0)
+                       goto error;
+               result = i1480->evt_result;
+       }
+       if (result != reply_size) {
+               dev_err(i1480->dev, "%s returned only %zu bytes, %zu expected\n",
+                       cmd_name, result, reply_size);
+               result = -EINVAL;
+               goto error;
+       }
+       /* Verify we got the right event in response */
+       result = i1480_rceb_check(i1480, i1480->evt_buf, cmd_name, context,
+                                 expected_type, expected_event);
+error:
+       d_fnend(3, i1480->dev, "(%p, %s, %zu) = %zd\n",
+               i1480, cmd_name, cmd_size, result);
+       return result;
+}
+EXPORT_SYMBOL_GPL(i1480_cmd);
+
+
+static
+int i1480_print_state(struct i1480 *i1480)
+{
+       int result;
+       u32 *buf = (u32 *) i1480->cmd_buf;
+
+       result = i1480->read(i1480, 0x80080000, 2 * sizeof(*buf));
+       if (result < 0) {
+               dev_err(i1480->dev, "cannot read U & L states: %d\n", result);
+               goto error;
+       }
+       dev_info(i1480->dev, "state U 0x%08x, L 0x%08x\n", buf[0], buf[1]);
+error:
+       return result;
+}
+
+
+/*
+ * PCI probe, firmware uploader
+ *
+ * _mac_fw_upload() will call rc_setup(), which needs an rc_release().
+ */
+int i1480_fw_upload(struct i1480 *i1480)
+{
+       int result;
+
+       result = i1480_pre_fw_upload(i1480);    /* PHY pre fw */
+       if (result < 0 && result != -ENOENT) {
+               i1480_print_state(i1480);
+               goto error;
+       }
+       result = i1480_mac_fw_upload(i1480);    /* MAC fw */
+       if (result < 0) {
+               if (result == -ENOENT)
+                       dev_err(i1480->dev, "Cannot locate MAC FW file '%s'\n",
+                               i1480->mac_fw_name);
+               else
+                       i1480_print_state(i1480);
+               goto error;
+       }
+       result = i1480_phy_fw_upload(i1480);    /* PHY fw */
+       if (result < 0 && result != -ENOENT) {
+               i1480_print_state(i1480);
+               goto error_rc_release;
+       }
+       /*
+        * FIXME: find some reliable way to check whether firmware is running
+        * properly. Maybe use some standard request that has no side effects?
+        */
+       dev_info(i1480->dev, "firmware uploaded successfully\n");
+error_rc_release:
+       if (i1480->rc_release)
+               i1480->rc_release(i1480);
+       result = 0;
+error:
+       return result;
+}
+EXPORT_SYMBOL_GPL(i1480_fw_upload);
diff --git a/drivers/uwb/i1480/dfu/i1480-dfu.h b/drivers/uwb/i1480/dfu/i1480-dfu.h
new file mode 100644 (file)
index 0000000..46f45e8
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+ * i1480 Device Firmware Upload
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * This driver is the firmware uploader for the Intel Wireless UWB
+ * Link 1480 device (both in the USB and PCI incarnations).
+ *
+ * The process is quite simple: we stop the device, write the firmware
+ * to its memory and then restart it. Wait for the device to let us
+ * know it is done booting firmware. Ready.
+ *
+ * We might have to upload before or after a phy firmware (which might
+ * be done in two methods, using a normal firmware image or through
+ * the MPI port).
+ *
+ * Because USB and PCI use common methods, we just make ops out of the
+ * common operations (read, write, wait_init_done and cmd) and
+ * implement them in usb.c and pci.c.
+ *
+ * The flow is (some parts omitted):
+ *
+ * i1480_{usb,pci}_probe()       On enumerate/discovery
+ *   i1480_fw_upload()
+ *     i1480_pre_fw_upload()
+ *       __mac_fw_upload()
+ *         fw_hdrs_load()
+ *         mac_fw_hdrs_push()
+ *           i1480->write()       [i1480_{usb,pci}_write()]
+ *           i1480_fw_cmp()
+ *             i1480->read()      [i1480_{usb,pci}_read()]
+ *     i1480_mac_fw_upload()
+ *       __mac_fw_upload()
+ *       i1480->setup(()
+ *       i1480->wait_init_done()
+ *       i1480_cmd_reset()
+ *         i1480->cmd()           [i1480_{usb,pci}_cmd()]
+ *         ...
+ *     i1480_phy_fw_upload()
+ *       request_firmware()
+ *       i1480_mpi_write()
+ *         i1480->cmd()           [i1480_{usb,pci}_cmd()]
+ *
+ * Once the probe function enumerates the device and uploads the
+ * firmware, we just exit with -ENODEV, as we don't really want to
+ * attach to the device.
+ */
+#ifndef __i1480_DFU_H__
+#define __i1480_DFU_H__
+
+#include <linux/uwb/spec.h>
+#include <linux/types.h>
+#include <linux/completion.h>
+
+#define i1480_FW_UPLOAD_MODE_MASK (cpu_to_le32(0x00000018))
+
+#if i1480_FW > 0x00000302
+#define i1480_RCEB_EXTENDED
+#endif
+
+struct uwb_rccb;
+struct uwb_rceb;
+
+/*
+ * Common firmware upload handlers
+ *
+ * Normally you embed this struct in another one specific to your hw.
+ *
+ * @write      Write to device's memory from buffer.
+ * @read       Read from device's memory to i1480->evt_buf.
+ * @setup      Setup device after basic firmware is uploaded
+ * @wait_init_done
+ *              Wait for the device to send a notification saying init
+ *              is done.
+ * @cmd         FOP for issuing the command to the hardware. The
+ *              command data is contained in i1480->cmd_buf and the size
+ *              is supplied as an argument. The command replied is put
+ *              in i1480->evt_buf and the size in i1480->evt_result (or if
+ *              an error, a < 0 errno code).
+ *
+ * @cmd_buf    Memory buffer used to send commands to the device.
+ *              Allocated by the upper layers i1480_fw_upload().
+ *              Size has to be @buf_size.
+ * @evt_buf    Memory buffer used to place the async notifications
+ *              received by the hw. Allocated by the upper layers
+ *              i1480_fw_upload().
+ *              Size has to be @buf_size.
+ * @cmd_complete
+ *              Low level driver uses this to notify code waiting afor
+ *              an event that the event has arrived and data is in
+ *              i1480->evt_buf (and size/result in i1480->evt_result).
+ * @hw_rev
+ *              Use this value to activate dfu code to support new revisions
+ *              of hardware.  i1480_init() sets this to a default value.
+ *              It should be updated by the USB and PCI code.
+ */
+struct i1480 {
+       struct device *dev;
+
+       int (*write)(struct i1480 *, u32 addr, const void *, size_t);
+       int (*read)(struct i1480 *, u32 addr, size_t);
+       int (*rc_setup)(struct i1480 *);
+       void (*rc_release)(struct i1480 *);
+       int (*wait_init_done)(struct i1480 *);
+       int (*cmd)(struct i1480 *, const char *cmd_name, size_t cmd_size);
+       const char *pre_fw_name;
+       const char *mac_fw_name;
+       const char *mac_fw_name_deprecate;      /* FIXME: Will go away */
+       const char *phy_fw_name;
+       u8 hw_rev;
+
+       size_t buf_size;        /* size of both evt_buf and cmd_buf */
+       void *evt_buf, *cmd_buf;
+       ssize_t evt_result;
+       struct completion evt_complete;
+};
+
+static inline
+void i1480_init(struct i1480 *i1480)
+{
+       i1480->hw_rev = 1;
+       init_completion(&i1480->evt_complete);
+}
+
+extern int i1480_fw_upload(struct i1480 *);
+extern int i1480_pre_fw_upload(struct i1480 *);
+extern int i1480_mac_fw_upload(struct i1480 *);
+extern int i1480_phy_fw_upload(struct i1480 *);
+extern ssize_t i1480_cmd(struct i1480 *, const char *, size_t, size_t);
+extern int i1480_rceb_check(const struct i1480 *,
+                           const struct uwb_rceb *, const char *, u8,
+                           u8, unsigned);
+
+enum {
+       /* Vendor specific command type */
+       i1480_CET_VS1 =                 0xfd,
+       /* i1480 commands */
+       i1480_CMD_SET_IP_MAS =          0x000e,
+       i1480_CMD_GET_MAC_PHY_INFO =    0x0003,
+       i1480_CMD_MPI_WRITE =           0x000f,
+       i1480_CMD_MPI_READ =            0x0010,
+       /* i1480 events */
+#if i1480_FW > 0x00000302
+       i1480_EVT_CONFIRM =             0x0002,
+       i1480_EVT_RM_INIT_DONE =        0x0101,
+       i1480_EVT_DEV_ADD =             0x0103,
+       i1480_EVT_DEV_RM =              0x0104,
+       i1480_EVT_DEV_ID_CHANGE =       0x0105,
+       i1480_EVT_GET_MAC_PHY_INFO =    i1480_CMD_GET_MAC_PHY_INFO,
+#else
+       i1480_EVT_CONFIRM =             0x0002,
+       i1480_EVT_RM_INIT_DONE =        0x0101,
+       i1480_EVT_DEV_ADD =             0x0103,
+       i1480_EVT_DEV_RM =              0x0104,
+       i1480_EVT_DEV_ID_CHANGE =       0x0105,
+       i1480_EVT_GET_MAC_PHY_INFO =    i1480_EVT_CONFIRM,
+#endif
+};
+
+
+struct i1480_evt_confirm {
+       struct uwb_rceb rceb;
+#ifdef i1480_RCEB_EXTENDED
+       __le16 wParamLength;
+#endif
+       u8 bResultCode;
+} __attribute__((packed));
+
+
+struct i1480_rceb {
+       struct uwb_rceb rceb;
+#ifdef i1480_RCEB_EXTENDED
+       __le16 wParamLength;
+#endif
+} __attribute__((packed));
+
+
+/**
+ * Get MAC & PHY Information confirm event structure
+ *
+ * Confirm event returned by the command.
+ */
+struct i1480_evt_confirm_GMPI {
+#if i1480_FW > 0x00000302
+       struct uwb_rceb rceb;
+       __le16 wParamLength;
+       __le16 status;
+       u8 mac_addr[6];         /* EUI-64 bit IEEE address [still 8 bytes?] */
+       u8 dev_addr[2];
+       __le16 mac_fw_rev;      /* major = v >> 8; minor = v & 0xff */
+       u8 hw_rev;
+       u8 phy_vendor;
+       u8 phy_rev;             /* major v = >> 8; minor = v & 0xff */
+       __le16 mac_caps;
+       u8 phy_caps[3];
+       u8 key_stores;
+       __le16 mcast_addr_stores;
+       u8 sec_mode_supported;
+#else
+       struct uwb_rceb rceb;
+       u8 status;
+       u8 mac_addr[8];         /* EUI-64 bit IEEE address [still 8 bytes?] */
+       u8 dev_addr[2];
+       __le16 mac_fw_rev;      /* major = v >> 8; minor = v & 0xff */
+       __le16 phy_fw_rev;      /* major v = >> 8; minor = v & 0xff */
+       __le16 mac_caps;
+       u8 phy_caps;
+       u8 key_stores;
+       __le16 mcast_addr_stores;
+       u8 sec_mode_supported;
+#endif
+} __attribute__((packed));
+
+
+struct i1480_cmd_mpi_write {
+       struct uwb_rccb rccb;
+       __le16 size;
+       u8 data[];
+};
+
+
+struct i1480_cmd_mpi_read {
+       struct uwb_rccb rccb;
+       __le16 size;
+       struct {
+               u8 page, offset;
+       } __attribute__((packed)) data[];
+} __attribute__((packed));
+
+
+struct i1480_evt_mpi_read {
+       struct uwb_rceb rceb;
+#ifdef i1480_RCEB_EXTENDED
+       __le16 wParamLength;
+#endif
+       u8 bResultCode;
+       __le16 size;
+       struct {
+               u8 page, offset, value;
+       } __attribute__((packed)) data[];
+} __attribute__((packed));
+
+
+#endif /* #ifndef __i1480_DFU_H__ */
diff --git a/drivers/uwb/i1480/dfu/mac.c b/drivers/uwb/i1480/dfu/mac.c
new file mode 100644 (file)
index 0000000..2e4d8f0
--- /dev/null
@@ -0,0 +1,527 @@
+/*
+ * Intel Wireless UWB Link 1480
+ * MAC Firmware upload implementation
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * Implementation of the code for parsing the firmware file (extract
+ * the headers and binary code chunks) in the fw_*() functions. The
+ * code to upload pre and mac firmwares is the same, so it uses a
+ * common entry point in __mac_fw_upload(), which uses the i1480
+ * function pointers to push the firmware to the device.
+ */
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/uwb.h>
+#include "i1480-dfu.h"
+
+#define D_LOCAL 0
+#include <linux/uwb/debug.h>
+
+/*
+ * Descriptor for a continuous segment of MAC fw data
+ */
+struct fw_hdr {
+       unsigned long address;
+       size_t length;
+       const u32 *bin;
+       struct fw_hdr *next;
+};
+
+
+/* Free a chain of firmware headers */
+static
+void fw_hdrs_free(struct fw_hdr *hdr)
+{
+       struct fw_hdr *next;
+
+       while (hdr) {
+               next = hdr->next;
+               kfree(hdr);
+               hdr = next;
+       }
+}
+
+
+/* Fill a firmware header descriptor from a memory buffer */
+static
+int fw_hdr_load(struct i1480 *i1480, struct fw_hdr *hdr, unsigned hdr_cnt,
+               const char *_data, const u32 *data_itr, const u32 *data_top)
+{
+       size_t hdr_offset =  (const char *) data_itr - _data;
+       size_t remaining_size = (void *) data_top - (void *) data_itr;
+       if (data_itr + 2 > data_top) {
+               dev_err(i1480->dev, "fw hdr #%u/%zu: EOF reached in header at "
+                      "offset %zu, limit %zu\n",
+                      hdr_cnt, hdr_offset,
+                      (const char *) data_itr + 2 - _data,
+                      (const char *) data_top - _data);
+               return -EINVAL;
+       }
+       hdr->next = NULL;
+       hdr->address = le32_to_cpu(*data_itr++);
+       hdr->length = le32_to_cpu(*data_itr++);
+       hdr->bin = data_itr;
+       if (hdr->length > remaining_size) {
+               dev_err(i1480->dev, "fw hdr #%u/%zu: EOF reached in data; "
+                      "chunk too long (%zu bytes), only %zu left\n",
+                      hdr_cnt, hdr_offset, hdr->length, remaining_size);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+
+/**
+ * Get a buffer where the firmware is supposed to be and create a
+ * chain of headers linking them together.
+ *
+ * @phdr: where to place the pointer to the first header (headers link
+ *        to the next via the @hdr->next ptr); need to free the whole
+ *        chain when done.
+ *
+ * @_data: Pointer to the data buffer.
+ *
+ * @_data_size: Size of the data buffer (bytes); data size has to be a
+ *              multiple of 4. Function will fail if not.
+ *
+ * Goes over the whole binary blob; reads the first chunk and creates
+ * a fw hdr from it (which points to where the data is in @_data and
+ * the length of the chunk); then goes on to the next chunk until
+ * done. Each header is linked to the next.
+ */
+static
+int fw_hdrs_load(struct i1480 *i1480, struct fw_hdr **phdr,
+                const char *_data, size_t data_size)
+{
+       int result;
+       unsigned hdr_cnt = 0;
+       u32 *data = (u32 *) _data, *data_itr, *data_top;
+       struct fw_hdr *hdr, **prev_hdr = phdr;
+
+       result = -EINVAL;
+       /* Check size is ok and pointer is aligned */
+       if (data_size % sizeof(u32) != 0)
+               goto error;
+       if ((unsigned long) _data % sizeof(u16) != 0)
+               goto error;
+       *phdr = NULL;
+       data_itr = data;
+       data_top = (u32 *) (_data + data_size);
+       while (data_itr < data_top) {
+               result = -ENOMEM;
+               hdr = kmalloc(sizeof(*hdr), GFP_KERNEL);
+               if (hdr == NULL) {
+                       dev_err(i1480->dev, "Cannot allocate fw header "
+                              "for chunk #%u\n", hdr_cnt);
+                       goto error_alloc;
+               }
+               result = fw_hdr_load(i1480, hdr, hdr_cnt,
+                                    _data, data_itr, data_top);
+               if (result < 0)
+                       goto error_load;
+               data_itr += 2 + hdr->length;
+               *prev_hdr = hdr;
+               prev_hdr = &hdr->next;
+               hdr_cnt++;
+       };
+       *prev_hdr = NULL;
+       return 0;
+
+error_load:
+       kfree(hdr);
+error_alloc:
+       fw_hdrs_free(*phdr);
+error:
+       return result;
+}
+
+
+/**
+ * Compares a chunk of fw with one in the devices's memory
+ *
+ * @i1480:     Device instance
+ * @hdr:     Pointer to the firmware chunk
+ * @returns: 0 if equal, < 0 errno on error. If > 0, it is the offset
+ *           where the difference was found (plus one).
+ *
+ * Kind of dirty and simplistic, but does the trick in both the PCI
+ * and USB version. We do a quick[er] memcmp(), and if it fails, we do
+ * a byte-by-byte to find the offset.
+ */
+static
+ssize_t i1480_fw_cmp(struct i1480 *i1480, struct fw_hdr *hdr)
+{
+       ssize_t result = 0;
+       u32 src_itr = 0, cnt;
+       size_t size = hdr->length*sizeof(hdr->bin[0]);
+       size_t chunk_size;
+       u8 *bin = (u8 *) hdr->bin;
+
+       while (size > 0) {
+               chunk_size = size < i1480->buf_size ? size : i1480->buf_size;
+               result = i1480->read(i1480, hdr->address + src_itr, chunk_size);
+               if (result < 0) {
+                       dev_err(i1480->dev, "error reading for verification: "
+                               "%zd\n", result);
+                       goto error;
+               }
+               if (memcmp(i1480->cmd_buf, bin + src_itr, result)) {
+                       u8 *buf = i1480->cmd_buf;
+                       d_printf(2, i1480->dev,
+                                "original data @ %p + %u, %zu bytes\n",
+                                bin, src_itr, result);
+                       d_dump(4, i1480->dev, bin + src_itr, result);
+                       for (cnt = 0; cnt < result; cnt++)
+                               if (bin[src_itr + cnt] != buf[cnt]) {
+                                       dev_err(i1480->dev, "byte failed at "
+                                               "src_itr %u cnt %u [0x%02x "
+                                               "vs 0x%02x]\n", src_itr, cnt,
+                                               bin[src_itr + cnt], buf[cnt]);
+                                       result = src_itr + cnt + 1;
+                                       goto cmp_failed;
+                               }
+               }
+               src_itr += result;
+               size -= result;
+       }
+       result = 0;
+error:
+cmp_failed:
+       return result;
+}
+
+
+/**
+ * Writes firmware headers to the device.
+ *
+ * @prd:     PRD instance
+ * @hdr:     Processed firmware
+ * @returns: 0 if ok, < 0 errno on error.
+ */
+static
+int mac_fw_hdrs_push(struct i1480 *i1480, struct fw_hdr *hdr,
+                    const char *fw_name, const char *fw_tag)
+{
+       struct device *dev = i1480->dev;
+       ssize_t result = 0;
+       struct fw_hdr *hdr_itr;
+       int verif_retry_count;
+
+       d_fnstart(3, dev, "(%p, %p)\n", i1480, hdr);
+       /* Now, header by header, push them to the hw */
+       for (hdr_itr = hdr; hdr_itr != NULL; hdr_itr = hdr_itr->next) {
+               verif_retry_count = 0;
+retry:
+               dev_dbg(dev, "fw chunk (%zu @ 0x%08lx)\n",
+                       hdr_itr->length * sizeof(hdr_itr->bin[0]),
+                       hdr_itr->address);
+               result = i1480->write(i1480, hdr_itr->address, hdr_itr->bin,
+                                   hdr_itr->length*sizeof(hdr_itr->bin[0]));
+               if (result < 0) {
+                       dev_err(dev, "%s fw '%s': write failed (%zuB @ 0x%lx):"
+                               " %zd\n", fw_tag, fw_name,
+                               hdr_itr->length * sizeof(hdr_itr->bin[0]),
+                               hdr_itr->address, result);
+                       break;
+               }
+               result = i1480_fw_cmp(i1480, hdr_itr);
+               if (result < 0) {
+                       dev_err(dev, "%s fw '%s': verification read "
+                               "failed (%zuB @ 0x%lx): %zd\n",
+                               fw_tag, fw_name,
+                               hdr_itr->length * sizeof(hdr_itr->bin[0]),
+                               hdr_itr->address, result);
+                       break;
+               }
+               if (result > 0) {       /* Offset where it failed + 1 */
+                       result--;
+                       dev_err(dev, "%s fw '%s': WARNING: verification "
+                               "failed at 0x%lx: retrying\n",
+                               fw_tag, fw_name, hdr_itr->address + result);
+                       if (++verif_retry_count < 3)
+                               goto retry;     /* write this block again! */
+                       dev_err(dev, "%s fw '%s': verification failed at 0x%lx: "
+                               "tried %d times\n", fw_tag, fw_name,
+                               hdr_itr->address + result, verif_retry_count);
+                       result = -EINVAL;
+                       break;
+               }
+       }
+       d_fnend(3, dev, "(%zd)\n", result);
+       return result;
+}
+
+
+/** Puts the device in firmware upload mode.*/
+static
+int mac_fw_upload_enable(struct i1480 *i1480)
+{
+       int result;
+       u32 reg = 0x800000c0;
+       u32 *buffer = (u32 *)i1480->cmd_buf;
+
+       if (i1480->hw_rev > 1)
+               reg = 0x8000d0d4;
+       result = i1480->read(i1480, reg, sizeof(u32));
+       if (result < 0)
+               goto error_cmd;
+       *buffer &= ~i1480_FW_UPLOAD_MODE_MASK;
+       result = i1480->write(i1480, reg, buffer, sizeof(u32));
+       if (result < 0)
+               goto error_cmd;
+       return 0;
+error_cmd:
+       dev_err(i1480->dev, "can't enable fw upload mode: %d\n", result);
+       return result;
+}
+
+
+/** Gets the device out of firmware upload mode. */
+static
+int mac_fw_upload_disable(struct i1480 *i1480)
+{
+       int result;
+       u32 reg = 0x800000c0;
+       u32 *buffer = (u32 *)i1480->cmd_buf;
+
+       if (i1480->hw_rev > 1)
+               reg = 0x8000d0d4;
+       result = i1480->read(i1480, reg, sizeof(u32));
+       if (result < 0)
+               goto error_cmd;
+       *buffer |= i1480_FW_UPLOAD_MODE_MASK;
+       result = i1480->write(i1480, reg, buffer, sizeof(u32));
+       if (result < 0)
+               goto error_cmd;
+       return 0;
+error_cmd:
+       dev_err(i1480->dev, "can't disable fw upload mode: %d\n", result);
+       return result;
+}
+
+
+
+/**
+ * Generic function for uploading a MAC firmware.
+ *
+ * @i1480:     Device instance
+ * @fw_name: Name of firmware file to upload.
+ * @fw_tag:  Name of the firmware type (for messages)
+ *           [eg: MAC, PRE]
+ * @do_wait: Wait for device to emit initialization done message (0
+ *           for PRE fws, 1 for MAC fws).
+ * @returns: 0 if ok, < 0 errno on error.
+ */
+static
+int __mac_fw_upload(struct i1480 *i1480, const char *fw_name,
+                   const char *fw_tag)
+{
+       int result;
+       const struct firmware *fw;
+       struct fw_hdr *fw_hdrs;
+
+       d_fnstart(3, i1480->dev, "(%p, %s, %s)\n", i1480, fw_name, fw_tag);
+       result = request_firmware(&fw, fw_name, i1480->dev);
+       if (result < 0) /* Up to caller to complain on -ENOENT */
+               goto out;
+       d_printf(3, i1480->dev, "%s fw '%s': uploading\n", fw_tag, fw_name);
+       result = fw_hdrs_load(i1480, &fw_hdrs, fw->data, fw->size);
+       if (result < 0) {
+               dev_err(i1480->dev, "%s fw '%s': failed to parse firmware "
+                       "file: %d\n", fw_tag, fw_name, result);
+               goto out_release;
+       }
+       result = mac_fw_upload_enable(i1480);
+       if (result < 0)
+               goto out_hdrs_release;
+       result = mac_fw_hdrs_push(i1480, fw_hdrs, fw_name, fw_tag);
+       mac_fw_upload_disable(i1480);
+out_hdrs_release:
+       if (result >= 0)
+               dev_info(i1480->dev, "%s fw '%s': uploaded\n", fw_tag, fw_name);
+       else
+               dev_err(i1480->dev, "%s fw '%s': failed to upload (%d), "
+                       "power cycle device\n", fw_tag, fw_name, result);
+       fw_hdrs_free(fw_hdrs);
+out_release:
+       release_firmware(fw);
+out:
+       d_fnend(3, i1480->dev, "(%p, %s, %s) = %d\n", i1480, fw_name, fw_tag,
+               result);
+       return result;
+}
+
+
+/**
+ * Upload a pre-PHY firmware
+ *
+ */
+int i1480_pre_fw_upload(struct i1480 *i1480)
+{
+       int result;
+       result = __mac_fw_upload(i1480, i1480->pre_fw_name, "PRE");
+       if (result == 0)
+               msleep(400);
+       return result;
+}
+
+
+/**
+ * Reset a the MAC and PHY
+ *
+ * @i1480:     Device's instance
+ * @returns: 0 if ok, < 0 errno code on error
+ *
+ * We put the command on kmalloc'ed memory as some arches cannot do
+ * USB from the stack. The reply event is copied from an stage buffer,
+ * so it can be in the stack. See WUSB1.0[8.6.2.4] for more details.
+ *
+ * We issue the reset to make sure the UWB controller reinits the PHY;
+ * this way we can now if the PHY init went ok.
+ */
+static
+int i1480_cmd_reset(struct i1480 *i1480)
+{
+       int result;
+       struct uwb_rccb *cmd = (void *) i1480->cmd_buf;
+       struct i1480_evt_reset {
+               struct uwb_rceb rceb;
+               u8 bResultCode;
+       } __attribute__((packed)) *reply = (void *) i1480->evt_buf;
+
+       result = -ENOMEM;
+       cmd->bCommandType = UWB_RC_CET_GENERAL;
+       cmd->wCommand = cpu_to_le16(UWB_RC_CMD_RESET);
+       reply->rceb.bEventType = UWB_RC_CET_GENERAL;
+       reply->rceb.wEvent = UWB_RC_CMD_RESET;
+       result = i1480_cmd(i1480, "RESET", sizeof(*cmd), sizeof(*reply));
+       if (result < 0)
+               goto out;
+       if (reply->bResultCode != UWB_RC_RES_SUCCESS) {
+               dev_err(i1480->dev, "RESET: command execution failed: %u\n",
+                       reply->bResultCode);
+               result = -EIO;
+       }
+out:
+       return result;
+
+}
+
+
+/* Wait for the MAC FW to start running */
+static
+int i1480_fw_is_running_q(struct i1480 *i1480)
+{
+       int cnt = 0;
+       int result;
+       u32 *val = (u32 *) i1480->cmd_buf;
+
+       d_fnstart(3, i1480->dev, "(i1480 %p)\n", i1480);
+       for (cnt = 0; cnt < 10; cnt++) {
+               msleep(100);
+               result = i1480->read(i1480, 0x80080000, 4);
+               if (result < 0) {
+                       dev_err(i1480->dev, "Can't read 0x8008000: %d\n", result);
+                       goto out;
+               }
+               if (*val == 0x55555555UL)       /* fw running? cool */
+                       goto out;
+       }
+       dev_err(i1480->dev, "Timed out waiting for fw to start\n");
+       result = -ETIMEDOUT;
+out:
+       d_fnend(3, i1480->dev, "(i1480 %p) = %d\n", i1480, result);
+       return result;
+
+}
+
+
+/**
+ * Upload MAC firmware, wait for it to start
+ *
+ * @i1480:     Device instance
+ * @fw_name: Name of the file that contains the firmware
+ *
+ * This has to be called after the pre fw has been uploaded (if
+ * there is any).
+ */
+int i1480_mac_fw_upload(struct i1480 *i1480)
+{
+       int result = 0, deprecated_name = 0;
+       struct i1480_rceb *rcebe = (void *) i1480->evt_buf;
+
+       d_fnstart(3, i1480->dev, "(%p)\n", i1480);
+       result = __mac_fw_upload(i1480, i1480->mac_fw_name, "MAC");
+       if (result == -ENOENT) {
+               result = __mac_fw_upload(i1480, i1480->mac_fw_name_deprecate,
+                                        "MAC");
+               deprecated_name = 1;
+       }
+       if (result < 0)
+               return result;
+       if (deprecated_name == 1)
+               dev_warn(i1480->dev,
+                        "WARNING: firmware file name %s is deprecated, "
+                        "please rename to %s\n",
+                        i1480->mac_fw_name_deprecate, i1480->mac_fw_name);
+       result = i1480_fw_is_running_q(i1480);
+       if (result < 0)
+               goto error_fw_not_running;
+       result = i1480->rc_setup ? i1480->rc_setup(i1480) : 0;
+       if (result < 0) {
+               dev_err(i1480->dev, "Cannot setup after MAC fw upload: %d\n",
+                       result);
+               goto error_setup;
+       }
+       result = i1480->wait_init_done(i1480);  /* wait init'on */
+       if (result < 0) {
+               dev_err(i1480->dev, "MAC fw '%s': Initialization timed out "
+                       "(%d)\n", i1480->mac_fw_name, result);
+               goto error_init_timeout;
+       }
+       /* verify we got the right initialization done event */
+       if (i1480->evt_result != sizeof(*rcebe)) {
+               dev_err(i1480->dev, "MAC fw '%s': initialization event returns "
+                       "wrong size (%zu bytes vs %zu needed)\n",
+                       i1480->mac_fw_name, i1480->evt_result, sizeof(*rcebe));
+               dump_bytes(i1480->dev, rcebe, min(i1480->evt_result, (ssize_t)32));
+               goto error_size;
+       }
+       result = -EIO;
+       if (i1480_rceb_check(i1480, &rcebe->rceb, NULL, 0, i1480_CET_VS1,
+                            i1480_EVT_RM_INIT_DONE) < 0) {
+               dev_err(i1480->dev, "wrong initialization event 0x%02x/%04x/%02x "
+                       "received; expected 0x%02x/%04x/00\n",
+                       rcebe->rceb.bEventType, le16_to_cpu(rcebe->rceb.wEvent),
+                       rcebe->rceb.bEventContext, i1480_CET_VS1,
+                       i1480_EVT_RM_INIT_DONE);
+               goto error_init_timeout;
+       }
+       result = i1480_cmd_reset(i1480);
+       if (result < 0)
+               dev_err(i1480->dev, "MAC fw '%s': MBOA reset failed (%d)\n",
+                       i1480->mac_fw_name, result);
+error_fw_not_running:
+error_init_timeout:
+error_size:
+error_setup:
+       d_fnend(3, i1480->dev, "(i1480 %p) = %d\n", i1480, result);
+       return result;
+}
diff --git a/drivers/uwb/i1480/dfu/phy.c b/drivers/uwb/i1480/dfu/phy.c
new file mode 100644 (file)
index 0000000..3b1a87d
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Intel Wireless UWB Link 1480
+ * PHY parameters upload
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * Code for uploading the PHY parameters to the PHY through the UWB
+ * Radio Control interface.
+ *
+ * We just send the data through the MPI interface using HWA-like
+ * commands and then reset the PHY to make sure it is ok.
+ */
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/usb/wusb.h>
+#include "i1480-dfu.h"
+
+
+/**
+ * Write a value array to an address of the MPI interface
+ *
+ * @i1480:     Device descriptor
+ * @data:      Data array to write
+ * @size:      Size of the data array
+ * @returns:   0 if ok, < 0 errno code on error.
+ *
+ * The data array is organized into pairs:
+ *
+ * ADDRESS VALUE
+ *
+ * ADDRESS is BE 16 bit unsigned, VALUE 8 bit unsigned. Size thus has
+ * to be a multiple of three.
+ */
+static
+int i1480_mpi_write(struct i1480 *i1480, const void *data, size_t size)
+{
+       int result;
+       struct i1480_cmd_mpi_write *cmd = i1480->cmd_buf;
+       struct i1480_evt_confirm *reply = i1480->evt_buf;
+
+       BUG_ON(size > 480);
+       result = -ENOMEM;
+       cmd->rccb.bCommandType = i1480_CET_VS1;
+       cmd->rccb.wCommand = cpu_to_le16(i1480_CMD_MPI_WRITE);
+       cmd->size = cpu_to_le16(size);
+       memcpy(cmd->data, data, size);
+       reply->rceb.bEventType = i1480_CET_VS1;
+       reply->rceb.wEvent = i1480_CMD_MPI_WRITE;
+       result = i1480_cmd(i1480, "MPI-WRITE", sizeof(*cmd) + size, sizeof(*reply));
+       if (result < 0)
+               goto out;
+       if (reply->bResultCode != UWB_RC_RES_SUCCESS) {
+               dev_err(i1480->dev, "MPI-WRITE: command execution failed: %d\n",
+                       reply->bResultCode);
+               result = -EIO;
+       }
+out:
+       return result;
+}
+
+
+/**
+ * Read a value array to from an address of the MPI interface
+ *
+ * @i1480:     Device descriptor
+ * @data:      where to place the read array
+ * @srcaddr:   Where to read from
+ * @size:      Size of the data read array
+ * @returns:   0 if ok, < 0 errno code on error.
+ *
+ * The command data array is organized into pairs ADDR0 ADDR1..., and
+ * the returned data in ADDR0 VALUE0 ADDR1 VALUE1...
+ *
+ * We generate the command array to be a sequential read and then
+ * rearrange the result.
+ *
+ * We use the i1480->cmd_buf for the command, i1480->evt_buf for the reply.
+ *
+ * As the reply has to fit in 512 bytes (i1480->evt_buffer), the max amount
+ * of values we can read is (512 - sizeof(*reply)) / 3
+ */
+static
+int i1480_mpi_read(struct i1480 *i1480, u8 *data, u16 srcaddr, size_t size)
+{
+       int result;
+       struct i1480_cmd_mpi_read *cmd = i1480->cmd_buf;
+       struct i1480_evt_mpi_read *reply = i1480->evt_buf;
+       unsigned cnt;
+
+       memset(i1480->cmd_buf, 0x69, 512);
+       memset(i1480->evt_buf, 0x69, 512);
+
+       BUG_ON(size > (i1480->buf_size - sizeof(*reply)) / 3);
+       result = -ENOMEM;
+       cmd->rccb.bCommandType = i1480_CET_VS1;
+       cmd->rccb.wCommand = cpu_to_le16(i1480_CMD_MPI_READ);
+       cmd->size = cpu_to_le16(3*size);
+       for (cnt = 0; cnt < size; cnt++) {
+               cmd->data[cnt].page = (srcaddr + cnt) >> 8;
+               cmd->data[cnt].offset = (srcaddr + cnt) & 0xff;
+       }
+       reply->rceb.bEventType = i1480_CET_VS1;
+       reply->rceb.wEvent = i1480_CMD_MPI_READ;
+       result = i1480_cmd(i1480, "MPI-READ", sizeof(*cmd) + 2*size,
+                       sizeof(*reply) + 3*size);
+       if (result < 0)
+               goto out;
+       if (reply->bResultCode != UWB_RC_RES_SUCCESS) {
+               dev_err(i1480->dev, "MPI-READ: command execution failed: %d\n",
+                       reply->bResultCode);
+               result = -EIO;
+       }
+       for (cnt = 0; cnt < size; cnt++) {
+               if (reply->data[cnt].page != (srcaddr + cnt) >> 8)
+                       dev_err(i1480->dev, "MPI-READ: page inconsistency at "
+                               "index %u: expected 0x%02x, got 0x%02x\n", cnt,
+                               (srcaddr + cnt) >> 8, reply->data[cnt].page);
+               if (reply->data[cnt].offset != ((srcaddr + cnt) & 0x00ff))
+                       dev_err(i1480->dev, "MPI-READ: offset inconsistency at "
+                               "index %u: expected 0x%02x, got 0x%02x\n", cnt,
+                               (srcaddr + cnt) & 0x00ff,
+                               reply->data[cnt].offset);
+               data[cnt] = reply->data[cnt].value;
+       }
+       result = 0;
+out:
+       return result;
+}
+
+
+/**
+ * Upload a PHY firmware, wait for it to start
+ *
+ * @i1480:     Device instance
+ * @fw_name: Name of the file that contains the firmware
+ *
+ * We assume the MAC fw is up and running. This means we can use the
+ * MPI interface to write the PHY firmware. Once done, we issue an
+ * MBOA Reset, which will force the MAC to reset and reinitialize the
+ * PHY. If that works, we are ready to go.
+ *
+ * Max packet size for the MPI write is 512, so the max buffer is 480
+ * (which gives us 160 byte triads of MSB, LSB and VAL for the data).
+ */
+int i1480_phy_fw_upload(struct i1480 *i1480)
+{
+       int result;
+       const struct firmware *fw;
+       const char *data_itr, *data_top;
+       const size_t MAX_BLK_SIZE = 480;        /* 160 triads */
+       size_t data_size;
+       u8 phy_stat;
+
+       result = request_firmware(&fw, i1480->phy_fw_name, i1480->dev);
+       if (result < 0)
+               goto out;
+       /* Loop writing data in chunks as big as possible until done. */
+       for (data_itr = fw->data, data_top = data_itr + fw->size;
+            data_itr < data_top; data_itr += MAX_BLK_SIZE) {
+               data_size = min(MAX_BLK_SIZE, (size_t) (data_top - data_itr));
+               result = i1480_mpi_write(i1480, data_itr, data_size);
+               if (result < 0)
+                       goto error_mpi_write;
+       }
+       /* Read MPI page 0, offset 6; if 0, PHY was initialized correctly. */
+       result = i1480_mpi_read(i1480, &phy_stat, 0x0006, 1);
+       if (result < 0) {
+               dev_err(i1480->dev, "PHY: can't get status: %d\n", result);
+               goto error_mpi_status;
+       }
+       if (phy_stat != 0) {
+               result = -ENODEV;
+               dev_info(i1480->dev, "error, PHY not ready: %u\n", phy_stat);
+               goto error_phy_status;
+       }
+       dev_info(i1480->dev, "PHY fw '%s': uploaded\n", i1480->phy_fw_name);
+error_phy_status:
+error_mpi_status:
+error_mpi_write:
+       release_firmware(fw);
+       if (result < 0)
+               dev_err(i1480->dev, "PHY fw '%s': failed to upload (%d), "
+                       "power cycle device\n", i1480->phy_fw_name, result);
+out:
+       return result;
+}
diff --git a/drivers/uwb/i1480/dfu/usb.c b/drivers/uwb/i1480/dfu/usb.c
new file mode 100644 (file)
index 0000000..98eeeff
--- /dev/null
@@ -0,0 +1,500 @@
+/*
+ * Intel Wireless UWB Link 1480
+ * USB SKU firmware upload implementation
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * This driver will prepare the i1480 device to behave as a real
+ * Wireless USB HWA adaptor by uploading the firmware.
+ *
+ * When the device is connected or driver is loaded, i1480_usb_probe()
+ * is called--this will allocate and initialize the device structure,
+ * fill in the pointers to the common functions (read, write,
+ * wait_init_done and cmd for HWA command execution) and once that is
+ * done, call the common firmware uploading routine. Then clean up and
+ * return -ENODEV, as we don't attach to the device.
+ *
+ * The rest are the basic ops we implement that the fw upload code
+ * uses to do its job. All the ops in the common code are i1480->NAME,
+ * the functions are i1480_usb_NAME().
+ */
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/usb.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/uwb.h>
+#include <linux/usb/wusb.h>
+#include <linux/usb/wusb-wa.h>
+#include "i1480-dfu.h"
+
+#define D_LOCAL 0
+#include <linux/uwb/debug.h>
+
+
+struct i1480_usb {
+       struct i1480 i1480;
+       struct usb_device *usb_dev;
+       struct usb_interface *usb_iface;
+       struct urb *neep_urb;   /* URB for reading from EP1 */
+};
+
+
+static
+void i1480_usb_init(struct i1480_usb *i1480_usb)
+{
+       i1480_init(&i1480_usb->i1480);
+}
+
+
+static
+int i1480_usb_create(struct i1480_usb *i1480_usb, struct usb_interface *iface)
+{
+       struct usb_device *usb_dev = interface_to_usbdev(iface);
+       int result = -ENOMEM;
+
+       i1480_usb->usb_dev = usb_get_dev(usb_dev);      /* bind the USB device */
+       i1480_usb->usb_iface = usb_get_intf(iface);
+       usb_set_intfdata(iface, i1480_usb);             /* Bind the driver to iface0 */
+       i1480_usb->neep_urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (i1480_usb->neep_urb == NULL)
+               goto error;
+       return 0;
+
+error:
+       usb_set_intfdata(iface, NULL);
+       usb_put_intf(iface);
+       usb_put_dev(usb_dev);
+       return result;
+}
+
+
+static
+void i1480_usb_destroy(struct i1480_usb *i1480_usb)
+{
+       usb_kill_urb(i1480_usb->neep_urb);
+       usb_free_urb(i1480_usb->neep_urb);
+       usb_set_intfdata(i1480_usb->usb_iface, NULL);
+       usb_put_intf(i1480_usb->usb_iface);
+       usb_put_dev(i1480_usb->usb_dev);
+}
+
+
+/**
+ * Write a buffer to a memory address in the i1480 device
+ *
+ * @i1480:  i1480 instance
+ * @memory_address:
+ *          Address where to write the data buffer to.
+ * @buffer: Buffer to the data
+ * @size:   Size of the buffer [has to be < 512].
+ * @returns: 0 if ok, < 0 errno code on error.
+ *
+ * Data buffers to USB cannot be on the stack or in vmalloc'ed areas,
+ * so we copy it to the local i1480 buffer before proceeding. In any
+ * case, we have a max size we can send, soooo.
+ */
+static
+int i1480_usb_write(struct i1480 *i1480, u32 memory_address,
+                   const void *buffer, size_t size)
+{
+       int result = 0;
+       struct i1480_usb *i1480_usb = container_of(i1480, struct i1480_usb, i1480);
+       size_t buffer_size, itr = 0;
+
+       d_fnstart(3, i1480->dev, "(%p, 0x%08x, %p, %zu)\n",
+                 i1480, memory_address, buffer, size);
+       BUG_ON(size & 0x3); /* Needs to be a multiple of 4 */
+       while (size > 0) {
+               buffer_size = size < i1480->buf_size ? size : i1480->buf_size;
+               memcpy(i1480->cmd_buf, buffer + itr, buffer_size);
+               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),
+                       i1480->cmd_buf, buffer_size, 100 /* FIXME: arbitrary */);
+               if (result < 0)
+                       break;
+               d_printf(3, i1480->dev,
+                        "wrote @ 0x%08x %u bytes (of %zu bytes requested)\n",
+                        memory_address, result, buffer_size);
+               d_dump(4, i1480->dev, i1480->cmd_buf, result);
+               itr += result;
+               memory_address += result;
+               size -= result;
+       }
+       d_fnend(3, i1480->dev, "(%p, 0x%08x, %p, %zu) = %d\n",
+               i1480, memory_address, buffer, size, result);
+       return result;
+}
+
+
+/**
+ * Read a block [max size 512] of the device's memory to @i1480's buffer.
+ *
+ * @i1480: i1480 instance
+ * @memory_address:
+ *         Address where to read from.
+ * @size:  Size to read. Smaller than or equal to 512.
+ * @returns: >= 0 number of bytes written if ok, < 0 errno code on error.
+ *
+ * NOTE: if the memory address or block is incorrect, you might get a
+ *       stall or a different memory read. Caller has to verify the
+ *       memory address and size passed back in the @neh structure.
+ */
+static
+int i1480_usb_read(struct i1480 *i1480, u32 addr, size_t size)
+{
+       ssize_t result = 0, bytes = 0;
+       size_t itr, read_size = i1480->buf_size;
+       struct i1480_usb *i1480_usb = container_of(i1480, struct i1480_usb, i1480);
+
+       d_fnstart(3, i1480->dev, "(%p, 0x%08x, %zu)\n",
+                 i1480, addr, size);
+       BUG_ON(size > i1480->buf_size);
+       BUG_ON(size & 0x3); /* Needs to be a multiple of 4 */
+       BUG_ON(read_size > 512);
+
+       if (addr >= 0x8000d200 && addr < 0x8000d400)    /* Yeah, HW quirk */
+               read_size = 4;
+
+       for (itr = 0; itr < size; itr += read_size) {
+               size_t itr_addr = addr + itr;
+               size_t itr_size = min(read_size, size - itr);
+               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),
+                       i1480->cmd_buf + itr, itr_size,
+                       100 /* FIXME: arbitrary */);
+               if (result < 0) {
+                       dev_err(i1480->dev, "%s: USB read error: %zd\n",
+                               __func__, result);
+                       goto out;
+               }
+               if (result != itr_size) {
+                       result = -EIO;
+                       dev_err(i1480->dev,
+                               "%s: partial read got only %zu bytes vs %zu expected\n",
+                               __func__, result, itr_size);
+                       goto out;
+               }
+               bytes += result;
+       }
+       result = bytes;
+out:
+       d_fnend(3, i1480->dev, "(%p, 0x%08x, %zu) = %zd\n",
+               i1480, addr, size, result);
+       if (result > 0)
+               d_dump(4, i1480->dev, i1480->cmd_buf, result);
+       return result;
+}
+
+
+/**
+ * Callback for reads on the notification/event endpoint
+ *
+ * Just enables the completion read handler.
+ */
+static
+void i1480_usb_neep_cb(struct urb *urb)
+{
+       struct i1480 *i1480 = urb->context;
+       struct device *dev = i1480->dev;
+
+       switch (urb->status) {
+       case 0:
+               break;
+       case -ECONNRESET:       /* Not an error, but a controlled situation; */
+       case -ENOENT:           /* (we killed the URB)...so, no broadcast */
+               dev_dbg(dev, "NEEP: reset/noent %d\n", urb->status);
+               break;
+       case -ESHUTDOWN:        /* going away! */
+               dev_dbg(dev, "NEEP: down %d\n", urb->status);
+               break;
+       default:
+               dev_err(dev, "NEEP: unknown status %d\n", urb->status);
+               break;
+       }
+       i1480->evt_result = urb->actual_length;
+       complete(&i1480->evt_complete);
+       return;
+}
+
+
+/**
+ * Wait for the MAC FW to initialize
+ *
+ * MAC FW sends a 0xfd/0101/00 notification to EP1 when done
+ * initializing. Get that notification into i1480->evt_buf; upper layer
+ * will verify it.
+ *
+ * Set i1480->evt_result with the result of getting the event or its
+ * size (if succesful).
+ *
+ * Delivers the data directly to i1480->evt_buf
+ */
+static
+int i1480_usb_wait_init_done(struct i1480 *i1480)
+{
+       int result;
+       struct device *dev = i1480->dev;
+       struct i1480_usb *i1480_usb = container_of(i1480, struct i1480_usb, i1480);
+       struct usb_endpoint_descriptor *epd;
+
+       d_fnstart(3, dev, "(%p)\n", i1480);
+       init_completion(&i1480->evt_complete);
+       i1480->evt_result = -EINPROGRESS;
+       epd = &i1480_usb->usb_iface->cur_altsetting->endpoint[0].desc;
+       usb_fill_int_urb(i1480_usb->neep_urb, i1480_usb->usb_dev,
+                        usb_rcvintpipe(i1480_usb->usb_dev, epd->bEndpointAddress),
+                        i1480->evt_buf, i1480->buf_size,
+                        i1480_usb_neep_cb, i1480, epd->bInterval);
+       result = usb_submit_urb(i1480_usb->neep_urb, GFP_KERNEL);
+       if (result < 0) {
+               dev_err(dev, "init done: cannot submit NEEP read: %d\n",
+                       result);
+               goto error_submit;
+       }
+       /* Wait for the USB callback to get the data */
+       result = wait_for_completion_interruptible_timeout(
+               &i1480->evt_complete, HZ);
+       if (result <= 0) {
+               result = result == 0 ? -ETIMEDOUT : result;
+               goto error_wait;
+       }
+       usb_kill_urb(i1480_usb->neep_urb);
+       d_fnend(3, dev, "(%p) = 0\n", i1480);
+       return 0;
+
+error_wait:
+       usb_kill_urb(i1480_usb->neep_urb);
+error_submit:
+       i1480->evt_result = result;
+       d_fnend(3, dev, "(%p) = %d\n", i1480, result);
+       return result;
+}
+
+
+/**
+ * Generic function for issuing commands to the i1480
+ *
+ * @i1480:      i1480 instance
+ * @cmd_name:   Name of the command (for error messages)
+ * @cmd:        Pointer to command buffer
+ * @cmd_size:   Size of the command buffer
+ * @reply:      Buffer for the reply event
+ * @reply_size: Expected size back (including RCEB); the reply buffer
+ *              is assumed to be as big as this.
+ * @returns:    >= 0 size of the returned event data if ok,
+ *              < 0 errno code on error.
+ *
+ * Arms the NE handle, issues the command to the device and checks the
+ * basics of the reply event.
+ */
+static
+int i1480_usb_cmd(struct i1480 *i1480, const char *cmd_name, size_t cmd_size)
+{
+       int result;
+       struct device *dev = i1480->dev;
+       struct i1480_usb *i1480_usb = container_of(i1480, struct i1480_usb, i1480);
+       struct usb_endpoint_descriptor *epd;
+       struct uwb_rccb *cmd = i1480->cmd_buf;
+       u8 iface_no;
+
+       d_fnstart(3, dev, "(%p, %s, %zu)\n", i1480, cmd_name, cmd_size);
+       /* Post a read on the notification & event endpoint */
+       iface_no = i1480_usb->usb_iface->cur_altsetting->desc.bInterfaceNumber;
+       epd = &i1480_usb->usb_iface->cur_altsetting->endpoint[0].desc;
+       usb_fill_int_urb(
+               i1480_usb->neep_urb, i1480_usb->usb_dev,
+               usb_rcvintpipe(i1480_usb->usb_dev, epd->bEndpointAddress),
+               i1480->evt_buf, i1480->buf_size,
+               i1480_usb_neep_cb, i1480, epd->bInterval);
+       result = usb_submit_urb(i1480_usb->neep_urb, GFP_KERNEL);
+       if (result < 0) {
+               dev_err(dev, "%s: cannot submit NEEP read: %d\n",
+                       cmd_name, result);
+                       goto error_submit_ep1;
+       }
+       /* Now post the command on EP0 */
+       result = usb_control_msg(
+               i1480_usb->usb_dev, usb_sndctrlpipe(i1480_usb->usb_dev, 0),
+               WA_EXEC_RC_CMD,
+               USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
+               0, iface_no,
+               cmd, cmd_size,
+               100 /* FIXME: this is totally arbitrary */);
+       if (result < 0) {
+               dev_err(dev, "%s: control request failed: %d\n",
+                       cmd_name, result);
+               goto error_submit_ep0;
+       }
+       d_fnend(3, dev, "(%p, %s, %zu) = %d\n",
+               i1480, cmd_name, cmd_size, result);
+       return result;
+
+error_submit_ep0:
+       usb_kill_urb(i1480_usb->neep_urb);
+error_submit_ep1:
+       d_fnend(3, dev, "(%p, %s, %zu) = %d\n",
+               i1480, cmd_name, cmd_size, result);
+       return result;
+}
+
+
+/*
+ * Probe a i1480 device for uploading firmware.
+ *
+ * We attach only to interface #0, which is the radio control interface.
+ */
+static
+int i1480_usb_probe(struct usb_interface *iface, const struct usb_device_id *id)
+{
+       struct i1480_usb *i1480_usb;
+       struct i1480 *i1480;
+       struct device *dev = &iface->dev;
+       int result;
+
+       result = -ENODEV;
+       if (iface->cur_altsetting->desc.bInterfaceNumber != 0) {
+               dev_dbg(dev, "not attaching to iface %d\n",
+                       iface->cur_altsetting->desc.bInterfaceNumber);
+               goto error;
+       }
+       if (iface->num_altsetting > 1
+           && interface_to_usbdev(iface)->descriptor.idProduct == 0xbabe) {
+               /* Need altsetting #1 [HW QUIRK] or EP1 won't work */
+               result = usb_set_interface(interface_to_usbdev(iface), 0, 1);
+               if (result < 0)
+                       dev_warn(dev,
+                                "can't set altsetting 1 on iface 0: %d\n",
+                                result);
+       }
+
+       result = -ENOMEM;
+       i1480_usb = kzalloc(sizeof(*i1480_usb), GFP_KERNEL);
+       if (i1480_usb == NULL) {
+               dev_err(dev, "Unable to allocate instance\n");
+               goto error;
+       }
+       i1480_usb_init(i1480_usb);
+
+       i1480 = &i1480_usb->i1480;
+       i1480->buf_size = 512;
+       i1480->cmd_buf = kmalloc(2 * i1480->buf_size, GFP_KERNEL);
+       if (i1480->cmd_buf == NULL) {
+               dev_err(dev, "Cannot allocate transfer buffers\n");
+               result = -ENOMEM;
+               goto error_buf_alloc;
+       }
+       i1480->evt_buf = i1480->cmd_buf + i1480->buf_size;
+
+       result = i1480_usb_create(i1480_usb, iface);
+       if (result < 0) {
+               dev_err(dev, "Cannot create instance: %d\n", result);
+               goto error_create;
+       }
+
+       /* setup the fops and upload the firmare */
+       i1480->pre_fw_name = "i1480-pre-phy-0.0.bin";
+       i1480->mac_fw_name = "i1480-usb-0.0.bin";
+       i1480->mac_fw_name_deprecate = "ptc-0.0.bin";
+       i1480->phy_fw_name = "i1480-phy-0.0.bin";
+       i1480->dev = &iface->dev;
+       i1480->write = i1480_usb_write;
+       i1480->read = i1480_usb_read;
+       i1480->rc_setup = NULL;
+       i1480->wait_init_done = i1480_usb_wait_init_done;
+       i1480->cmd = i1480_usb_cmd;
+
+       result = i1480_fw_upload(&i1480_usb->i1480);    /* the real thing */
+       if (result >= 0) {
+               usb_reset_device(i1480_usb->usb_dev);
+               result = -ENODEV;       /* we don't want to bind to the iface */
+       }
+       i1480_usb_destroy(i1480_usb);
+error_create:
+       kfree(i1480->cmd_buf);
+error_buf_alloc:
+       kfree(i1480_usb);
+error:
+       return result;
+}
+
+#define i1480_USB_DEV(v, p)                            \
+{                                                      \
+       .match_flags = USB_DEVICE_ID_MATCH_DEVICE       \
+                | USB_DEVICE_ID_MATCH_DEV_INFO         \
+                | USB_DEVICE_ID_MATCH_INT_INFO,        \
+       .idVendor = (v),                                \
+       .idProduct = (p),                               \
+       .bDeviceClass = 0xff,                           \
+       .bDeviceSubClass = 0xff,                        \
+       .bDeviceProtocol = 0xff,                        \
+       .bInterfaceClass = 0xff,                        \
+       .bInterfaceSubClass = 0xff,                     \
+       .bInterfaceProtocol = 0xff,                     \
+}
+
+
+/** USB device ID's that we handle */
+static struct usb_device_id i1480_usb_id_table[] = {
+       i1480_USB_DEV(0x8086, 0xdf3b),
+       i1480_USB_DEV(0x15a9, 0x0005),
+       i1480_USB_DEV(0x07d1, 0x3802),
+       i1480_USB_DEV(0x050d, 0x305a),
+       i1480_USB_DEV(0x3495, 0x3007),
+       {},
+};
+MODULE_DEVICE_TABLE(usb, i1480_usb_id_table);
+
+
+static struct usb_driver i1480_dfu_driver = {
+       .name =         "i1480-dfu-usb",
+       .id_table =     i1480_usb_id_table,
+       .probe =        i1480_usb_probe,
+       .disconnect =   NULL,
+};
+
+
+/*
+ * Initialize the i1480 DFU driver.
+ *
+ * We also need to register our function for guessing event sizes.
+ */
+static int __init i1480_dfu_driver_init(void)
+{
+       return usb_register(&i1480_dfu_driver);
+}
+module_init(i1480_dfu_driver_init);
+
+
+static void __exit i1480_dfu_driver_exit(void)
+{
+       usb_deregister(&i1480_dfu_driver);
+}
+module_exit(i1480_dfu_driver_exit);
+
+
+MODULE_AUTHOR("Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>");
+MODULE_DESCRIPTION("Intel Wireless UWB Link 1480 firmware uploader for USB");
+MODULE_LICENSE("GPL");
diff --git a/drivers/uwb/i1480/i1480-est.c b/drivers/uwb/i1480/i1480-est.c
new file mode 100644 (file)
index 0000000..7bf8c6f
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Intel Wireless UWB Link 1480
+ * Event Size tables for Wired Adaptors
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/uwb.h>
+#include "dfu/i1480-dfu.h"
+
+
+/** Event size table for wEvents 0x00XX */
+static struct uwb_est_entry i1480_est_fd00[] = {
+       /* Anybody expecting this response has to use
+        * neh->extra_size to specify the real size that will
+        * come back. */
+       [i1480_EVT_CONFIRM] = { .size = sizeof(struct i1480_evt_confirm) },
+       [i1480_CMD_SET_IP_MAS] = { .size = sizeof(struct i1480_evt_confirm) },
+#ifdef i1480_RCEB_EXTENDED
+       [0x09] = {
+               .size = sizeof(struct i1480_rceb),
+               .offset = 1 + offsetof(struct i1480_rceb, wParamLength),
+       },
+#endif
+};
+
+/** Event size table for wEvents 0x01XX */
+static struct uwb_est_entry i1480_est_fd01[] = {
+       [0xff & i1480_EVT_RM_INIT_DONE] = { .size = sizeof(struct i1480_rceb) },
+       [0xff & i1480_EVT_DEV_ADD] = { .size = sizeof(struct i1480_rceb) + 9 },
+       [0xff & i1480_EVT_DEV_RM] = { .size = sizeof(struct i1480_rceb) + 9 },
+       [0xff & i1480_EVT_DEV_ID_CHANGE] = {
+               .size = sizeof(struct i1480_rceb) + 2 },
+};
+
+static int i1480_est_init(void)
+{
+       int result = uwb_est_register(i1480_CET_VS1, 0x00, 0x8086, 0x0c3b,
+                                     i1480_est_fd00,
+                                     ARRAY_SIZE(i1480_est_fd00));
+       if (result < 0) {
+               printk(KERN_ERR "Can't register EST table fd00: %d\n", result);
+               return result;
+       }
+       result = uwb_est_register(i1480_CET_VS1, 0x01, 0x8086, 0x0c3b,
+                                 i1480_est_fd01, ARRAY_SIZE(i1480_est_fd01));
+       if (result < 0) {
+               printk(KERN_ERR "Can't register EST table fd01: %d\n", result);
+               return result;
+       }
+       return 0;
+}
+module_init(i1480_est_init);
+
+static void i1480_est_exit(void)
+{
+       uwb_est_unregister(i1480_CET_VS1, 0x00, 0x8086, 0x0c3b,
+                          i1480_est_fd00, ARRAY_SIZE(i1480_est_fd00));
+       uwb_est_unregister(i1480_CET_VS1, 0x01, 0x8086, 0x0c3b,
+                          i1480_est_fd01, ARRAY_SIZE(i1480_est_fd01));
+}
+module_exit(i1480_est_exit);
+
+MODULE_AUTHOR("Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>");
+MODULE_DESCRIPTION("i1480's Vendor Specific Event Size Tables");
+MODULE_LICENSE("GPL");
+
+/**
+ * USB device ID's that we handle
+ *
+ * [so we are loaded when this kind device is connected]
+ */
+static struct usb_device_id i1480_est_id_table[] = {
+       { USB_DEVICE(0x8086, 0xdf3b), },
+       { USB_DEVICE(0x8086, 0x0c3b), },
+       { },
+};
+MODULE_DEVICE_TABLE(usb, i1480_est_id_table);
diff --git a/drivers/uwb/i1480/i1480-wlp.h b/drivers/uwb/i1480/i1480-wlp.h
new file mode 100644 (file)
index 0000000..18a8b0e
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Intel 1480 Wireless UWB Link
+ * WLP specific definitions
+ *
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ */
+
+#ifndef __i1480_wlp_h__
+#define __i1480_wlp_h__
+
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/uwb.h>
+#include <linux/if_ether.h>
+#include <asm/byteorder.h>
+
+/* New simplified header format? */
+#undef WLP_HDR_FMT_2           /* FIXME: rename */
+
+/**
+ * Values of the Delivery ID & Type field when PCA or DRP
+ *
+ * The Delivery ID & Type field in the WLP TX header indicates whether
+ * the frame is PCA or DRP. This is done based on the high level bit of
+ * this field.
+ * We use this constant to test if the traffic is PCA or DRP as follows:
+ * if (wlp_tx_hdr_delivery_id_type(wlp_tx_hdr) & WLP_DRP)
+ *     this is DRP traffic
+ * else
+ *     this is PCA traffic
+ */
+enum deliver_id_type_bit {
+       WLP_DRP = 8,
+};
+
+/**
+ * WLP TX header
+ *
+ * Indicates UWB/WLP-specific transmission parameters for a network
+ * packet.
+ */
+struct wlp_tx_hdr {
+       /* dword 0 */
+       struct uwb_dev_addr dstaddr;
+       u8                  key_index;
+       u8                  mac_params;
+       /* dword 1 */
+       u8                  phy_params;
+#ifndef WLP_HDR_FMT_2
+       u8                  reserved;
+       __le16              oui01;              /* FIXME: not so sure if __le16 or u8[2] */
+       /* dword 2 */
+       u8                  oui2;               /*        if all LE, it could be merged */
+       __le16              prid;
+#endif
+} __attribute__((packed));
+
+static inline int wlp_tx_hdr_delivery_id_type(const struct wlp_tx_hdr *hdr)
+{
+       return hdr->mac_params & 0x0f;
+}
+
+static inline int wlp_tx_hdr_ack_policy(const struct wlp_tx_hdr *hdr)
+{
+       return (hdr->mac_params >> 4) & 0x07;
+}
+
+static inline int wlp_tx_hdr_rts_cts(const struct wlp_tx_hdr *hdr)
+{
+       return (hdr->mac_params >> 7) & 0x01;
+}
+
+static inline void wlp_tx_hdr_set_delivery_id_type(struct wlp_tx_hdr *hdr, int id)
+{
+       hdr->mac_params = (hdr->mac_params & ~0x0f) | id;
+}
+
+static inline void wlp_tx_hdr_set_ack_policy(struct wlp_tx_hdr *hdr,
+                                            enum uwb_ack_pol policy)
+{
+       hdr->mac_params = (hdr->mac_params & ~0x70) | (policy << 4);
+}
+
+static inline void wlp_tx_hdr_set_rts_cts(struct wlp_tx_hdr *hdr, int rts_cts)
+{
+       hdr->mac_params = (hdr->mac_params & ~0x80) | (rts_cts << 7);
+}
+
+static inline enum uwb_phy_rate wlp_tx_hdr_phy_rate(const struct wlp_tx_hdr *hdr)
+{
+       return hdr->phy_params & 0x0f;
+}
+
+static inline int wlp_tx_hdr_tx_power(const struct wlp_tx_hdr *hdr)
+{
+       return (hdr->phy_params >> 4) & 0x0f;
+}
+
+static inline void wlp_tx_hdr_set_phy_rate(struct wlp_tx_hdr *hdr, enum uwb_phy_rate rate)
+{
+       hdr->phy_params = (hdr->phy_params & ~0x0f) | rate;
+}
+
+static inline void wlp_tx_hdr_set_tx_power(struct wlp_tx_hdr *hdr, int pwr)
+{
+       hdr->phy_params = (hdr->phy_params & ~0xf0) | (pwr << 4);
+}
+
+
+/**
+ * WLP RX header
+ *
+ * Provides UWB/WLP-specific transmission data for a received
+ * network packet.
+ */
+struct wlp_rx_hdr {
+       /* dword 0 */
+       struct uwb_dev_addr dstaddr;
+       struct uwb_dev_addr srcaddr;
+       /* dword 1 */
+       u8                  LQI;
+       s8                  RSSI;
+       u8                  reserved3;
+#ifndef WLP_HDR_FMT_2
+       u8                  oui0;
+       /* dword 2 */
+       __le16              oui12;
+       __le16              prid;
+#endif
+} __attribute__((packed));
+
+
+/** User configurable options for WLP */
+struct wlp_options {
+       struct mutex mutex; /* access to user configurable options*/
+       struct wlp_tx_hdr def_tx_hdr;   /* default tx hdr */
+       u8 pca_base_priority;
+       u8 bw_alloc; /*index into bw_allocs[] for PCA/DRP reservations*/
+};
+
+
+static inline
+void wlp_options_init(struct wlp_options *options)
+{
+       mutex_init(&options->mutex);
+       wlp_tx_hdr_set_ack_policy(&options->def_tx_hdr, UWB_ACK_INM);
+       wlp_tx_hdr_set_rts_cts(&options->def_tx_hdr, 1);
+       /* FIXME: default to phy caps */
+       wlp_tx_hdr_set_phy_rate(&options->def_tx_hdr, UWB_PHY_RATE_480);
+#ifndef WLP_HDR_FMT_2
+       options->def_tx_hdr.prid = cpu_to_le16(0x0000);
+#endif
+}
+
+
+/* sysfs helpers */
+
+extern ssize_t uwb_pca_base_priority_store(struct wlp_options *,
+                                          const char *, size_t);
+extern ssize_t uwb_pca_base_priority_show(const struct wlp_options *, char *);
+extern ssize_t uwb_bw_alloc_store(struct wlp_options *, const char *, size_t);
+extern ssize_t uwb_bw_alloc_show(const struct wlp_options *, char *);
+extern ssize_t uwb_ack_policy_store(struct wlp_options *,
+                                   const char *, size_t);
+extern ssize_t uwb_ack_policy_show(const struct wlp_options *, char *);
+extern ssize_t uwb_rts_cts_store(struct wlp_options *, const char *, size_t);
+extern ssize_t uwb_rts_cts_show(const struct wlp_options *, char *);
+extern ssize_t uwb_phy_rate_store(struct wlp_options *, const char *, size_t);
+extern ssize_t uwb_phy_rate_show(const struct wlp_options *, char *);
+
+
+/** Simple bandwidth allocation (temporary and too simple) */
+struct wlp_bw_allocs {
+       const char *name;
+       struct {
+               u8 mask, stream;
+       } tx, rx;
+};
+
+
+#endif /* #ifndef __i1480_wlp_h__ */
diff --git a/drivers/uwb/i1480/i1480u-wlp/Makefile b/drivers/uwb/i1480/i1480u-wlp/Makefile
new file mode 100644 (file)
index 0000000..fe6709b
--- /dev/null
@@ -0,0 +1,8 @@
+obj-$(CONFIG_UWB_I1480U_WLP) += i1480u-wlp.o
+
+i1480u-wlp-objs :=     \
+       lc.o            \
+       netdev.o        \
+       rx.o            \
+       sysfs.o         \
+       tx.o
diff --git a/drivers/uwb/i1480/i1480u-wlp/i1480u-wlp.h b/drivers/uwb/i1480/i1480u-wlp/i1480u-wlp.h
new file mode 100644 (file)
index 0000000..5f1b295
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ * Intel 1480 Wireless UWB Link USB
+ * Header formats, constants, general internal interfaces
+ *
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * This is not an standard interface.
+ *
+ * FIXME: docs
+ *
+ * i1480u-wlp is pretty simple: two endpoints, one for tx, one for
+ * rx. rx is polled. Network packets (ethernet, whatever) are wrapped
+ * in i1480 TX or RX headers (for sending over the air), and these
+ * packets are wrapped in UNTD headers (for sending to the WLP UWB
+ * controller).
+ *
+ * UNTD packets (UNTD hdr + i1480 hdr + network packet) packets
+ * cannot be bigger than i1480u_MAX_FRG_SIZE. When this happens, the
+ * i1480 packet is broken in chunks/packets:
+ *
+ * UNTD-1st.hdr + i1480.hdr + payload
+ * UNTD-next.hdr + payload
+ * ...
+ * UNTD-last.hdr + payload
+ *
+ * so that each packet is smaller or equal than i1480u_MAX_FRG_SIZE.
+ *
+ * All HW structures and bitmaps are little endian, so we need to play
+ * ugly tricks when defining bitfields. Hoping for the day GCC
+ * implements __attribute__((endian(1234))).
+ *
+ * FIXME: ROADMAP to the whole implementation
+ */
+
+#ifndef __i1480u_wlp_h__
+#define __i1480u_wlp_h__
+
+#include <linux/usb.h>
+#include <linux/netdevice.h>
+#include <linux/uwb.h>         /* struct uwb_rc, struct uwb_notifs_handler */
+#include <linux/wlp.h>
+#include "../i1480-wlp.h"
+
+#undef i1480u_FLOW_CONTROL     /* Enable flow control code */
+
+/**
+ * Basic flow control
+ */
+enum {
+       i1480u_TX_INFLIGHT_MAX = 1000,
+       i1480u_TX_INFLIGHT_THRESHOLD = 100,
+};
+
+/** Maximum size of a transaction that we can tx/rx */
+enum {
+       /* Maximum packet size computed as follows: max UNTD header (8) +
+        * i1480 RX header (8) + max Ethernet header and payload (4096) +
+        * Padding added by skb_reserve (2) to make post Ethernet payload
+        * start on 16 byte boundary*/
+       i1480u_MAX_RX_PKT_SIZE = 4114,
+       i1480u_MAX_FRG_SIZE = 512,
+       i1480u_RX_BUFS = 9,
+};
+
+
+/**
+ * UNTD packet type
+ *
+ * We need to fragment any payload whose UNTD packet is going to be
+ * bigger than i1480u_MAX_FRG_SIZE.
+ */
+enum i1480u_pkt_type {
+       i1480u_PKT_FRAG_1ST = 0x1,
+       i1480u_PKT_FRAG_NXT = 0x0,
+       i1480u_PKT_FRAG_LST = 0x2,
+       i1480u_PKT_FRAG_CMP = 0x3
+};
+enum {
+       i1480u_PKT_NONE = 0x4,
+};
+
+/** USB Network Transfer Descriptor - common */
+struct untd_hdr {
+       u8     type;
+       __le16 len;
+} __attribute__((packed));
+
+static inline enum i1480u_pkt_type untd_hdr_type(const struct untd_hdr *hdr)
+{
+       return hdr->type & 0x03;
+}
+
+static inline int untd_hdr_rx_tx(const struct untd_hdr *hdr)
+{
+       return (hdr->type >> 2) & 0x01;
+}
+
+static inline void untd_hdr_set_type(struct untd_hdr *hdr, enum i1480u_pkt_type type)
+{
+       hdr->type = (hdr->type & ~0x03) | type;
+}
+
+static inline void untd_hdr_set_rx_tx(struct untd_hdr *hdr, int rx_tx)
+{
+       hdr->type = (hdr->type & ~0x04) | (rx_tx << 2);
+}
+
+
+/**
+ * USB Network Transfer Descriptor - Complete Packet
+ *
+ * This is for a packet that is smaller (header + payload) than
+ * i1480u_MAX_FRG_SIZE.
+ *
+ * @hdr.total_len is the size of the payload; the payload doesn't
+ * count this header nor the padding, but includes the size of i1480
+ * header.
+ */
+struct untd_hdr_cmp {
+       struct untd_hdr hdr;
+       u8              padding;
+} __attribute__((packed));
+
+
+/**
+ * USB Network Transfer Descriptor - First fragment
+ *
+ * @hdr.len is the size of the *whole packet* (excluding UNTD
+ * headers); @fragment_len is the size of the payload (excluding UNTD
+ * headers, but including i1480 headers).
+ */
+struct untd_hdr_1st {
+       struct untd_hdr hdr;
+       __le16          fragment_len;
+       u8              padding[3];
+} __attribute__((packed));
+
+
+/**
+ * USB Network Transfer Descriptor - Next / Last [Rest]
+ *
+ * @hdr.len is the size of the payload, not including headrs.
+ */
+struct untd_hdr_rst {
+       struct untd_hdr hdr;
+       u8              padding;
+} __attribute__((packed));
+
+
+/**
+ * Transmission context
+ *
+ * Wraps all the stuff needed to track a pending/active tx
+ * operation.
+ */
+struct i1480u_tx {
+       struct list_head list_node;
+       struct i1480u *i1480u;
+       struct urb *urb;
+
+       struct sk_buff *skb;
+       struct wlp_tx_hdr *wlp_tx_hdr;
+
+       void *buf;      /* if NULL, no new buf was used */
+       size_t buf_size;
+};
+
+/**
+ * Basic flow control
+ *
+ * We maintain a basic flow control counter. "count" how many TX URBs are
+ * outstanding. Only allow "max"
+ * TX URBs to be outstanding. If this value is reached the queue will be
+ * stopped. The queue will be restarted when there are
+ * "threshold" URBs outstanding.
+ * Maintain a counter of how many time the TX queue needed to be restarted
+ * due to the "max" being exceeded and the "threshold" reached again. The
+ * timestamp "restart_ts" is to keep track from when the counter was last
+ * queried (see sysfs handling of file wlp_tx_inflight).
+ */
+struct i1480u_tx_inflight {
+       atomic_t count;
+       unsigned long max;
+       unsigned long threshold;
+       unsigned long restart_ts;
+       atomic_t restart_count;
+};
+
+/**
+ * Instance of a i1480u WLP interface
+ *
+ * Keeps references to the USB device that wraps it, as well as it's
+ * interface and associated UWB host controller. As well, it also
+ * keeps a link to the netdevice for integration into the networking
+ * stack.
+ * We maintian separate error history for the tx and rx endpoints because
+ * the implementation does not rely on locking - having one shared
+ * structure between endpoints may cause problems. Adding locking to the
+ * implementation will have higher cost than adding a separate structure.
+ */
+struct i1480u {
+       struct usb_device *usb_dev;
+       struct usb_interface *usb_iface;
+       struct net_device *net_dev;
+
+       spinlock_t lock;
+       struct net_device_stats stats;
+
+       /* RX context handling */
+       struct sk_buff *rx_skb;
+       struct uwb_dev_addr rx_srcaddr;
+       size_t rx_untd_pkt_size;
+       struct i1480u_rx_buf {
+               struct i1480u *i1480u;  /* back pointer */
+               struct urb *urb;
+               struct sk_buff *data;   /* i1480u_MAX_RX_PKT_SIZE each */
+       } rx_buf[i1480u_RX_BUFS];       /* N bufs */
+
+       spinlock_t tx_list_lock;        /* TX context */
+       struct list_head tx_list;
+       u8 tx_stream;
+
+       struct stats lqe_stats, rssi_stats;     /* radio statistics */
+
+       /* Options we can set from sysfs */
+       struct wlp_options options;
+       struct uwb_notifs_handler uwb_notifs_handler;
+       struct edc tx_errors;
+       struct edc rx_errors;
+       struct wlp wlp;
+#ifdef i1480u_FLOW_CONTROL
+       struct urb *notif_urb;
+       struct edc notif_edc;           /* error density counter */
+       u8 notif_buffer[1];
+#endif
+       struct i1480u_tx_inflight tx_inflight;
+};
+
+/* Internal interfaces */
+extern void i1480u_rx_cb(struct urb *urb);
+extern int i1480u_rx_setup(struct i1480u *);
+extern void i1480u_rx_release(struct i1480u *);
+extern void i1480u_tx_release(struct i1480u *);
+extern int i1480u_xmit_frame(struct wlp *, struct sk_buff *,
+                            struct uwb_dev_addr *);
+extern void i1480u_stop_queue(struct wlp *);
+extern void i1480u_start_queue(struct wlp *);
+extern int i1480u_sysfs_setup(struct i1480u *);
+extern void i1480u_sysfs_release(struct i1480u *);
+
+/* netdev interface */
+extern int i1480u_open(struct net_device *);
+extern int i1480u_stop(struct net_device *);
+extern int i1480u_hard_start_xmit(struct sk_buff *, struct net_device *);
+extern void i1480u_tx_timeout(struct net_device *);
+extern int i1480u_set_config(struct net_device *, struct ifmap *);
+extern struct net_device_stats *i1480u_get_stats(struct net_device *);
+extern int i1480u_change_mtu(struct net_device *, int);
+extern void i1480u_uwb_notifs_cb(void *, struct uwb_dev *, enum uwb_notifs);
+
+/* bandwidth allocation callback */
+extern void  i1480u_bw_alloc_cb(struct uwb_rsv *);
+
+/* Sys FS */
+extern struct attribute_group i1480u_wlp_attr_group;
+
+#endif /* #ifndef __i1480u_wlp_h__ */
diff --git a/drivers/uwb/i1480/i1480u-wlp/lc.c b/drivers/uwb/i1480/i1480u-wlp/lc.c
new file mode 100644 (file)
index 0000000..737d60c
--- /dev/null
@@ -0,0 +1,421 @@
+/*
+ * WUSB Wire Adapter: WLP interface
+ * Driver for the Linux Network stack.
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ *
+ * This implements a very simple network driver for the WLP USB
+ * device that is associated to a UWB (Ultra Wide Band) host.
+ *
+ * This is seen as an interface of a composite device. Once the UWB
+ * host has an association to another WLP capable device, the
+ * networking interface (aka WLP) can start to send packets back and
+ * forth.
+ *
+ * Limitations:
+ *
+ *  - Hand cranked; can't ifup the interface until there is an association
+ *
+ *  - BW allocation very simplistic [see i1480u_mas_set() and callees].
+ *
+ *
+ * ROADMAP:
+ *
+ *   ENTRY POINTS (driver model):
+ *
+ *     i1480u_driver_{exit,init}(): initialization of the driver.
+ *
+ *     i1480u_probe(): called by the driver code when a device
+ *                     matching 'i1480u_id_table' is connected.
+ *
+ *                     This allocs a netdev instance, inits with
+ *                     i1480u_add(), then registers_netdev().
+ *         i1480u_init()
+ *         i1480u_add()
+ *
+ *     i1480u_disconnect(): device has been disconnected/module
+ *                          is being removed.
+ *         i1480u_rm()
+ */
+#include <linux/version.h>
+#include <linux/if_arp.h>
+#include <linux/etherdevice.h>
+#include <linux/uwb/debug.h>
+#include "i1480u-wlp.h"
+
+
+
+static inline
+void i1480u_init(struct i1480u *i1480u)
+{
+       /* nothing so far... doesn't it suck? */
+       spin_lock_init(&i1480u->lock);
+       INIT_LIST_HEAD(&i1480u->tx_list);
+       spin_lock_init(&i1480u->tx_list_lock);
+       wlp_options_init(&i1480u->options);
+       edc_init(&i1480u->tx_errors);
+       edc_init(&i1480u->rx_errors);
+#ifdef i1480u_FLOW_CONTROL
+       edc_init(&i1480u->notif_edc);
+#endif
+       stats_init(&i1480u->lqe_stats);
+       stats_init(&i1480u->rssi_stats);
+       wlp_init(&i1480u->wlp);
+}
+
+/**
+ * Fill WLP device information structure
+ *
+ * The structure will contain a few character arrays, each ending with a
+ * null terminated string. Each string has to fit (excluding terminating
+ * character) into a specified range obtained from the WLP substack.
+ *
+ * It is still not clear exactly how this device information should be
+ * obtained. Until we find out we use the USB device descriptor as backup, some
+ * information elements have intuitive mappings, other not.
+ */
+static
+void i1480u_fill_device_info(struct wlp *wlp, struct wlp_device_info *dev_info)
+{
+       struct i1480u *i1480u = container_of(wlp, struct i1480u, wlp);
+       struct usb_device *usb_dev = i1480u->usb_dev;
+       /* Treat device name and model name the same */
+       if (usb_dev->descriptor.iProduct) {
+               usb_string(usb_dev, usb_dev->descriptor.iProduct,
+                          dev_info->name, sizeof(dev_info->name));
+               usb_string(usb_dev, usb_dev->descriptor.iProduct,
+                          dev_info->model_name, sizeof(dev_info->model_name));
+       }
+       if (usb_dev->descriptor.iManufacturer)
+               usb_string(usb_dev, usb_dev->descriptor.iManufacturer,
+                          dev_info->manufacturer,
+                          sizeof(dev_info->manufacturer));
+       scnprintf(dev_info->model_nr, sizeof(dev_info->model_nr), "%04x",
+                 __le16_to_cpu(usb_dev->descriptor.bcdDevice));
+       if (usb_dev->descriptor.iSerialNumber)
+               usb_string(usb_dev, usb_dev->descriptor.iSerialNumber,
+                          dev_info->serial, sizeof(dev_info->serial));
+       /* FIXME: where should we obtain category? */
+       dev_info->prim_dev_type.category = cpu_to_le16(WLP_DEV_CAT_OTHER);
+       /* FIXME: Complete OUI and OUIsubdiv attributes */
+}
+
+#ifdef i1480u_FLOW_CONTROL
+/**
+ * Callback for the notification endpoint
+ *
+ * This mostly controls the xon/xoff protocol. In case of hard error,
+ * we stop the queue. If not, we always retry.
+ */
+static
+void i1480u_notif_cb(struct urb *urb, struct pt_regs *regs)
+{
+       struct i1480u *i1480u = urb->context;
+       struct usb_interface *usb_iface = i1480u->usb_iface;
+       struct device *dev = &usb_iface->dev;
+       int result;
+
+       switch (urb->status) {
+       case 0:                         /* Got valid data, do xon/xoff */
+               switch (i1480u->notif_buffer[0]) {
+               case 'N':
+                       dev_err(dev, "XOFF STOPPING queue at %lu\n", jiffies);
+                       netif_stop_queue(i1480u->net_dev);
+                       break;
+               case 'A':
+                       dev_err(dev, "XON STARTING queue at %lu\n", jiffies);
+                       netif_start_queue(i1480u->net_dev);
+                       break;
+               default:
+                       dev_err(dev, "NEP: unknown data 0x%02hhx\n",
+                               i1480u->notif_buffer[0]);
+               }
+               break;
+       case -ECONNRESET:               /* Controlled situation ... */
+       case -ENOENT:                   /* we killed the URB... */
+               dev_err(dev, "NEP: URB reset/noent %d\n", urb->status);
+               goto error;
+       case -ESHUTDOWN:                /* going away! */
+               dev_err(dev, "NEP: URB down %d\n", urb->status);
+               goto error;
+       default:                        /* Retry unless it gets ugly */
+               if (edc_inc(&i1480u->notif_edc, EDC_MAX_ERRORS,
+                           EDC_ERROR_TIMEFRAME)) {
+                       dev_err(dev, "NEP: URB max acceptable errors "
+                               "exceeded; resetting device\n");
+                       goto error_reset;
+               }
+               dev_err(dev, "NEP: URB error %d\n", urb->status);
+               break;
+       }
+       result = usb_submit_urb(urb, GFP_ATOMIC);
+       if (result < 0) {
+               dev_err(dev, "NEP: Can't resubmit URB: %d; resetting device\n",
+                       result);
+               goto error_reset;
+       }
+       return;
+
+error_reset:
+       wlp_reset_all(&i1480-wlp);
+error:
+       netif_stop_queue(i1480u->net_dev);
+       return;
+}
+#endif
+
+static
+int i1480u_add(struct i1480u *i1480u, struct usb_interface *iface)
+{
+       int result = -ENODEV;
+       struct wlp *wlp = &i1480u->wlp;
+       struct usb_device *usb_dev = interface_to_usbdev(iface);
+       struct net_device *net_dev = i1480u->net_dev;
+       struct uwb_rc *rc;
+       struct uwb_dev *uwb_dev;
+#ifdef i1480u_FLOW_CONTROL
+       struct usb_endpoint_descriptor *epd;
+#endif
+
+       i1480u->usb_dev = usb_get_dev(usb_dev);
+       i1480u->usb_iface = iface;
+       rc = uwb_rc_get_by_grandpa(&i1480u->usb_dev->dev);
+       if (rc == NULL) {
+               dev_err(&iface->dev, "Cannot get associated UWB Radio "
+                       "Controller\n");
+               goto out;
+       }
+       wlp->xmit_frame = i1480u_xmit_frame;
+       wlp->fill_device_info = i1480u_fill_device_info;
+       wlp->stop_queue = i1480u_stop_queue;
+       wlp->start_queue = i1480u_start_queue;
+       result = wlp_setup(wlp, rc);
+       if (result < 0) {
+               dev_err(&iface->dev, "Cannot setup WLP\n");
+               goto error_wlp_setup;
+       }
+       result = 0;
+       ether_setup(net_dev);                   /* make it an etherdevice */
+       uwb_dev = &rc->uwb_dev;
+       /* FIXME: hookup address change notifications? */
+
+       memcpy(net_dev->dev_addr, uwb_dev->mac_addr.data,
+              sizeof(net_dev->dev_addr));
+
+       net_dev->hard_header_len = sizeof(struct untd_hdr_cmp)
+               + sizeof(struct wlp_tx_hdr)
+               + WLP_DATA_HLEN
+               + ETH_HLEN;
+       net_dev->mtu = 3500;
+       net_dev->tx_queue_len = 20;             /* FIXME: maybe use 1000? */
+
+/*     net_dev->flags &= ~IFF_BROADCAST;       FIXME: BUG in firmware */
+       /* FIXME: multicast disabled */
+       net_dev->flags &= ~IFF_MULTICAST;
+       net_dev->features &= ~NETIF_F_SG;
+       net_dev->features &= ~NETIF_F_FRAGLIST;
+       /* All NETIF_F_*_CSUM disabled */
+       net_dev->features |= NETIF_F_HIGHDMA;
+       net_dev->watchdog_timeo = 5*HZ;         /* FIXME: a better default? */
+
+       net_dev->open = i1480u_open;
+       net_dev->stop = i1480u_stop;
+       net_dev->hard_start_xmit = i1480u_hard_start_xmit;
+       net_dev->tx_timeout = i1480u_tx_timeout;
+       net_dev->get_stats = i1480u_get_stats;
+       net_dev->set_config = i1480u_set_config;
+       net_dev->change_mtu = i1480u_change_mtu;
+
+#ifdef i1480u_FLOW_CONTROL
+       /* Notification endpoint setup (submitted when we open the device) */
+       i1480u->notif_urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (i1480u->notif_urb == NULL) {
+               dev_err(&iface->dev, "Unable to allocate notification URB\n");
+               result = -ENOMEM;
+               goto error_urb_alloc;
+       }
+       epd = &iface->cur_altsetting->endpoint[0].desc;
+       usb_fill_int_urb(i1480u->notif_urb, usb_dev,
+                        usb_rcvintpipe(usb_dev, epd->bEndpointAddress),
+                        i1480u->notif_buffer, sizeof(i1480u->notif_buffer),
+                        i1480u_notif_cb, i1480u, epd->bInterval);
+
+#endif
+
+       i1480u->tx_inflight.max = i1480u_TX_INFLIGHT_MAX;
+       i1480u->tx_inflight.threshold = i1480u_TX_INFLIGHT_THRESHOLD;
+       i1480u->tx_inflight.restart_ts = jiffies;
+       usb_set_intfdata(iface, i1480u);
+       return result;
+
+#ifdef i1480u_FLOW_CONTROL
+error_urb_alloc:
+#endif
+       wlp_remove(wlp);
+error_wlp_setup:
+       uwb_rc_put(rc);
+out:
+       usb_put_dev(i1480u->usb_dev);
+       return result;
+}
+
+static void i1480u_rm(struct i1480u *i1480u)
+{
+       struct uwb_rc *rc = i1480u->wlp.rc;
+       usb_set_intfdata(i1480u->usb_iface, NULL);
+#ifdef i1480u_FLOW_CONTROL
+       usb_kill_urb(i1480u->notif_urb);
+       usb_free_urb(i1480u->notif_urb);
+#endif
+       wlp_remove(&i1480u->wlp);
+       uwb_rc_put(rc);
+       usb_put_dev(i1480u->usb_dev);
+}
+
+/** Just setup @net_dev's i1480u private data */
+static void i1480u_netdev_setup(struct net_device *net_dev)
+{
+       struct i1480u *i1480u = netdev_priv(net_dev);
+       /* Initialize @i1480u */
+       memset(i1480u, 0, sizeof(*i1480u));
+       i1480u_init(i1480u);
+}
+
+/**
+ * Probe a i1480u interface and register it
+ *
+ * @iface:   USB interface to link to
+ * @id:      USB class/subclass/protocol id
+ * @returns: 0 if ok, < 0 errno code on error.
+ *
+ * Does basic housekeeping stuff and then allocs a netdev with space
+ * for the i1480u  data. Initializes, registers in i1480u, registers in
+ * netdev, ready to go.
+ */
+static int i1480u_probe(struct usb_interface *iface,
+                       const struct usb_device_id *id)
+{
+       int result;
+       struct net_device *net_dev;
+       struct device *dev = &iface->dev;
+       struct i1480u *i1480u;
+
+       /* Allocate instance [calls i1480u_netdev_setup() on it] */
+       result = -ENOMEM;
+       net_dev = alloc_netdev(sizeof(*i1480u), "wlp%d", i1480u_netdev_setup);
+       if (net_dev == NULL) {
+               dev_err(dev, "no memory for network device instance\n");
+               goto error_alloc_netdev;
+       }
+       SET_NETDEV_DEV(net_dev, dev);
+       i1480u = netdev_priv(net_dev);
+       i1480u->net_dev = net_dev;
+       result = i1480u_add(i1480u, iface);     /* Now setup all the wlp stuff */
+       if (result < 0) {
+               dev_err(dev, "cannot add i1480u device: %d\n", result);
+               goto error_i1480u_add;
+       }
+       result = register_netdev(net_dev);      /* Okey dokey, bring it up */
+       if (result < 0) {
+               dev_err(dev, "cannot register network device: %d\n", result);
+               goto error_register_netdev;
+       }
+       i1480u_sysfs_setup(i1480u);
+       if (result < 0)
+               goto error_sysfs_init;
+       return 0;
+
+error_sysfs_init:
+       unregister_netdev(net_dev);
+error_register_netdev:
+       i1480u_rm(i1480u);
+error_i1480u_add:
+       free_netdev(net_dev);
+error_alloc_netdev:
+       return result;
+}
+
+
+/**
+ * Disconect a i1480u from the system.
+ *
+ * i1480u_stop() has been called before, so al the rx and tx contexts
+ * have been taken down already. Make sure the queue is stopped,
+ * unregister netdev and i1480u, free and kill.
+ */
+static void i1480u_disconnect(struct usb_interface *iface)
+{
+       struct i1480u *i1480u;
+       struct net_device *net_dev;
+
+       i1480u = usb_get_intfdata(iface);
+       net_dev = i1480u->net_dev;
+       netif_stop_queue(net_dev);
+#ifdef i1480u_FLOW_CONTROL
+       usb_kill_urb(i1480u->notif_urb);
+#endif
+       i1480u_sysfs_release(i1480u);
+       unregister_netdev(net_dev);
+       i1480u_rm(i1480u);
+       free_netdev(net_dev);
+}
+
+static struct usb_device_id i1480u_id_table[] = {
+       {
+               .match_flags = USB_DEVICE_ID_MATCH_DEVICE \
+                               |  USB_DEVICE_ID_MATCH_DEV_INFO \
+                               |  USB_DEVICE_ID_MATCH_INT_INFO,
+               .idVendor = 0x8086,
+               .idProduct = 0x0c3b,
+               .bDeviceClass = 0xef,
+               .bDeviceSubClass = 0x02,
+               .bDeviceProtocol = 0x02,
+               .bInterfaceClass = 0xff,
+               .bInterfaceSubClass = 0xff,
+               .bInterfaceProtocol = 0xff,
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(usb, i1480u_id_table);
+
+static struct usb_driver i1480u_driver = {
+       .name =         KBUILD_MODNAME,
+       .probe =        i1480u_probe,
+       .disconnect =   i1480u_disconnect,
+       .id_table =     i1480u_id_table,
+};
+
+static int __init i1480u_driver_init(void)
+{
+       return usb_register(&i1480u_driver);
+}
+module_init(i1480u_driver_init);
+
+
+static void __exit i1480u_driver_exit(void)
+{
+       usb_deregister(&i1480u_driver);
+}
+module_exit(i1480u_driver_exit);
+
+MODULE_AUTHOR("Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>");
+MODULE_DESCRIPTION("i1480 Wireless UWB Link WLP networking for USB");
+MODULE_LICENSE("GPL");
diff --git a/drivers/uwb/i1480/i1480u-wlp/netdev.c b/drivers/uwb/i1480/i1480u-wlp/netdev.c
new file mode 100644 (file)
index 0000000..8802ac4
--- /dev/null
@@ -0,0 +1,368 @@
+/*
+ * WUSB Wire Adapter: WLP interface
+ * Driver for the Linux Network stack.
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ *
+ * Implementation of the netdevice linkage (except tx and rx related stuff).
+ *
+ * ROADMAP:
+ *
+ *   ENTRY POINTS (Net device):
+ *
+ *     i1480u_open(): Called when we ifconfig up the interface;
+ *                    associates to a UWB host controller, reserves
+ *                    bandwidth (MAS), sets up RX USB URB and starts
+ *                    the queue.
+ *
+ *     i1480u_stop(): Called when we ifconfig down a interface;
+ *                    reverses _open().
+ *
+ *     i1480u_set_config():
+ */
+
+#include <linux/if_arp.h>
+#include <linux/etherdevice.h>
+#include <linux/uwb/debug.h>
+#include "i1480u-wlp.h"
+
+struct i1480u_cmd_set_ip_mas {
+       struct uwb_rccb     rccb;
+       struct uwb_dev_addr addr;
+       u8                  stream;
+       u8                  owner;
+       u8                  type;       /* enum uwb_drp_type */
+       u8                  baMAS[32];
+} __attribute__((packed));
+
+
+static
+int i1480u_set_ip_mas(
+       struct uwb_rc *rc,
+       const struct uwb_dev_addr *dstaddr,
+       u8 stream, u8 owner, u8 type, unsigned long *mas)
+{
+
+       int result;
+       struct i1480u_cmd_set_ip_mas *cmd;
+       struct uwb_rc_evt_confirm reply;
+
+       result = -ENOMEM;
+       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+       if (cmd == NULL)
+               goto error_kzalloc;
+       cmd->rccb.bCommandType = 0xfd;
+       cmd->rccb.wCommand = cpu_to_le16(0x000e);
+       cmd->addr = *dstaddr;
+       cmd->stream = stream;
+       cmd->owner = owner;
+       cmd->type = type;
+       if (mas == NULL)
+               memset(cmd->baMAS, 0x00, sizeof(cmd->baMAS));
+       else
+               memcpy(cmd->baMAS, mas, sizeof(cmd->baMAS));
+       reply.rceb.bEventType = 0xfd;
+       reply.rceb.wEvent = cpu_to_le16(0x000e);
+       result = uwb_rc_cmd(rc, "SET-IP-MAS", &cmd->rccb, sizeof(*cmd),
+                           &reply.rceb, sizeof(reply));
+       if (result < 0)
+               goto error_cmd;
+       if (reply.bResultCode != UWB_RC_RES_FAIL) {
+               dev_err(&rc->uwb_dev.dev,
+                       "SET-IP-MAS: command execution failed: %d\n",
+                       reply.bResultCode);
+               result = -EIO;
+       }
+error_cmd:
+       kfree(cmd);
+error_kzalloc:
+       return result;
+}
+
+/*
+ * Inform a WLP interface of a MAS reservation
+ *
+ * @rc is assumed refcnted.
+ */
+/* FIXME: detect if remote device is WLP capable? */
+static int i1480u_mas_set_dev(struct uwb_dev *uwb_dev, struct uwb_rc *rc,
+                             u8 stream, u8 owner, u8 type, unsigned long *mas)
+{
+       int result = 0;
+       struct device *dev = &rc->uwb_dev.dev;
+
+       result = i1480u_set_ip_mas(rc, &uwb_dev->dev_addr, stream, owner,
+                                  type, mas);
+       if (result < 0) {
+               char rcaddrbuf[UWB_ADDR_STRSIZE], devaddrbuf[UWB_ADDR_STRSIZE];
+               uwb_dev_addr_print(rcaddrbuf, sizeof(rcaddrbuf),
+                                  &rc->uwb_dev.dev_addr);
+               uwb_dev_addr_print(devaddrbuf, sizeof(devaddrbuf),
+                                  &uwb_dev->dev_addr);
+               dev_err(dev, "Set IP MAS (%s to %s) failed: %d\n",
+                       rcaddrbuf, devaddrbuf, result);
+       }
+       return result;
+}
+
+/**
+ * Called by bandwidth allocator when change occurs in reservation.
+ *
+ * @rsv:     The reservation that is being established, modified, or
+ *           terminated.
+ *
+ * When a reservation is established, modified, or terminated the upper layer
+ * (WLP here) needs set/update the currently available Media Access Slots
+ * that can be use for IP traffic.
+ *
+ * Our action taken during failure depends on how the reservation is being
+ * changed:
+ * - if reservation is being established we do nothing if we cannot set the
+ *   new MAS to be used
+ * - if reservation is being terminated we revert back to PCA whether the
+ *   SET IP MAS command succeeds or not.
+ */
+void i1480u_bw_alloc_cb(struct uwb_rsv *rsv)
+{
+       int result = 0;
+       struct i1480u *i1480u = rsv->pal_priv;
+       struct device *dev = &i1480u->usb_iface->dev;
+       struct uwb_dev *target_dev = rsv->target.dev;
+       struct uwb_rc *rc = i1480u->wlp.rc;
+       u8 stream = rsv->stream;
+       int type = rsv->type;
+       int is_owner = rsv->owner == &rc->uwb_dev;
+       unsigned long *bmp = rsv->mas.bm;
+
+       dev_err(dev, "WLP callback called - sending set ip mas\n");
+       /*user cannot change options while setting configuration*/
+       mutex_lock(&i1480u->options.mutex);
+       switch (rsv->state) {
+       case UWB_RSV_STATE_T_ACCEPTED:
+       case UWB_RSV_STATE_O_ESTABLISHED:
+               result = i1480u_mas_set_dev(target_dev, rc, stream, is_owner,
+                                       type, bmp);
+               if (result < 0) {
+                       dev_err(dev, "MAS reservation failed: %d\n", result);
+                       goto out;
+               }
+               if (is_owner) {
+                       wlp_tx_hdr_set_delivery_id_type(&i1480u->options.def_tx_hdr,
+                                                       WLP_DRP | stream);
+                       wlp_tx_hdr_set_rts_cts(&i1480u->options.def_tx_hdr, 0);
+               }
+               break;
+       case UWB_RSV_STATE_NONE:
+               /* revert back to PCA */
+               result = i1480u_mas_set_dev(target_dev, rc, stream, is_owner,
+                                           type, bmp);
+               if (result < 0)
+                       dev_err(dev, "MAS reservation failed: %d\n", result);
+               /* Revert to PCA even though SET IP MAS failed. */
+               wlp_tx_hdr_set_delivery_id_type(&i1480u->options.def_tx_hdr,
+                                               i1480u->options.pca_base_priority);
+               wlp_tx_hdr_set_rts_cts(&i1480u->options.def_tx_hdr, 1);
+               break;
+       default:
+               dev_err(dev, "unexpected WLP reservation state: %s (%d).\n",
+                       uwb_rsv_state_str(rsv->state), rsv->state);
+               break;
+       }
+out:
+       mutex_unlock(&i1480u->options.mutex);
+       return;
+}
+
+/**
+ *
+ * Called on 'ifconfig up'
+ */
+int i1480u_open(struct net_device *net_dev)
+{
+       int result;
+       struct i1480u *i1480u = netdev_priv(net_dev);
+       struct wlp *wlp = &i1480u->wlp;
+       struct uwb_rc *rc;
+       struct device *dev = &i1480u->usb_iface->dev;
+
+       rc = wlp->rc;
+       result = i1480u_rx_setup(i1480u);               /* Alloc RX stuff */
+       if (result < 0)
+               goto error_rx_setup;
+       netif_wake_queue(net_dev);
+#ifdef i1480u_FLOW_CONTROL
+       result = usb_submit_urb(i1480u->notif_urb, GFP_KERNEL);;
+       if (result < 0) {
+               dev_err(dev, "Can't submit notification URB: %d\n", result);
+               goto error_notif_urb_submit;
+       }
+#endif
+       i1480u->uwb_notifs_handler.cb = i1480u_uwb_notifs_cb;
+       i1480u->uwb_notifs_handler.data = i1480u;
+       if (uwb_bg_joined(rc))
+               netif_carrier_on(net_dev);
+       else
+               netif_carrier_off(net_dev);
+       uwb_notifs_register(rc, &i1480u->uwb_notifs_handler);
+       /* Interface is up with an address, now we can create WSS */
+       result = wlp_wss_setup(net_dev, &wlp->wss);
+       if (result < 0) {
+               dev_err(dev, "Can't create WSS: %d. \n", result);
+               goto error_notif_deregister;
+       }
+       return 0;
+error_notif_deregister:
+       uwb_notifs_deregister(rc, &i1480u->uwb_notifs_handler);
+#ifdef i1480u_FLOW_CONTROL
+error_notif_urb_submit:
+#endif
+       netif_stop_queue(net_dev);
+       i1480u_rx_release(i1480u);
+error_rx_setup:
+       return result;
+}
+
+
+/**
+ * Called on 'ifconfig down'
+ */
+int i1480u_stop(struct net_device *net_dev)
+{
+       struct i1480u *i1480u = netdev_priv(net_dev);
+       struct wlp *wlp = &i1480u->wlp;
+       struct uwb_rc *rc = wlp->rc;
+
+       BUG_ON(wlp->rc == NULL);
+       wlp_wss_remove(&wlp->wss);
+       uwb_notifs_deregister(rc, &i1480u->uwb_notifs_handler);
+       netif_carrier_off(net_dev);
+#ifdef i1480u_FLOW_CONTROL
+       usb_kill_urb(i1480u->notif_urb);
+#endif
+       netif_stop_queue(net_dev);
+       i1480u_rx_release(i1480u);
+       i1480u_tx_release(i1480u);
+       return 0;
+}
+
+
+/** Report statistics */
+struct net_device_stats *i1480u_get_stats(struct net_device *net_dev)
+{
+       struct i1480u *i1480u = netdev_priv(net_dev);
+       return &i1480u->stats;
+}
+
+
+/**
+ *
+ * Change the interface config--we probably don't have to do anything.
+ */
+int i1480u_set_config(struct net_device *net_dev, struct ifmap *map)
+{
+       int result;
+       struct i1480u *i1480u = netdev_priv(net_dev);
+       BUG_ON(i1480u->wlp.rc == NULL);
+       result = 0;
+       return result;
+}
+
+/**
+ * Change the MTU of the interface
+ */
+int i1480u_change_mtu(struct net_device *net_dev, int mtu)
+{
+       static union {
+               struct wlp_tx_hdr tx;
+               struct wlp_rx_hdr rx;
+       } i1480u_all_hdrs;
+
+       if (mtu < ETH_HLEN)     /* We encap eth frames */
+               return -ERANGE;
+       if (mtu > 4000 - sizeof(i1480u_all_hdrs))
+               return -ERANGE;
+       net_dev->mtu = mtu;
+       return 0;
+}
+
+
+/**
+ * Callback function to handle events from UWB
+ * When we see other devices we know the carrier is ok,
+ * if we are the only device in the beacon group we set the carrier
+ * state to off.
+ * */
+void i1480u_uwb_notifs_cb(void *data, struct uwb_dev *uwb_dev,
+                         enum uwb_notifs event)
+{
+       struct i1480u *i1480u = data;
+       struct net_device *net_dev = i1480u->net_dev;
+       struct device *dev = &i1480u->usb_iface->dev;
+       switch (event) {
+       case UWB_NOTIF_BG_JOIN:
+               netif_carrier_on(net_dev);
+               dev_info(dev, "Link is up\n");
+               break;
+       case UWB_NOTIF_BG_LEAVE:
+               netif_carrier_off(net_dev);
+               dev_info(dev, "Link is down\n");
+               break;
+       default:
+               dev_err(dev, "don't know how to handle event %d from uwb\n",
+                               event);
+       }
+}
+
+/**
+ * Stop the network queue
+ *
+ * Enable WLP substack to stop network queue. We also set the flow control
+ * threshold at this time to prevent the flow control from restarting the
+ * queue.
+ *
+ * we are loosing the current threshold value here ... FIXME?
+ */
+void i1480u_stop_queue(struct wlp *wlp)
+{
+       struct i1480u *i1480u = container_of(wlp, struct i1480u, wlp);
+       struct net_device *net_dev = i1480u->net_dev;
+       i1480u->tx_inflight.threshold = 0;
+       netif_stop_queue(net_dev);
+}
+
+/**
+ * Start the network queue
+ *
+ * Enable WLP substack to start network queue. Also re-enable the flow
+ * control to manage the queue again.
+ *
+ * We re-enable the flow control by storing the default threshold in the
+ * flow control threshold. This means that if the user modified the
+ * threshold before the queue was stopped and restarted that information
+ * will be lost. FIXME?
+ */
+void i1480u_start_queue(struct wlp *wlp)
+{
+       struct i1480u *i1480u = container_of(wlp, struct i1480u, wlp);
+       struct net_device *net_dev = i1480u->net_dev;
+       i1480u->tx_inflight.threshold = i1480u_TX_INFLIGHT_THRESHOLD;
+       netif_start_queue(net_dev);
+}
diff --git a/drivers/uwb/i1480/i1480u-wlp/rx.c b/drivers/uwb/i1480/i1480u-wlp/rx.c
new file mode 100644 (file)
index 0000000..9fc0353
--- /dev/null
@@ -0,0 +1,486 @@
+/*
+ * WUSB Wire Adapter: WLP interface
+ * Driver for the Linux Network stack.
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * i1480u's RX handling is simple. i1480u will send the received
+ * network packets broken up in fragments; 1 to N fragments make a
+ * packet, we assemble them together and deliver the packet with netif_rx().
+ *
+ * Beacuse each USB transfer is a *single* fragment (except when the
+ * transfer contains a first fragment), each URB called thus
+ * back contains one or two fragments. So we queue N URBs, each with its own
+ * fragment buffer. When a URB is done, we process it (adding to the
+ * current skb from the fragment buffer until complete). Once
+ * processed, we requeue the URB. There is always a bunch of URBs
+ * ready to take data, so the intergap should be minimal.
+ *
+ * An URB's transfer buffer is the data field of a socket buffer. This
+ * reduces copying as data can be passed directly to network layer. If a
+ * complete packet or 1st fragment is received the URB's transfer buffer is
+ * taken away from it and used to send data to the network layer. In this
+ * case a new transfer buffer is allocated to the URB before being requeued.
+ * If a "NEXT" or "LAST" fragment is received, the fragment contents is
+ * appended to the RX packet under construction and the transfer buffer
+ * is reused. To be able to use this buffer to assemble complete packets
+ * we set each buffer's size to that of the MAX ethernet packet that can
+ * be received. There is thus room for improvement in memory usage.
+ *
+ * When the max tx fragment size increases, we should be able to read
+ * data into the skbs directly with very simple code.
+ *
+ * ROADMAP:
+ *
+ *   ENTRY POINTS:
+ *
+ *     i1480u_rx_setup(): setup RX context [from i1480u_open()]
+ *
+ *     i1480u_rx_release(): release RX context [from i1480u_stop()]
+ *
+ *     i1480u_rx_cb(): called when the RX USB URB receives a
+ *                     packet. It removes the header and pushes it up
+ *                     the Linux netdev stack with netif_rx().
+ *
+ *       i1480u_rx_buffer()
+ *         i1480u_drop() and i1480u_fix()
+ *         i1480u_skb_deliver
+ *
+ */
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include "i1480u-wlp.h"
+
+#define D_LOCAL 0
+#include <linux/uwb/debug.h>
+
+
+/**
+ * Setup the RX context
+ *
+ * Each URB is provided with a transfer_buffer that is the data field
+ * of a new socket buffer.
+ */
+int i1480u_rx_setup(struct i1480u *i1480u)
+{
+       int result, cnt;
+       struct device *dev = &i1480u->usb_iface->dev;
+       struct net_device *net_dev = i1480u->net_dev;
+       struct usb_endpoint_descriptor *epd;
+       struct sk_buff *skb;
+
+       /* Alloc RX stuff */
+       i1480u->rx_skb = NULL;  /* not in process of receiving packet */
+       result = -ENOMEM;
+       epd = &i1480u->usb_iface->cur_altsetting->endpoint[1].desc;
+       for (cnt = 0; cnt < i1480u_RX_BUFS; cnt++) {
+               struct i1480u_rx_buf *rx_buf = &i1480u->rx_buf[cnt];
+               rx_buf->i1480u = i1480u;
+               skb = dev_alloc_skb(i1480u_MAX_RX_PKT_SIZE);
+               if (!skb) {
+                       dev_err(dev,
+                               "RX: cannot allocate RX buffer %d\n", cnt);
+                       result = -ENOMEM;
+                       goto error;
+               }
+               skb->dev = net_dev;
+               skb->ip_summed = CHECKSUM_NONE;
+               skb_reserve(skb, 2);
+               rx_buf->data = skb;
+               rx_buf->urb = usb_alloc_urb(0, GFP_KERNEL);
+               if (unlikely(rx_buf->urb == NULL)) {
+                       dev_err(dev, "RX: cannot allocate URB %d\n", cnt);
+                       result = -ENOMEM;
+                       goto error;
+               }
+               usb_fill_bulk_urb(rx_buf->urb, i1480u->usb_dev,
+                         usb_rcvbulkpipe(i1480u->usb_dev, epd->bEndpointAddress),
+                         rx_buf->data->data, i1480u_MAX_RX_PKT_SIZE - 2,
+                         i1480u_rx_cb, rx_buf);
+               result = usb_submit_urb(rx_buf->urb, GFP_NOIO);
+               if (unlikely(result < 0)) {
+                       dev_err(dev, "RX: cannot submit URB %d: %d\n",
+                               cnt, result);
+                       goto error;
+               }
+       }
+       return 0;
+
+error:
+       i1480u_rx_release(i1480u);
+       return result;
+}
+
+
+/** Release resources associated to the rx context */
+void i1480u_rx_release(struct i1480u *i1480u)
+{
+       int cnt;
+       for (cnt = 0; cnt < i1480u_RX_BUFS; cnt++) {
+               if (i1480u->rx_buf[cnt].data)
+                       dev_kfree_skb(i1480u->rx_buf[cnt].data);
+               if (i1480u->rx_buf[cnt].urb) {
+                       usb_kill_urb(i1480u->rx_buf[cnt].urb);
+                       usb_free_urb(i1480u->rx_buf[cnt].urb);
+               }
+       }
+       if (i1480u->rx_skb != NULL)
+               dev_kfree_skb(i1480u->rx_skb);
+}
+
+static
+void i1480u_rx_unlink_urbs(struct i1480u *i1480u)
+{
+       int cnt;
+       for (cnt = 0; cnt < i1480u_RX_BUFS; cnt++) {
+               if (i1480u->rx_buf[cnt].urb)
+                       usb_unlink_urb(i1480u->rx_buf[cnt].urb);
+       }
+}
+
+/** Fix an out-of-sequence packet */
+#define i1480u_fix(i1480u, msg...)                     \
+do {                                                   \
+       if (printk_ratelimit())                         \
+               dev_err(&i1480u->usb_iface->dev, msg);  \
+       dev_kfree_skb_irq(i1480u->rx_skb);              \
+       i1480u->rx_skb = NULL;                          \
+       i1480u->rx_untd_pkt_size = 0;                   \
+} while (0)
+
+
+/** Drop an out-of-sequence packet */
+#define i1480u_drop(i1480u, msg...)                    \
+do {                                                   \
+       if (printk_ratelimit())                         \
+               dev_err(&i1480u->usb_iface->dev, msg);  \
+       i1480u->stats.rx_dropped++;                     \
+} while (0)
+
+
+
+
+/** Finalizes setting up the SKB and delivers it
+ *
+ * We first pass the incoming frame to WLP substack for verification. It
+ * may also be a WLP association frame in which case WLP will take over the
+ * processing. If WLP does not take it over it will still verify it, if the
+ * frame is invalid the skb will be freed by WLP and we will not continue
+ * parsing.
+ * */
+static
+void i1480u_skb_deliver(struct i1480u *i1480u)
+{
+       int should_parse;
+       struct net_device *net_dev = i1480u->net_dev;
+       struct device *dev = &i1480u->usb_iface->dev;
+
+       d_printf(6, dev, "RX delivered pre skb(%p), %u bytes\n",
+                i1480u->rx_skb, i1480u->rx_skb->len);
+       d_dump(7, dev, i1480u->rx_skb->data, i1480u->rx_skb->len);
+       should_parse = wlp_receive_frame(dev, &i1480u->wlp, i1480u->rx_skb,
+                                        &i1480u->rx_srcaddr);
+       if (!should_parse)
+               goto out;
+       i1480u->rx_skb->protocol = eth_type_trans(i1480u->rx_skb, net_dev);
+       d_printf(5, dev, "RX delivered skb(%p), %u bytes\n",
+                i1480u->rx_skb, i1480u->rx_skb->len);
+       d_dump(7, dev, i1480u->rx_skb->data,
+              i1480u->rx_skb->len > 72 ? 72 : i1480u->rx_skb->len);
+       i1480u->stats.rx_packets++;
+       i1480u->stats.rx_bytes += i1480u->rx_untd_pkt_size;
+       net_dev->last_rx = jiffies;
+       /* FIXME: flow control: check netif_rx() retval */
+
+       netif_rx(i1480u->rx_skb);               /* deliver */
+out:
+       i1480u->rx_skb = NULL;
+       i1480u->rx_untd_pkt_size = 0;
+}
+
+
+/**
+ * Process a buffer of data received from the USB RX endpoint
+ *
+ * First fragment arrives with next or last fragment. All other fragments
+ * arrive alone.
+ *
+ * /me hates long functions.
+ */
+static
+void i1480u_rx_buffer(struct i1480u_rx_buf *rx_buf)
+{
+       unsigned pkt_completed = 0;     /* !0 when we got all pkt fragments */
+       size_t untd_hdr_size, untd_frg_size;
+       size_t i1480u_hdr_size;
+       struct wlp_rx_hdr *i1480u_hdr = NULL;
+
+       struct i1480u *i1480u = rx_buf->i1480u;
+       struct sk_buff *skb = rx_buf->data;
+       int size_left = rx_buf->urb->actual_length;
+       void *ptr = rx_buf->urb->transfer_buffer; /* also rx_buf->data->data */
+       struct untd_hdr *untd_hdr;
+
+       struct net_device *net_dev = i1480u->net_dev;
+       struct device *dev = &i1480u->usb_iface->dev;
+       struct sk_buff *new_skb;
+
+#if 0
+       dev_fnstart(dev,
+                   "(i1480u %p ptr %p size_left %zu)\n", i1480u, ptr, size_left);
+       dev_err(dev, "RX packet, %zu bytes\n", size_left);
+       dump_bytes(dev, ptr, size_left);
+#endif
+       i1480u_hdr_size = sizeof(struct wlp_rx_hdr);
+
+       while (size_left > 0) {
+               if (pkt_completed) {
+                       i1480u_drop(i1480u, "RX: fragment follows completed"
+                                        "packet in same buffer. Dropping\n");
+                       break;
+               }
+               untd_hdr = ptr;
+               if (size_left < sizeof(*untd_hdr)) {    /*  Check the UNTD header */
+                       i1480u_drop(i1480u, "RX: short UNTD header! Dropping\n");
+                       goto out;
+               }
+               if (unlikely(untd_hdr_rx_tx(untd_hdr) == 0)) {  /* Paranoia: TX set? */
+                       i1480u_drop(i1480u, "RX: TX bit set! Dropping\n");
+                       goto out;
+               }
+               switch (untd_hdr_type(untd_hdr)) {      /* Check the UNTD header type */
+               case i1480u_PKT_FRAG_1ST: {
+                       struct untd_hdr_1st *untd_hdr_1st = (void *) untd_hdr;
+                       dev_dbg(dev, "1st fragment\n");
+                       untd_hdr_size = sizeof(struct untd_hdr_1st);
+                       if (i1480u->rx_skb != NULL)
+                               i1480u_fix(i1480u, "RX: 1st fragment out of "
+                                       "sequence! Fixing\n");
+                       if (size_left < untd_hdr_size + i1480u_hdr_size) {
+                               i1480u_drop(i1480u, "RX: short 1st fragment! "
+                                       "Dropping\n");
+                               goto out;
+                       }
+                       i1480u->rx_untd_pkt_size = le16_to_cpu(untd_hdr->len)
+                                                - i1480u_hdr_size;
+                       untd_frg_size = le16_to_cpu(untd_hdr_1st->fragment_len);
+                       if (size_left < untd_hdr_size + untd_frg_size) {
+                               i1480u_drop(i1480u,
+                                           "RX: short payload! Dropping\n");
+                               goto out;
+                       }
+                       i1480u->rx_skb = skb;
+                       i1480u_hdr = (void *) untd_hdr_1st + untd_hdr_size;
+                       i1480u->rx_srcaddr = i1480u_hdr->srcaddr;
+                       skb_put(i1480u->rx_skb, untd_hdr_size + untd_frg_size);
+                       skb_pull(i1480u->rx_skb, untd_hdr_size + i1480u_hdr_size);
+                       stats_add_sample(&i1480u->lqe_stats, (s8) i1480u_hdr->LQI - 7);
+                       stats_add_sample(&i1480u->rssi_stats, i1480u_hdr->RSSI + 18);
+                       rx_buf->data = NULL; /* need to create new buffer */
+                       break;
+               }
+               case i1480u_PKT_FRAG_NXT: {
+                       dev_dbg(dev, "nxt fragment\n");
+                       untd_hdr_size = sizeof(struct untd_hdr_rst);
+                       if (i1480u->rx_skb == NULL) {
+                               i1480u_drop(i1480u, "RX: next fragment out of "
+                                           "sequence! Dropping\n");
+                               goto out;
+                       }
+                       if (size_left < untd_hdr_size) {
+                               i1480u_drop(i1480u, "RX: short NXT fragment! "
+                                           "Dropping\n");
+                               goto out;
+                       }
+                       untd_frg_size = le16_to_cpu(untd_hdr->len);
+                       if (size_left < untd_hdr_size + untd_frg_size) {
+                               i1480u_drop(i1480u,
+                                           "RX: short payload! Dropping\n");
+                               goto out;
+                       }
+                       memmove(skb_put(i1480u->rx_skb, untd_frg_size),
+                                       ptr + untd_hdr_size, untd_frg_size);
+                       break;
+               }
+               case i1480u_PKT_FRAG_LST: {
+                       dev_dbg(dev, "Lst fragment\n");
+                       untd_hdr_size = sizeof(struct untd_hdr_rst);
+                       if (i1480u->rx_skb == NULL) {
+                               i1480u_drop(i1480u, "RX: last fragment out of "
+                                           "sequence! Dropping\n");
+                               goto out;
+                       }
+                       if (size_left < untd_hdr_size) {
+                               i1480u_drop(i1480u, "RX: short LST fragment! "
+                                           "Dropping\n");
+                               goto out;
+                       }
+                       untd_frg_size = le16_to_cpu(untd_hdr->len);
+                       if (size_left < untd_frg_size + untd_hdr_size) {
+                               i1480u_drop(i1480u,
+                                           "RX: short payload! Dropping\n");
+                               goto out;
+                       }
+                       memmove(skb_put(i1480u->rx_skb, untd_frg_size),
+                                       ptr + untd_hdr_size, untd_frg_size);
+                       pkt_completed = 1;
+                       break;
+               }
+               case i1480u_PKT_FRAG_CMP: {
+                       dev_dbg(dev, "cmp fragment\n");
+                       untd_hdr_size = sizeof(struct untd_hdr_cmp);
+                       if (i1480u->rx_skb != NULL)
+                               i1480u_fix(i1480u, "RX: fix out-of-sequence CMP"
+                                          " fragment!\n");
+                       if (size_left < untd_hdr_size + i1480u_hdr_size) {
+                               i1480u_drop(i1480u, "RX: short CMP fragment! "
+                                           "Dropping\n");
+                               goto out;
+                       }
+                       i1480u->rx_untd_pkt_size = le16_to_cpu(untd_hdr->len);
+                       untd_frg_size = i1480u->rx_untd_pkt_size;
+                       if (size_left < i1480u->rx_untd_pkt_size + untd_hdr_size) {
+                               i1480u_drop(i1480u,
+                                           "RX: short payload! Dropping\n");
+                               goto out;
+                       }
+                       i1480u->rx_skb = skb;
+                       i1480u_hdr = (void *) untd_hdr + untd_hdr_size;
+                       i1480u->rx_srcaddr = i1480u_hdr->srcaddr;
+                       stats_add_sample(&i1480u->lqe_stats, (s8) i1480u_hdr->LQI - 7);
+                       stats_add_sample(&i1480u->rssi_stats, i1480u_hdr->RSSI + 18);
+                       skb_put(i1480u->rx_skb, untd_hdr_size + i1480u->rx_untd_pkt_size);
+                       skb_pull(i1480u->rx_skb, untd_hdr_size + i1480u_hdr_size);
+                       rx_buf->data = NULL;    /* for hand off skb to network stack */
+                       pkt_completed = 1;
+                       i1480u->rx_untd_pkt_size -= i1480u_hdr_size; /* accurate stat */
+                       break;
+               }
+               default:
+                       i1480u_drop(i1480u, "RX: unknown packet type %u! "
+                                   "Dropping\n", untd_hdr_type(untd_hdr));
+                       goto out;
+               }
+               size_left -= untd_hdr_size + untd_frg_size;
+               if (size_left > 0)
+                       ptr += untd_hdr_size + untd_frg_size;
+       }
+       if (pkt_completed)
+               i1480u_skb_deliver(i1480u);
+out:
+       /* recreate needed RX buffers*/
+       if (rx_buf->data == NULL) {
+               /* buffer is being used to receive packet, create new */
+               new_skb = dev_alloc_skb(i1480u_MAX_RX_PKT_SIZE);
+               if (!new_skb) {
+                       if (printk_ratelimit())
+                               dev_err(dev,
+                               "RX: cannot allocate RX buffer\n");
+               } else {
+                       new_skb->dev = net_dev;
+                       new_skb->ip_summed = CHECKSUM_NONE;
+                       skb_reserve(new_skb, 2);
+                       rx_buf->data = new_skb;
+               }
+       }
+       return;
+}
+
+
+/**
+ * Called when an RX URB has finished receiving or has found some kind
+ * of error condition.
+ *
+ * LIMITATIONS:
+ *
+ *  - We read USB-transfers, each transfer contains a SINGLE fragment
+ *    (can contain a complete packet, or a 1st, next, or last fragment
+ *    of a packet).
+ *    Looks like a transfer can contain more than one fragment (07/18/06)
+ *
+ *  - Each transfer buffer is the size of the maximum packet size (minus
+ *    headroom), i1480u_MAX_PKT_SIZE - 2
+ *
+ *  - We always read the full USB-transfer, no partials.
+ *
+ *  - Each transfer is read directly into a skb. This skb will be used to
+ *    send data to the upper layers if it is the first fragment or a complete
+ *    packet. In the other cases the data will be copied from the skb to
+ *    another skb that is being prepared for the upper layers from a prev
+ *    first fragment.
+ *
+ * It is simply too much of a pain. Gosh, there should be a unified
+ * SG infrastructure for *everything* [so that I could declare a SG
+ * buffer, pass it to USB for receiving, append some space to it if
+ * I wish, receive more until I have the whole chunk, adapt
+ * pointers on each fragment to remove hardware headers and then
+ * attach that to an skbuff and netif_rx()].
+ */
+void i1480u_rx_cb(struct urb *urb)
+{
+       int result;
+       int do_parse_buffer = 1;
+       struct i1480u_rx_buf *rx_buf = urb->context;
+       struct i1480u *i1480u = rx_buf->i1480u;
+       struct device *dev = &i1480u->usb_iface->dev;
+       unsigned long flags;
+       u8 rx_buf_idx = rx_buf - i1480u->rx_buf;
+
+       switch (urb->status) {
+       case 0:
+               break;
+       case -ECONNRESET:       /* Not an error, but a controlled situation; */
+       case -ENOENT:           /* (we killed the URB)...so, no broadcast */
+       case -ESHUTDOWN:        /* going away! */
+               dev_err(dev, "RX URB[%u]: goind down %d\n",
+                       rx_buf_idx, urb->status);
+               goto error;
+       default:
+               dev_err(dev, "RX URB[%u]: unknown status %d\n",
+                       rx_buf_idx, urb->status);
+               if (edc_inc(&i1480u->rx_errors, EDC_MAX_ERRORS,
+                                       EDC_ERROR_TIMEFRAME)) {
+                       dev_err(dev, "RX: max acceptable errors exceeded,"
+                                       " resetting device.\n");
+                       i1480u_rx_unlink_urbs(i1480u);
+                       wlp_reset_all(&i1480u->wlp);
+                       goto error;
+               }
+               do_parse_buffer = 0;
+               break;
+       }
+       spin_lock_irqsave(&i1480u->lock, flags);
+       /* chew the data fragments, extract network packets */
+       if (do_parse_buffer) {
+               i1480u_rx_buffer(rx_buf);
+               if (rx_buf->data) {
+                       rx_buf->urb->transfer_buffer = rx_buf->data->data;
+                       result = usb_submit_urb(rx_buf->urb, GFP_ATOMIC);
+                       if (result < 0) {
+                               dev_err(dev, "RX URB[%u]: cannot submit %d\n",
+                                       rx_buf_idx, result);
+                       }
+               }
+       }
+       spin_unlock_irqrestore(&i1480u->lock, flags);
+error:
+       return;
+}
+
diff --git a/drivers/uwb/i1480/i1480u-wlp/sysfs.c b/drivers/uwb/i1480/i1480u-wlp/sysfs.c
new file mode 100644 (file)
index 0000000..a1d8ca6
--- /dev/null
@@ -0,0 +1,408 @@
+/*
+ * WUSB Wire Adapter: WLP interface
+ * Sysfs interfaces
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ */
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/uwb/debug.h>
+#include <linux/device.h>
+#include "i1480u-wlp.h"
+
+
+/**
+ *
+ * @dev: Class device from the net_device; assumed refcnted.
+ *
+ * Yes, I don't lock--we assume it is refcounted and I am getting a
+ * single byte value that is kind of atomic to read.
+ */
+ssize_t uwb_phy_rate_show(const struct wlp_options *options, char *buf)
+{
+       return sprintf(buf, "%u\n",
+                      wlp_tx_hdr_phy_rate(&options->def_tx_hdr));
+}
+EXPORT_SYMBOL_GPL(uwb_phy_rate_show);
+
+
+ssize_t uwb_phy_rate_store(struct wlp_options *options,
+                          const char *buf, size_t size)
+{
+       ssize_t result;
+       unsigned rate;
+
+       result = sscanf(buf, "%u\n", &rate);
+       if (result != 1) {
+               result = -EINVAL;
+               goto out;
+       }
+       result = -EINVAL;
+       if (rate >= UWB_PHY_RATE_INVALID)
+               goto out;
+       wlp_tx_hdr_set_phy_rate(&options->def_tx_hdr, rate);
+       result = 0;
+out:
+       return result < 0 ? result : size;
+}
+EXPORT_SYMBOL_GPL(uwb_phy_rate_store);
+
+
+ssize_t uwb_rts_cts_show(const struct wlp_options *options, char *buf)
+{
+       return sprintf(buf, "%u\n",
+                      wlp_tx_hdr_rts_cts(&options->def_tx_hdr));
+}
+EXPORT_SYMBOL_GPL(uwb_rts_cts_show);
+
+
+ssize_t uwb_rts_cts_store(struct wlp_options *options,
+                         const char *buf, size_t size)
+{
+       ssize_t result;
+       unsigned value;
+
+       result = sscanf(buf, "%u\n", &value);
+       if (result != 1) {
+               result = -EINVAL;
+               goto out;
+       }
+       result = -EINVAL;
+       wlp_tx_hdr_set_rts_cts(&options->def_tx_hdr, !!value);
+       result = 0;
+out:
+       return result < 0 ? result : size;
+}
+EXPORT_SYMBOL_GPL(uwb_rts_cts_store);
+
+
+ssize_t uwb_ack_policy_show(const struct wlp_options *options, char *buf)
+{
+       return sprintf(buf, "%u\n",
+                      wlp_tx_hdr_ack_policy(&options->def_tx_hdr));
+}
+EXPORT_SYMBOL_GPL(uwb_ack_policy_show);
+
+
+ssize_t uwb_ack_policy_store(struct wlp_options *options,
+                            const char *buf, size_t size)
+{
+       ssize_t result;
+       unsigned value;
+
+       result = sscanf(buf, "%u\n", &value);
+       if (result != 1 || value > UWB_ACK_B_REQ) {
+               result = -EINVAL;
+               goto out;
+       }
+       wlp_tx_hdr_set_ack_policy(&options->def_tx_hdr, value);
+       result = 0;
+out:
+       return result < 0 ? result : size;
+}
+EXPORT_SYMBOL_GPL(uwb_ack_policy_store);
+
+
+/**
+ * Show the PCA base priority.
+ *
+ * We can access without locking, as the value is (for now) orthogonal
+ * to other values.
+ */
+ssize_t uwb_pca_base_priority_show(const struct wlp_options *options,
+                                  char *buf)
+{
+       return sprintf(buf, "%u\n",
+                      options->pca_base_priority);
+}
+EXPORT_SYMBOL_GPL(uwb_pca_base_priority_show);
+
+
+/**
+ * Set the PCA base priority.
+ *
+ * We can access without locking, as the value is (for now) orthogonal
+ * to other values.
+ */
+ssize_t uwb_pca_base_priority_store(struct wlp_options *options,
+                                   const char *buf, size_t size)
+{
+       ssize_t result = -EINVAL;
+       u8 pca_base_priority;
+
+       result = sscanf(buf, "%hhu\n", &pca_base_priority);
+       if (result != 1) {
+               result = -EINVAL;
+               goto out;
+       }
+       result = -EINVAL;
+       if (pca_base_priority >= 8)
+               goto out;
+       options->pca_base_priority = pca_base_priority;
+       /* Update TX header if we are currently using PCA. */
+       if (result >= 0 && (wlp_tx_hdr_delivery_id_type(&options->def_tx_hdr) & WLP_DRP) == 0)
+               wlp_tx_hdr_set_delivery_id_type(&options->def_tx_hdr, options->pca_base_priority);
+       result = 0;
+out:
+       return result < 0 ? result : size;
+}
+EXPORT_SYMBOL_GPL(uwb_pca_base_priority_store);
+
+/**
+ * Show current inflight values
+ *
+ * Will print the current MAX and THRESHOLD values for the basic flow
+ * control. In addition it will report how many times the TX queue needed
+ * to be restarted since the last time this query was made.
+ */
+static ssize_t wlp_tx_inflight_show(struct i1480u_tx_inflight *inflight,
+                                   char *buf)
+{
+       ssize_t result;
+       unsigned long sec_elapsed = (jiffies - inflight->restart_ts)/HZ;
+       unsigned long restart_count = atomic_read(&inflight->restart_count);
+
+       result = scnprintf(buf, PAGE_SIZE, "%lu %lu %d %lu %lu %lu\n"
+                          "#read: threshold max inflight_count restarts "
+                          "seconds restarts/sec\n"
+                          "#write: threshold max\n",
+                          inflight->threshold, inflight->max,
+                          atomic_read(&inflight->count),
+                          restart_count, sec_elapsed,
+                          sec_elapsed == 0 ? 0 : restart_count/sec_elapsed);
+       inflight->restart_ts = jiffies;
+       atomic_set(&inflight->restart_count, 0);
+       return result;
+}
+
+static
+ssize_t wlp_tx_inflight_store(struct i1480u_tx_inflight *inflight,
+                               const char *buf, size_t size)
+{
+       unsigned long in_threshold, in_max;
+       ssize_t result;
+       result = sscanf(buf, "%lu %lu", &in_threshold, &in_max);
+       if (result != 2)
+               return -EINVAL;
+       if (in_max <= in_threshold)
+               return -EINVAL;
+       inflight->max = in_max;
+       inflight->threshold = in_threshold;
+       return size;
+}
+/*
+ * Glue (or function adaptors) for accesing info on sysfs
+ *
+ * [we need this indirection because the PCI driver does almost the
+ * same]
+ *
+ * Linux 2.6.21 changed how 'struct netdevice' does attributes (from
+ * having a 'struct class_dev' to having a 'struct device'). That is
+ * quite of a pain.
+ *
+ * So we try to abstract that here. i1480u_SHOW() and i1480u_STORE()
+ * create adaptors for extracting the 'struct i1480u' from a 'struct
+ * dev' and calling a function for doing a sysfs operation (as we have
+ * them factorized already). i1480u_ATTR creates the attribute file
+ * (CLASS_DEVICE_ATTR or DEVICE_ATTR) and i1480u_ATTR_NAME produces a
+ * class_device_attr_NAME or device_attr_NAME (for group registration).
+ */
+#include <linux/version.h>
+
+#define i1480u_SHOW(name, fn, param)                           \
+static ssize_t i1480u_show_##name(struct device *dev,          \
+                                 struct device_attribute *attr,\
+                                 char *buf)                    \
+{                                                              \
+       struct i1480u *i1480u = netdev_priv(to_net_dev(dev));   \
+       return fn(&i1480u->param, buf);                         \
+}
+
+#define i1480u_STORE(name, fn, param)                          \
+static ssize_t i1480u_store_##name(struct device *dev,         \
+                                  struct device_attribute *attr,\
+                                  const char *buf, size_t size)\
+{                                                              \
+       struct i1480u *i1480u = netdev_priv(to_net_dev(dev));   \
+       return fn(&i1480u->param, buf, size);                   \
+}
+
+#define i1480u_ATTR(name, perm) static DEVICE_ATTR(name, perm,  \
+                                            i1480u_show_##name,\
+                                            i1480u_store_##name)
+
+#define i1480u_ATTR_SHOW(name) static DEVICE_ATTR(name,                \
+                                       S_IRUGO,                \
+                                       i1480u_show_##name, NULL)
+
+#define i1480u_ATTR_NAME(a) (dev_attr_##a)
+
+
+/*
+ * Sysfs adaptors
+ */
+i1480u_SHOW(uwb_phy_rate, uwb_phy_rate_show, options);
+i1480u_STORE(uwb_phy_rate, uwb_phy_rate_store, options);
+i1480u_ATTR(uwb_phy_rate, S_IRUGO | S_IWUSR);
+
+i1480u_SHOW(uwb_rts_cts, uwb_rts_cts_show, options);
+i1480u_STORE(uwb_rts_cts, uwb_rts_cts_store, options);
+i1480u_ATTR(uwb_rts_cts, S_IRUGO | S_IWUSR);
+
+i1480u_SHOW(uwb_ack_policy, uwb_ack_policy_show, options);
+i1480u_STORE(uwb_ack_policy, uwb_ack_policy_store, options);
+i1480u_ATTR(uwb_ack_policy, S_IRUGO | S_IWUSR);
+
+i1480u_SHOW(uwb_pca_base_priority, uwb_pca_base_priority_show, options);
+i1480u_STORE(uwb_pca_base_priority, uwb_pca_base_priority_store, options);
+i1480u_ATTR(uwb_pca_base_priority, S_IRUGO | S_IWUSR);
+
+i1480u_SHOW(wlp_eda, wlp_eda_show, wlp);
+i1480u_STORE(wlp_eda, wlp_eda_store, wlp);
+i1480u_ATTR(wlp_eda, S_IRUGO | S_IWUSR);
+
+i1480u_SHOW(wlp_uuid, wlp_uuid_show, wlp);
+i1480u_STORE(wlp_uuid, wlp_uuid_store, wlp);
+i1480u_ATTR(wlp_uuid, S_IRUGO | S_IWUSR);
+
+i1480u_SHOW(wlp_dev_name, wlp_dev_name_show, wlp);
+i1480u_STORE(wlp_dev_name, wlp_dev_name_store, wlp);
+i1480u_ATTR(wlp_dev_name, S_IRUGO | S_IWUSR);
+
+i1480u_SHOW(wlp_dev_manufacturer, wlp_dev_manufacturer_show, wlp);
+i1480u_STORE(wlp_dev_manufacturer, wlp_dev_manufacturer_store, wlp);
+i1480u_ATTR(wlp_dev_manufacturer, S_IRUGO | S_IWUSR);
+
+i1480u_SHOW(wlp_dev_model_name, wlp_dev_model_name_show, wlp);
+i1480u_STORE(wlp_dev_model_name, wlp_dev_model_name_store, wlp);
+i1480u_ATTR(wlp_dev_model_name, S_IRUGO | S_IWUSR);
+
+i1480u_SHOW(wlp_dev_model_nr, wlp_dev_model_nr_show, wlp);
+i1480u_STORE(wlp_dev_model_nr, wlp_dev_model_nr_store, wlp);
+i1480u_ATTR(wlp_dev_model_nr, S_IRUGO | S_IWUSR);
+
+i1480u_SHOW(wlp_dev_serial, wlp_dev_serial_show, wlp);
+i1480u_STORE(wlp_dev_serial, wlp_dev_serial_store, wlp);
+i1480u_ATTR(wlp_dev_serial, S_IRUGO | S_IWUSR);
+
+i1480u_SHOW(wlp_dev_prim_category, wlp_dev_prim_category_show, wlp);
+i1480u_STORE(wlp_dev_prim_category, wlp_dev_prim_category_store, wlp);
+i1480u_ATTR(wlp_dev_prim_category, S_IRUGO | S_IWUSR);
+
+i1480u_SHOW(wlp_dev_prim_OUI, wlp_dev_prim_OUI_show, wlp);
+i1480u_STORE(wlp_dev_prim_OUI, wlp_dev_prim_OUI_store, wlp);
+i1480u_ATTR(wlp_dev_prim_OUI, S_IRUGO | S_IWUSR);
+
+i1480u_SHOW(wlp_dev_prim_OUI_sub, wlp_dev_prim_OUI_sub_show, wlp);
+i1480u_STORE(wlp_dev_prim_OUI_sub, wlp_dev_prim_OUI_sub_store, wlp);
+i1480u_ATTR(wlp_dev_prim_OUI_sub, S_IRUGO | S_IWUSR);
+
+i1480u_SHOW(wlp_dev_prim_subcat, wlp_dev_prim_subcat_show, wlp);
+i1480u_STORE(wlp_dev_prim_subcat, wlp_dev_prim_subcat_store, wlp);
+i1480u_ATTR(wlp_dev_prim_subcat, S_IRUGO | S_IWUSR);
+
+i1480u_SHOW(wlp_neighborhood, wlp_neighborhood_show, wlp);
+i1480u_ATTR_SHOW(wlp_neighborhood);
+
+i1480u_SHOW(wss_activate, wlp_wss_activate_show, wlp.wss);
+i1480u_STORE(wss_activate, wlp_wss_activate_store, wlp.wss);
+i1480u_ATTR(wss_activate, S_IRUGO | S_IWUSR);
+
+/*
+ * Show the (min, max, avg) Line Quality Estimate (LQE, in dB) as over
+ * the last 256 received WLP frames (ECMA-368 13.3).
+ *
+ * [the -7dB that have to be substracted from the LQI to make the LQE
+ * are already taken into account].
+ */
+i1480u_SHOW(wlp_lqe, stats_show, lqe_stats);
+i1480u_STORE(wlp_lqe, stats_store, lqe_stats);
+i1480u_ATTR(wlp_lqe, S_IRUGO | S_IWUSR);
+
+/*
+ * Show the Receive Signal Strength Indicator averaged over all the
+ * received WLP frames (ECMA-368 13.3). Still is not clear what
+ * this value is, but is kind of a percentage of the signal strength
+ * at the antenna.
+ */
+i1480u_SHOW(wlp_rssi, stats_show, rssi_stats);
+i1480u_STORE(wlp_rssi, stats_store, rssi_stats);
+i1480u_ATTR(wlp_rssi, S_IRUGO | S_IWUSR);
+
+/**
+ * We maintain a basic flow control counter. "count" how many TX URBs are
+ * outstanding. Only allow "max"
+ * TX URBs to be outstanding. If this value is reached the queue will be
+ * stopped. The queue will be restarted when there are
+ * "threshold" URBs outstanding.
+ */
+i1480u_SHOW(wlp_tx_inflight, wlp_tx_inflight_show, tx_inflight);
+i1480u_STORE(wlp_tx_inflight, wlp_tx_inflight_store, tx_inflight);
+i1480u_ATTR(wlp_tx_inflight, S_IRUGO | S_IWUSR);
+
+static struct attribute *i1480u_attrs[] = {
+       &i1480u_ATTR_NAME(uwb_phy_rate).attr,
+       &i1480u_ATTR_NAME(uwb_rts_cts).attr,
+       &i1480u_ATTR_NAME(uwb_ack_policy).attr,
+       &i1480u_ATTR_NAME(uwb_pca_base_priority).attr,
+       &i1480u_ATTR_NAME(wlp_lqe).attr,
+       &i1480u_ATTR_NAME(wlp_rssi).attr,
+       &i1480u_ATTR_NAME(wlp_eda).attr,
+       &i1480u_ATTR_NAME(wlp_uuid).attr,
+       &i1480u_ATTR_NAME(wlp_dev_name).attr,
+       &i1480u_ATTR_NAME(wlp_dev_manufacturer).attr,
+       &i1480u_ATTR_NAME(wlp_dev_model_name).attr,
+       &i1480u_ATTR_NAME(wlp_dev_model_nr).attr,
+       &i1480u_ATTR_NAME(wlp_dev_serial).attr,
+       &i1480u_ATTR_NAME(wlp_dev_prim_category).attr,
+       &i1480u_ATTR_NAME(wlp_dev_prim_OUI).attr,
+       &i1480u_ATTR_NAME(wlp_dev_prim_OUI_sub).attr,
+       &i1480u_ATTR_NAME(wlp_dev_prim_subcat).attr,
+       &i1480u_ATTR_NAME(wlp_neighborhood).attr,
+       &i1480u_ATTR_NAME(wss_activate).attr,
+       &i1480u_ATTR_NAME(wlp_tx_inflight).attr,
+       NULL,
+};
+
+static struct attribute_group i1480u_attr_group = {
+       .name = NULL,   /* we want them in the same directory */
+       .attrs = i1480u_attrs,
+};
+
+int i1480u_sysfs_setup(struct i1480u *i1480u)
+{
+       int result;
+       struct device *dev = &i1480u->usb_iface->dev;
+       result = sysfs_create_group(&i1480u->net_dev->dev.kobj,
+                                   &i1480u_attr_group);
+       if (result < 0)
+               dev_err(dev, "cannot initialize sysfs attributes: %d\n",
+                       result);
+       return result;
+}
+
+
+void i1480u_sysfs_release(struct i1480u *i1480u)
+{
+       sysfs_remove_group(&i1480u->net_dev->dev.kobj,
+                          &i1480u_attr_group);
+}
diff --git a/drivers/uwb/i1480/i1480u-wlp/tx.c b/drivers/uwb/i1480/i1480u-wlp/tx.c
new file mode 100644 (file)
index 0000000..3426bfb
--- /dev/null
@@ -0,0 +1,632 @@
+/*
+ * WUSB Wire Adapter: WLP interface
+ * Deal with TX (massaging data to transmit, handling it)
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * Transmission engine. Get an skb, create from that a WLP transmit
+ * context, add a WLP TX header (which we keep prefilled in the
+ * device's instance), fill out the target-specific fields and
+ * fire it.
+ *
+ * ROADMAP:
+ *
+ *   Entry points:
+ *
+ *     i1480u_tx_release(): called by i1480u_disconnect() to release
+ *                          pending tx contexts.
+ *
+ *     i1480u_tx_cb(): callback for TX contexts (USB URBs)
+ *       i1480u_tx_destroy():
+ *
+ *     i1480u_tx_timeout(): called for timeout handling from the
+ *                          network stack.
+ *
+ *     i1480u_hard_start_xmit(): called for transmitting an skb from
+ *                               the network stack. Will interact with WLP
+ *                               substack to verify and prepare frame.
+ *       i1480u_xmit_frame(): actual transmission on hardware
+ *
+ *         i1480u_tx_create()      Creates TX context
+ *            i1480u_tx_create_1()    For packets in 1 fragment
+ *            i1480u_tx_create_n()    For packets in >1 fragments
+ *
+ * TODO:
+ *
+ * - FIXME: rewrite using usb_sg_*(), add asynch support to
+ *          usb_sg_*(). It might not make too much sense as most of
+ *          the times the MTU will be smaller than one page...
+ */
+
+#include "i1480u-wlp.h"
+#define D_LOCAL 5
+#include <linux/uwb/debug.h>
+
+enum {
+       /* This is only for Next and Last TX packets */
+       i1480u_MAX_PL_SIZE = i1480u_MAX_FRG_SIZE
+               - sizeof(struct untd_hdr_rst),
+};
+
+/** Free resources allocated to a i1480u tx context. */
+static
+void i1480u_tx_free(struct i1480u_tx *wtx)
+{
+       kfree(wtx->buf);
+       if (wtx->skb)
+               dev_kfree_skb_irq(wtx->skb);
+       usb_free_urb(wtx->urb);
+       kfree(wtx);
+}
+
+static
+void i1480u_tx_destroy(struct i1480u *i1480u, struct i1480u_tx *wtx)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&i1480u->tx_list_lock, flags);        /* not active any more */
+       list_del(&wtx->list_node);
+       i1480u_tx_free(wtx);
+       spin_unlock_irqrestore(&i1480u->tx_list_lock, flags);
+}
+
+static
+void i1480u_tx_unlink_urbs(struct i1480u *i1480u)
+{
+       unsigned long flags;
+       struct i1480u_tx *wtx, *next;
+
+       spin_lock_irqsave(&i1480u->tx_list_lock, flags);
+       list_for_each_entry_safe(wtx, next, &i1480u->tx_list, list_node) {
+               usb_unlink_urb(wtx->urb);
+       }
+       spin_unlock_irqrestore(&i1480u->tx_list_lock, flags);
+}
+
+
+/**
+ * Callback for a completed tx USB URB.
+ *
+ * TODO:
+ *
+ * - FIXME: recover errors more gracefully
+ * - FIXME: handle NAKs (I dont think they come here) for flow ctl
+ */
+static
+void i1480u_tx_cb(struct urb *urb)
+{
+       struct i1480u_tx *wtx = urb->context;
+       struct i1480u *i1480u = wtx->i1480u;
+       struct net_device *net_dev = i1480u->net_dev;
+       struct device *dev = &i1480u->usb_iface->dev;
+       unsigned long flags;
+
+       switch (urb->status) {
+       case 0:
+               spin_lock_irqsave(&i1480u->lock, flags);
+               i1480u->stats.tx_packets++;
+               i1480u->stats.tx_bytes += urb->actual_length;
+               spin_unlock_irqrestore(&i1480u->lock, flags);
+               break;
+       case -ECONNRESET:       /* Not an error, but a controlled situation; */
+       case -ENOENT:           /* (we killed the URB)...so, no broadcast */
+               dev_dbg(dev, "notif endp: reset/noent %d\n", urb->status);
+               netif_stop_queue(net_dev);
+               break;
+       case -ESHUTDOWN:        /* going away! */
+               dev_dbg(dev, "notif endp: down %d\n", urb->status);
+               netif_stop_queue(net_dev);
+               break;
+       default:
+               dev_err(dev, "TX: unknown URB status %d\n", urb->status);
+               if (edc_inc(&i1480u->tx_errors, EDC_MAX_ERRORS,
+                                       EDC_ERROR_TIMEFRAME)) {
+                       dev_err(dev, "TX: max acceptable errors exceeded."
+                                       "Reset device.\n");
+                       netif_stop_queue(net_dev);
+                       i1480u_tx_unlink_urbs(i1480u);
+                       wlp_reset_all(&i1480u->wlp);
+               }
+               break;
+       }
+       i1480u_tx_destroy(i1480u, wtx);
+       if (atomic_dec_return(&i1480u->tx_inflight.count)
+           <= i1480u->tx_inflight.threshold
+           && netif_queue_stopped(net_dev)
+           && i1480u->tx_inflight.threshold != 0) {
+               if (d_test(2) && printk_ratelimit())
+                       d_printf(2, dev, "Restart queue. \n");
+               netif_start_queue(net_dev);
+               atomic_inc(&i1480u->tx_inflight.restart_count);
+       }
+       return;
+}
+
+
+/**
+ * Given a buffer that doesn't fit in a single fragment, create an
+ * scatter/gather structure for delivery to the USB pipe.
+ *
+ * Implements functionality of i1480u_tx_create().
+ *
+ * @wtx:       tx descriptor
+ * @skb:       skb to send
+ * @gfp_mask:  gfp allocation mask
+ * @returns:    Pointer to @wtx if ok, NULL on error.
+ *
+ * Sorry, TOO LONG a function, but breaking it up is kind of hard
+ *
+ * This will break the buffer in chunks smaller than
+ * i1480u_MAX_FRG_SIZE (including the header) and add proper headers
+ * to each:
+ *
+ *   1st header           \
+ *   i1480 tx header      |  fragment 1
+ *   fragment data        /
+ *   nxt header           \  fragment 2
+ *   fragment data        /
+ *   ..
+ *   ..
+ *   last header          \  fragment 3
+ *   last fragment data   /
+ *
+ * This does not fill the i1480 TX header, it is left up to the
+ * caller to do that; you can get it from @wtx->wlp_tx_hdr.
+ *
+ * This function consumes the skb unless there is an error.
+ */
+static
+int i1480u_tx_create_n(struct i1480u_tx *wtx, struct sk_buff *skb,
+                      gfp_t gfp_mask)
+{
+       int result;
+       void *pl;
+       size_t pl_size;
+
+       void *pl_itr, *buf_itr;
+       size_t pl_size_left, frgs, pl_size_1st, frg_pl_size = 0;
+       struct untd_hdr_1st *untd_hdr_1st;
+       struct wlp_tx_hdr *wlp_tx_hdr;
+       struct untd_hdr_rst *untd_hdr_rst;
+
+       wtx->skb = NULL;
+       pl = skb->data;
+       pl_itr = pl;
+       pl_size = skb->len;
+       pl_size_left = pl_size; /* payload size */
+       /* First fragment; fits as much as i1480u_MAX_FRG_SIZE minus
+        * the headers */
+       pl_size_1st = i1480u_MAX_FRG_SIZE
+               - sizeof(struct untd_hdr_1st) - sizeof(struct wlp_tx_hdr);
+       BUG_ON(pl_size_1st > pl_size);
+       pl_size_left -= pl_size_1st;
+       /* The rest have an smaller header (no i1480 TX header). We
+        * need to break up the payload in blocks smaller than
+        * i1480u_MAX_PL_SIZE (payload excluding header). */
+       frgs = (pl_size_left + i1480u_MAX_PL_SIZE - 1) / i1480u_MAX_PL_SIZE;
+       /* Allocate space for the new buffer. In this new buffer we'll
+        * place the headers followed by the data fragment, headers,
+        * data fragments, etc..
+        */
+       result = -ENOMEM;
+       wtx->buf_size = sizeof(*untd_hdr_1st)
+               + sizeof(*wlp_tx_hdr)
+               + frgs * sizeof(*untd_hdr_rst)
+               + pl_size;
+       wtx->buf = kmalloc(wtx->buf_size, gfp_mask);
+       if (wtx->buf == NULL)
+               goto error_buf_alloc;
+
+       buf_itr = wtx->buf;             /* We got the space, let's fill it up */
+       /* Fill 1st fragment */
+       untd_hdr_1st = buf_itr;
+       buf_itr += sizeof(*untd_hdr_1st);
+       untd_hdr_set_type(&untd_hdr_1st->hdr, i1480u_PKT_FRAG_1ST);
+       untd_hdr_set_rx_tx(&untd_hdr_1st->hdr, 0);
+       untd_hdr_1st->hdr.len = cpu_to_le16(pl_size + sizeof(*wlp_tx_hdr));
+       untd_hdr_1st->fragment_len =
+               cpu_to_le16(pl_size_1st + sizeof(*wlp_tx_hdr));
+       memset(untd_hdr_1st->padding, 0, sizeof(untd_hdr_1st->padding));
+       /* Set up i1480 header info */
+       wlp_tx_hdr = wtx->wlp_tx_hdr = buf_itr;
+       buf_itr += sizeof(*wlp_tx_hdr);
+       /* Copy the first fragment */
+       memcpy(buf_itr, pl_itr, pl_size_1st);
+       pl_itr += pl_size_1st;
+       buf_itr += pl_size_1st;
+
+       /* Now do each remaining fragment */
+       result = -EINVAL;
+       while (pl_size_left > 0) {
+               d_printf(5, NULL, "ITR HDR: pl_size_left %zu buf_itr %zu\n",
+                        pl_size_left, buf_itr - wtx->buf);
+               if (buf_itr + sizeof(*untd_hdr_rst) - wtx->buf
+                   > wtx->buf_size) {
+                       printk(KERN_ERR "BUG: no space for header\n");
+                       goto error_bug;
+               }
+               d_printf(5, NULL, "ITR HDR 2: pl_size_left %zu buf_itr %zu\n",
+                        pl_size_left, buf_itr - wtx->buf);
+               untd_hdr_rst = buf_itr;
+               buf_itr += sizeof(*untd_hdr_rst);
+               if (pl_size_left > i1480u_MAX_PL_SIZE) {
+                       frg_pl_size = i1480u_MAX_PL_SIZE;
+                       untd_hdr_set_type(&untd_hdr_rst->hdr, i1480u_PKT_FRAG_NXT);
+               } else {
+                       frg_pl_size = pl_size_left;
+                       untd_hdr_set_type(&untd_hdr_rst->hdr, i1480u_PKT_FRAG_LST);
+               }
+               d_printf(5, NULL,
+                        "ITR PL: pl_size_left %zu buf_itr %zu frg_pl_size %zu\n",
+                        pl_size_left, buf_itr - wtx->buf, frg_pl_size);
+               untd_hdr_set_rx_tx(&untd_hdr_rst->hdr, 0);
+               untd_hdr_rst->hdr.len = cpu_to_le16(frg_pl_size);
+               untd_hdr_rst->padding = 0;
+               if (buf_itr + frg_pl_size - wtx->buf
+                   > wtx->buf_size) {
+                       printk(KERN_ERR "BUG: no space for payload\n");
+                       goto error_bug;
+               }
+               memcpy(buf_itr, pl_itr, frg_pl_size);
+               buf_itr += frg_pl_size;
+               pl_itr += frg_pl_size;
+               pl_size_left -= frg_pl_size;
+               d_printf(5, NULL,
+                        "ITR PL 2: pl_size_left %zu buf_itr %zu frg_pl_size %zu\n",
+                        pl_size_left, buf_itr - wtx->buf, frg_pl_size);
+       }
+       dev_kfree_skb_irq(skb);
+       return 0;
+
+error_bug:
+       printk(KERN_ERR
+              "BUG: skb %u bytes\n"
+              "BUG: frg_pl_size %zd i1480u_MAX_FRG_SIZE %u\n"
+              "BUG: buf_itr %zu buf_size %zu pl_size_left %zu\n",
+              skb->len,
+              frg_pl_size, i1480u_MAX_FRG_SIZE,
+              buf_itr - wtx->buf, wtx->buf_size, pl_size_left);
+
+       kfree(wtx->buf);
+error_buf_alloc:
+       return result;
+}
+
+
+/**
+ * Given a buffer that fits in a single fragment, fill out a @wtx
+ * struct for transmitting it down the USB pipe.
+ *
+ * Uses the fact that we have space reserved in front of the skbuff
+ * for hardware headers :]
+ *
+ * This does not fill the i1480 TX header, it is left up to the
+ * caller to do that; you can get it from @wtx->wlp_tx_hdr.
+ *
+ * @pl:                pointer to payload data
+ * @pl_size:    size of the payuload
+ *
+ * This function does not consume the @skb.
+ */
+static
+int i1480u_tx_create_1(struct i1480u_tx *wtx, struct sk_buff *skb,
+                      gfp_t gfp_mask)
+{
+       struct untd_hdr_cmp *untd_hdr_cmp;
+       struct wlp_tx_hdr *wlp_tx_hdr;
+
+       wtx->buf = NULL;
+       wtx->skb = skb;
+       BUG_ON(skb_headroom(skb) < sizeof(*wlp_tx_hdr));
+       wlp_tx_hdr = (void *) __skb_push(skb, sizeof(*wlp_tx_hdr));
+       wtx->wlp_tx_hdr = wlp_tx_hdr;
+       BUG_ON(skb_headroom(skb) < sizeof(*untd_hdr_cmp));
+       untd_hdr_cmp = (void *) __skb_push(skb, sizeof(*untd_hdr_cmp));
+
+       untd_hdr_set_type(&untd_hdr_cmp->hdr, i1480u_PKT_FRAG_CMP);
+       untd_hdr_set_rx_tx(&untd_hdr_cmp->hdr, 0);
+       untd_hdr_cmp->hdr.len = cpu_to_le16(skb->len - sizeof(*untd_hdr_cmp));
+       untd_hdr_cmp->padding = 0;
+       return 0;
+}
+
+
+/**
+ * Given a skb to transmit, massage it to become palatable for the TX pipe
+ *
+ * This will break the buffer in chunks smaller than
+ * i1480u_MAX_FRG_SIZE and add proper headers to each.
+ *
+ *   1st header           \
+ *   i1480 tx header      |  fragment 1
+ *   fragment data        /
+ *   nxt header           \  fragment 2
+ *   fragment data        /
+ *   ..
+ *   ..
+ *   last header          \  fragment 3
+ *   last fragment data   /
+ *
+ * Each fragment will be always smaller or equal to i1480u_MAX_FRG_SIZE.
+ *
+ * If the first fragment is smaller than i1480u_MAX_FRG_SIZE, then the
+ * following is composed:
+ *
+ *   complete header      \
+ *   i1480 tx header      | single fragment
+ *   packet data          /
+ *
+ * We were going to use s/g support, but because the interface is
+ * synch and at the end there is plenty of overhead to do it, it
+ * didn't seem that worth for data that is going to be smaller than
+ * one page.
+ */
+static
+struct i1480u_tx *i1480u_tx_create(struct i1480u *i1480u,
+                                  struct sk_buff *skb, gfp_t gfp_mask)
+{
+       int result;
+       struct usb_endpoint_descriptor *epd;
+       int usb_pipe;
+       unsigned long flags;
+
+       struct i1480u_tx *wtx;
+       const size_t pl_max_size =
+               i1480u_MAX_FRG_SIZE - sizeof(struct untd_hdr_cmp)
+               - sizeof(struct wlp_tx_hdr);
+
+       wtx = kmalloc(sizeof(*wtx), gfp_mask);
+       if (wtx == NULL)
+               goto error_wtx_alloc;
+       wtx->urb = usb_alloc_urb(0, gfp_mask);
+       if (wtx->urb == NULL)
+               goto error_urb_alloc;
+       epd = &i1480u->usb_iface->cur_altsetting->endpoint[2].desc;
+       usb_pipe = usb_sndbulkpipe(i1480u->usb_dev, epd->bEndpointAddress);
+       /* Fits in a single complete packet or need to split? */
+       if (skb->len > pl_max_size) {
+               result = i1480u_tx_create_n(wtx, skb, gfp_mask);
+               if (result < 0)
+                       goto error_create;
+               usb_fill_bulk_urb(wtx->urb, i1480u->usb_dev, usb_pipe,
+                                 wtx->buf, wtx->buf_size, i1480u_tx_cb, wtx);
+       } else {
+               result = i1480u_tx_create_1(wtx, skb, gfp_mask);
+               if (result < 0)
+                       goto error_create;
+               usb_fill_bulk_urb(wtx->urb, i1480u->usb_dev, usb_pipe,
+                                 skb->data, skb->len, i1480u_tx_cb, wtx);
+       }
+       spin_lock_irqsave(&i1480u->tx_list_lock, flags);
+       list_add(&wtx->list_node, &i1480u->tx_list);
+       spin_unlock_irqrestore(&i1480u->tx_list_lock, flags);
+       return wtx;
+
+error_create:
+       kfree(wtx->urb);
+error_urb_alloc:
+       kfree(wtx);
+error_wtx_alloc:
+       return NULL;
+}
+
+/**
+ * Actual fragmentation and transmission of frame
+ *
+ * @wlp:  WLP substack data structure
+ * @skb:  To be transmitted
+ * @dst:  Device address of destination
+ * @returns: 0 on success, <0 on failure
+ *
+ * This function can also be called directly (not just from
+ * hard_start_xmit), so we also check here if the interface is up before
+ * taking sending anything.
+ */
+int i1480u_xmit_frame(struct wlp *wlp, struct sk_buff *skb,
+                     struct uwb_dev_addr *dst)
+{
+       int result = -ENXIO;
+       struct i1480u *i1480u = container_of(wlp, struct i1480u, wlp);
+       struct device *dev = &i1480u->usb_iface->dev;
+       struct net_device *net_dev = i1480u->net_dev;
+       struct i1480u_tx *wtx;
+       struct wlp_tx_hdr *wlp_tx_hdr;
+       static unsigned char dev_bcast[2] = { 0xff, 0xff };
+#if 0
+       int lockup = 50;
+#endif
+
+       d_fnstart(6, dev, "(skb %p (%u), net_dev %p)\n", skb, skb->len,
+                 net_dev);
+       BUG_ON(i1480u->wlp.rc == NULL);
+       if ((net_dev->flags & IFF_UP) == 0)
+               goto out;
+       result = -EBUSY;
+       if (atomic_read(&i1480u->tx_inflight.count) >= i1480u->tx_inflight.max) {
+               if (d_test(2) && printk_ratelimit())
+                       d_printf(2, dev, "Max frames in flight "
+                                "stopping queue.\n");
+               netif_stop_queue(net_dev);
+               goto error_max_inflight;
+       }
+       result = -ENOMEM;
+       wtx = i1480u_tx_create(i1480u, skb, GFP_ATOMIC);
+       if (unlikely(wtx == NULL)) {
+               if (printk_ratelimit())
+                       dev_err(dev, "TX: no memory for WLP TX URB,"
+                               "dropping packet (in flight %d)\n",
+                               atomic_read(&i1480u->tx_inflight.count));
+               netif_stop_queue(net_dev);
+               goto error_wtx_alloc;
+       }
+       wtx->i1480u = i1480u;
+       /* Fill out the i1480 header; @i1480u->def_tx_hdr read without
+        * locking. We do so because they are kind of orthogonal to
+        * each other (and thus not changed in an atomic batch).
+        * The ETH header is right after the WLP TX header. */
+       wlp_tx_hdr = wtx->wlp_tx_hdr;
+       *wlp_tx_hdr = i1480u->options.def_tx_hdr;
+       wlp_tx_hdr->dstaddr = *dst;
+       if (!memcmp(&wlp_tx_hdr->dstaddr, dev_bcast, sizeof(dev_bcast))
+           && (wlp_tx_hdr_delivery_id_type(wlp_tx_hdr) & WLP_DRP)) {
+               /*Broadcast message directed to DRP host. Send as best effort
+                * on PCA. */
+               wlp_tx_hdr_set_delivery_id_type(wlp_tx_hdr, i1480u->options.pca_base_priority);
+       }
+
+#if 0
+       dev_info(dev, "TX delivering skb -> USB, %zu bytes\n", skb->len);
+       dump_bytes(dev, skb->data, skb->len > 72 ? 72 : skb->len);
+#endif
+#if 0
+       /* simulates a device lockup after every lockup# packets */
+       if (lockup && ((i1480u->stats.tx_packets + 1) % lockup) == 0) {
+               /* Simulate a dropped transmit interrupt */
+               net_dev->trans_start = jiffies;
+               netif_stop_queue(net_dev);
+               dev_err(dev, "Simulate lockup at %ld\n", jiffies);
+               return result;
+       }
+#endif
+
+       result = usb_submit_urb(wtx->urb, GFP_ATOMIC);          /* Go baby */
+       if (result < 0) {
+               dev_err(dev, "TX: cannot submit URB: %d\n", result);
+               /* We leave the freeing of skb to calling function */
+               wtx->skb = NULL;
+               goto error_tx_urb_submit;
+       }
+       atomic_inc(&i1480u->tx_inflight.count);
+       net_dev->trans_start = jiffies;
+       d_fnend(6, dev, "(skb %p (%u), net_dev %p) = %d\n", skb, skb->len,
+               net_dev, result);
+       return result;
+
+error_tx_urb_submit:
+       i1480u_tx_destroy(i1480u, wtx);
+error_wtx_alloc:
+error_max_inflight:
+out:
+       d_fnend(6, dev, "(skb %p (%u), net_dev %p) = %d\n", skb, skb->len,
+               net_dev, result);
+       return result;
+}
+
+
+/**
+ * Transmit an skb  Called when an skbuf has to be transmitted
+ *
+ * The skb is first passed to WLP substack to ensure this is a valid
+ * frame. If valid the device address of destination will be filled and
+ * the WLP header prepended to the skb. If this step fails we fake sending
+ * the frame, if we return an error the network stack will just keep trying.
+ *
+ * Broadcast frames inside a WSS needs to be treated special as multicast is
+ * not supported. A broadcast frame is sent as unicast to each member of the
+ * WSS - this is done by the WLP substack when it finds a broadcast frame.
+ * So, we test if the WLP substack took over the skb and only transmit it
+ * if it has not (been taken over).
+ *
+ * @net_dev->xmit_lock is held
+ */
+int i1480u_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
+{
+       int result;
+       struct i1480u *i1480u = netdev_priv(net_dev);
+       struct device *dev = &i1480u->usb_iface->dev;
+       struct uwb_dev_addr dst;
+
+       d_fnstart(6, dev, "(skb %p (%u), net_dev %p)\n", skb, skb->len,
+                 net_dev);
+       BUG_ON(i1480u->wlp.rc == NULL);
+       if ((net_dev->flags & IFF_UP) == 0)
+               goto error;
+       result = wlp_prepare_tx_frame(dev, &i1480u->wlp, skb, &dst);
+       if (result < 0) {
+               dev_err(dev, "WLP verification of TX frame failed (%d). "
+                       "Dropping packet.\n", result);
+               goto error;
+       } else if (result == 1) {
+               d_printf(6, dev, "WLP will transmit frame. \n");
+               /* trans_start time will be set when WLP actually transmits
+                * the frame */
+               goto out;
+       }
+       d_printf(6, dev, "Transmitting frame. \n");
+       result = i1480u_xmit_frame(&i1480u->wlp, skb, &dst);
+       if (result < 0) {
+               dev_err(dev, "Frame TX failed (%d).\n", result);
+               goto error;
+       }
+       d_fnend(6, dev, "(skb %p (%u), net_dev %p) = %d\n", skb, skb->len,
+               net_dev, result);
+       return NETDEV_TX_OK;
+error:
+       dev_kfree_skb_any(skb);
+       i1480u->stats.tx_dropped++;
+out:
+       d_fnend(6, dev, "(skb %p (%u), net_dev %p) = %d\n", skb, skb->len,
+               net_dev, result);
+       return NETDEV_TX_OK;
+}
+
+
+/**
+ * Called when a pkt transmission doesn't complete in a reasonable period
+ * Device reset may sleep - do it outside of interrupt context (delayed)
+ */
+void i1480u_tx_timeout(struct net_device *net_dev)
+{
+       struct i1480u *i1480u = netdev_priv(net_dev);
+
+       wlp_reset_all(&i1480u->wlp);
+}
+
+
+void i1480u_tx_release(struct i1480u *i1480u)
+{
+       unsigned long flags;
+       struct i1480u_tx *wtx, *next;
+       int count = 0, empty;
+
+       spin_lock_irqsave(&i1480u->tx_list_lock, flags);
+       list_for_each_entry_safe(wtx, next, &i1480u->tx_list, list_node) {
+               count++;
+               usb_unlink_urb(wtx->urb);
+       }
+       spin_unlock_irqrestore(&i1480u->tx_list_lock, flags);
+       count = count*10; /* i1480ut 200ms per unlinked urb (intervals of 20ms) */
+       /*
+        * We don't like this sollution too much (dirty as it is), but
+        * it is cheaper than putting a refcount on each i1480u_tx and
+        * i1480uting for all of them to go away...
+        *
+        * Called when no more packets can be added to tx_list
+        * so can i1480ut for it to be empty.
+        */
+       while (1) {
+               spin_lock_irqsave(&i1480u->tx_list_lock, flags);
+               empty = list_empty(&i1480u->tx_list);
+               spin_unlock_irqrestore(&i1480u->tx_list_lock, flags);
+               if (empty)
+                       break;
+               count--;
+               BUG_ON(count == 0);
+               msleep(20);
+       }
+}
diff --git a/drivers/uwb/ie.c b/drivers/uwb/ie.c
new file mode 100644 (file)
index 0000000..cf6f3d1
--- /dev/null
@@ -0,0 +1,541 @@
+/*
+ * Ultra Wide Band
+ * Information Element Handling
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ * Reinette Chatre <reinette.chatre@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ */
+
+#include "uwb-internal.h"
+#define D_LOCAL 0
+#include <linux/uwb/debug.h>
+
+/**
+ * uwb_ie_next - get the next IE in a buffer
+ * @ptr: start of the buffer containing the IE data
+ * @len: length of the buffer
+ *
+ * Both @ptr and @len are updated so subsequent calls to uwb_ie_next()
+ * will get the next IE.
+ *
+ * NULL is returned (and @ptr and @len will not be updated) if there
+ * are no more IEs in the buffer or the buffer is too short.
+ */
+struct uwb_ie_hdr *uwb_ie_next(void **ptr, size_t *len)
+{
+       struct uwb_ie_hdr *hdr;
+       size_t ie_len;
+
+       if (*len < sizeof(struct uwb_ie_hdr))
+               return NULL;
+
+       hdr = *ptr;
+       ie_len = sizeof(struct uwb_ie_hdr) + hdr->length;
+
+       if (*len < ie_len)
+               return NULL;
+
+       *ptr += ie_len;
+       *len -= ie_len;
+
+       return hdr;
+}
+EXPORT_SYMBOL_GPL(uwb_ie_next);
+
+/**
+ * Get the IEs that a radio controller is sending in its beacon
+ *
+ * @uwb_rc:  UWB Radio Controller
+ * @returns: Size read from the system
+ *
+ * We don't need to lock the uwb_rc's mutex because we don't modify
+ * anything. Once done with the iedata buffer, call
+ * uwb_rc_ie_release(iedata). Don't call kfree on it.
+ */
+ssize_t uwb_rc_get_ie(struct uwb_rc *uwb_rc, struct uwb_rc_evt_get_ie **pget_ie)
+{
+       ssize_t result;
+       struct device *dev = &uwb_rc->uwb_dev.dev;
+       struct uwb_rccb *cmd = NULL;
+       struct uwb_rceb *reply = NULL;
+       struct uwb_rc_evt_get_ie *get_ie;
+
+       d_fnstart(3, dev, "(%p, %p)\n", uwb_rc, pget_ie);
+       result = -ENOMEM;
+       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+       if (cmd == NULL)
+               goto error_kzalloc;
+       cmd->bCommandType = UWB_RC_CET_GENERAL;
+       cmd->wCommand = cpu_to_le16(UWB_RC_CMD_GET_IE);
+       result = uwb_rc_vcmd(uwb_rc, "GET_IE", cmd, sizeof(*cmd),
+                            UWB_RC_CET_GENERAL, UWB_RC_CMD_GET_IE,
+                            &reply);
+       if (result < 0)
+               goto error_cmd;
+       get_ie = container_of(reply, struct uwb_rc_evt_get_ie, rceb);
+       if (result < sizeof(*get_ie)) {
+               dev_err(dev, "not enough data returned for decoding GET IE "
+                       "(%zu bytes received vs %zu needed)\n",
+                       result, sizeof(*get_ie));
+               result = -EINVAL;
+       } else if (result < sizeof(*get_ie) + le16_to_cpu(get_ie->wIELength)) {
+               dev_err(dev, "not enough data returned for decoding GET IE "
+                       "payload (%zu bytes received vs %zu needed)\n", result,
+                       sizeof(*get_ie) + le16_to_cpu(get_ie->wIELength));
+               result = -EINVAL;
+       } else
+               *pget_ie = get_ie;
+error_cmd:
+       kfree(cmd);
+error_kzalloc:
+       d_fnend(3, dev, "(%p, %p) = %d\n", uwb_rc, pget_ie, (int)result);
+       return result;
+}
+EXPORT_SYMBOL_GPL(uwb_rc_get_ie);
+
+
+/*
+ * Given a pointer to an IE, print it in ASCII/hex followed by a new line
+ *
+ * @ie_hdr: pointer to the IE header. Length is in there, and it is
+ *          guaranteed that the ie_hdr->length bytes following it are
+ *          safely accesible.
+ *
+ * @_data: context data passed from uwb_ie_for_each(), an struct output_ctx
+ */
+int uwb_ie_dump_hex(struct uwb_dev *uwb_dev, const struct uwb_ie_hdr *ie_hdr,
+                   size_t offset, void *_ctx)
+{
+       struct uwb_buf_ctx *ctx = _ctx;
+       const u8 *pl = (void *)(ie_hdr + 1);
+       u8 pl_itr;
+
+       ctx->bytes += scnprintf(ctx->buf + ctx->bytes, ctx->size - ctx->bytes,
+                               "%02x %02x ", (unsigned) ie_hdr->element_id,
+                               (unsigned) ie_hdr->length);
+       pl_itr = 0;
+       while (pl_itr < ie_hdr->length && ctx->bytes < ctx->size)
+               ctx->bytes += scnprintf(ctx->buf + ctx->bytes,
+                                       ctx->size - ctx->bytes,
+                                       "%02x ", (unsigned) pl[pl_itr++]);
+       if (ctx->bytes < ctx->size)
+               ctx->buf[ctx->bytes++] = '\n';
+       return 0;
+}
+EXPORT_SYMBOL_GPL(uwb_ie_dump_hex);
+
+
+/**
+ * Verify that a pointer in a buffer points to valid IE
+ *
+ * @start: pointer to start of buffer in which IE appears
+ * @itr:   pointer to IE inside buffer that will be verified
+ * @top:   pointer to end of buffer
+ *
+ * @returns: 0 if IE is valid, <0 otherwise
+ *
+ * Verification involves checking that the buffer can contain a
+ * header and the amount of data reported in the IE header can be found in
+ * the buffer.
+ */
+static
+int uwb_rc_ie_verify(struct uwb_dev *uwb_dev, const void *start,
+                    const void *itr, const void *top)
+{
+       struct device *dev = &uwb_dev->dev;
+       const struct uwb_ie_hdr *ie_hdr;
+
+       if (top - itr < sizeof(*ie_hdr)) {
+               dev_err(dev, "Bad IE: no data to decode header "
+                       "(%zu bytes left vs %zu needed) at offset %zu\n",
+                       top - itr, sizeof(*ie_hdr), itr - start);
+               return -EINVAL;
+       }
+       ie_hdr = itr;
+       itr += sizeof(*ie_hdr);
+       if (top - itr < ie_hdr->length) {
+               dev_err(dev, "Bad IE: not enough data for payload "
+                       "(%zu bytes left vs %zu needed) at offset %zu\n",
+                       top - itr, (size_t)ie_hdr->length,
+                       (void *)ie_hdr - start);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+
+/**
+ * Walk a buffer filled with consecutive IE's a buffer
+ *
+ * @uwb_dev: UWB device this IEs belong to (for err messages mainly)
+ *
+ * @fn: function to call with each IE; if it returns 0, we keep
+ *      traversing the buffer. If it returns !0, we'll stop and return
+ *      that value.
+ *
+ * @data: pointer passed to @fn
+ *
+ * @buf: buffer where the consecutive IEs are located
+ *
+ * @size: size of @buf
+ *
+ * Each IE is checked for basic correctness (there is space left for
+ * the header and the payload). If that test is failed, we stop
+ * processing. For every good IE, @fn is called.
+ */
+ssize_t uwb_ie_for_each(struct uwb_dev *uwb_dev, uwb_ie_f fn, void *data,
+                       const void *buf, size_t size)
+{
+       ssize_t result = 0;
+       const struct uwb_ie_hdr *ie_hdr;
+       const void *itr = buf, *top = itr + size;
+
+       while (itr < top) {
+               if (uwb_rc_ie_verify(uwb_dev, buf, itr, top) != 0)
+                       break;
+               ie_hdr = itr;
+               itr += sizeof(*ie_hdr) + ie_hdr->length;
+               result = fn(uwb_dev, ie_hdr, itr - buf, data);
+               if (result != 0)
+                       break;
+       }
+       return result;
+}
+EXPORT_SYMBOL_GPL(uwb_ie_for_each);
+
+
+/**
+ * Replace all IEs currently being transmitted by a device
+ *
+ * @cmd:    pointer to the SET-IE command with the IEs to set
+ * @size:   size of @buf
+ */
+int uwb_rc_set_ie(struct uwb_rc *rc, struct uwb_rc_cmd_set_ie *cmd)
+{
+       int result;
+       struct device *dev = &rc->uwb_dev.dev;
+       struct uwb_rc_evt_set_ie reply;
+
+       reply.rceb.bEventType = UWB_RC_CET_GENERAL;
+       reply.rceb.wEvent = UWB_RC_CMD_SET_IE;
+       result = uwb_rc_cmd(rc, "SET-IE", &cmd->rccb,
+                           sizeof(*cmd) + le16_to_cpu(cmd->wIELength),
+                           &reply.rceb, sizeof(reply));
+       if (result < 0)
+               goto error_cmd;
+       else if (result != sizeof(reply)) {
+               dev_err(dev, "SET-IE: not enough data to decode reply "
+                       "(%d bytes received vs %zu needed)\n",
+                       result, sizeof(reply));
+               result = -EIO;
+       } else if (reply.bResultCode != UWB_RC_RES_SUCCESS) {
+               dev_err(dev, "SET-IE: command execution failed: %s (%d)\n",
+                       uwb_rc_strerror(reply.bResultCode), reply.bResultCode);
+               result = -EIO;
+       } else
+               result = 0;
+error_cmd:
+       return result;
+}
+
+/**
+ * Determine by IE id if IE is host settable
+ * WUSB 1.0 [8.6.2.8 Table 8.85]
+ *
+ * EXCEPTION:
+ * All but UWB_IE_WLP appears in Table 8.85 from WUSB 1.0. Setting this IE
+ * is required for the WLP substack to perform association with its WSS so
+ * we hope that the WUSB spec will be changed to reflect this.
+ */
+static
+int uwb_rc_ie_is_host_settable(enum uwb_ie element_id)
+{
+       if (element_id == UWB_PCA_AVAILABILITY ||
+           element_id == UWB_BP_SWITCH_IE ||
+           element_id == UWB_MAC_CAPABILITIES_IE ||
+           element_id == UWB_PHY_CAPABILITIES_IE ||
+           element_id == UWB_APP_SPEC_PROBE_IE ||
+           element_id == UWB_IDENTIFICATION_IE ||
+           element_id == UWB_MASTER_KEY_ID_IE ||
+           element_id == UWB_IE_WLP ||
+           element_id == UWB_APP_SPEC_IE)
+               return 1;
+       return 0;
+}
+
+
+/**
+ * Extract Host Settable IEs from IE
+ *
+ * @ie_data: pointer to buffer containing all IEs
+ * @size:    size of buffer
+ *
+ * @returns: length of buffer that only includes host settable IEs
+ *
+ * Given a buffer of IEs we move all Host Settable IEs to front of buffer
+ * by overwriting the IEs that are not Host Settable.
+ * Buffer length is adjusted accordingly.
+ */
+static
+ssize_t uwb_rc_parse_host_settable_ie(struct uwb_dev *uwb_dev,
+                                     void *ie_data, size_t size)
+{
+       size_t new_len = size;
+       struct uwb_ie_hdr *ie_hdr;
+       size_t ie_length;
+       void *itr = ie_data, *top = itr + size;
+
+       while (itr < top) {
+               if (uwb_rc_ie_verify(uwb_dev, ie_data, itr, top) != 0)
+                       break;
+               ie_hdr = itr;
+               ie_length = sizeof(*ie_hdr) + ie_hdr->length;
+               if (uwb_rc_ie_is_host_settable(ie_hdr->element_id)) {
+                       itr += ie_length;
+               } else {
+                       memmove(itr, itr + ie_length, top - (itr + ie_length));
+                       new_len -= ie_length;
+                       top -= ie_length;
+               }
+       }
+       return new_len;
+}
+
+
+/* Cleanup the whole IE management subsystem */
+void uwb_rc_ie_init(struct uwb_rc *uwb_rc)
+{
+       mutex_init(&uwb_rc->ies_mutex);
+}
+
+
+/**
+ * Set up cache for host settable IEs currently being transmitted
+ *
+ * First we just call GET-IE to get the current IEs being transmitted
+ * (or we workaround and pretend we did) and (because the format is
+ * the same) reuse that as the IE cache (with the command prefix, as
+ * explained in 'struct uwb_rc').
+ *
+ * @returns: size of cache created
+ */
+ssize_t uwb_rc_ie_setup(struct uwb_rc *uwb_rc)
+{
+       struct device *dev = &uwb_rc->uwb_dev.dev;
+       ssize_t result;
+       size_t capacity;
+       struct uwb_rc_evt_get_ie *ie_info;
+
+       d_fnstart(3, dev, "(%p)\n", uwb_rc);
+       mutex_lock(&uwb_rc->ies_mutex);
+       result = uwb_rc_get_ie(uwb_rc, &ie_info);
+       if (result < 0)
+               goto error_get_ie;
+       capacity = result;
+       d_printf(5, dev, "Got IEs %zu bytes (%zu long at %p)\n", result,
+                (size_t)le16_to_cpu(ie_info->wIELength), ie_info);
+
+       /* Remove IEs that host should not set. */
+       result = uwb_rc_parse_host_settable_ie(&uwb_rc->uwb_dev,
+                       ie_info->IEData, le16_to_cpu(ie_info->wIELength));
+       if (result < 0)
+               goto error_parse;
+       d_printf(5, dev, "purged non-settable IEs to %zu bytes\n", result);
+       uwb_rc->ies = (void *) ie_info;
+       uwb_rc->ies->rccb.bCommandType = UWB_RC_CET_GENERAL;
+       uwb_rc->ies->rccb.wCommand = cpu_to_le16(UWB_RC_CMD_SET_IE);
+       uwb_rc->ies_capacity = capacity;
+       d_printf(5, dev, "IE cache at %p %zu bytes, %zu capacity\n",
+                ie_info, result, capacity);
+       result = 0;
+error_parse:
+error_get_ie:
+       mutex_unlock(&uwb_rc->ies_mutex);
+       d_fnend(3, dev, "(%p) = %zu\n", uwb_rc, result);
+       return result;
+}
+
+
+/* Cleanup the whole IE management subsystem */
+void uwb_rc_ie_release(struct uwb_rc *uwb_rc)
+{
+       kfree(uwb_rc->ies);
+       uwb_rc->ies = NULL;
+       uwb_rc->ies_capacity = 0;
+}
+
+
+static
+int __acc_size(struct uwb_dev *uwb_dev, const struct uwb_ie_hdr *ie_hdr,
+              size_t offset, void *_ctx)
+{
+       size_t *acc_size = _ctx;
+       *acc_size += sizeof(*ie_hdr) + ie_hdr->length;
+       d_printf(6, &uwb_dev->dev, "new acc size %zu\n", *acc_size);
+       return 0;
+}
+
+
+/**
+ * Add a new IE to IEs currently being transmitted by device
+ *
+ * @ies: the buffer containing the new IE or IEs to be added to
+ *       the device's beacon. The buffer will be verified for
+ *       consistence (meaning the headers should be right) and
+ *       consistent with the buffer size.
+ * @size: size of @ies (in bytes, total buffer size)
+ * @returns: 0 if ok, <0 errno code on error
+ *
+ * According to WHCI 0.95 [4.13.6] the driver will only receive the RCEB
+ * after the device sent the first beacon that includes the IEs specified
+ * in the SET IE command. We thus cannot send this command if the device is
+ * not beaconing. Instead, a SET IE command will be sent later right after
+ * we start beaconing.
+ *
+ * Setting an IE on the device will overwrite all current IEs in device. So
+ * we take the current IEs being transmitted by the device, append the
+ * new one, and call SET IE with all the IEs needed.
+ *
+ * The local IE cache will only be updated with the new IE if SET IE
+ * completed successfully.
+ */
+int uwb_rc_ie_add(struct uwb_rc *uwb_rc,
+                 const struct uwb_ie_hdr *ies, size_t size)
+{
+       int result = 0;
+       struct device *dev = &uwb_rc->uwb_dev.dev;
+       struct uwb_rc_cmd_set_ie *new_ies;
+       size_t ies_size, total_size, acc_size = 0;
+
+       if (uwb_rc->ies == NULL)
+               return -ESHUTDOWN;
+       uwb_ie_for_each(&uwb_rc->uwb_dev, __acc_size, &acc_size, ies, size);
+       if (acc_size != size) {
+               dev_err(dev, "BUG: bad IEs, misconstructed headers "
+                       "[%zu bytes reported vs %zu calculated]\n",
+                       size, acc_size);
+               WARN_ON(1);
+               return -EINVAL;
+       }
+       mutex_lock(&uwb_rc->ies_mutex);
+       ies_size = le16_to_cpu(uwb_rc->ies->wIELength);
+       total_size = sizeof(*uwb_rc->ies) + ies_size;
+       if (total_size + size > uwb_rc->ies_capacity) {
+               d_printf(4, dev, "Reallocating IE cache from %p capacity %zu "
+                        "to capacity %zu\n", uwb_rc->ies, uwb_rc->ies_capacity,
+                        total_size + size);
+               new_ies = kzalloc(total_size + size, GFP_KERNEL);
+               if (new_ies == NULL) {
+                       dev_err(dev, "No memory for adding new IE\n");
+                       result = -ENOMEM;
+                       goto error_alloc;
+               }
+               memcpy(new_ies, uwb_rc->ies, total_size);
+               uwb_rc->ies_capacity = total_size + size;
+               kfree(uwb_rc->ies);
+               uwb_rc->ies = new_ies;
+               d_printf(4, dev, "New IE cache at %p capacity %zu\n",
+                        uwb_rc->ies, uwb_rc->ies_capacity);
+       }
+       memcpy((void *)uwb_rc->ies + total_size, ies, size);
+       uwb_rc->ies->wIELength = cpu_to_le16(ies_size + size);
+       if (uwb_rc->beaconing != -1) {
+               result = uwb_rc_set_ie(uwb_rc, uwb_rc->ies);
+               if (result < 0) {
+                       dev_err(dev, "Cannot set new IE on device: %d\n",
+                               result);
+                       uwb_rc->ies->wIELength = cpu_to_le16(ies_size);
+               } else
+                       result = 0;
+       }
+       d_printf(4, dev, "IEs now occupy %hu bytes of %zu capacity at %p\n",
+                le16_to_cpu(uwb_rc->ies->wIELength), uwb_rc->ies_capacity,
+                uwb_rc->ies);
+error_alloc:
+       mutex_unlock(&uwb_rc->ies_mutex);
+       return result;
+}
+EXPORT_SYMBOL_GPL(uwb_rc_ie_add);
+
+
+/*
+ * Remove an IE from internal cache
+ *
+ * We are dealing with our internal IE cache so no need to verify that the
+ * IEs are valid (it has been done already).
+ *
+ * Should be called with ies_mutex held
+ *
+ * We do not break out once an IE is found in the cache. It is currently
+ * possible to have more than one IE with the same ID included in the
+ * beacon. We don't reallocate, we just mark the size smaller.
+ */
+static
+int uwb_rc_ie_cache_rm(struct uwb_rc *uwb_rc, enum uwb_ie to_remove)
+{
+       struct uwb_ie_hdr *ie_hdr;
+       size_t new_len = le16_to_cpu(uwb_rc->ies->wIELength);
+       void *itr = uwb_rc->ies->IEData;
+       void *top = itr + new_len;
+
+       while (itr < top) {
+               ie_hdr = itr;
+               if (ie_hdr->element_id != to_remove) {
+                       itr += sizeof(*ie_hdr) + ie_hdr->length;
+               } else {
+                       int ie_length;
+                       ie_length = sizeof(*ie_hdr) + ie_hdr->length;
+                       if (top - itr != ie_length)
+                               memmove(itr, itr + ie_length, top - itr + ie_length);
+                       top -= ie_length;
+                       new_len -= ie_length;
+               }
+       }
+       uwb_rc->ies->wIELength = cpu_to_le16(new_len);
+       return 0;
+}
+
+
+/**
+ * Remove an IE currently being transmitted by device
+ *
+ * @element_id: id of IE to be removed from device's beacon
+ */
+int uwb_rc_ie_rm(struct uwb_rc *uwb_rc, enum uwb_ie element_id)
+{
+       struct device *dev = &uwb_rc->uwb_dev.dev;
+       int result;
+
+       if (uwb_rc->ies == NULL)
+               return -ESHUTDOWN;
+       mutex_lock(&uwb_rc->ies_mutex);
+       result = uwb_rc_ie_cache_rm(uwb_rc, element_id);
+       if (result < 0)
+               dev_err(dev, "Cannot remove IE from cache.\n");
+       if (uwb_rc->beaconing != -1) {
+               result = uwb_rc_set_ie(uwb_rc, uwb_rc->ies);
+               if (result < 0)
+                       dev_err(dev, "Cannot set new IE on device.\n");
+       }
+       mutex_unlock(&uwb_rc->ies_mutex);
+       return result;
+}
+EXPORT_SYMBOL_GPL(uwb_rc_ie_rm);
diff --git a/drivers/uwb/lc-dev.c b/drivers/uwb/lc-dev.c
new file mode 100644 (file)
index 0000000..15f856c
--- /dev/null
@@ -0,0 +1,492 @@
+/*
+ * Ultra Wide Band
+ * Life cycle of devices
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/kdev_t.h>
+#include <linux/random.h>
+#include "uwb-internal.h"
+
+#define D_LOCAL 1
+#include <linux/uwb/debug.h>
+
+
+/* We initialize addresses to 0xff (invalid, as it is bcast) */
+static inline void uwb_dev_addr_init(struct uwb_dev_addr *addr)
+{
+       memset(&addr->data, 0xff, sizeof(addr->data));
+}
+
+static inline void uwb_mac_addr_init(struct uwb_mac_addr *addr)
+{
+       memset(&addr->data, 0xff, sizeof(addr->data));
+}
+
+/* @returns !0 if a device @addr is a broadcast address */
+static inline int uwb_dev_addr_bcast(const struct uwb_dev_addr *addr)
+{
+       static const struct uwb_dev_addr bcast = { .data = { 0xff, 0xff } };
+       return !uwb_dev_addr_cmp(addr, &bcast);
+}
+
+/*
+ * Add callback @new to be called when an event occurs in @rc.
+ */
+int uwb_notifs_register(struct uwb_rc *rc, struct uwb_notifs_handler *new)
+{
+       if (mutex_lock_interruptible(&rc->notifs_chain.mutex))
+               return -ERESTARTSYS;
+       list_add(&new->list_node, &rc->notifs_chain.list);
+       mutex_unlock(&rc->notifs_chain.mutex);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(uwb_notifs_register);
+
+/*
+ * Remove event handler (callback)
+ */
+int uwb_notifs_deregister(struct uwb_rc *rc, struct uwb_notifs_handler *entry)
+{
+       if (mutex_lock_interruptible(&rc->notifs_chain.mutex))
+               return -ERESTARTSYS;
+       list_del(&entry->list_node);
+       mutex_unlock(&rc->notifs_chain.mutex);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(uwb_notifs_deregister);
+
+/*
+ * Notify all event handlers of a given event on @rc
+ *
+ * We are called with a valid reference to the device, or NULL if the
+ * event is not for a particular event (e.g., a BG join event).
+ */
+void uwb_notify(struct uwb_rc *rc, struct uwb_dev *uwb_dev, enum uwb_notifs event)
+{
+       struct uwb_notifs_handler *handler;
+       if (mutex_lock_interruptible(&rc->notifs_chain.mutex))
+               return;
+       if (!list_empty(&rc->notifs_chain.list)) {
+               list_for_each_entry(handler, &rc->notifs_chain.list, list_node) {
+                       handler->cb(handler->data, uwb_dev, event);
+               }
+       }
+       mutex_unlock(&rc->notifs_chain.mutex);
+}
+
+/*
+ * Release the backing device of a uwb_dev that has been dynamically allocated.
+ */
+static void uwb_dev_sys_release(struct device *dev)
+{
+       struct uwb_dev *uwb_dev = to_uwb_dev(dev);
+
+       d_fnstart(4, NULL, "(dev %p uwb_dev %p)\n", dev, uwb_dev);
+       uwb_bce_put(uwb_dev->bce);
+       d_printf(0, &uwb_dev->dev, "uwb_dev %p freed\n", uwb_dev);
+       memset(uwb_dev, 0x69, sizeof(*uwb_dev));
+       kfree(uwb_dev);
+       d_fnend(4, NULL, "(dev %p uwb_dev %p) = void\n", dev, uwb_dev);
+}
+
+/*
+ * Initialize a UWB device instance
+ *
+ * Alloc, zero and call this function.
+ */
+void uwb_dev_init(struct uwb_dev *uwb_dev)
+{
+       mutex_init(&uwb_dev->mutex);
+       device_initialize(&uwb_dev->dev);
+       uwb_dev->dev.release = uwb_dev_sys_release;
+       uwb_dev_addr_init(&uwb_dev->dev_addr);
+       uwb_mac_addr_init(&uwb_dev->mac_addr);
+       bitmap_fill(uwb_dev->streams, UWB_NUM_GLOBAL_STREAMS);
+}
+
+static ssize_t uwb_dev_EUI_48_show(struct device *dev,
+                                  struct device_attribute *attr, char *buf)
+{
+       struct uwb_dev *uwb_dev = to_uwb_dev(dev);
+       char addr[UWB_ADDR_STRSIZE];
+
+       uwb_mac_addr_print(addr, sizeof(addr), &uwb_dev->mac_addr);
+       return sprintf(buf, "%s\n", addr);
+}
+static DEVICE_ATTR(EUI_48, S_IRUGO, uwb_dev_EUI_48_show, NULL);
+
+static ssize_t uwb_dev_DevAddr_show(struct device *dev,
+                                   struct device_attribute *attr, char *buf)
+{
+       struct uwb_dev *uwb_dev = to_uwb_dev(dev);
+       char addr[UWB_ADDR_STRSIZE];
+
+       uwb_dev_addr_print(addr, sizeof(addr), &uwb_dev->dev_addr);
+       return sprintf(buf, "%s\n", addr);
+}
+static DEVICE_ATTR(DevAddr, S_IRUGO, uwb_dev_DevAddr_show, NULL);
+
+/*
+ * Show the BPST of this device.
+ *
+ * Calculated from the receive time of the device's beacon and it's
+ * slot number.
+ */
+static ssize_t uwb_dev_BPST_show(struct device *dev,
+                                struct device_attribute *attr, char *buf)
+{
+       struct uwb_dev *uwb_dev = to_uwb_dev(dev);
+       struct uwb_beca_e *bce;
+       struct uwb_beacon_frame *bf;
+       u16 bpst;
+
+       bce = uwb_dev->bce;
+       mutex_lock(&bce->mutex);
+       bf = (struct uwb_beacon_frame *)bce->be->BeaconInfo;
+       bpst = bce->be->wBPSTOffset
+               - (u16)(bf->Beacon_Slot_Number * UWB_BEACON_SLOT_LENGTH_US);
+       mutex_unlock(&bce->mutex);
+
+       return sprintf(buf, "%d\n", bpst);
+}
+static DEVICE_ATTR(BPST, S_IRUGO, uwb_dev_BPST_show, NULL);
+
+/*
+ * Show the IEs a device is beaconing
+ *
+ * We need to access the beacon cache, so we just lock it really
+ * quick, print the IEs and unlock.
+ *
+ * We have a reference on the cache entry, so that should be
+ * quite safe.
+ */
+static ssize_t uwb_dev_IEs_show(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct uwb_dev *uwb_dev = to_uwb_dev(dev);
+
+       return uwb_bce_print_IEs(uwb_dev, uwb_dev->bce, buf, PAGE_SIZE);
+}
+static DEVICE_ATTR(IEs, S_IRUGO | S_IWUSR, uwb_dev_IEs_show, NULL);
+
+static ssize_t uwb_dev_LQE_show(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct uwb_dev *uwb_dev = to_uwb_dev(dev);
+       struct uwb_beca_e *bce = uwb_dev->bce;
+       size_t result;
+
+       mutex_lock(&bce->mutex);
+       result = stats_show(&uwb_dev->bce->lqe_stats, buf);
+       mutex_unlock(&bce->mutex);
+       return result;
+}
+
+static ssize_t uwb_dev_LQE_store(struct device *dev,
+                                struct device_attribute *attr,
+                                const char *buf, size_t size)
+{
+       struct uwb_dev *uwb_dev = to_uwb_dev(dev);
+       struct uwb_beca_e *bce = uwb_dev->bce;
+       ssize_t result;
+
+       mutex_lock(&bce->mutex);
+       result = stats_store(&uwb_dev->bce->lqe_stats, buf, size);
+       mutex_unlock(&bce->mutex);
+       return result;
+}
+static DEVICE_ATTR(LQE, S_IRUGO | S_IWUSR, uwb_dev_LQE_show, uwb_dev_LQE_store);
+
+static ssize_t uwb_dev_RSSI_show(struct device *dev,
+                                struct device_attribute *attr, char *buf)
+{
+       struct uwb_dev *uwb_dev = to_uwb_dev(dev);
+       struct uwb_beca_e *bce = uwb_dev->bce;
+       size_t result;
+
+       mutex_lock(&bce->mutex);
+       result = stats_show(&uwb_dev->bce->rssi_stats, buf);
+       mutex_unlock(&bce->mutex);
+       return result;
+}
+
+static ssize_t uwb_dev_RSSI_store(struct device *dev,
+                                 struct device_attribute *attr,
+                                 const char *buf, size_t size)
+{
+       struct uwb_dev *uwb_dev = to_uwb_dev(dev);
+       struct uwb_beca_e *bce = uwb_dev->bce;
+       ssize_t result;
+
+       mutex_lock(&bce->mutex);
+       result = stats_store(&uwb_dev->bce->rssi_stats, buf, size);
+       mutex_unlock(&bce->mutex);
+       return result;
+}
+static DEVICE_ATTR(RSSI, S_IRUGO | S_IWUSR, uwb_dev_RSSI_show, uwb_dev_RSSI_store);
+
+
+static struct attribute *dev_attrs[] = {
+       &dev_attr_EUI_48.attr,
+       &dev_attr_DevAddr.attr,
+       &dev_attr_BPST.attr,
+       &dev_attr_IEs.attr,
+       &dev_attr_LQE.attr,
+       &dev_attr_RSSI.attr,
+       NULL,
+};
+
+static struct attribute_group dev_attr_group = {
+       .attrs = dev_attrs,
+};
+
+static struct attribute_group *groups[] = {
+       &dev_attr_group,
+       NULL,
+};
+
+/**
+ * Device SYSFS registration
+ *
+ *
+ */
+static int __uwb_dev_sys_add(struct uwb_dev *uwb_dev, struct device *parent_dev)
+{
+       int result;
+       struct device *dev;
+
+       d_fnstart(4, NULL, "(uwb_dev %p parent_dev %p)\n", uwb_dev, parent_dev);
+       BUG_ON(parent_dev == NULL);
+
+       dev = &uwb_dev->dev;
+       /* Device sysfs files are only useful for neighbor devices not
+          local radio controllers. */
+       if (&uwb_dev->rc->uwb_dev != uwb_dev)
+               dev->groups = groups;
+       dev->parent = parent_dev;
+       dev_set_drvdata(dev, uwb_dev);
+
+       result = device_add(dev);
+       d_fnend(4, NULL, "(uwb_dev %p parent_dev %p) = %d\n", uwb_dev, parent_dev, result);
+       return result;
+}
+
+
+static void __uwb_dev_sys_rm(struct uwb_dev *uwb_dev)
+{
+       d_fnstart(4, NULL, "(uwb_dev %p)\n", uwb_dev);
+       dev_set_drvdata(&uwb_dev->dev, NULL);
+       device_del(&uwb_dev->dev);
+       d_fnend(4, NULL, "(uwb_dev %p) = void\n", uwb_dev);
+}
+
+
+/**
+ * Register and initialize a new UWB device
+ *
+ * Did you call uwb_dev_init() on it?
+ *
+ * @parent_rc: is the parent radio controller who has the link to the
+ *             device. When registering the UWB device that is a UWB
+ *             Radio Controller, we point back to it.
+ *
+ * If registering the device that is part of a radio, caller has set
+ * rc->uwb_dev->dev. Otherwise it is to be left NULL--a new one will
+ * be allocated.
+ */
+int uwb_dev_add(struct uwb_dev *uwb_dev, struct device *parent_dev,
+               struct uwb_rc *parent_rc)
+{
+       int result;
+       struct device *dev;
+
+       BUG_ON(uwb_dev == NULL);
+       BUG_ON(parent_dev == NULL);
+       BUG_ON(parent_rc == NULL);
+
+       mutex_lock(&uwb_dev->mutex);
+       dev = &uwb_dev->dev;
+       uwb_dev->rc = parent_rc;
+       result = __uwb_dev_sys_add(uwb_dev, parent_dev);
+       if (result < 0)
+               printk(KERN_ERR "UWB: unable to register dev %s with sysfs: %d\n",
+                      dev_name(dev), result);
+       mutex_unlock(&uwb_dev->mutex);
+       return result;
+}
+
+
+void uwb_dev_rm(struct uwb_dev *uwb_dev)
+{
+       mutex_lock(&uwb_dev->mutex);
+       __uwb_dev_sys_rm(uwb_dev);
+       mutex_unlock(&uwb_dev->mutex);
+}
+
+
+static
+int __uwb_dev_try_get(struct device *dev, void *__target_uwb_dev)
+{
+       struct uwb_dev *target_uwb_dev = __target_uwb_dev;
+       struct uwb_dev *uwb_dev = to_uwb_dev(dev);
+       if (uwb_dev == target_uwb_dev) {
+               uwb_dev_get(uwb_dev);
+               return 1;
+       } else
+               return 0;
+}
+
+
+/**
+ * Given a UWB device descriptor, validate and refcount it
+ *
+ * @returns NULL if the device does not exist or is quiescing; the ptr to
+ *               it otherwise.
+ */
+struct uwb_dev *uwb_dev_try_get(struct uwb_rc *rc, struct uwb_dev *uwb_dev)
+{
+       if (uwb_dev_for_each(rc, __uwb_dev_try_get, uwb_dev))
+               return uwb_dev;
+       else
+               return NULL;
+}
+EXPORT_SYMBOL_GPL(uwb_dev_try_get);
+
+
+/**
+ * Remove a device from the system [grunt for other functions]
+ */
+int __uwb_dev_offair(struct uwb_dev *uwb_dev, struct uwb_rc *rc)
+{
+       struct device *dev = &uwb_dev->dev;
+       char macbuf[UWB_ADDR_STRSIZE], devbuf[UWB_ADDR_STRSIZE];
+
+       d_fnstart(3, NULL, "(dev %p [uwb_dev %p], uwb_rc %p)\n", dev, uwb_dev, rc);
+       uwb_mac_addr_print(macbuf, sizeof(macbuf), &uwb_dev->mac_addr);
+       uwb_dev_addr_print(devbuf, sizeof(devbuf), &uwb_dev->dev_addr);
+       dev_info(dev, "uwb device (mac %s dev %s) disconnected from %s %s\n",
+                macbuf, devbuf,
+                rc ? rc->uwb_dev.dev.parent->bus->name : "n/a",
+                rc ? dev_name(rc->uwb_dev.dev.parent) : "");
+       uwb_dev_rm(uwb_dev);
+       uwb_dev_put(uwb_dev);   /* for the creation in _onair() */
+       d_fnend(3, NULL, "(dev %p [uwb_dev %p], uwb_rc %p) = 0\n", dev, uwb_dev, rc);
+       return 0;
+}
+
+
+/**
+ * A device went off the air, clean up after it!
+ *
+ * This is called by the UWB Daemon (through the beacon purge function
+ * uwb_bcn_cache_purge) when it is detected that a device has been in
+ * radio silence for a while.
+ *
+ * If this device is actually a local radio controller we don't need
+ * to go through the offair process, as it is not registered as that.
+ *
+ * NOTE: uwb_bcn_cache.mutex is held!
+ */
+void uwbd_dev_offair(struct uwb_beca_e *bce)
+{
+       struct uwb_dev *uwb_dev;
+
+       uwb_dev = bce->uwb_dev;
+       if (uwb_dev) {
+               uwb_notify(uwb_dev->rc, uwb_dev, UWB_NOTIF_OFFAIR);
+               __uwb_dev_offair(uwb_dev, uwb_dev->rc);
+       }
+}
+
+
+/**
+ * A device went on the air, start it up!
+ *
+ * This is called by the UWB Daemon when it is detected that a device
+ * has popped up in the radio range of the radio controller.
+ *
+ * It will just create the freaking device, register the beacon and
+ * stuff and yatla, done.
+ *
+ *
+ * NOTE: uwb_beca.mutex is held, bce->mutex is held
+ */
+void uwbd_dev_onair(struct uwb_rc *rc, struct uwb_beca_e *bce)
+{
+       int result;
+       struct device *dev = &rc->uwb_dev.dev;
+       struct uwb_dev *uwb_dev;
+       char macbuf[UWB_ADDR_STRSIZE], devbuf[UWB_ADDR_STRSIZE];
+
+       uwb_mac_addr_print(macbuf, sizeof(macbuf), bce->mac_addr);
+       uwb_dev_addr_print(devbuf, sizeof(devbuf), &bce->dev_addr);
+       uwb_dev = kzalloc(sizeof(struct uwb_dev), GFP_KERNEL);
+       if (uwb_dev == NULL) {
+               dev_err(dev, "new device %s: Cannot allocate memory\n",
+                       macbuf);
+               return;
+       }
+       uwb_dev_init(uwb_dev);          /* This sets refcnt to one, we own it */
+       uwb_dev->mac_addr = *bce->mac_addr;
+       uwb_dev->dev_addr = bce->dev_addr;
+       dev_set_name(&uwb_dev->dev, macbuf);
+       result = uwb_dev_add(uwb_dev, &rc->uwb_dev.dev, rc);
+       if (result < 0) {
+               dev_err(dev, "new device %s: cannot instantiate device\n",
+                       macbuf);
+               goto error_dev_add;
+       }
+       /* plug the beacon cache */
+       bce->uwb_dev = uwb_dev;
+       uwb_dev->bce = bce;
+       uwb_bce_get(bce);               /* released in uwb_dev_sys_release() */
+       dev_info(dev, "uwb device (mac %s dev %s) connected to %s %s\n",
+                macbuf, devbuf, rc->uwb_dev.dev.parent->bus->name,
+                dev_name(rc->uwb_dev.dev.parent));
+       uwb_notify(rc, uwb_dev, UWB_NOTIF_ONAIR);
+       return;
+
+error_dev_add:
+       kfree(uwb_dev);
+       return;
+}
+
+/**
+ * Iterate over the list of UWB devices, calling a @function on each
+ *
+ * See docs for bus_for_each()....
+ *
+ * @rc:       radio controller for the devices.
+ * @function: function to call.
+ * @priv:     data to pass to @function.
+ * @returns:  0 if no invocation of function() returned a value
+ *            different to zero. That value otherwise.
+ */
+int uwb_dev_for_each(struct uwb_rc *rc, uwb_dev_for_each_f function, void *priv)
+{
+       return device_for_each_child(&rc->uwb_dev.dev, priv, function);
+}
+EXPORT_SYMBOL_GPL(uwb_dev_for_each);
diff --git a/drivers/uwb/lc-rc.c b/drivers/uwb/lc-rc.c
new file mode 100644 (file)
index 0000000..ee5772f
--- /dev/null
@@ -0,0 +1,495 @@
+/*
+ * Ultra Wide Band
+ * Life cycle of radio controllers
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ *
+ * A UWB radio controller is also a UWB device, so it embeds one...
+ *
+ * List of RCs comes from the 'struct class uwb_rc_class'.
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/random.h>
+#include <linux/kdev_t.h>
+#include <linux/etherdevice.h>
+#include <linux/usb.h>
+
+#define D_LOCAL 1
+#include <linux/uwb/debug.h>
+#include "uwb-internal.h"
+
+static int uwb_rc_index_match(struct device *dev, void *data)
+{
+       int *index = data;
+       struct uwb_rc *rc = dev_get_drvdata(dev);
+
+       if (rc->index == *index)
+               return 1;
+       return 0;
+}
+
+static struct uwb_rc *uwb_rc_find_by_index(int index)
+{
+       struct device *dev;
+       struct uwb_rc *rc = NULL;
+
+       dev = class_find_device(&uwb_rc_class, NULL, &index, uwb_rc_index_match);
+       if (dev)
+               rc = dev_get_drvdata(dev);
+       return rc;
+}
+
+static int uwb_rc_new_index(void)
+{
+       int index = 0;
+
+       for (;;) {
+               if (!uwb_rc_find_by_index(index))
+                       return index;
+               if (++index < 0)
+                       index = 0;
+       }
+}
+
+/**
+ * Release the backing device of a uwb_rc that has been dynamically allocated.
+ */
+static void uwb_rc_sys_release(struct device *dev)
+{
+       struct uwb_dev *uwb_dev = container_of(dev, struct uwb_dev, dev);
+       struct uwb_rc *rc = container_of(uwb_dev, struct uwb_rc, uwb_dev);
+
+       uwb_rc_neh_destroy(rc);
+       uwb_rc_ie_release(rc);
+       d_printf(1, dev, "freed uwb_rc %p\n", rc);
+       kfree(rc);
+}
+
+
+void uwb_rc_init(struct uwb_rc *rc)
+{
+       struct uwb_dev *uwb_dev = &rc->uwb_dev;
+
+       uwb_dev_init(uwb_dev);
+       rc->uwb_dev.dev.class = &uwb_rc_class;
+       rc->uwb_dev.dev.release = uwb_rc_sys_release;
+       uwb_rc_neh_create(rc);
+       rc->beaconing = -1;
+       rc->scan_type = UWB_SCAN_DISABLED;
+       INIT_LIST_HEAD(&rc->notifs_chain.list);
+       mutex_init(&rc->notifs_chain.mutex);
+       uwb_drp_avail_init(rc);
+       uwb_rc_ie_init(rc);
+       uwb_rsv_init(rc);
+       uwb_rc_pal_init(rc);
+}
+EXPORT_SYMBOL_GPL(uwb_rc_init);
+
+
+struct uwb_rc *uwb_rc_alloc(void)
+{
+       struct uwb_rc *rc;
+       rc = kzalloc(sizeof(*rc), GFP_KERNEL);
+       if (rc == NULL)
+               return NULL;
+       uwb_rc_init(rc);
+       return rc;
+}
+EXPORT_SYMBOL_GPL(uwb_rc_alloc);
+
+static struct attribute *rc_attrs[] = {
+               &dev_attr_mac_address.attr,
+               &dev_attr_scan.attr,
+               &dev_attr_beacon.attr,
+               NULL,
+};
+
+static struct attribute_group rc_attr_group = {
+       .attrs = rc_attrs,
+};
+
+/*
+ * Registration of sysfs specific stuff
+ */
+static int uwb_rc_sys_add(struct uwb_rc *rc)
+{
+       return sysfs_create_group(&rc->uwb_dev.dev.kobj, &rc_attr_group);
+}
+
+
+static void __uwb_rc_sys_rm(struct uwb_rc *rc)
+{
+       sysfs_remove_group(&rc->uwb_dev.dev.kobj, &rc_attr_group);
+}
+
+/**
+ * uwb_rc_mac_addr_setup - get an RC's EUI-48 address or set it
+ * @rc:  the radio controller.
+ *
+ * If the EUI-48 address is 00:00:00:00:00:00 or FF:FF:FF:FF:FF:FF
+ * then a random locally administered EUI-48 is generated and set on
+ * the device.  The probability of address collisions is sufficiently
+ * unlikely (1/2^40 = 9.1e-13) that they're not checked for.
+ */
+static
+int uwb_rc_mac_addr_setup(struct uwb_rc *rc)
+{
+       int result;
+       struct device *dev = &rc->uwb_dev.dev;
+       struct uwb_dev *uwb_dev = &rc->uwb_dev;
+       char devname[UWB_ADDR_STRSIZE];
+       struct uwb_mac_addr addr;
+
+       result = uwb_rc_mac_addr_get(rc, &addr);
+       if (result < 0) {
+               dev_err(dev, "cannot retrieve UWB EUI-48 address: %d\n", result);
+               return result;
+       }
+
+       if (uwb_mac_addr_unset(&addr) || uwb_mac_addr_bcast(&addr)) {
+               addr.data[0] = 0x02; /* locally adminstered and unicast */
+               get_random_bytes(&addr.data[1], sizeof(addr.data)-1);
+
+               result = uwb_rc_mac_addr_set(rc, &addr);
+               if (result < 0) {
+                       uwb_mac_addr_print(devname, sizeof(devname), &addr);
+                       dev_err(dev, "cannot set EUI-48 address %s: %d\n",
+                               devname, result);
+                       return result;
+               }
+       }
+       uwb_dev->mac_addr = addr;
+       return 0;
+}
+
+
+
+static int uwb_rc_setup(struct uwb_rc *rc)
+{
+       int result;
+       struct device *dev = &rc->uwb_dev.dev;
+
+       result = uwb_rc_reset(rc);
+       if (result < 0) {
+               dev_err(dev, "cannot reset UWB radio: %d\n", result);
+               goto error;
+       }
+       result = uwb_rc_mac_addr_setup(rc);
+       if (result < 0) {
+               dev_err(dev, "cannot setup UWB MAC address: %d\n", result);
+               goto error;
+       }
+       result = uwb_rc_dev_addr_assign(rc);
+       if (result < 0) {
+               dev_err(dev, "cannot assign UWB DevAddr: %d\n", result);
+               goto error;
+       }
+       result = uwb_rc_ie_setup(rc);
+       if (result < 0) {
+               dev_err(dev, "cannot setup IE subsystem: %d\n", result);
+               goto error_ie_setup;
+       }
+       result = uwb_rsv_setup(rc);
+       if (result < 0) {
+               dev_err(dev, "cannot setup reservation subsystem: %d\n", result);
+               goto error_rsv_setup;
+       }
+       uwb_dbg_add_rc(rc);
+       return 0;
+
+error_rsv_setup:
+       uwb_rc_ie_release(rc);
+error_ie_setup:
+error:
+       return result;
+}
+
+
+/**
+ * Register a new UWB radio controller
+ *
+ * Did you call uwb_rc_init() on your rc?
+ *
+ * We assume that this is being called with a > 0 refcount on
+ * it [through ops->{get|put}_device(). We'll take our own, though.
+ *
+ * @parent_dev is our real device, the one that provides the actual UWB device
+ */
+int uwb_rc_add(struct uwb_rc *rc, struct device *parent_dev, void *priv)
+{
+       int result;
+       struct device *dev;
+       char macbuf[UWB_ADDR_STRSIZE], devbuf[UWB_ADDR_STRSIZE];
+
+       rc->index = uwb_rc_new_index();
+
+       dev = &rc->uwb_dev.dev;
+       dev_set_name(dev, "uwb%d", rc->index);
+
+       rc->priv = priv;
+
+       result = rc->start(rc);
+       if (result < 0)
+               goto error_rc_start;
+
+       result = uwb_rc_setup(rc);
+       if (result < 0) {
+               dev_err(dev, "cannot setup UWB radio controller: %d\n", result);
+               goto error_rc_setup;
+       }
+
+       result = uwb_dev_add(&rc->uwb_dev, parent_dev, rc);
+       if (result < 0 && result != -EADDRNOTAVAIL)
+               goto error_dev_add;
+
+       result = uwb_rc_sys_add(rc);
+       if (result < 0) {
+               dev_err(parent_dev, "cannot register UWB radio controller "
+                       "dev attributes: %d\n", result);
+               goto error_sys_add;
+       }
+
+       uwb_mac_addr_print(macbuf, sizeof(macbuf), &rc->uwb_dev.mac_addr);
+       uwb_dev_addr_print(devbuf, sizeof(devbuf), &rc->uwb_dev.dev_addr);
+       dev_info(dev,
+                "new uwb radio controller (mac %s dev %s) on %s %s\n",
+                macbuf, devbuf, parent_dev->bus->name, dev_name(parent_dev));
+       rc->ready = 1;
+       return 0;
+
+error_sys_add:
+       uwb_dev_rm(&rc->uwb_dev);
+error_dev_add:
+error_rc_setup:
+       rc->stop(rc);
+       uwbd_flush(rc);
+error_rc_start:
+       return result;
+}
+EXPORT_SYMBOL_GPL(uwb_rc_add);
+
+
+static int uwb_dev_offair_helper(struct device *dev, void *priv)
+{
+       struct uwb_dev *uwb_dev = to_uwb_dev(dev);
+
+       return __uwb_dev_offair(uwb_dev, uwb_dev->rc);
+}
+
+/*
+ * Remove a Radio Controller; stop beaconing/scanning, disconnect all children
+ */
+void uwb_rc_rm(struct uwb_rc *rc)
+{
+       rc->ready = 0;
+
+       uwb_dbg_del_rc(rc);
+       uwb_rsv_cleanup(rc);
+       uwb_rc_ie_rm(rc, UWB_IDENTIFICATION_IE);
+       if (rc->beaconing >= 0)
+               uwb_rc_beacon(rc, -1, 0);
+       if (rc->scan_type != UWB_SCAN_DISABLED)
+               uwb_rc_scan(rc, rc->scanning, UWB_SCAN_DISABLED, 0);
+       uwb_rc_reset(rc);
+
+       rc->stop(rc);
+       uwbd_flush(rc);
+
+       uwb_dev_lock(&rc->uwb_dev);
+       rc->priv = NULL;
+       rc->cmd = NULL;
+       uwb_dev_unlock(&rc->uwb_dev);
+       mutex_lock(&uwb_beca.mutex);
+       uwb_dev_for_each(rc, uwb_dev_offair_helper, NULL);
+       __uwb_rc_sys_rm(rc);
+       mutex_unlock(&uwb_beca.mutex);
+       uwb_dev_rm(&rc->uwb_dev);
+}
+EXPORT_SYMBOL_GPL(uwb_rc_rm);
+
+static int find_rc_try_get(struct device *dev, void *data)
+{
+       struct uwb_rc *target_rc = data;
+       struct uwb_rc *rc = dev_get_drvdata(dev);
+
+       if (rc == NULL) {
+               WARN_ON(1);
+               return 0;
+       }
+       if (rc == target_rc) {
+               if (rc->ready == 0)
+                       return 0;
+               else
+                       return 1;
+       }
+       return 0;
+}
+
+/**
+ * Given a radio controller descriptor, validate and refcount it
+ *
+ * @returns NULL if the rc does not exist or is quiescing; the ptr to
+ *               it otherwise.
+ */
+struct uwb_rc *__uwb_rc_try_get(struct uwb_rc *target_rc)
+{
+       struct device *dev;
+       struct uwb_rc *rc = NULL;
+
+       dev = class_find_device(&uwb_rc_class, NULL, target_rc,
+                               find_rc_try_get);
+       if (dev) {
+               rc = dev_get_drvdata(dev);
+               __uwb_rc_get(rc);
+       }
+       return rc;
+}
+EXPORT_SYMBOL_GPL(__uwb_rc_try_get);
+
+/*
+ * RC get for external refcount acquirers...
+ *
+ * Increments the refcount of the device and it's backend modules
+ */
+static inline struct uwb_rc *uwb_rc_get(struct uwb_rc *rc)
+{
+       if (rc->ready == 0)
+               return NULL;
+       uwb_dev_get(&rc->uwb_dev);
+       return rc;
+}
+
+static int find_rc_grandpa(struct device *dev, void *data)
+{
+       struct device *grandpa_dev = data;
+       struct uwb_rc *rc = dev_get_drvdata(dev);
+
+       if (rc->uwb_dev.dev.parent->parent == grandpa_dev) {
+               rc = uwb_rc_get(rc);
+               return 1;
+       }
+       return 0;
+}
+
+/**
+ * Locate and refcount a radio controller given a common grand-parent
+ *
+ * @grandpa_dev  Pointer to the 'grandparent' device structure.
+ * @returns NULL If the rc does not exist or is quiescing; the ptr to
+ *               it otherwise, properly referenced.
+ *
+ * The Radio Control interface (or the UWB Radio Controller) is always
+ * an interface of a device. The parent is the interface, the
+ * grandparent is the device that encapsulates the interface.
+ *
+ * There is no need to lock around as the "grandpa" would be
+ * refcounted by the target, and to remove the referemes, the
+ * uwb_rc_class->sem would have to be taken--we hold it, ergo we
+ * should be safe.
+ */
+struct uwb_rc *uwb_rc_get_by_grandpa(const struct device *grandpa_dev)
+{
+       struct device *dev;
+       struct uwb_rc *rc = NULL;
+
+       dev = class_find_device(&uwb_rc_class, NULL, (void *)grandpa_dev,
+                               find_rc_grandpa);
+       if (dev)
+               rc = dev_get_drvdata(dev);
+       return rc;
+}
+EXPORT_SYMBOL_GPL(uwb_rc_get_by_grandpa);
+
+/**
+ * Find a radio controller by device address
+ *
+ * @returns the pointer to the radio controller, properly referenced
+ */
+static int find_rc_dev(struct device *dev, void *data)
+{
+       struct uwb_dev_addr *addr = data;
+       struct uwb_rc *rc = dev_get_drvdata(dev);
+
+       if (rc == NULL) {
+               WARN_ON(1);
+               return 0;
+       }
+       if (!uwb_dev_addr_cmp(&rc->uwb_dev.dev_addr, addr)) {
+               rc = uwb_rc_get(rc);
+               return 1;
+       }
+       return 0;
+}
+
+struct uwb_rc *uwb_rc_get_by_dev(const struct uwb_dev_addr *addr)
+{
+       struct device *dev;
+       struct uwb_rc *rc = NULL;
+
+       dev = class_find_device(&uwb_rc_class, NULL, (void *)addr,
+                               find_rc_dev);
+       if (dev)
+               rc = dev_get_drvdata(dev);
+
+       return rc;
+}
+EXPORT_SYMBOL_GPL(uwb_rc_get_by_dev);
+
+/**
+ * Drop a reference on a radio controller
+ *
+ * This is the version that should be done by entities external to the
+ * UWB Radio Control stack (ie: clients of the API).
+ */
+void uwb_rc_put(struct uwb_rc *rc)
+{
+       __uwb_rc_put(rc);
+}
+EXPORT_SYMBOL_GPL(uwb_rc_put);
+
+/*
+ *
+ *
+ */
+ssize_t uwb_rc_print_IEs(struct uwb_rc *uwb_rc, char *buf, size_t size)
+{
+       ssize_t result;
+       struct uwb_rc_evt_get_ie *ie_info;
+       struct uwb_buf_ctx ctx;
+
+       result = uwb_rc_get_ie(uwb_rc, &ie_info);
+       if (result < 0)
+               goto error_get_ie;
+       ctx.buf = buf;
+       ctx.size = size;
+       ctx.bytes = 0;
+       uwb_ie_for_each(&uwb_rc->uwb_dev, uwb_ie_dump_hex, &ctx,
+                       ie_info->IEData, result - sizeof(*ie_info));
+       result = ctx.bytes;
+       kfree(ie_info);
+error_get_ie:
+       return result;
+}
+
diff --git a/drivers/uwb/neh.c b/drivers/uwb/neh.c
new file mode 100644 (file)
index 0000000..9b4eb64
--- /dev/null
@@ -0,0 +1,616 @@
+/*
+ * WUSB Wire Adapter: Radio Control Interface (WUSB[8])
+ * Notification and Event Handling
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * The RC interface of the Host Wire Adapter (USB dongle) or WHCI PCI
+ * card delivers a stream of notifications and events to the
+ * notification end event endpoint or area. This code takes care of
+ * getting a buffer with that data, breaking it up in separate
+ * notifications and events and then deliver those.
+ *
+ * Events are answers to commands and they carry a context ID that
+ * associates them to the command. Notifications are that,
+ * notifications, they come out of the blue and have a context ID of
+ * zero. Think of the context ID kind of like a handler. The
+ * uwb_rc_neh_* code deals with managing context IDs.
+ *
+ * This is why you require a handle to operate on a UWB host. When you
+ * open a handle a context ID is assigned to you.
+ *
+ * So, as it is done is:
+ *
+ * 1. Add an event handler [uwb_rc_neh_add()] (assigns a ctx id)
+ * 2. Issue command [rc->cmd(rc, ...)]
+ * 3. Arm the timeout timer [uwb_rc_neh_arm()]
+ * 4, Release the reference to the neh [uwb_rc_neh_put()]
+ * 5. Wait for the callback
+ * 6. Command result (RCEB) is passed to the callback
+ *
+ * If (2) fails, you should remove the handle [uwb_rc_neh_rm()]
+ * instead of arming the timer.
+ *
+ * Handles are for using in *serialized* code, single thread.
+ *
+ * When the notification/event comes, the IRQ handler/endpoint
+ * callback passes the data read to uwb_rc_neh_grok() which will break
+ * it up in a discrete series of events, look up who is listening for
+ * them and execute the pertinent callbacks.
+ *
+ * If the reader detects an error while reading the data stream, call
+ * uwb_rc_neh_error().
+ *
+ * CONSTRAINTS/ASSUMPTIONS:
+ *
+ * - Most notifications/events are small (less thank .5k), copying
+ *   around is ok.
+ *
+ * - Notifications/events are ALWAYS smaller than PAGE_SIZE
+ *
+ * - Notifications/events always come in a single piece (ie: a buffer
+ *   will always contain entire notifications/events).
+ *
+ * - we cannot know in advance how long each event is (because they
+ *   lack a length field in their header--smart move by the standards
+ *   body, btw). So we need a facility to get the event size given the
+ *   header. This is what the EST code does (notif/Event Size
+ *   Tables), check nest.c--as well, you can associate the size to
+ *   the handle [w/ neh->extra_size()].
+ *
+ * - Most notifications/events are fixed size; only a few are variable
+ *   size (NEST takes care of that).
+ *
+ * - Listeners of events expect them, so they usually provide a
+ *   buffer, as they know the size. Listeners to notifications don't,
+ *   so we allocate their buffers dynamically.
+ */
+#include <linux/kernel.h>
+#include <linux/timer.h>
+#include <linux/err.h>
+
+#include "uwb-internal.h"
+#define D_LOCAL 0
+#include <linux/uwb/debug.h>
+
+/*
+ * UWB Radio Controller Notification/Event Handle
+ *
+ * Represents an entity waiting for an event coming from the UWB Radio
+ * Controller with a given context id (context) and type (evt_type and
+ * evt). On reception of the notification/event, the callback (cb) is
+ * called with the event.
+ *
+ * If the timer expires before the event is received, the callback is
+ * called with -ETIMEDOUT as the event size.
+ */
+struct uwb_rc_neh {
+       struct kref kref;
+
+       struct uwb_rc *rc;
+       u8 evt_type;
+       __le16 evt;
+       u8 context;
+       uwb_rc_cmd_cb_f cb;
+       void *arg;
+
+       struct timer_list timer;
+       struct list_head list_node;
+};
+
+static void uwb_rc_neh_timer(unsigned long arg);
+
+static void uwb_rc_neh_release(struct kref *kref)
+{
+       struct uwb_rc_neh *neh = container_of(kref, struct uwb_rc_neh, kref);
+
+       kfree(neh);
+}
+
+static void uwb_rc_neh_get(struct uwb_rc_neh *neh)
+{
+       kref_get(&neh->kref);
+}
+
+/**
+ * uwb_rc_neh_put - release reference to a neh
+ * @neh: the neh
+ */
+void uwb_rc_neh_put(struct uwb_rc_neh *neh)
+{
+       kref_put(&neh->kref, uwb_rc_neh_release);
+}
+
+
+/**
+ * Assigns @neh a context id from @rc's pool
+ *
+ * @rc:            UWB Radio Controller descriptor; @rc->neh_lock taken
+ * @neh:    Notification/Event Handle
+ * @returns 0 if context id was assigned ok; < 0 errno on error (if
+ *         all the context IDs are taken).
+ *
+ * (assumes @wa is locked).
+ *
+ * NOTE: WUSB spec reserves context ids 0x00 for notifications and
+ *      0xff is invalid, so they must not be used. Initialization
+ *      fills up those two in the bitmap so they are not allocated.
+ *
+ * We spread the allocation around to reduce the posiblity of two
+ * consecutive opened @neh's getting the same context ID assigned (to
+ * avoid surprises with late events that timed out long time ago). So
+ * first we search from where @rc->ctx_roll is, if not found, we
+ * search from zero.
+ */
+static
+int __uwb_rc_ctx_get(struct uwb_rc *rc, struct uwb_rc_neh *neh)
+{
+       int result;
+       result = find_next_zero_bit(rc->ctx_bm, UWB_RC_CTX_MAX,
+                                   rc->ctx_roll++);
+       if (result < UWB_RC_CTX_MAX)
+               goto found;
+       result = find_first_zero_bit(rc->ctx_bm, UWB_RC_CTX_MAX);
+       if (result < UWB_RC_CTX_MAX)
+               goto found;
+       return -ENFILE;
+found:
+       set_bit(result, rc->ctx_bm);
+       neh->context = result;
+       return 0;
+}
+
+
+/** Releases @neh's context ID back to @rc (@rc->neh_lock is locked). */
+static
+void __uwb_rc_ctx_put(struct uwb_rc *rc, struct uwb_rc_neh *neh)
+{
+       struct device *dev = &rc->uwb_dev.dev;
+       if (neh->context == 0)
+               return;
+       if (test_bit(neh->context, rc->ctx_bm) == 0) {
+               dev_err(dev, "context %u not set in bitmap\n",
+                       neh->context);
+               WARN_ON(1);
+       }
+       clear_bit(neh->context, rc->ctx_bm);
+       neh->context = 0;
+}
+
+/**
+ * uwb_rc_neh_add - add a neh for a radio controller command
+ * @rc:             the radio controller
+ * @cmd:            the radio controller command
+ * @expected_type:  the type of the expected response event
+ * @expected_event: the expected event ID
+ * @cb:             callback for when the event is received
+ * @arg:            argument for the callback
+ *
+ * Creates a neh and adds it to the list of those waiting for an
+ * event.  A context ID will be assigned to the command.
+ */
+struct uwb_rc_neh *uwb_rc_neh_add(struct uwb_rc *rc, struct uwb_rccb *cmd,
+                                 u8 expected_type, u16 expected_event,
+                                 uwb_rc_cmd_cb_f cb, void *arg)
+{
+       int result;
+       unsigned long flags;
+       struct device *dev = &rc->uwb_dev.dev;
+       struct uwb_rc_neh *neh;
+
+       neh = kzalloc(sizeof(*neh), GFP_KERNEL);
+       if (neh == NULL) {
+               result = -ENOMEM;
+               goto error_kzalloc;
+       }
+
+       kref_init(&neh->kref);
+       INIT_LIST_HEAD(&neh->list_node);
+       init_timer(&neh->timer);
+       neh->timer.function = uwb_rc_neh_timer;
+       neh->timer.data     = (unsigned long)neh;
+
+       neh->rc = rc;
+       neh->evt_type = expected_type;
+       neh->evt = cpu_to_le16(expected_event);
+       neh->cb = cb;
+       neh->arg = arg;
+
+       spin_lock_irqsave(&rc->neh_lock, flags);
+       result = __uwb_rc_ctx_get(rc, neh);
+       if (result >= 0) {
+               cmd->bCommandContext = neh->context;
+               list_add_tail(&neh->list_node, &rc->neh_list);
+               uwb_rc_neh_get(neh);
+       }
+       spin_unlock_irqrestore(&rc->neh_lock, flags);
+       if (result < 0)
+               goto error_ctx_get;
+
+       return neh;
+
+error_ctx_get:
+       kfree(neh);
+error_kzalloc:
+       dev_err(dev, "cannot open handle to radio controller: %d\n", result);
+       return ERR_PTR(result);
+}
+
+static void __uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh)
+{
+       del_timer(&neh->timer);
+       __uwb_rc_ctx_put(rc, neh);
+       list_del(&neh->list_node);
+}
+
+/**
+ * uwb_rc_neh_rm - remove a neh.
+ * @rc:  the radio controller
+ * @neh: the neh to remove
+ *
+ * Remove an active neh immediately instead of waiting for the event
+ * (or a time out).
+ */
+void uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&rc->neh_lock, flags);
+       __uwb_rc_neh_rm(rc, neh);
+       spin_unlock_irqrestore(&rc->neh_lock, flags);
+
+       uwb_rc_neh_put(neh);
+}
+
+/**
+ * uwb_rc_neh_arm - arm an event handler timeout timer
+ *
+ * @rc:     UWB Radio Controller
+ * @neh:    Notification/event handler for @rc
+ *
+ * The timer is only armed if the neh is active.
+ */
+void uwb_rc_neh_arm(struct uwb_rc *rc, struct uwb_rc_neh *neh)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&rc->neh_lock, flags);
+       if (neh->context)
+               mod_timer(&neh->timer,
+                         jiffies + msecs_to_jiffies(UWB_RC_CMD_TIMEOUT_MS));
+       spin_unlock_irqrestore(&rc->neh_lock, flags);
+}
+
+static void uwb_rc_neh_cb(struct uwb_rc_neh *neh, struct uwb_rceb *rceb, size_t size)
+{
+       (*neh->cb)(neh->rc, neh->arg, rceb, size);
+       uwb_rc_neh_put(neh);
+}
+
+static bool uwb_rc_neh_match(struct uwb_rc_neh *neh, const struct uwb_rceb *rceb)
+{
+       return neh->evt_type == rceb->bEventType
+               && neh->evt == rceb->wEvent
+               && neh->context == rceb->bEventContext;
+}
+
+/**
+ * Find the handle waiting for a RC Radio Control Event
+ *
+ * @rc:         UWB Radio Controller
+ * @rceb:       Pointer to the RCEB buffer
+ * @event_size: Pointer to the size of the RCEB buffer. Might be
+ *              adjusted to take into account the @neh->extra_size
+ *              settings.
+ *
+ * If the listener has no buffer (NULL buffer), one is allocated for
+ * the right size (the amount of data received). @neh->ptr will point
+ * to the event payload, which always starts with a 'struct
+ * uwb_rceb'. kfree() it when done.
+ */
+static
+struct uwb_rc_neh *uwb_rc_neh_lookup(struct uwb_rc *rc,
+                                    const struct uwb_rceb *rceb)
+{
+       struct uwb_rc_neh *neh = NULL, *h;
+       unsigned long flags;
+
+       spin_lock_irqsave(&rc->neh_lock, flags);
+
+       list_for_each_entry(h, &rc->neh_list, list_node) {
+               if (uwb_rc_neh_match(h, rceb)) {
+                       neh = h;
+                       break;
+               }
+       }
+
+       if (neh)
+               __uwb_rc_neh_rm(rc, neh);
+
+       spin_unlock_irqrestore(&rc->neh_lock, flags);
+
+       return neh;
+}
+
+
+/**
+ * Process notifications coming from the radio control interface
+ *
+ * @rc:    UWB Radio Control Interface descriptor
+ * @neh:   Notification/Event Handler @neh->ptr points to
+ *         @uwb_evt->buffer.
+ *
+ * This function is called by the event/notif handling subsystem when
+ * notifications arrive (hwarc_probe() arms a notification/event handle
+ * that calls back this function for every received notification; this
+ * function then will rearm itself).
+ *
+ * Notification data buffers are dynamically allocated by the NEH
+ * handling code in neh.c [uwb_rc_neh_lookup()]. What is actually
+ * allocated is space to contain the notification data.
+ *
+ * Buffers are prefixed with a Radio Control Event Block (RCEB) as
+ * defined by the WUSB Wired-Adapter Radio Control interface. We
+ * just use it for the notification code.
+ *
+ * On each case statement we just transcode endianess of the different
+ * fields. We declare a pointer to a RCI definition of an event, and
+ * then to a UWB definition of the same event (which are the same,
+ * remember). Event if we use different pointers
+ */
+static
+void uwb_rc_notif(struct uwb_rc *rc, struct uwb_rceb *rceb, ssize_t size)
+{
+       struct device *dev = &rc->uwb_dev.dev;
+       struct uwb_event *uwb_evt;
+
+       if (size == -ESHUTDOWN)
+               return;
+       if (size < 0) {
+               dev_err(dev, "ignoring event with error code %zu\n",
+                       size);
+               return;
+       }
+
+       uwb_evt = kzalloc(sizeof(*uwb_evt), GFP_ATOMIC);
+       if (unlikely(uwb_evt == NULL)) {
+               dev_err(dev, "no memory to queue event 0x%02x/%04x/%02x\n",
+                       rceb->bEventType, le16_to_cpu(rceb->wEvent),
+                       rceb->bEventContext);
+               return;
+       }
+       uwb_evt->rc = __uwb_rc_get(rc); /* will be put by uwbd's uwbd_event_handle() */
+       uwb_evt->ts_jiffies = jiffies;
+       uwb_evt->type = UWB_EVT_TYPE_NOTIF;
+       uwb_evt->notif.size = size;
+       uwb_evt->notif.rceb = rceb;
+
+       switch (le16_to_cpu(rceb->wEvent)) {
+               /* Trap some vendor specific events
+                *
+                * FIXME: move this to handling in ptc-est, where we
+                * register a NULL event handler for these two guys
+                * using the Intel IDs.
+                */
+       case 0x0103:
+               dev_info(dev, "FIXME: DEVICE ADD\n");
+               return;
+       case 0x0104:
+               dev_info(dev, "FIXME: DEVICE RM\n");
+               return;
+       default:
+               break;
+       }
+
+       uwbd_event_queue(uwb_evt);
+}
+
+static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size_t size)
+{
+       struct device *dev = &rc->uwb_dev.dev;
+       struct uwb_rc_neh *neh;
+       struct uwb_rceb *notif;
+
+       if (rceb->bEventContext == 0) {
+               notif = kmalloc(size, GFP_ATOMIC);
+               if (notif) {
+                       memcpy(notif, rceb, size);
+                       uwb_rc_notif(rc, notif, size);
+               } else
+                       dev_err(dev, "event 0x%02x/%04x/%02x (%zu bytes): no memory\n",
+                               rceb->bEventType, le16_to_cpu(rceb->wEvent),
+                               rceb->bEventContext, size);
+       } else {
+               neh = uwb_rc_neh_lookup(rc, rceb);
+               if (neh)
+                       uwb_rc_neh_cb(neh, rceb, size);
+               else
+                       dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n",
+                                rceb->bEventType, le16_to_cpu(rceb->wEvent),
+                                rceb->bEventContext, size);
+       }
+}
+
+/**
+ * Given a buffer with one or more UWB RC events/notifications, break
+ * them up and dispatch them.
+ *
+ * @rc:              UWB Radio Controller
+ * @buf:      Buffer with the stream of notifications/events
+ * @buf_size: Amount of data in the buffer
+ *
+ * Note each notification/event starts always with a 'struct
+ * uwb_rceb', so the minimum size if 4 bytes.
+ *
+ * The device may pass us events formatted differently than expected.
+ * These are first filtered, potentially creating a new event in a new
+ * memory location. If a new event is created by the filter it is also
+ * freed here.
+ *
+ * For each notif/event, tries to guess the size looking at the EST
+ * tables, then looks for a neh that is waiting for that event and if
+ * found, copies the payload to the neh's buffer and calls it back. If
+ * not, the data is ignored.
+ *
+ * Note that if we can't find a size description in the EST tables, we
+ * still might find a size in the 'neh' handle in uwb_rc_neh_lookup().
+ *
+ * Assumptions:
+ *
+ *   @rc->neh_lock is NOT taken
+ *
+ * We keep track of various sizes here:
+ * size:      contains the size of the buffer that is processed for the
+ *            incoming event. this buffer may contain events that are not
+ *            formatted as WHCI.
+ * real_size: the actual space taken by this event in the buffer.
+ *            We need to keep track of the real size of an event to be able to
+ *            advance the buffer correctly.
+ * event_size: the size of the event as expected by the core layer
+ *            [OR] the size of the event after filtering. if the filtering
+ *            created a new event in a new memory location then this is
+ *            effectively the size of a new event buffer
+ */
+void uwb_rc_neh_grok(struct uwb_rc *rc, void *buf, size_t buf_size)
+{
+       struct device *dev = &rc->uwb_dev.dev;
+       void *itr;
+       struct uwb_rceb *rceb;
+       size_t size, real_size, event_size;
+       int needtofree;
+
+       d_fnstart(3, dev, "(rc %p buf %p %zu buf_size)\n", rc, buf, buf_size);
+       d_printf(2, dev, "groking event block: %zu bytes\n", buf_size);
+       itr = buf;
+       size = buf_size;
+       while (size > 0) {
+               if (size < sizeof(*rceb)) {
+                       dev_err(dev, "not enough data in event buffer to "
+                               "process incoming events (%zu left, minimum is "
+                               "%zu)\n", size, sizeof(*rceb));
+                       break;
+               }
+
+               rceb = itr;
+               if (rc->filter_event) {
+                       needtofree = rc->filter_event(rc, &rceb, size,
+                                                     &real_size, &event_size);
+                       if (needtofree < 0 && needtofree != -ENOANO) {
+                               dev_err(dev, "BUG: Unable to filter event "
+                                       "(0x%02x/%04x/%02x) from "
+                                       "device. \n", rceb->bEventType,
+                                       le16_to_cpu(rceb->wEvent),
+                                       rceb->bEventContext);
+                               break;
+                       }
+               } else
+                       needtofree = -ENOANO;
+               /* do real processing if there was no filtering or the
+                * filtering didn't act */
+               if (needtofree == -ENOANO) {
+                       ssize_t ret = uwb_est_find_size(rc, rceb, size);
+                       if (ret < 0)
+                               break;
+                       if (ret > size) {
+                               dev_err(dev, "BUG: hw sent incomplete event "
+                                       "0x%02x/%04x/%02x (%zd bytes), only got "
+                                       "%zu bytes. We don't handle that.\n",
+                                       rceb->bEventType, le16_to_cpu(rceb->wEvent),
+                                       rceb->bEventContext, ret, size);
+                               break;
+                       }
+                       real_size = event_size = ret;
+               }
+               uwb_rc_neh_grok_event(rc, rceb, event_size);
+
+               if (needtofree == 1)
+                       kfree(rceb);
+
+               itr += real_size;
+               size -= real_size;
+               d_printf(2, dev, "consumed %zd bytes, %zu left\n",
+                        event_size, size);
+       }
+       d_fnend(3, dev, "(rc %p buf %p %zu buf_size) = void\n", rc, buf, buf_size);
+}
+EXPORT_SYMBOL_GPL(uwb_rc_neh_grok);
+
+
+/**
+ * The entity that reads from the device notification/event channel has
+ * detected an error.
+ *
+ * @rc:    UWB Radio Controller
+ * @error: Errno error code
+ *
+ */
+void uwb_rc_neh_error(struct uwb_rc *rc, int error)
+{
+       struct uwb_rc_neh *neh, *next;
+       unsigned long flags;
+
+       BUG_ON(error >= 0);
+       spin_lock_irqsave(&rc->neh_lock, flags);
+       list_for_each_entry_safe(neh, next, &rc->neh_list, list_node) {
+               __uwb_rc_neh_rm(rc, neh);
+               uwb_rc_neh_cb(neh, NULL, error);
+       }
+       spin_unlock_irqrestore(&rc->neh_lock, flags);
+}
+EXPORT_SYMBOL_GPL(uwb_rc_neh_error);
+
+
+static void uwb_rc_neh_timer(unsigned long arg)
+{
+       struct uwb_rc_neh *neh = (struct uwb_rc_neh *)arg;
+       struct uwb_rc *rc = neh->rc;
+       unsigned long flags;
+
+       spin_lock_irqsave(&rc->neh_lock, flags);
+       __uwb_rc_neh_rm(rc, neh);
+       spin_unlock_irqrestore(&rc->neh_lock, flags);
+
+       uwb_rc_neh_cb(neh, NULL, -ETIMEDOUT);
+}
+
+/** Initializes the @rc's neh subsystem
+ */
+void uwb_rc_neh_create(struct uwb_rc *rc)
+{
+       spin_lock_init(&rc->neh_lock);
+       INIT_LIST_HEAD(&rc->neh_list);
+       set_bit(0, rc->ctx_bm);         /* 0 is reserved (see [WUSB] table 8-65) */
+       set_bit(0xff, rc->ctx_bm);      /* and 0xff is invalid */
+       rc->ctx_roll = 1;
+}
+
+
+/** Release's the @rc's neh subsystem */
+void uwb_rc_neh_destroy(struct uwb_rc *rc)
+{
+       unsigned long flags;
+       struct uwb_rc_neh *neh, *next;
+
+       spin_lock_irqsave(&rc->neh_lock, flags);
+       list_for_each_entry_safe(neh, next, &rc->neh_list, list_node) {
+               __uwb_rc_neh_rm(rc, neh);
+               uwb_rc_neh_put(neh);
+       }
+       spin_unlock_irqrestore(&rc->neh_lock, flags);
+}
diff --git a/drivers/uwb/pal.c b/drivers/uwb/pal.c
new file mode 100644 (file)
index 0000000..1afb38e
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * UWB PAL support.
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/kernel.h>
+#include <linux/uwb.h>
+
+#include "uwb-internal.h"
+
+/**
+ * uwb_pal_init - initialize a UWB PAL
+ * @pal: the PAL to initialize
+ */
+void uwb_pal_init(struct uwb_pal *pal)
+{
+       INIT_LIST_HEAD(&pal->node);
+}
+EXPORT_SYMBOL_GPL(uwb_pal_init);
+
+/**
+ * uwb_pal_register - register a UWB PAL
+ * @rc: the radio controller the PAL will be using
+ * @pal: the PAL
+ *
+ * The PAL must be initialized with uwb_pal_init().
+ */
+int uwb_pal_register(struct uwb_rc *rc, struct uwb_pal *pal)
+{
+       int ret;
+
+       if (pal->device) {
+               ret = sysfs_create_link(&pal->device->kobj,
+                                       &rc->uwb_dev.dev.kobj, "uwb_rc");
+               if (ret < 0)
+                       return ret;
+               ret = sysfs_create_link(&rc->uwb_dev.dev.kobj,
+                                       &pal->device->kobj, pal->name);
+               if (ret < 0) {
+                       sysfs_remove_link(&pal->device->kobj, "uwb_rc");
+                       return ret;
+               }
+       }
+
+       spin_lock(&rc->pal_lock);
+       list_add(&pal->node, &rc->pals);
+       spin_unlock(&rc->pal_lock);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(uwb_pal_register);
+
+/**
+ * uwb_pal_register - unregister a UWB PAL
+ * @rc: the radio controller the PAL was using
+ * @pal: the PAL
+ */
+void uwb_pal_unregister(struct uwb_rc *rc, struct uwb_pal *pal)
+{
+       spin_lock(&rc->pal_lock);
+       list_del(&pal->node);
+       spin_unlock(&rc->pal_lock);
+
+       if (pal->device) {
+               sysfs_remove_link(&rc->uwb_dev.dev.kobj, pal->name);
+               sysfs_remove_link(&pal->device->kobj, "uwb_rc");
+       }
+}
+EXPORT_SYMBOL_GPL(uwb_pal_unregister);
+
+/**
+ * uwb_rc_pal_init - initialize the PAL related parts of a radio controller
+ * @rc: the radio controller
+ */
+void uwb_rc_pal_init(struct uwb_rc *rc)
+{
+       spin_lock_init(&rc->pal_lock);
+       INIT_LIST_HEAD(&rc->pals);
+}
diff --git a/drivers/uwb/reset.c b/drivers/uwb/reset.c
new file mode 100644 (file)
index 0000000..8de856f
--- /dev/null
@@ -0,0 +1,362 @@
+/*
+ * Ultra Wide Band
+ * UWB basic command support and radio reset
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME:
+ *
+ *  - docs
+ *
+ *  - Now we are serializing (using the uwb_dev->mutex) the command
+ *    execution; it should be parallelized as much as possible some
+ *    day.
+ */
+#include <linux/kernel.h>
+#include <linux/err.h>
+
+#include "uwb-internal.h"
+#define D_LOCAL 0
+#include <linux/uwb/debug.h>
+
+/**
+ * Command result codes (WUSB1.0[T8-69])
+ */
+static
+const char *__strerror[] = {
+       "success",
+       "failure",
+       "hardware failure",
+       "no more slots",
+       "beacon is too large",
+       "invalid parameter",
+       "unsupported power level",
+       "time out (wa) or invalid ie data (whci)",
+       "beacon size exceeded",
+       "cancelled",
+       "invalid state",
+       "invalid size",
+       "ack not recieved",
+       "no more asie notification",
+};
+
+
+/** Return a string matching the given error code */
+const char *uwb_rc_strerror(unsigned code)
+{
+       if (code == 255)
+               return "time out";
+       if (code >= ARRAY_SIZE(__strerror))
+               return "unknown error";
+       return __strerror[code];
+}
+
+int uwb_rc_cmd_async(struct uwb_rc *rc, const char *cmd_name,
+                    struct uwb_rccb *cmd, size_t cmd_size,
+                    u8 expected_type, u16 expected_event,
+                    uwb_rc_cmd_cb_f cb, void *arg)
+{
+       struct device *dev = &rc->uwb_dev.dev;
+       struct uwb_rc_neh *neh;
+       int needtofree = 0;
+       int result;
+
+       uwb_dev_lock(&rc->uwb_dev);     /* Protect against rc->priv being removed */
+       if (rc->priv == NULL) {
+               uwb_dev_unlock(&rc->uwb_dev);
+               return -ESHUTDOWN;
+       }
+
+       if (rc->filter_cmd) {
+               needtofree = rc->filter_cmd(rc, &cmd, &cmd_size);
+               if (needtofree < 0 && needtofree != -ENOANO) {
+                       dev_err(dev, "%s: filter error: %d\n",
+                               cmd_name, needtofree);
+                       uwb_dev_unlock(&rc->uwb_dev);
+                       return needtofree;
+               }
+       }
+
+       neh = uwb_rc_neh_add(rc, cmd, expected_type, expected_event, cb, arg);
+       if (IS_ERR(neh)) {
+               result = PTR_ERR(neh);
+               goto out;
+       }
+
+       result = rc->cmd(rc, cmd, cmd_size);
+       uwb_dev_unlock(&rc->uwb_dev);
+       if (result < 0)
+               uwb_rc_neh_rm(rc, neh);
+       else
+               uwb_rc_neh_arm(rc, neh);
+       uwb_rc_neh_put(neh);
+out:
+       if (needtofree == 1)
+               kfree(cmd);
+       return result < 0 ? result : 0;
+}
+EXPORT_SYMBOL_GPL(uwb_rc_cmd_async);
+
+struct uwb_rc_cmd_done_params {
+       struct completion completion;
+       struct uwb_rceb *reply;
+       ssize_t reply_size;
+};
+
+static void uwb_rc_cmd_done(struct uwb_rc *rc, void *arg,
+                           struct uwb_rceb *reply, ssize_t reply_size)
+{
+       struct uwb_rc_cmd_done_params *p = (struct uwb_rc_cmd_done_params *)arg;
+
+       if (reply_size > 0) {
+               if (p->reply)
+                       reply_size = min(p->reply_size, reply_size);
+               else
+                       p->reply = kmalloc(reply_size, GFP_ATOMIC);
+
+               if (p->reply)
+                       memcpy(p->reply, reply, reply_size);
+               else
+                       reply_size = -ENOMEM;
+       }
+       p->reply_size = reply_size;
+       complete(&p->completion);
+}
+
+
+/**
+ * Generic function for issuing commands to the Radio Control Interface
+ *
+ * @rc:       UWB Radio Control descriptor
+ * @cmd_name: Name of the command being issued (for error messages)
+ * @cmd:      Pointer to rccb structure containing the command;
+ *            normally you embed this structure as the first member of
+ *            the full command structure.
+ * @cmd_size: Size of the whole command buffer pointed to by @cmd.
+ * @reply:    Pointer to where to store the reply
+ * @reply_size: @reply's size
+ * @expected_type: Expected type in the return event
+ * @expected_event: Expected event code in the return event
+ * @preply:   Here a pointer to where the event data is received will
+ *            be stored. Once done with the data, free with kfree().
+ *
+ * This function is generic; it works for commands that return a fixed
+ * and known size or for commands that return a variable amount of data.
+ *
+ * If a buffer is provided, that is used, although it could be chopped
+ * to the maximum size of the buffer. If the buffer is NULL, then one
+ * be allocated in *preply with the whole contents of the reply.
+ *
+ * @rc needs to be referenced
+ */
+static
+ssize_t __uwb_rc_cmd(struct uwb_rc *rc, const char *cmd_name,
+                    struct uwb_rccb *cmd, size_t cmd_size,
+                    struct uwb_rceb *reply, size_t reply_size,
+                    u8 expected_type, u16 expected_event,
+                    struct uwb_rceb **preply)
+{
+       ssize_t result = 0;
+       struct device *dev = &rc->uwb_dev.dev;
+       struct uwb_rc_cmd_done_params params;
+
+       init_completion(&params.completion);
+       params.reply = reply;
+       params.reply_size = reply_size;
+
+       result = uwb_rc_cmd_async(rc, cmd_name, cmd, cmd_size,
+                                 expected_type, expected_event,
+                                 uwb_rc_cmd_done, &params);
+       if (result)
+               return result;
+
+       wait_for_completion(&params.completion);
+
+       if (preply)
+               *preply = params.reply;
+
+       if (params.reply_size < 0)
+               dev_err(dev, "%s: confirmation event 0x%02x/%04x/%02x "
+                       "reception failed: %d\n", cmd_name,
+                       expected_type, expected_event, cmd->bCommandContext,
+                       (int)params.reply_size);
+       return params.reply_size;
+}
+
+
+/**
+ * Generic function for issuing commands to the Radio Control Interface
+ *
+ * @rc:       UWB Radio Control descriptor
+ * @cmd_name: Name of the command being issued (for error messages)
+ * @cmd:      Pointer to rccb structure containing the command;
+ *            normally you embed this structure as the first member of
+ *            the full command structure.
+ * @cmd_size: Size of the whole command buffer pointed to by @cmd.
+ * @reply:    Pointer to the beginning of the confirmation event
+ *            buffer. Normally bigger than an 'struct hwarc_rceb'.
+ *            You need to fill out reply->bEventType and reply->wEvent (in
+ *            cpu order) as the function will use them to verify the
+ *            confirmation event.
+ * @reply_size: Size of the reply buffer
+ *
+ * The function checks that the length returned in the reply is at
+ * least as big as @reply_size; if not, it will be deemed an error and
+ * -EIO returned.
+ *
+ * @rc needs to be referenced
+ */
+ssize_t uwb_rc_cmd(struct uwb_rc *rc, const char *cmd_name,
+                  struct uwb_rccb *cmd, size_t cmd_size,
+                  struct uwb_rceb *reply, size_t reply_size)
+{
+       struct device *dev = &rc->uwb_dev.dev;
+       ssize_t result;
+
+       result = __uwb_rc_cmd(rc, cmd_name,
+                             cmd, cmd_size, reply, reply_size,
+                             reply->bEventType, reply->wEvent, NULL);
+
+       if (result > 0 && result < reply_size) {
+               dev_err(dev, "%s: not enough data returned for decoding reply "
+                       "(%zu bytes received vs at least %zu needed)\n",
+                       cmd_name, result, reply_size);
+               result = -EIO;
+       }
+       return result;
+}
+EXPORT_SYMBOL_GPL(uwb_rc_cmd);
+
+
+/**
+ * Generic function for issuing commands to the Radio Control
+ * Interface that return an unknown amount of data
+ *
+ * @rc:       UWB Radio Control descriptor
+ * @cmd_name: Name of the command being issued (for error messages)
+ * @cmd:      Pointer to rccb structure containing the command;
+ *            normally you embed this structure as the first member of
+ *            the full command structure.
+ * @cmd_size: Size of the whole command buffer pointed to by @cmd.
+ * @expected_type: Expected type in the return event
+ * @expected_event: Expected event code in the return event
+ * @preply:   Here a pointer to where the event data is received will
+ *            be stored. Once done with the data, free with kfree().
+ *
+ * The function checks that the length returned in the reply is at
+ * least as big as a 'struct uwb_rceb *'; if not, it will be deemed an
+ * error and -EIO returned.
+ *
+ * @rc needs to be referenced
+ */
+ssize_t uwb_rc_vcmd(struct uwb_rc *rc, const char *cmd_name,
+                   struct uwb_rccb *cmd, size_t cmd_size,
+                   u8 expected_type, u16 expected_event,
+                   struct uwb_rceb **preply)
+{
+       return __uwb_rc_cmd(rc, cmd_name, cmd, cmd_size, NULL, 0,
+                           expected_type, expected_event, preply);
+}
+EXPORT_SYMBOL_GPL(uwb_rc_vcmd);
+
+
+/**
+ * Reset a UWB Host Controller (and all radio settings)
+ *
+ * @rc:      Host Controller descriptor
+ * @returns: 0 if ok, < 0 errno code on error
+ *
+ * We put the command on kmalloc'ed memory as some arches cannot do
+ * USB from the stack. The reply event is copied from an stage buffer,
+ * so it can be in the stack. See WUSB1.0[8.6.2.4] for more details.
+ */
+int uwb_rc_reset(struct uwb_rc *rc)
+{
+       int result = -ENOMEM;
+       struct uwb_rc_evt_confirm reply;
+       struct uwb_rccb *cmd;
+       size_t cmd_size = sizeof(*cmd);
+
+       mutex_lock(&rc->uwb_dev.mutex);
+       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+       if (cmd == NULL)
+               goto error_kzalloc;
+       cmd->bCommandType = UWB_RC_CET_GENERAL;
+       cmd->wCommand = cpu_to_le16(UWB_RC_CMD_RESET);
+       reply.rceb.bEventType = UWB_RC_CET_GENERAL;
+       reply.rceb.wEvent = UWB_RC_CMD_RESET;
+       result = uwb_rc_cmd(rc, "RESET", cmd, cmd_size,
+                           &reply.rceb, sizeof(reply));
+       if (result < 0)
+               goto error_cmd;
+       if (reply.bResultCode != UWB_RC_RES_SUCCESS) {
+               dev_err(&rc->uwb_dev.dev,
+                       "RESET: command execution failed: %s (%d)\n",
+                       uwb_rc_strerror(reply.bResultCode), reply.bResultCode);
+               result = -EIO;
+       }
+error_cmd:
+       kfree(cmd);
+error_kzalloc:
+       mutex_unlock(&rc->uwb_dev.mutex);
+       return result;
+}
+
+int uwbd_msg_handle_reset(struct uwb_event *evt)
+{
+       struct uwb_rc *rc = evt->rc;
+       int ret;
+
+       /* Need to prevent the RC hardware module going away while in
+          the rc->reset() call. */
+       if (!try_module_get(rc->owner))
+               return 0;
+
+       dev_info(&rc->uwb_dev.dev, "resetting radio controller\n");
+       ret = rc->reset(rc);
+       if (ret)
+               dev_err(&rc->uwb_dev.dev, "failed to reset hardware: %d\n", ret);
+
+       module_put(rc->owner);
+       return ret;
+}
+
+/**
+ * uwb_rc_reset_all - request a reset of the radio controller and PALs
+ * @rc: the radio controller of the hardware device to be reset.
+ *
+ * The full hardware reset of the radio controller and all the PALs
+ * will be scheduled.
+ */
+void uwb_rc_reset_all(struct uwb_rc *rc)
+{
+       struct uwb_event *evt;
+
+       evt = kzalloc(sizeof(struct uwb_event), GFP_ATOMIC);
+       if (unlikely(evt == NULL))
+               return;
+
+       evt->rc = __uwb_rc_get(rc);     /* will be put by uwbd's uwbd_event_handle() */
+       evt->ts_jiffies = jiffies;
+       evt->type = UWB_EVT_TYPE_MSG;
+       evt->message = UWB_EVT_MSG_RESET;
+
+       uwbd_event_queue(evt);
+}
+EXPORT_SYMBOL_GPL(uwb_rc_reset_all);
diff --git a/drivers/uwb/rsv.c b/drivers/uwb/rsv.c
new file mode 100644 (file)
index 0000000..bae1620
--- /dev/null
@@ -0,0 +1,680 @@
+/*
+ * UWB reservation management.
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/uwb.h>
+
+#include "uwb-internal.h"
+
+static void uwb_rsv_timer(unsigned long arg);
+
+static const char *rsv_states[] = {
+       [UWB_RSV_STATE_NONE]          = "none",
+       [UWB_RSV_STATE_O_INITIATED]   = "initiated",
+       [UWB_RSV_STATE_O_PENDING]     = "pending",
+       [UWB_RSV_STATE_O_MODIFIED]    = "modified",
+       [UWB_RSV_STATE_O_ESTABLISHED] = "established",
+       [UWB_RSV_STATE_T_ACCEPTED]    = "accepted",
+       [UWB_RSV_STATE_T_DENIED]      = "denied",
+       [UWB_RSV_STATE_T_PENDING]     = "pending",
+};
+
+static const char *rsv_types[] = {
+       [UWB_DRP_TYPE_ALIEN_BP] = "alien-bp",
+       [UWB_DRP_TYPE_HARD]     = "hard",
+       [UWB_DRP_TYPE_SOFT]     = "soft",
+       [UWB_DRP_TYPE_PRIVATE]  = "private",
+       [UWB_DRP_TYPE_PCA]      = "pca",
+};
+
+/**
+ * uwb_rsv_state_str - return a string for a reservation state
+ * @state: the reservation state.
+ */
+const char *uwb_rsv_state_str(enum uwb_rsv_state state)
+{
+       if (state < UWB_RSV_STATE_NONE || state >= UWB_RSV_STATE_LAST)
+               return "unknown";
+       return rsv_states[state];
+}
+EXPORT_SYMBOL_GPL(uwb_rsv_state_str);
+
+/**
+ * uwb_rsv_type_str - return a string for a reservation type
+ * @type: the reservation type
+ */
+const char *uwb_rsv_type_str(enum uwb_drp_type type)
+{
+       if (type < UWB_DRP_TYPE_ALIEN_BP || type > UWB_DRP_TYPE_PCA)
+               return "invalid";
+       return rsv_types[type];
+}
+EXPORT_SYMBOL_GPL(uwb_rsv_type_str);
+
+static void uwb_rsv_dump(struct uwb_rsv *rsv)
+{
+       struct device *dev = &rsv->rc->uwb_dev.dev;
+       struct uwb_dev_addr devaddr;
+       char owner[UWB_ADDR_STRSIZE], target[UWB_ADDR_STRSIZE];
+
+       uwb_dev_addr_print(owner, sizeof(owner), &rsv->owner->dev_addr);
+       if (rsv->target.type == UWB_RSV_TARGET_DEV)
+               devaddr = rsv->target.dev->dev_addr;
+       else
+               devaddr = rsv->target.devaddr;
+       uwb_dev_addr_print(target, sizeof(target), &devaddr);
+
+       dev_dbg(dev, "rsv %s -> %s: %s\n", owner, target, uwb_rsv_state_str(rsv->state));
+}
+
+/*
+ * Get a free stream index for a reservation.
+ *
+ * If the target is a DevAddr (e.g., a WUSB cluster reservation) then
+ * the stream is allocated from a pool of per-RC stream indexes,
+ * otherwise a unique stream index for the target is selected.
+ */
+static int uwb_rsv_get_stream(struct uwb_rsv *rsv)
+{
+       struct uwb_rc *rc = rsv->rc;
+       unsigned long *streams_bm;
+       int stream;
+
+       switch (rsv->target.type) {
+       case UWB_RSV_TARGET_DEV:
+               streams_bm = rsv->target.dev->streams;
+               break;
+       case UWB_RSV_TARGET_DEVADDR:
+               streams_bm = rc->uwb_dev.streams;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       stream = find_first_zero_bit(streams_bm, UWB_NUM_STREAMS);
+       if (stream >= UWB_NUM_STREAMS)
+               return -EBUSY;
+
+       rsv->stream = stream;
+       set_bit(stream, streams_bm);
+
+       return 0;
+}
+
+static void uwb_rsv_put_stream(struct uwb_rsv *rsv)
+{
+       struct uwb_rc *rc = rsv->rc;
+       unsigned long *streams_bm;
+
+       switch (rsv->target.type) {
+       case UWB_RSV_TARGET_DEV:
+               streams_bm = rsv->target.dev->streams;
+               break;
+       case UWB_RSV_TARGET_DEVADDR:
+               streams_bm = rc->uwb_dev.streams;
+               break;
+       default:
+               return;
+       }
+
+       clear_bit(rsv->stream, streams_bm);
+}
+
+/*
+ * Generate a MAS allocation with a single row component.
+ */
+static void uwb_rsv_gen_alloc_row(struct uwb_mas_bm *mas,
+                                 int first_mas, int mas_per_zone,
+                                 int zs, int ze)
+{
+       struct uwb_mas_bm col;
+       int z;
+
+       bitmap_zero(mas->bm, UWB_NUM_MAS);
+       bitmap_zero(col.bm, UWB_NUM_MAS);
+       bitmap_fill(col.bm, mas_per_zone);
+       bitmap_shift_left(col.bm, col.bm, first_mas + zs * UWB_MAS_PER_ZONE, UWB_NUM_MAS);
+
+       for (z = zs; z <= ze; z++) {
+               bitmap_or(mas->bm, mas->bm, col.bm, UWB_NUM_MAS);
+               bitmap_shift_left(col.bm, col.bm, UWB_MAS_PER_ZONE, UWB_NUM_MAS);
+       }
+}
+
+/*
+ * Allocate some MAS for this reservation based on current local
+ * availability, the reservation parameters (max_mas, min_mas,
+ * sparsity), and the WiMedia rules for MAS allocations.
+ *
+ * Returns -EBUSY is insufficient free MAS are available.
+ *
+ * FIXME: to simplify this, only safe reservations with a single row
+ * component in zones 1 to 15 are tried (zone 0 is skipped to avoid
+ * problems with the MAS reserved for the BP).
+ *
+ * [ECMA-368] section B.2.
+ */
+static int uwb_rsv_alloc_mas(struct uwb_rsv *rsv)
+{
+       static const int safe_mas_in_row[UWB_NUM_ZONES] = {
+               8, 7, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 2, 1,
+       };
+       int n, r;
+       struct uwb_mas_bm mas;
+       bool found = false;
+
+       /*
+        * Search all valid safe allocations until either: too few MAS
+        * are available; or the smallest allocation with sufficient
+        * MAS is found.
+        *
+        * The top of the zones are preferred, so space for larger
+        * allocations is available in the bottom of the zone (e.g., a
+        * 15 MAS allocation should start in row 14 leaving space for
+        * a 120 MAS allocation at row 0).
+        */
+       for (n = safe_mas_in_row[0]; n >= 1; n--) {
+               int num_mas;
+
+               num_mas = n * (UWB_NUM_ZONES - 1);
+               if (num_mas < rsv->min_mas)
+                       break;
+               if (found && num_mas < rsv->max_mas)
+                       break;
+
+               for (r = UWB_MAS_PER_ZONE-1;  r >= 0; r--) {
+                       if (safe_mas_in_row[r] < n)
+                               continue;
+                       uwb_rsv_gen_alloc_row(&mas, r, n, 1, UWB_NUM_ZONES);
+                       if (uwb_drp_avail_reserve_pending(rsv->rc, &mas) == 0) {
+                               found = true;
+                               break;
+                       }
+               }
+       }
+
+       if (!found)
+               return -EBUSY;
+
+       bitmap_copy(rsv->mas.bm, mas.bm, UWB_NUM_MAS);
+       return 0;
+}
+
+static void uwb_rsv_stroke_timer(struct uwb_rsv *rsv)
+{
+       int sframes = UWB_MAX_LOST_BEACONS;
+
+       /*
+        * Multicast reservations can become established within 1
+        * super frame and should not be terminated if no response is
+        * received.
+        */
+       if (rsv->is_multicast) {
+               if (rsv->state == UWB_RSV_STATE_O_INITIATED)
+                       sframes = 1;
+               if (rsv->state == UWB_RSV_STATE_O_ESTABLISHED)
+                       sframes = 0;
+       }
+
+       rsv->expired = false;
+       if (sframes > 0) {
+               /*
+                * Add an additional 2 superframes to account for the
+                * time to send the SET DRP IE command.
+                */
+               unsigned timeout_us = (sframes + 2) * UWB_SUPERFRAME_LENGTH_US;
+               mod_timer(&rsv->timer, jiffies + usecs_to_jiffies(timeout_us));
+       } else
+               del_timer(&rsv->timer);
+}
+
+/*
+ * Update a reservations state, and schedule an update of the
+ * transmitted DRP IEs.
+ */
+static void uwb_rsv_state_update(struct uwb_rsv *rsv,
+                                enum uwb_rsv_state new_state)
+{
+       rsv->state = new_state;
+       rsv->ie_valid = false;
+
+       uwb_rsv_dump(rsv);
+
+       uwb_rsv_stroke_timer(rsv);
+       uwb_rsv_sched_update(rsv->rc);
+}
+
+static void uwb_rsv_callback(struct uwb_rsv *rsv)
+{
+       if (rsv->callback)
+               rsv->callback(rsv);
+}
+
+void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state)
+{
+       if (rsv->state == new_state) {
+               switch (rsv->state) {
+               case UWB_RSV_STATE_O_ESTABLISHED:
+               case UWB_RSV_STATE_T_ACCEPTED:
+               case UWB_RSV_STATE_NONE:
+                       uwb_rsv_stroke_timer(rsv);
+                       break;
+               default:
+                       /* Expecting a state transition so leave timer
+                          as-is. */
+                       break;
+               }
+               return;
+       }
+
+       switch (new_state) {
+       case UWB_RSV_STATE_NONE:
+               uwb_drp_avail_release(rsv->rc, &rsv->mas);
+               uwb_rsv_put_stream(rsv);
+               uwb_rsv_state_update(rsv, UWB_RSV_STATE_NONE);
+               uwb_rsv_callback(rsv);
+               break;
+       case UWB_RSV_STATE_O_INITIATED:
+               uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_INITIATED);
+               break;
+       case UWB_RSV_STATE_O_PENDING:
+               uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_PENDING);
+               break;
+       case UWB_RSV_STATE_O_ESTABLISHED:
+               uwb_drp_avail_reserve(rsv->rc, &rsv->mas);
+               uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_ESTABLISHED);
+               uwb_rsv_callback(rsv);
+               break;
+       case UWB_RSV_STATE_T_ACCEPTED:
+               uwb_drp_avail_reserve(rsv->rc, &rsv->mas);
+               uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_ACCEPTED);
+               uwb_rsv_callback(rsv);
+               break;
+       case UWB_RSV_STATE_T_DENIED:
+               uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_DENIED);
+               break;
+       default:
+               dev_err(&rsv->rc->uwb_dev.dev, "unhandled state: %s (%d)\n",
+                       uwb_rsv_state_str(new_state), new_state);
+       }
+}
+
+static struct uwb_rsv *uwb_rsv_alloc(struct uwb_rc *rc)
+{
+       struct uwb_rsv *rsv;
+
+       rsv = kzalloc(sizeof(struct uwb_rsv), GFP_KERNEL);
+       if (!rsv)
+               return NULL;
+
+       INIT_LIST_HEAD(&rsv->rc_node);
+       INIT_LIST_HEAD(&rsv->pal_node);
+       init_timer(&rsv->timer);
+       rsv->timer.function = uwb_rsv_timer;
+       rsv->timer.data     = (unsigned long)rsv;
+
+       rsv->rc = rc;
+
+       return rsv;
+}
+
+static void uwb_rsv_free(struct uwb_rsv *rsv)
+{
+       uwb_dev_put(rsv->owner);
+       if (rsv->target.type == UWB_RSV_TARGET_DEV)
+               uwb_dev_put(rsv->target.dev);
+       kfree(rsv);
+}
+
+/**
+ * uwb_rsv_create - allocate and initialize a UWB reservation structure
+ * @rc: the radio controller
+ * @cb: callback to use when the reservation completes or terminates
+ * @pal_priv: data private to the PAL to be passed in the callback
+ *
+ * The callback is called when the state of the reservation changes from:
+ *
+ *   - pending to accepted
+ *   - pending to denined
+ *   - accepted to terminated
+ *   - pending to terminated
+ */
+struct uwb_rsv *uwb_rsv_create(struct uwb_rc *rc, uwb_rsv_cb_f cb, void *pal_priv)
+{
+       struct uwb_rsv *rsv;
+
+       rsv = uwb_rsv_alloc(rc);
+       if (!rsv)
+               return NULL;
+
+       rsv->callback = cb;
+       rsv->pal_priv = pal_priv;
+
+       return rsv;
+}
+EXPORT_SYMBOL_GPL(uwb_rsv_create);
+
+void uwb_rsv_remove(struct uwb_rsv *rsv)
+{
+       if (rsv->state != UWB_RSV_STATE_NONE)
+               uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE);
+       del_timer_sync(&rsv->timer);
+       list_del(&rsv->rc_node);
+       uwb_rsv_free(rsv);
+}
+
+/**
+ * uwb_rsv_destroy - free a UWB reservation structure
+ * @rsv: the reservation to free
+ *
+ * The reservation will be terminated if it is pending or established.
+ */
+void uwb_rsv_destroy(struct uwb_rsv *rsv)
+{
+       struct uwb_rc *rc = rsv->rc;
+
+       mutex_lock(&rc->rsvs_mutex);
+       uwb_rsv_remove(rsv);
+       mutex_unlock(&rc->rsvs_mutex);
+}
+EXPORT_SYMBOL_GPL(uwb_rsv_destroy);
+
+/**
+ * usb_rsv_establish - start a reservation establishment
+ * @rsv: the reservation
+ *
+ * The PAL should fill in @rsv's owner, target, type, max_mas,
+ * min_mas, sparsity and is_multicast fields.  If the target is a
+ * uwb_dev it must be referenced.
+ *
+ * The reservation's callback will be called when the reservation is
+ * accepted, denied or times out.
+ */
+int uwb_rsv_establish(struct uwb_rsv *rsv)
+{
+       struct uwb_rc *rc = rsv->rc;
+       int ret;
+
+       mutex_lock(&rc->rsvs_mutex);
+
+       ret = uwb_rsv_get_stream(rsv);
+       if (ret)
+               goto out;
+
+       ret = uwb_rsv_alloc_mas(rsv);
+       if (ret) {
+               uwb_rsv_put_stream(rsv);
+               goto out;
+       }
+
+       list_add_tail(&rsv->rc_node, &rc->reservations);
+       rsv->owner = &rc->uwb_dev;
+       uwb_dev_get(rsv->owner);
+       uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_INITIATED);
+out:
+       mutex_unlock(&rc->rsvs_mutex);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(uwb_rsv_establish);
+
+/**
+ * uwb_rsv_modify - modify an already established reservation
+ * @rsv: the reservation to modify
+ * @max_mas: new maximum MAS to reserve
+ * @min_mas: new minimum MAS to reserve
+ * @sparsity: new sparsity to use
+ *
+ * FIXME: implement this once there are PALs that use it.
+ */
+int uwb_rsv_modify(struct uwb_rsv *rsv, int max_mas, int min_mas, int sparsity)
+{
+       return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(uwb_rsv_modify);
+
+/**
+ * uwb_rsv_terminate - terminate an established reservation
+ * @rsv: the reservation to terminate
+ *
+ * A reservation is terminated by removing the DRP IE from the beacon,
+ * the other end will consider the reservation to be terminated when
+ * it does not see the DRP IE for at least mMaxLostBeacons.
+ *
+ * If applicable, the reference to the target uwb_dev will be released.
+ */
+void uwb_rsv_terminate(struct uwb_rsv *rsv)
+{
+       struct uwb_rc *rc = rsv->rc;
+
+       mutex_lock(&rc->rsvs_mutex);
+
+       uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE);
+
+       mutex_unlock(&rc->rsvs_mutex);
+}
+EXPORT_SYMBOL_GPL(uwb_rsv_terminate);
+
+/**
+ * uwb_rsv_accept - accept a new reservation from a peer
+ * @rsv:      the reservation
+ * @cb:       call back for reservation changes
+ * @pal_priv: data to be passed in the above call back
+ *
+ * Reservation requests from peers are denied unless a PAL accepts it
+ * by calling this function.
+ */
+void uwb_rsv_accept(struct uwb_rsv *rsv, uwb_rsv_cb_f cb, void *pal_priv)
+{
+       rsv->callback = cb;
+       rsv->pal_priv = pal_priv;
+       rsv->state    = UWB_RSV_STATE_T_ACCEPTED;
+}
+EXPORT_SYMBOL_GPL(uwb_rsv_accept);
+
+/*
+ * Is a received DRP IE for this reservation?
+ */
+static bool uwb_rsv_match(struct uwb_rsv *rsv, struct uwb_dev *src,
+                         struct uwb_ie_drp *drp_ie)
+{
+       struct uwb_dev_addr *rsv_src;
+       int stream;
+
+       stream = uwb_ie_drp_stream_index(drp_ie);
+
+       if (rsv->stream != stream)
+               return false;
+
+       switch (rsv->target.type) {
+       case UWB_RSV_TARGET_DEVADDR:
+               return rsv->stream == stream;
+       case UWB_RSV_TARGET_DEV:
+               if (uwb_ie_drp_owner(drp_ie))
+                       rsv_src = &rsv->owner->dev_addr;
+               else
+                       rsv_src = &rsv->target.dev->dev_addr;
+               return uwb_dev_addr_cmp(&src->dev_addr, rsv_src) == 0;
+       }
+       return false;
+}
+
+static struct uwb_rsv *uwb_rsv_new_target(struct uwb_rc *rc,
+                                         struct uwb_dev *src,
+                                         struct uwb_ie_drp *drp_ie)
+{
+       struct uwb_rsv *rsv;
+       struct uwb_pal *pal;
+       enum uwb_rsv_state state;
+
+       rsv = uwb_rsv_alloc(rc);
+       if (!rsv)
+               return NULL;
+
+       rsv->rc          = rc;
+       rsv->owner       = src;
+       uwb_dev_get(rsv->owner);
+       rsv->target.type = UWB_RSV_TARGET_DEV;
+       rsv->target.dev  = &rc->uwb_dev;
+       rsv->type        = uwb_ie_drp_type(drp_ie);
+       rsv->stream      = uwb_ie_drp_stream_index(drp_ie);
+       set_bit(rsv->stream, rsv->owner->streams);
+       uwb_drp_ie_to_bm(&rsv->mas, drp_ie);
+
+       /*
+        * See if any PALs are interested in this reservation. If not,
+        * deny the request.
+        */
+       rsv->state = UWB_RSV_STATE_T_DENIED;
+       spin_lock(&rc->pal_lock);
+       list_for_each_entry(pal, &rc->pals, node) {
+               if (pal->new_rsv)
+                       pal->new_rsv(rsv);
+               if (rsv->state == UWB_RSV_STATE_T_ACCEPTED)
+                       break;
+       }
+       spin_unlock(&rc->pal_lock);
+
+       list_add_tail(&rsv->rc_node, &rc->reservations);
+       state = rsv->state;
+       rsv->state = UWB_RSV_STATE_NONE;
+       uwb_rsv_set_state(rsv, state);
+
+       return rsv;
+}
+
+/**
+ * uwb_rsv_find - find a reservation for a received DRP IE.
+ * @rc: the radio controller
+ * @src: source of the DRP IE
+ * @drp_ie: the DRP IE
+ *
+ * If the reservation cannot be found and the DRP IE is from a peer
+ * attempting to establish a new reservation, create a new reservation
+ * and add it to the list.
+ */
+struct uwb_rsv *uwb_rsv_find(struct uwb_rc *rc, struct uwb_dev *src,
+                            struct uwb_ie_drp *drp_ie)
+{
+       struct uwb_rsv *rsv;
+
+       list_for_each_entry(rsv, &rc->reservations, rc_node) {
+               if (uwb_rsv_match(rsv, src, drp_ie))
+                       return rsv;
+       }
+
+       if (uwb_ie_drp_owner(drp_ie))
+               return uwb_rsv_new_target(rc, src, drp_ie);
+
+       return NULL;
+}
+
+/*
+ * Go through all the reservations and check for timeouts and (if
+ * necessary) update their DRP IEs.
+ *
+ * FIXME: look at building the SET_DRP_IE command here rather than
+ * having to rescan the list in uwb_rc_send_all_drp_ie().
+ */
+static bool uwb_rsv_update_all(struct uwb_rc *rc)
+{
+       struct uwb_rsv *rsv, *t;
+       bool ie_updated = false;
+
+       list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) {
+               if (rsv->expired)
+                       uwb_drp_handle_timeout(rsv);
+               if (!rsv->ie_valid) {
+                       uwb_drp_ie_update(rsv);
+                       ie_updated = true;
+               }
+       }
+
+       return ie_updated;
+}
+
+void uwb_rsv_sched_update(struct uwb_rc *rc)
+{
+       queue_work(rc->rsv_workq, &rc->rsv_update_work);
+}
+
+/*
+ * Update DRP IEs and, if necessary, the DRP Availability IE and send
+ * the updated IEs to the radio controller.
+ */
+static void uwb_rsv_update_work(struct work_struct *work)
+{
+       struct uwb_rc *rc = container_of(work, struct uwb_rc, rsv_update_work);
+       bool ie_updated;
+
+       mutex_lock(&rc->rsvs_mutex);
+
+       ie_updated = uwb_rsv_update_all(rc);
+
+       if (!rc->drp_avail.ie_valid) {
+               uwb_drp_avail_ie_update(rc);
+               ie_updated = true;
+       }
+
+       if (ie_updated)
+               uwb_rc_send_all_drp_ie(rc);
+
+       mutex_unlock(&rc->rsvs_mutex);
+}
+
+static void uwb_rsv_timer(unsigned long arg)
+{
+       struct uwb_rsv *rsv = (struct uwb_rsv *)arg;
+
+       rsv->expired = true;
+       uwb_rsv_sched_update(rsv->rc);
+}
+
+void uwb_rsv_init(struct uwb_rc *rc)
+{
+       INIT_LIST_HEAD(&rc->reservations);
+       mutex_init(&rc->rsvs_mutex);
+       INIT_WORK(&rc->rsv_update_work, uwb_rsv_update_work);
+
+       bitmap_complement(rc->uwb_dev.streams, rc->uwb_dev.streams, UWB_NUM_STREAMS);
+}
+
+int uwb_rsv_setup(struct uwb_rc *rc)
+{
+       char name[16];
+
+       snprintf(name, sizeof(name), "%s_rsvd", dev_name(&rc->uwb_dev.dev));
+       rc->rsv_workq = create_singlethread_workqueue(name);
+       if (rc->rsv_workq == NULL)
+               return -ENOMEM;
+
+       return 0;
+}
+
+void uwb_rsv_cleanup(struct uwb_rc *rc)
+{
+       struct uwb_rsv *rsv, *t;
+
+       mutex_lock(&rc->rsvs_mutex);
+       list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) {
+               uwb_rsv_remove(rsv);
+       }
+       mutex_unlock(&rc->rsvs_mutex);
+
+       cancel_work_sync(&rc->rsv_update_work);
+       destroy_workqueue(rc->rsv_workq);
+}
diff --git a/drivers/uwb/scan.c b/drivers/uwb/scan.c
new file mode 100644 (file)
index 0000000..2d27074
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Ultra Wide Band
+ * Scanning management
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ *
+ * FIXME: docs
+ * FIXME: there are issues here on how BEACON and SCAN on USB RCI deal
+ *        with each other. Currently seems that START_BEACON while
+ *        SCAN_ONLY will cancel the scan, so we need to update the
+ *        state here. Clarification request sent by email on
+ *        10/05/2005.
+ *        10/28/2005 No clear answer heard--maybe we'll hack the API
+ *                   so that when we start beaconing, if the HC is
+ *                   scanning in a mode not compatible with beaconing
+ *                   we just fail.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include "uwb-internal.h"
+
+
+/**
+ * Start/stop scanning in a radio controller
+ *
+ * @rc:      UWB Radio Controlller
+ * @channel: Channel to scan; encodings in WUSB1.0[Table 5.12]
+ * @type:    Type of scanning to do.
+ * @bpst_offset: value at which to start scanning (if type ==
+ *                UWB_SCAN_ONLY_STARTTIME)
+ * @returns: 0 if ok, < 0 errno code on error
+ *
+ * We put the command on kmalloc'ed memory as some arches cannot do
+ * USB from the stack. The reply event is copied from an stage buffer,
+ * so it can be in the stack. See WUSB1.0[8.6.2.4] for more details.
+ */
+int uwb_rc_scan(struct uwb_rc *rc,
+               unsigned channel, enum uwb_scan_type type,
+               unsigned bpst_offset)
+{
+       int result;
+       struct uwb_rc_cmd_scan *cmd;
+       struct uwb_rc_evt_confirm reply;
+
+       result = -ENOMEM;
+       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+       if (cmd == NULL)
+               goto error_kzalloc;
+       mutex_lock(&rc->uwb_dev.mutex);
+       cmd->rccb.bCommandType = UWB_RC_CET_GENERAL;
+       cmd->rccb.wCommand = cpu_to_le16(UWB_RC_CMD_SCAN);
+       cmd->bChannelNumber = channel;
+       cmd->bScanState = type;
+       cmd->wStartTime = cpu_to_le16(bpst_offset);
+       reply.rceb.bEventType = UWB_RC_CET_GENERAL;
+       reply.rceb.wEvent = UWB_RC_CMD_SCAN;
+       result = uwb_rc_cmd(rc, "SCAN", &cmd->rccb, sizeof(*cmd),
+                           &reply.rceb, sizeof(reply));
+       if (result < 0)
+               goto error_cmd;
+       if (reply.bResultCode != UWB_RC_RES_SUCCESS) {
+               dev_err(&rc->uwb_dev.dev,
+                       "SCAN: command execution failed: %s (%d)\n",
+                       uwb_rc_strerror(reply.bResultCode), reply.bResultCode);
+               result = -EIO;
+               goto error_cmd;
+       }
+       rc->scanning = channel;
+       rc->scan_type = type;
+error_cmd:
+       mutex_unlock(&rc->uwb_dev.mutex);
+       kfree(cmd);
+error_kzalloc:
+       return result;
+}
+
+/*
+ * Print scanning state
+ */
+static ssize_t uwb_rc_scan_show(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct uwb_dev *uwb_dev = to_uwb_dev(dev);
+       struct uwb_rc *rc = uwb_dev->rc;
+       ssize_t result;
+
+       mutex_lock(&rc->uwb_dev.mutex);
+       result = sprintf(buf, "%d %d\n", rc->scanning, rc->scan_type);
+       mutex_unlock(&rc->uwb_dev.mutex);
+       return result;
+}
+
+/*
+ *
+ */
+static ssize_t uwb_rc_scan_store(struct device *dev,
+                                struct device_attribute *attr,
+                                const char *buf, size_t size)
+{
+       struct uwb_dev *uwb_dev = to_uwb_dev(dev);
+       struct uwb_rc *rc = uwb_dev->rc;
+       unsigned channel;
+       unsigned type;
+       unsigned bpst_offset = 0;
+       ssize_t result = -EINVAL;
+
+       result = sscanf(buf, "%u %u %u\n", &channel, &type, &bpst_offset);
+       if (result >= 2 && type < UWB_SCAN_TOP)
+               result = uwb_rc_scan(rc, channel, type, bpst_offset);
+
+       return result < 0 ? result : size;
+}
+
+/** Radio Control sysfs interface (declaration) */
+DEVICE_ATTR(scan, S_IRUGO | S_IWUSR, uwb_rc_scan_show, uwb_rc_scan_store);
diff --git a/drivers/uwb/umc-bus.c b/drivers/uwb/umc-bus.c
new file mode 100644 (file)
index 0000000..2d8d62d
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * Bus for UWB Multi-interface Controller capabilities.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * This file is released under the GNU GPL v2.
+ */
+#include <linux/kernel.h>
+#include <linux/sysfs.h>
+#include <linux/workqueue.h>
+#include <linux/uwb/umc.h>
+#include <linux/pci.h>
+
+static int umc_bus_unbind_helper(struct device *dev, void *data)
+{
+       struct device *parent = data;
+
+       if (dev->parent == parent && dev->driver)
+               device_release_driver(dev);
+       return 0;
+}
+
+/**
+ * umc_controller_reset - reset the whole UMC controller
+ * @umc: the UMC device for the radio controller.
+ *
+ * Drivers will be unbound from all UMC devices belonging to the
+ * controller and then the radio controller will be rebound.  The
+ * radio controller is expected to do a full hardware reset when it is
+ * probed.
+ *
+ * If this is called while a probe() or remove() is in progress it
+ * will return -EAGAIN and not perform the reset.
+ */
+int umc_controller_reset(struct umc_dev *umc)
+{
+       struct device *parent = umc->dev.parent;
+       int ret;
+
+       if (down_trylock(&parent->sem))
+               return -EAGAIN;
+       bus_for_each_dev(&umc_bus_type, NULL, parent, umc_bus_unbind_helper);
+       ret = device_attach(&umc->dev);
+       if (ret == 1)
+               ret = 0;
+       up(&parent->sem);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(umc_controller_reset);
+
+/**
+ * umc_match_pci_id - match a UMC driver to a UMC device's parent PCI device.
+ * @umc_drv: umc driver with match_data pointing to a zero-terminated
+ * table of pci_device_id's.
+ * @umc: umc device whose parent is to be matched.
+ */
+int umc_match_pci_id(struct umc_driver *umc_drv, struct umc_dev *umc)
+{
+       const struct pci_device_id *id_table = umc_drv->match_data;
+       struct pci_dev *pci;
+
+       if (umc->dev.parent->bus != &pci_bus_type)
+               return 0;
+
+       pci = to_pci_dev(umc->dev.parent);
+       return pci_match_id(id_table, pci) != NULL;
+}
+EXPORT_SYMBOL_GPL(umc_match_pci_id);
+
+static int umc_bus_rescan_helper(struct device *dev, void *data)
+{
+       int ret = 0;
+
+       if (!dev->driver)
+               ret = device_attach(dev);
+
+       return ret < 0 ? ret : 0;
+}
+
+static void umc_bus_rescan(void)
+{
+       int err;
+
+       /*
+        * We can't use bus_rescan_devices() here as it deadlocks when
+        * it tries to retake the dev->parent semaphore.
+        */
+       err = bus_for_each_dev(&umc_bus_type, NULL, NULL, umc_bus_rescan_helper);
+       if (err < 0)
+               printk(KERN_WARNING "%s: rescan of bus failed: %d\n",
+                      KBUILD_MODNAME, err);
+}
+
+static int umc_bus_match(struct device *dev, struct device_driver *drv)
+{
+       struct umc_dev *umc = to_umc_dev(dev);
+       struct umc_driver *umc_driver = to_umc_driver(drv);
+
+       if (umc->cap_id == umc_driver->cap_id) {
+               if (umc_driver->match)
+                       return umc_driver->match(umc_driver, umc);
+               else
+                       return 1;
+       }
+       return 0;
+}
+
+static int umc_device_probe(struct device *dev)
+{
+       struct umc_dev *umc;
+       struct umc_driver *umc_driver;
+       int err;
+
+       umc_driver = to_umc_driver(dev->driver);
+       umc = to_umc_dev(dev);
+
+       get_device(dev);
+       err = umc_driver->probe(umc);
+       if (err)
+               put_device(dev);
+       else
+               umc_bus_rescan();
+
+       return err;
+}
+
+static int umc_device_remove(struct device *dev)
+{
+       struct umc_dev *umc;
+       struct umc_driver *umc_driver;
+
+       umc_driver = to_umc_driver(dev->driver);
+       umc = to_umc_dev(dev);
+
+       umc_driver->remove(umc);
+       put_device(dev);
+       return 0;
+}
+
+static int umc_device_suspend(struct device *dev, pm_message_t state)
+{
+       struct umc_dev *umc;
+       struct umc_driver *umc_driver;
+       int err = 0;
+
+       umc = to_umc_dev(dev);
+
+       if (dev->driver) {
+               umc_driver = to_umc_driver(dev->driver);
+               if (umc_driver->suspend)
+                       err = umc_driver->suspend(umc, state);
+       }
+       return err;
+}
+
+static int umc_device_resume(struct device *dev)
+{
+       struct umc_dev *umc;
+       struct umc_driver *umc_driver;
+       int err = 0;
+
+       umc = to_umc_dev(dev);
+
+       if (dev->driver) {
+               umc_driver = to_umc_driver(dev->driver);
+               if (umc_driver->resume)
+                       err = umc_driver->resume(umc);
+       }
+       return err;
+}
+
+static ssize_t capability_id_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct umc_dev *umc = to_umc_dev(dev);
+
+       return sprintf(buf, "0x%02x\n", umc->cap_id);
+}
+
+static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct umc_dev *umc = to_umc_dev(dev);
+
+       return sprintf(buf, "0x%04x\n", umc->version);
+}
+
+static struct device_attribute umc_dev_attrs[] = {
+       __ATTR_RO(capability_id),
+       __ATTR_RO(version),
+       __ATTR_NULL,
+};
+
+struct bus_type umc_bus_type = {
+       .name           = "umc",
+       .match          = umc_bus_match,
+       .probe          = umc_device_probe,
+       .remove         = umc_device_remove,
+       .suspend        = umc_device_suspend,
+       .resume         = umc_device_resume,
+       .dev_attrs      = umc_dev_attrs,
+};
+EXPORT_SYMBOL_GPL(umc_bus_type);
+
+static int __init umc_bus_init(void)
+{
+       return bus_register(&umc_bus_type);
+}
+module_init(umc_bus_init);
+
+static void __exit umc_bus_exit(void)
+{
+       bus_unregister(&umc_bus_type);
+}
+module_exit(umc_bus_exit);
+
+MODULE_DESCRIPTION("UWB Multi-interface Controller capability bus");
+MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
+MODULE_LICENSE("GPL");
diff --git a/drivers/uwb/umc-dev.c b/drivers/uwb/umc-dev.c
new file mode 100644 (file)
index 0000000..aa44e1c
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * UWB Multi-interface Controller device management.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * This file is released under the GNU GPL v2.
+ */
+#include <linux/kernel.h>
+#include <linux/uwb/umc.h>
+#define D_LOCAL 0
+#include <linux/uwb/debug.h>
+
+static void umc_device_release(struct device *dev)
+{
+       struct umc_dev *umc = to_umc_dev(dev);
+
+       kfree(umc);
+}
+
+/**
+ * umc_device_create - allocate a child UMC device
+ * @parent: parent of the new UMC device.
+ * @n:      index of the new device.
+ *
+ * The new UMC device will have a bus ID of the parent with '-n'
+ * appended.
+ */
+struct umc_dev *umc_device_create(struct device *parent, int n)
+{
+       struct umc_dev *umc;
+
+       umc = kzalloc(sizeof(struct umc_dev), GFP_KERNEL);
+       if (umc) {
+               snprintf(umc->dev.bus_id, sizeof(umc->dev.bus_id), "%s-%d",
+                        parent->bus_id, n);
+               umc->dev.parent  = parent;
+               umc->dev.bus     = &umc_bus_type;
+               umc->dev.release = umc_device_release;
+
+               umc->dev.dma_mask = parent->dma_mask;
+       }
+       return umc;
+}
+EXPORT_SYMBOL_GPL(umc_device_create);
+
+/**
+ * umc_device_register - register a UMC device
+ * @umc: pointer to the UMC device
+ *
+ * The memory resource for the UMC device is acquired and the device
+ * registered with the system.
+ */
+int umc_device_register(struct umc_dev *umc)
+{
+       int err;
+
+       d_fnstart(3, &umc->dev, "(umc_dev %p)\n", umc);
+
+       err = request_resource(umc->resource.parent, &umc->resource);
+       if (err < 0) {
+               dev_err(&umc->dev, "can't allocate resource range "
+                       "%016Lx to %016Lx: %d\n",
+                       (unsigned long long)umc->resource.start,
+                       (unsigned long long)umc->resource.end,
+                       err);
+               goto error_request_resource;
+       }
+
+       err = device_register(&umc->dev);
+       if (err < 0)
+               goto error_device_register;
+       d_fnend(3, &umc->dev, "(umc_dev %p) = 0\n", umc);
+       return 0;
+
+error_device_register:
+       release_resource(&umc->resource);
+error_request_resource:
+       d_fnend(3, &umc->dev, "(umc_dev %p) = %d\n", umc, err);
+       return err;
+}
+EXPORT_SYMBOL_GPL(umc_device_register);
+
+/**
+ * umc_device_unregister - unregister a UMC device
+ * @umc: pointer to the UMC device
+ *
+ * First we unregister the device, make sure the driver can do it's
+ * resource release thing and then we try to release any left over
+ * resources. We take a ref to the device, to make sure it doesn't
+ * dissapear under our feet.
+ */
+void umc_device_unregister(struct umc_dev *umc)
+{
+       struct device *dev;
+       if (!umc)
+               return;
+       dev = get_device(&umc->dev);
+       d_fnstart(3, dev, "(umc_dev %p)\n", umc);
+       device_unregister(&umc->dev);
+       release_resource(&umc->resource);
+       d_fnend(3, dev, "(umc_dev %p) = void\n", umc);
+       put_device(dev);
+}
+EXPORT_SYMBOL_GPL(umc_device_unregister);
diff --git a/drivers/uwb/umc-drv.c b/drivers/uwb/umc-drv.c
new file mode 100644 (file)
index 0000000..367b5eb
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * UWB Multi-interface Controller driver management.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * This file is released under the GNU GPL v2.
+ */
+#include <linux/kernel.h>
+#include <linux/uwb/umc.h>
+
+int __umc_driver_register(struct umc_driver *umc_drv, struct module *module,
+                         const char *mod_name)
+{
+       umc_drv->driver.name     = umc_drv->name;
+       umc_drv->driver.owner    = module;
+       umc_drv->driver.mod_name = mod_name;
+       umc_drv->driver.bus      = &umc_bus_type;
+
+       return driver_register(&umc_drv->driver);
+}
+EXPORT_SYMBOL_GPL(__umc_driver_register);
+
+/**
+ * umc_driver_register - unregister a UMC capabiltity driver.
+ * @umc_drv:  pointer to the driver.
+ */
+void umc_driver_unregister(struct umc_driver *umc_drv)
+{
+       driver_unregister(&umc_drv->driver);
+}
+EXPORT_SYMBOL_GPL(umc_driver_unregister);
diff --git a/drivers/uwb/uwb-debug.c b/drivers/uwb/uwb-debug.c
new file mode 100644 (file)
index 0000000..6d232c3
--- /dev/null
@@ -0,0 +1,367 @@
+/*
+ * Ultra Wide Band
+ * Debug support
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: doc
+ */
+
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/notifier.h>
+#include <linux/device.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/seq_file.h>
+
+#include <linux/uwb/debug-cmd.h>
+#define D_LOCAL 0
+#include <linux/uwb/debug.h>
+
+#include "uwb-internal.h"
+
+void dump_bytes(struct device *dev, const void *_buf, size_t rsize)
+{
+       const char *buf = _buf;
+       char line[32];
+       size_t offset = 0;
+       int cnt, cnt2;
+       for (cnt = 0; cnt < rsize; cnt += 8) {
+               size_t rtop = rsize - cnt < 8 ? rsize - cnt : 8;
+               for (offset = cnt2 = 0; cnt2 < rtop; cnt2++) {
+                       offset += scnprintf(line + offset, sizeof(line) - offset,
+                                           "%02x ", buf[cnt + cnt2] & 0xff);
+               }
+               if (dev)
+                       dev_info(dev, "%s\n", line);
+               else
+                       printk(KERN_INFO "%s\n", line);
+       }
+}
+EXPORT_SYMBOL_GPL(dump_bytes);
+
+/*
+ * Debug interface
+ *
+ * Per radio controller debugfs files (in uwb/uwbN/):
+ *
+ * command: Flexible command interface (see <linux/uwb/debug-cmd.h>).
+ *
+ * reservations: information on reservations.
+ *
+ * accept: Set to true (Y or 1) to accept reservation requests from
+ * peers.
+ *
+ * drp_avail: DRP availability information.
+ */
+
+struct uwb_dbg {
+       struct uwb_pal pal;
+
+       u32 accept;
+       struct list_head rsvs;
+
+       struct dentry *root_d;
+       struct dentry *command_f;
+       struct dentry *reservations_f;
+       struct dentry *accept_f;
+       struct dentry *drp_avail_f;
+};
+
+static struct dentry *root_dir;
+
+static void uwb_dbg_rsv_cb(struct uwb_rsv *rsv)
+{
+       struct uwb_rc *rc = rsv->rc;
+       struct device *dev = &rc->uwb_dev.dev;
+       struct uwb_dev_addr devaddr;
+       char owner[UWB_ADDR_STRSIZE], target[UWB_ADDR_STRSIZE];
+
+       uwb_dev_addr_print(owner, sizeof(owner), &rsv->owner->dev_addr);
+       if (rsv->target.type == UWB_RSV_TARGET_DEV)
+               devaddr = rsv->target.dev->dev_addr;
+       else
+               devaddr = rsv->target.devaddr;
+       uwb_dev_addr_print(target, sizeof(target), &devaddr);
+
+       dev_dbg(dev, "debug: rsv %s -> %s: %s\n",
+               owner, target, uwb_rsv_state_str(rsv->state));
+}
+
+static int cmd_rsv_establish(struct uwb_rc *rc,
+                            struct uwb_dbg_cmd_rsv_establish *cmd)
+{
+       struct uwb_mac_addr macaddr;
+       struct uwb_rsv *rsv;
+       struct uwb_dev *target;
+       int ret;
+
+       memcpy(&macaddr, cmd->target, sizeof(macaddr));
+       target = uwb_dev_get_by_macaddr(rc, &macaddr);
+       if (target == NULL)
+               return -ENODEV;
+
+       rsv = uwb_rsv_create(rc, uwb_dbg_rsv_cb, NULL);
+       if (rsv == NULL) {
+               uwb_dev_put(target);
+               return -ENOMEM;
+       }
+
+       rsv->owner       = &rc->uwb_dev;
+       rsv->target.type = UWB_RSV_TARGET_DEV;
+       rsv->target.dev  = target;
+       rsv->type        = cmd->type;
+       rsv->max_mas     = cmd->max_mas;
+       rsv->min_mas     = cmd->min_mas;
+       rsv->sparsity    = cmd->sparsity;
+
+       ret = uwb_rsv_establish(rsv);
+       if (ret)
+               uwb_rsv_destroy(rsv);
+       else
+               list_add_tail(&rsv->pal_node, &rc->dbg->rsvs);
+
+       return ret;
+}
+
+static int cmd_rsv_terminate(struct uwb_rc *rc,
+                            struct uwb_dbg_cmd_rsv_terminate *cmd)
+{
+       struct uwb_rsv *rsv, *found = NULL;
+       int i = 0;
+
+       list_for_each_entry(rsv, &rc->dbg->rsvs, pal_node) {
+               if (i == cmd->index) {
+                       found = rsv;
+                       break;
+               }
+       }
+       if (!found)
+               return -EINVAL;
+
+       list_del(&found->pal_node);
+       uwb_rsv_terminate(found);
+
+       return 0;
+}
+
+static int command_open(struct inode *inode, struct file *file)
+{
+       file->private_data = inode->i_private;
+
+       return 0;
+}
+
+static ssize_t command_write(struct file *file, const char __user *buf,
+                        size_t len, loff_t *off)
+{
+       struct uwb_rc *rc = file->private_data;
+       struct uwb_dbg_cmd cmd;
+       int ret;
+
+       if (len != sizeof(struct uwb_dbg_cmd))
+               return -EINVAL;
+
+       if (copy_from_user(&cmd, buf, len) != 0)
+               return -EFAULT;
+
+       switch (cmd.type) {
+       case UWB_DBG_CMD_RSV_ESTABLISH:
+               ret = cmd_rsv_establish(rc, &cmd.rsv_establish);
+               break;
+       case UWB_DBG_CMD_RSV_TERMINATE:
+               ret = cmd_rsv_terminate(rc, &cmd.rsv_terminate);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return ret < 0 ? ret : len;
+}
+
+static struct file_operations command_fops = {
+       .open   = command_open,
+       .write  = command_write,
+       .read   = NULL,
+       .llseek = no_llseek,
+       .owner  = THIS_MODULE,
+};
+
+static int reservations_print(struct seq_file *s, void *p)
+{
+       struct uwb_rc *rc = s->private;
+       struct uwb_rsv *rsv;
+
+       mutex_lock(&rc->rsvs_mutex);
+
+       list_for_each_entry(rsv, &rc->reservations, rc_node) {
+               struct uwb_dev_addr devaddr;
+               char owner[UWB_ADDR_STRSIZE], target[UWB_ADDR_STRSIZE];
+               bool is_owner;
+               char buf[72];
+
+               uwb_dev_addr_print(owner, sizeof(owner), &rsv->owner->dev_addr);
+               if (rsv->target.type == UWB_RSV_TARGET_DEV) {
+                       devaddr = rsv->target.dev->dev_addr;
+                       is_owner = &rc->uwb_dev == rsv->owner;
+               } else {
+                       devaddr = rsv->target.devaddr;
+                       is_owner = true;
+               }
+               uwb_dev_addr_print(target, sizeof(target), &devaddr);
+
+               seq_printf(s, "%c %s -> %s: %s\n",
+                          is_owner ? 'O' : 'T',
+                          owner, target, uwb_rsv_state_str(rsv->state));
+               seq_printf(s, "  stream: %d  type: %s\n",
+                          rsv->stream, uwb_rsv_type_str(rsv->type));
+               bitmap_scnprintf(buf, sizeof(buf), rsv->mas.bm, UWB_NUM_MAS);
+               seq_printf(s, "  %s\n", buf);
+       }
+
+       mutex_unlock(&rc->rsvs_mutex);
+
+       return 0;
+}
+
+static int reservations_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, reservations_print, inode->i_private);
+}
+
+static struct file_operations reservations_fops = {
+       .open    = reservations_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = single_release,
+       .owner   = THIS_MODULE,
+};
+
+static int drp_avail_print(struct seq_file *s, void *p)
+{
+       struct uwb_rc *rc = s->private;
+       char buf[72];
+
+       bitmap_scnprintf(buf, sizeof(buf), rc->drp_avail.global, UWB_NUM_MAS);
+       seq_printf(s, "global:  %s\n", buf);
+       bitmap_scnprintf(buf, sizeof(buf), rc->drp_avail.local, UWB_NUM_MAS);
+       seq_printf(s, "local:   %s\n", buf);
+       bitmap_scnprintf(buf, sizeof(buf), rc->drp_avail.pending, UWB_NUM_MAS);
+       seq_printf(s, "pending: %s\n", buf);
+
+       return 0;
+}
+
+static int drp_avail_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, drp_avail_print, inode->i_private);
+}
+
+static struct file_operations drp_avail_fops = {
+       .open    = drp_avail_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = single_release,
+       .owner   = THIS_MODULE,
+};
+
+static void uwb_dbg_new_rsv(struct uwb_rsv *rsv)
+{
+       struct uwb_rc *rc = rsv->rc;
+
+       if (rc->dbg->accept)
+               uwb_rsv_accept(rsv, uwb_dbg_rsv_cb, NULL);
+}
+
+/**
+ * uwb_dbg_add_rc - add a debug interface for a radio controller
+ * @rc: the radio controller
+ */
+void uwb_dbg_add_rc(struct uwb_rc *rc)
+{
+       rc->dbg = kzalloc(sizeof(struct uwb_dbg), GFP_KERNEL);
+       if (rc->dbg == NULL)
+               return;
+
+       INIT_LIST_HEAD(&rc->dbg->rsvs);
+
+       uwb_pal_init(&rc->dbg->pal);
+       rc->dbg->pal.new_rsv = uwb_dbg_new_rsv;
+       uwb_pal_register(rc, &rc->dbg->pal);
+       if (root_dir) {
+               rc->dbg->root_d = debugfs_create_dir(dev_name(&rc->uwb_dev.dev),
+                                                    root_dir);
+               rc->dbg->command_f = debugfs_create_file("command", 0200,
+                                                        rc->dbg->root_d, rc,
+                                                        &command_fops);
+               rc->dbg->reservations_f = debugfs_create_file("reservations", 0444,
+                                                             rc->dbg->root_d, rc,
+                                                             &reservations_fops);
+               rc->dbg->accept_f = debugfs_create_bool("accept", 0644,
+                                                       rc->dbg->root_d,
+                                                       &rc->dbg->accept);
+               rc->dbg->drp_avail_f = debugfs_create_file("drp_avail", 0444,
+                                                          rc->dbg->root_d, rc,
+                                                          &drp_avail_fops);
+       }
+}
+
+/**
+ * uwb_dbg_add_rc - remove a radio controller's debug interface
+ * @rc: the radio controller
+ */
+void uwb_dbg_del_rc(struct uwb_rc *rc)
+{
+       struct uwb_rsv *rsv, *t;
+
+       if (rc->dbg == NULL)
+               return;
+
+       list_for_each_entry_safe(rsv, t, &rc->dbg->rsvs, pal_node) {
+               uwb_rsv_destroy(rsv);
+       }
+
+       uwb_pal_unregister(rc, &rc->dbg->pal);
+
+       if (root_dir) {
+               debugfs_remove(rc->dbg->drp_avail_f);
+               debugfs_remove(rc->dbg->accept_f);
+               debugfs_remove(rc->dbg->reservations_f);
+               debugfs_remove(rc->dbg->command_f);
+               debugfs_remove(rc->dbg->root_d);
+       }
+}
+
+/**
+ * uwb_dbg_exit - initialize the debug interface sub-module
+ */
+void uwb_dbg_init(void)
+{
+       root_dir = debugfs_create_dir("uwb", NULL);
+}
+
+/**
+ * uwb_dbg_exit - clean-up the debug interface sub-module
+ */
+void uwb_dbg_exit(void)
+{
+       debugfs_remove(root_dir);
+}
diff --git a/drivers/uwb/uwb-internal.h b/drivers/uwb/uwb-internal.h
new file mode 100644 (file)
index 0000000..2ad307d
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+ * Ultra Wide Band
+ * UWB internal API
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * This contains most of the internal API for UWB. This is stuff used
+ * across the stack that of course, is of no interest to the rest.
+ *
+ * Some parts might end up going public (like uwb_rc_*())...
+ */
+
+#ifndef __UWB_INTERNAL_H__
+#define __UWB_INTERNAL_H__
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/uwb.h>
+#include <linux/mutex.h>
+
+struct uwb_beca_e;
+
+/* General device API */
+extern void uwb_dev_init(struct uwb_dev *uwb_dev);
+extern int __uwb_dev_offair(struct uwb_dev *, struct uwb_rc *);
+extern int uwb_dev_add(struct uwb_dev *uwb_dev, struct device *parent_dev,
+                      struct uwb_rc *parent_rc);
+extern void uwb_dev_rm(struct uwb_dev *uwb_dev);
+extern void uwbd_dev_onair(struct uwb_rc *, struct uwb_beca_e *);
+extern void uwbd_dev_offair(struct uwb_beca_e *);
+void uwb_notify(struct uwb_rc *rc, struct uwb_dev *uwb_dev, enum uwb_notifs event);
+
+/* General UWB Radio Controller Internal API */
+extern struct uwb_rc *__uwb_rc_try_get(struct uwb_rc *);
+static inline struct uwb_rc *__uwb_rc_get(struct uwb_rc *rc)
+{
+       uwb_dev_get(&rc->uwb_dev);
+       return rc;
+}
+
+static inline void __uwb_rc_put(struct uwb_rc *rc)
+{
+       uwb_dev_put(&rc->uwb_dev);
+}
+
+extern int uwb_rc_reset(struct uwb_rc *rc);
+extern int uwb_rc_beacon(struct uwb_rc *rc,
+                        int channel, unsigned bpst_offset);
+extern int uwb_rc_scan(struct uwb_rc *rc,
+                      unsigned channel, enum uwb_scan_type type,
+                      unsigned bpst_offset);
+extern int uwb_rc_send_all_drp_ie(struct uwb_rc *rc);
+extern ssize_t uwb_rc_print_IEs(struct uwb_rc *rc, char *, size_t);
+extern void uwb_rc_ie_init(struct uwb_rc *);
+extern void uwb_rc_ie_init(struct uwb_rc *);
+extern ssize_t uwb_rc_ie_setup(struct uwb_rc *);
+extern void uwb_rc_ie_release(struct uwb_rc *);
+extern int uwb_rc_ie_add(struct uwb_rc *,
+                        const struct uwb_ie_hdr *, size_t);
+extern int uwb_rc_ie_rm(struct uwb_rc *, enum uwb_ie);
+
+extern const char *uwb_rc_strerror(unsigned code);
+
+/*
+ * Time to wait for a response to an RC command.
+ *
+ * Some commands can take a long time to response. e.g., START_BEACON
+ * may scan for several superframes before joining an existing beacon
+ * group and this can take around 600 ms.
+ */
+#define UWB_RC_CMD_TIMEOUT_MS 1000 /* ms */
+
+/*
+ * Notification/Event Handlers
+ */
+
+struct uwb_rc_neh;
+
+void uwb_rc_neh_create(struct uwb_rc *rc);
+void uwb_rc_neh_destroy(struct uwb_rc *rc);
+
+struct uwb_rc_neh *uwb_rc_neh_add(struct uwb_rc *rc, struct uwb_rccb *cmd,
+                                 u8 expected_type, u16 expected_event,
+                                 uwb_rc_cmd_cb_f cb, void *arg);
+void uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh);
+void uwb_rc_neh_arm(struct uwb_rc *rc, struct uwb_rc_neh *neh);
+void uwb_rc_neh_put(struct uwb_rc_neh *neh);
+
+/* Event size tables */
+extern int uwb_est_create(void);
+extern void uwb_est_destroy(void);
+
+
+/*
+ * UWB Events & management daemon
+ */
+
+/**
+ * enum uwb_event_type - types of UWB management daemon events
+ *
+ * The UWB management daemon (uwbd) can receive two types of events:
+ *   UWB_EVT_TYPE_NOTIF - notification from the radio controller.
+ *   UWB_EVT_TYPE_MSG   - a simple message.
+ */
+enum uwb_event_type {
+       UWB_EVT_TYPE_NOTIF,
+       UWB_EVT_TYPE_MSG,
+};
+
+/**
+ * struct uwb_event_notif - an event for a radio controller notification
+ * @size: Size of the buffer (ie: Guaranteed to contain at least
+ *        a full 'struct uwb_rceb')
+ * @rceb: Pointer to a kmalloced() event payload
+ */
+struct uwb_event_notif {
+       size_t size;
+       struct uwb_rceb *rceb;
+};
+
+/**
+ * enum uwb_event_message - an event for a message for asynchronous processing
+ *
+ * UWB_EVT_MSG_RESET - reset the radio controller and all PAL hardware.
+ */
+enum uwb_event_message {
+       UWB_EVT_MSG_RESET,
+};
+
+/**
+ * UWB Event
+ * @rc:         Radio controller that emitted the event (referenced)
+ * @ts_jiffies: Timestamp, when was it received
+ * @type:       This event's type.
+ */
+struct uwb_event {
+       struct list_head list_node;
+       struct uwb_rc *rc;
+       unsigned long ts_jiffies;
+       enum uwb_event_type type;
+       union {
+               struct uwb_event_notif notif;
+               enum uwb_event_message message;
+       };
+};
+
+extern void uwbd_start(void);
+extern void uwbd_stop(void);
+extern struct uwb_event *uwb_event_alloc(size_t, gfp_t gfp_mask);
+extern void uwbd_event_queue(struct uwb_event *);
+void uwbd_flush(struct uwb_rc *rc);
+
+/* UWB event handlers */
+extern int uwbd_evt_handle_rc_beacon(struct uwb_event *);
+extern int uwbd_evt_handle_rc_beacon_size(struct uwb_event *);
+extern int uwbd_evt_handle_rc_bpoie_change(struct uwb_event *);
+extern int uwbd_evt_handle_rc_bp_slot_change(struct uwb_event *);
+extern int uwbd_evt_handle_rc_drp(struct uwb_event *);
+extern int uwbd_evt_handle_rc_drp_avail(struct uwb_event *);
+
+int uwbd_msg_handle_reset(struct uwb_event *evt);
+
+
+/*
+ * Address management
+ */
+int uwb_rc_dev_addr_assign(struct uwb_rc *rc);
+int uwbd_evt_handle_rc_dev_addr_conflict(struct uwb_event *evt);
+
+/*
+ * UWB Beacon Cache
+ *
+ * Each beacon we received is kept in a cache--when we receive that
+ * beacon consistently, that means there is a new device that we have
+ * to add to the system.
+ */
+
+extern unsigned long beacon_timeout_ms;
+
+/** Beacon cache list */
+struct uwb_beca {
+       struct list_head list;
+       size_t entries;
+       struct mutex mutex;
+};
+
+extern struct uwb_beca uwb_beca;
+
+/**
+ * Beacon cache entry
+ *
+ * @jiffies_refresh: last time a beacon was  received that refreshed
+ *                   this cache entry.
+ * @uwb_dev: device connected to this beacon. This pointer is not
+ *           safe, you need to get it with uwb_dev_try_get()
+ *
+ * @hits: how many time we have seen this beacon since last time we
+ *        cleared it
+ */
+struct uwb_beca_e {
+       struct mutex mutex;
+       struct kref refcnt;
+       struct list_head node;
+       struct uwb_mac_addr *mac_addr;
+       struct uwb_dev_addr dev_addr;
+       u8 hits;
+       unsigned long ts_jiffies;
+       struct uwb_dev *uwb_dev;
+       struct uwb_rc_evt_beacon *be;
+       struct stats lqe_stats, rssi_stats;     /* radio statistics */
+};
+struct uwb_beacon_frame;
+extern ssize_t uwb_bce_print_IEs(struct uwb_dev *, struct uwb_beca_e *,
+                                char *, size_t);
+extern struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *,
+                                        struct uwb_beacon_frame *,
+                                        unsigned long);
+
+extern void uwb_bce_kfree(struct kref *_bce);
+static inline void uwb_bce_get(struct uwb_beca_e *bce)
+{
+       kref_get(&bce->refcnt);
+}
+static inline void uwb_bce_put(struct uwb_beca_e *bce)
+{
+       kref_put(&bce->refcnt, uwb_bce_kfree);
+}
+extern void uwb_beca_purge(void);
+extern void uwb_beca_release(void);
+
+struct uwb_dev *uwb_dev_get_by_devaddr(struct uwb_rc *rc,
+                                      const struct uwb_dev_addr *devaddr);
+struct uwb_dev *uwb_dev_get_by_macaddr(struct uwb_rc *rc,
+                                      const struct uwb_mac_addr *macaddr);
+
+/* -- UWB Sysfs representation */
+extern struct class uwb_rc_class;
+extern struct device_attribute dev_attr_mac_address;
+extern struct device_attribute dev_attr_beacon;
+extern struct device_attribute dev_attr_scan;
+
+/* -- DRP Bandwidth allocator: bandwidth allocations, reservations, DRP */
+void uwb_rsv_init(struct uwb_rc *rc);
+int uwb_rsv_setup(struct uwb_rc *rc);
+void uwb_rsv_cleanup(struct uwb_rc *rc);
+
+void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state);
+void uwb_rsv_remove(struct uwb_rsv *rsv);
+struct uwb_rsv *uwb_rsv_find(struct uwb_rc *rc, struct uwb_dev *src,
+                            struct uwb_ie_drp *drp_ie);
+void uwb_rsv_sched_update(struct uwb_rc *rc);
+
+void uwb_drp_handle_timeout(struct uwb_rsv *rsv);
+int uwb_drp_ie_update(struct uwb_rsv *rsv);
+void uwb_drp_ie_to_bm(struct uwb_mas_bm *bm, const struct uwb_ie_drp *drp_ie);
+
+void uwb_drp_avail_init(struct uwb_rc *rc);
+int  uwb_drp_avail_reserve_pending(struct uwb_rc *rc, struct uwb_mas_bm *mas);
+void uwb_drp_avail_reserve(struct uwb_rc *rc, struct uwb_mas_bm *mas);
+void uwb_drp_avail_release(struct uwb_rc *rc, struct uwb_mas_bm *mas);
+void uwb_drp_avail_ie_update(struct uwb_rc *rc);
+
+/* -- PAL support */
+void uwb_rc_pal_init(struct uwb_rc *rc);
+
+/* -- Misc */
+
+extern ssize_t uwb_mac_frame_hdr_print(char *, size_t,
+                                      const struct uwb_mac_frame_hdr *);
+
+/* -- Debug interface */
+void uwb_dbg_init(void);
+void uwb_dbg_exit(void);
+void uwb_dbg_add_rc(struct uwb_rc *rc);
+void uwb_dbg_del_rc(struct uwb_rc *rc);
+
+/* Workarounds for version specific stuff */
+
+static inline void uwb_dev_lock(struct uwb_dev *uwb_dev)
+{
+       down(&uwb_dev->dev.sem);
+}
+
+static inline void uwb_dev_unlock(struct uwb_dev *uwb_dev)
+{
+       up(&uwb_dev->dev.sem);
+}
+
+#endif /* #ifndef __UWB_INTERNAL_H__ */
diff --git a/drivers/uwb/uwbd.c b/drivers/uwb/uwbd.c
new file mode 100644 (file)
index 0000000..7890841
--- /dev/null
@@ -0,0 +1,410 @@
+/*
+ * Ultra Wide Band
+ * Neighborhood Management Daemon
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * This daemon takes care of maintaing information that describes the
+ * UWB neighborhood that the radios in this machine can see. It also
+ * keeps a tab of which devices are visible, makes sure each HC sits
+ * on a different channel to avoid interfering, etc.
+ *
+ * Different drivers (radio controller, device, any API in general)
+ * communicate with this daemon through an event queue. Daemon wakes
+ * up, takes a list of events and handles them one by one; handling
+ * function is extracted from a table based on the event's type and
+ * subtype. Events are freed only if the handling function says so.
+ *
+ *   . Lock protecting the event list has to be an spinlock and locked
+ *     with IRQSAVE because it might be called from an interrupt
+ *     context (ie: when events arrive and the notification drops
+ *     down from the ISR).
+ *
+ *   . UWB radio controller drivers queue events to the daemon using
+ *     uwbd_event_queue(). They just get the event, chew it to make it
+ *     look like UWBD likes it and pass it in a buffer allocated with
+ *     uwb_event_alloc().
+ *
+ * EVENTS
+ *
+ * Events have a type, a subtype, a lenght, some other stuff and the
+ * data blob, which depends on the event. The header is 'struct
+ * uwb_event'; for payloads, see 'struct uwbd_evt_*'.
+ *
+ * EVENT HANDLER TABLES
+ *
+ * To find a handling function for an event, the type is used to index
+ * a subtype-table in the type-table. The subtype-table is indexed
+ * with the subtype to get the function that handles the event. Start
+ * with the main type-table 'uwbd_evt_type_handler'.
+ *
+ * DEVICES
+ *
+ * Devices are created when a bunch of beacons have been received and
+ * it is stablished that the device has stable radio presence. CREATED
+ * only, not configured. Devices are ONLY configured when an
+ * Application-Specific IE Probe is receieved, in which the device
+ * declares which Protocol ID it groks. Then the device is CONFIGURED
+ * (and the driver->probe() stuff of the device model is invoked).
+ *
+ * Devices are considered disconnected when a certain number of
+ * beacons are not received in an amount of time.
+ *
+ * Handler functions are called normally uwbd_evt_handle_*().
+ */
+
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/freezer.h>
+#include "uwb-internal.h"
+
+#define D_LOCAL 1
+#include <linux/uwb/debug.h>
+
+
+/**
+ * UWBD Event handler function signature
+ *
+ * Return !0 if the event needs not to be freed (ie the handler
+ * takes/took care of it). 0 means the daemon code will free the
+ * event.
+ *
+ * @evt->rc is already referenced and guaranteed to exist. See
+ * uwb_evt_handle().
+ */
+typedef int (*uwbd_evt_handler_f)(struct uwb_event *);
+
+/**
+ * Properties of a UWBD event
+ *
+ * @handler:    the function that will handle this event
+ * @name:       text name of event
+ */
+struct uwbd_event {
+       uwbd_evt_handler_f handler;
+       const char *name;
+};
+
+/** Table of handlers for and properties of the UWBD Radio Control Events */
+static
+struct uwbd_event uwbd_events[] = {
+       [UWB_RC_EVT_BEACON] = {
+               .handler = uwbd_evt_handle_rc_beacon,
+               .name = "BEACON_RECEIVED"
+       },
+       [UWB_RC_EVT_BEACON_SIZE] = {
+               .handler = uwbd_evt_handle_rc_beacon_size,
+               .name = "BEACON_SIZE_CHANGE"
+       },
+       [UWB_RC_EVT_BPOIE_CHANGE] = {
+               .handler = uwbd_evt_handle_rc_bpoie_change,
+               .name = "BPOIE_CHANGE"
+       },
+       [UWB_RC_EVT_BP_SLOT_CHANGE] = {
+               .handler = uwbd_evt_handle_rc_bp_slot_change,
+               .name = "BP_SLOT_CHANGE"
+       },
+       [UWB_RC_EVT_DRP_AVAIL] = {
+               .handler = uwbd_evt_handle_rc_drp_avail,
+               .name = "DRP_AVAILABILITY_CHANGE"
+       },
+       [UWB_RC_EVT_DRP] = {
+               .handler = uwbd_evt_handle_rc_drp,
+               .name = "DRP"
+       },
+       [UWB_RC_EVT_DEV_ADDR_CONFLICT] = {
+               .handler = uwbd_evt_handle_rc_dev_addr_conflict,
+               .name = "DEV_ADDR_CONFLICT",
+       },
+};
+
+
+
+struct uwbd_evt_type_handler {
+       const char *name;
+       struct uwbd_event *uwbd_events;
+       size_t size;
+};
+
+#define UWBD_EVT_TYPE_HANDLER(n,a) {           \
+       .name = (n),                            \
+       .uwbd_events = (a),                     \
+       .size = sizeof(a)/sizeof((a)[0])        \
+}
+
+
+/** Table of handlers for each UWBD Event type. */
+static
+struct uwbd_evt_type_handler uwbd_evt_type_handlers[] = {
+       [UWB_RC_CET_GENERAL] = UWBD_EVT_TYPE_HANDLER("RC", uwbd_events)
+};
+
+static const
+size_t uwbd_evt_type_handlers_len =
+       sizeof(uwbd_evt_type_handlers) / sizeof(uwbd_evt_type_handlers[0]);
+
+static const struct uwbd_event uwbd_message_handlers[] = {
+       [UWB_EVT_MSG_RESET] = {
+               .handler = uwbd_msg_handle_reset,
+               .name = "reset",
+       },
+};
+
+static DEFINE_MUTEX(uwbd_event_mutex);
+
+/**
+ * Handle an URC event passed to the UWB Daemon
+ *
+ * @evt: the event to handle
+ * @returns: 0 if the event can be kfreed, !0 on the contrary
+ *           (somebody else took ownership) [coincidentally, returning
+ *           a <0 errno code will free it :)].
+ *
+ * Looks up the two indirection tables (one for the type, one for the
+ * subtype) to decide which function handles it and then calls the
+ * handler.
+ *
+ * The event structure passed to the event handler has the radio
+ * controller in @evt->rc referenced. The reference will be dropped
+ * once the handler returns, so if it needs it for longer (async),
+ * it'll need to take another one.
+ */
+static
+int uwbd_event_handle_urc(struct uwb_event *evt)
+{
+       struct uwbd_evt_type_handler *type_table;
+       uwbd_evt_handler_f handler;
+       u8 type, context;
+       u16 event;
+
+       type = evt->notif.rceb->bEventType;
+       event = le16_to_cpu(evt->notif.rceb->wEvent);
+       context = evt->notif.rceb->bEventContext;
+
+       if (type > uwbd_evt_type_handlers_len) {
+               printk(KERN_ERR "UWBD: event type %u: unknown (too high)\n", type);
+               return -EINVAL;
+       }
+       type_table = &uwbd_evt_type_handlers[type];
+       if (type_table->uwbd_events == NULL) {
+               printk(KERN_ERR "UWBD: event type %u: unknown\n", type);
+               return -EINVAL;
+       }
+       if (event > type_table->size) {
+               printk(KERN_ERR "UWBD: event %s[%u]: unknown (too high)\n",
+                      type_table->name, event);
+               return -EINVAL;
+       }
+       handler = type_table->uwbd_events[event].handler;
+       if (handler == NULL) {
+               printk(KERN_ERR "UWBD: event %s[%u]: unknown\n", type_table->name, event);
+               return -EINVAL;
+       }
+       return (*handler)(evt);
+}
+
+static void uwbd_event_handle_message(struct uwb_event *evt)
+{
+       struct uwb_rc *rc;
+       int result;
+
+       rc = evt->rc;
+
+       if (evt->message < 0 || evt->message >= ARRAY_SIZE(uwbd_message_handlers)) {
+               dev_err(&rc->uwb_dev.dev, "UWBD: invalid message type %d\n", evt->message);
+               return;
+       }
+
+       /* If this is a reset event we need to drop the
+        * uwbd_event_mutex or it deadlocks when the reset handler
+        * attempts to flush the uwbd events. */
+       if (evt->message == UWB_EVT_MSG_RESET)
+               mutex_unlock(&uwbd_event_mutex);
+
+       result = uwbd_message_handlers[evt->message].handler(evt);
+       if (result < 0)
+               dev_err(&rc->uwb_dev.dev, "UWBD: '%s' message failed: %d\n",
+                       uwbd_message_handlers[evt->message].name, result);
+
+       if (evt->message == UWB_EVT_MSG_RESET)
+               mutex_lock(&uwbd_event_mutex);
+}
+
+static void uwbd_event_handle(struct uwb_event *evt)
+{
+       struct uwb_rc *rc;
+       int should_keep;
+
+       rc = evt->rc;
+
+       if (rc->ready) {
+               switch (evt->type) {
+               case UWB_EVT_TYPE_NOTIF:
+                       should_keep = uwbd_event_handle_urc(evt);
+                       if (should_keep <= 0)
+                               kfree(evt->notif.rceb);
+                       break;
+               case UWB_EVT_TYPE_MSG:
+                       uwbd_event_handle_message(evt);
+                       break;
+               default:
+                       dev_err(&rc->uwb_dev.dev, "UWBD: invalid event type %d\n", evt->type);
+                       break;
+               }
+       }
+
+       __uwb_rc_put(rc);       /* for the __uwb_rc_get() in uwb_rc_notif_cb() */
+}
+/* The UWB Daemon */
+
+
+/** Daemon's PID: used to decide if we can queue or not */
+static int uwbd_pid;
+/** Daemon's task struct for managing the kthread */
+static struct task_struct *uwbd_task;
+/** Daemon's waitqueue for waiting for new events */
+static DECLARE_WAIT_QUEUE_HEAD(uwbd_wq);
+/** Daemon's list of events; we queue/dequeue here */
+static struct list_head uwbd_event_list = LIST_HEAD_INIT(uwbd_event_list);
+/** Daemon's list lock to protect concurent access */
+static DEFINE_SPINLOCK(uwbd_event_list_lock);
+
+
+/**
+ * UWB Daemon
+ *
+ * Listens to all UWB notifications and takes care to track the state
+ * of the UWB neighboorhood for the kernel. When we do a run, we
+ * spinlock, move the list to a private copy and release the
+ * lock. Hold it as little as possible. Not a conflict: it is
+ * guaranteed we own the events in the private list.
+ *
+ * FIXME: should change so we don't have a 1HZ timer all the time, but
+ *        only if there are devices.
+ */
+static int uwbd(void *unused)
+{
+       unsigned long flags;
+       struct list_head list = LIST_HEAD_INIT(list);
+       struct uwb_event *evt, *nxt;
+       int should_stop = 0;
+       while (1) {
+               wait_event_interruptible_timeout(
+                       uwbd_wq,
+                       !list_empty(&uwbd_event_list)
+                         || (should_stop = kthread_should_stop()),
+                       HZ);
+               if (should_stop)
+                       break;
+               try_to_freeze();
+
+               mutex_lock(&uwbd_event_mutex);
+               spin_lock_irqsave(&uwbd_event_list_lock, flags);
+               list_splice_init(&uwbd_event_list, &list);
+               spin_unlock_irqrestore(&uwbd_event_list_lock, flags);
+               list_for_each_entry_safe(evt, nxt, &list, list_node) {
+                       list_del(&evt->list_node);
+                       uwbd_event_handle(evt);
+                       kfree(evt);
+               }
+               mutex_unlock(&uwbd_event_mutex);
+
+               uwb_beca_purge();       /* Purge devices that left */
+       }
+       return 0;
+}
+
+
+/** Start the UWB daemon */
+void uwbd_start(void)
+{
+       uwbd_task = kthread_run(uwbd, NULL, "uwbd");
+       if (uwbd_task == NULL)
+               printk(KERN_ERR "UWB: Cannot start management daemon; "
+                      "UWB won't work\n");
+       else
+               uwbd_pid = uwbd_task->pid;
+}
+
+/* Stop the UWB daemon and free any unprocessed events */
+void uwbd_stop(void)
+{
+       unsigned long flags;
+       struct uwb_event *evt, *nxt;
+       kthread_stop(uwbd_task);
+       spin_lock_irqsave(&uwbd_event_list_lock, flags);
+       uwbd_pid = 0;
+       list_for_each_entry_safe(evt, nxt, &uwbd_event_list, list_node) {
+               if (evt->type == UWB_EVT_TYPE_NOTIF)
+                       kfree(evt->notif.rceb);
+               kfree(evt);
+       }
+       spin_unlock_irqrestore(&uwbd_event_list_lock, flags);
+       uwb_beca_release();
+}
+
+/*
+ * Queue an event for the management daemon
+ *
+ * When some lower layer receives an event, it uses this function to
+ * push it forward to the UWB daemon.
+ *
+ * Once you pass the event, you don't own it any more, but the daemon
+ * does. It will uwb_event_free() it when done, so make sure you
+ * uwb_event_alloc()ed it or bad things will happen.
+ *
+ * If the daemon is not running, we just free the event.
+ */
+void uwbd_event_queue(struct uwb_event *evt)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&uwbd_event_list_lock, flags);
+       if (uwbd_pid != 0) {
+               list_add(&evt->list_node, &uwbd_event_list);
+               wake_up_all(&uwbd_wq);
+       } else {
+               __uwb_rc_put(evt->rc);
+               if (evt->type == UWB_EVT_TYPE_NOTIF)
+                       kfree(evt->notif.rceb);
+               kfree(evt);
+       }
+       spin_unlock_irqrestore(&uwbd_event_list_lock, flags);
+       return;
+}
+
+void uwbd_flush(struct uwb_rc *rc)
+{
+       struct uwb_event *evt, *nxt;
+
+       mutex_lock(&uwbd_event_mutex);
+
+       spin_lock_irq(&uwbd_event_list_lock);
+       list_for_each_entry_safe(evt, nxt, &uwbd_event_list, list_node) {
+               if (evt->rc == rc) {
+                       __uwb_rc_put(rc);
+                       list_del(&evt->list_node);
+                       if (evt->type == UWB_EVT_TYPE_NOTIF)
+                               kfree(evt->notif.rceb);
+                       kfree(evt);
+               }
+       }
+       spin_unlock_irq(&uwbd_event_list_lock);
+
+       mutex_unlock(&uwbd_event_mutex);
+}
diff --git a/drivers/uwb/whc-rc.c b/drivers/uwb/whc-rc.c
new file mode 100644 (file)
index 0000000..1711dea
--- /dev/null
@@ -0,0 +1,520 @@
+/*
+ * Wireless Host Controller: Radio Control Interface (WHCI v0.95[2.3])
+ * Radio Control command/event transport to the UWB stack
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * Initialize and hook up the Radio Control interface.
+ *
+ * For each device probed, creates an 'struct whcrc' which contains
+ * just the representation of the UWB Radio Controller, and the logic
+ * for reading notifications and passing them to the UWB Core.
+ *
+ * So we initialize all of those, register the UWB Radio Controller
+ * and setup the notification/event handle to pipe the notifications
+ * to the UWB management Daemon.
+ *
+ * Once uwb_rc_add() is called, the UWB stack takes control, resets
+ * the radio and readies the device to take commands the UWB
+ * API/user-space.
+ *
+ * Note this driver is just a transport driver; the commands are
+ * formed at the UWB stack and given to this driver who will deliver
+ * them to the hw and transfer the replies/notifications back to the
+ * UWB stack through the UWB daemon (UWBD).
+ */
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/uwb.h>
+#include <linux/uwb/whci.h>
+#include <linux/uwb/umc.h>
+#include "uwb-internal.h"
+
+#define D_LOCAL 0
+#include <linux/uwb/debug.h>
+
+/**
+ * Descriptor for an instance of the UWB Radio Control Driver that
+ * attaches to the URC interface of the WHCI PCI card.
+ *
+ * Unless there is a lock specific to the 'data members', all access
+ * is protected by uwb_rc->mutex.
+ */
+struct whcrc {
+       struct umc_dev *umc_dev;
+       struct uwb_rc *uwb_rc;          /* UWB host controller */
+
+       unsigned long area;
+       void __iomem *rc_base;
+       size_t rc_len;
+       spinlock_t irq_lock;
+
+       void *evt_buf, *cmd_buf;
+       dma_addr_t evt_dma_buf, cmd_dma_buf;
+       wait_queue_head_t cmd_wq;
+       struct work_struct event_work;
+};
+
+/**
+ * Execute an UWB RC command on WHCI/RC
+ *
+ * @rc:       Instance of a Radio Controller that is a whcrc
+ * @cmd:      Buffer containing the RCCB and payload to execute
+ * @cmd_size: Size of the command buffer.
+ *
+ * We copy the command into whcrc->cmd_buf (as it is pretty and
+ * aligned`and physically contiguous) and then press the right keys in
+ * the controller's URCCMD register to get it to read it. We might
+ * have to wait for the cmd_sem to be open to us.
+ *
+ * NOTE: rc's mutex has to be locked
+ */
+static int whcrc_cmd(struct uwb_rc *uwb_rc,
+             const struct uwb_rccb *cmd, size_t cmd_size)
+{
+       int result = 0;
+       struct whcrc *whcrc = uwb_rc->priv;
+       struct device *dev = &whcrc->umc_dev->dev;
+       u32 urccmd;
+
+       d_fnstart(3, dev, "(%p, %p, %zu)\n", uwb_rc, cmd, cmd_size);
+       might_sleep();
+
+       if (cmd_size >= 4096) {
+               result = -E2BIG;
+               goto error;
+       }
+
+       /*
+        * If the URC is halted, then the hardware has reset itself.
+        * Attempt to recover by restarting the device and then return
+        * an error as it's likely that the current command isn't
+        * valid for a newly started RC.
+        */
+       if (le_readl(whcrc->rc_base + URCSTS) & URCSTS_HALTED) {
+               dev_err(dev, "requesting reset of halted radio controller\n");
+               uwb_rc_reset_all(uwb_rc);
+               result = -EIO;
+               goto error;
+       }
+
+       result = wait_event_timeout(whcrc->cmd_wq,
+               !(le_readl(whcrc->rc_base + URCCMD) & URCCMD_ACTIVE), HZ/2);
+       if (result == 0) {
+               dev_err(dev, "device is not ready to execute commands\n");
+               result = -ETIMEDOUT;
+               goto error;
+       }
+
+       memmove(whcrc->cmd_buf, cmd, cmd_size);
+       le_writeq(whcrc->cmd_dma_buf, whcrc->rc_base + URCCMDADDR);
+
+       spin_lock(&whcrc->irq_lock);
+       urccmd = le_readl(whcrc->rc_base + URCCMD);
+       urccmd &= ~(URCCMD_EARV | URCCMD_SIZE_MASK);
+       le_writel(urccmd | URCCMD_ACTIVE | URCCMD_IWR | cmd_size,
+                 whcrc->rc_base + URCCMD);
+       spin_unlock(&whcrc->irq_lock);
+
+error:
+       d_fnend(3, dev, "(%p, %p, %zu) = %d\n",
+               uwb_rc, cmd, cmd_size, result);
+       return result;
+}
+
+static int whcrc_reset(struct uwb_rc *rc)
+{
+       struct whcrc *whcrc = rc->priv;
+
+       return umc_controller_reset(whcrc->umc_dev);
+}
+
+/**
+ * Reset event reception mechanism and tell hw we are ready to get more
+ *
+ * We have read all the events in the event buffer, so we are ready to
+ * reset it to the beginning.
+ *
+ * This is only called during initialization or after an event buffer
+ * has been retired.  This means we can be sure that event processing
+ * is disabled and it's safe to update the URCEVTADDR register.
+ *
+ * There's no need to wait for the event processing to start as the
+ * URC will not clear URCCMD_ACTIVE until (internal) event buffer
+ * space is available.
+ */
+static
+void whcrc_enable_events(struct whcrc *whcrc)
+{
+       struct device *dev = &whcrc->umc_dev->dev;
+       u32 urccmd;
+
+       d_fnstart(4, dev, "(whcrc %p)\n", whcrc);
+
+       le_writeq(whcrc->evt_dma_buf, whcrc->rc_base + URCEVTADDR);
+
+       spin_lock(&whcrc->irq_lock);
+       urccmd = le_readl(whcrc->rc_base + URCCMD) & ~URCCMD_ACTIVE;
+       le_writel(urccmd | URCCMD_EARV, whcrc->rc_base + URCCMD);
+       spin_unlock(&whcrc->irq_lock);
+
+       d_fnend(4, dev, "(whcrc %p) = void\n", whcrc);
+}
+
+static void whcrc_event_work(struct work_struct *work)
+{
+       struct whcrc *whcrc = container_of(work, struct whcrc, event_work);
+       struct device *dev = &whcrc->umc_dev->dev;
+       size_t size;
+       u64 urcevtaddr;
+
+       urcevtaddr = le_readq(whcrc->rc_base + URCEVTADDR);
+       size = urcevtaddr & URCEVTADDR_OFFSET_MASK;
+
+       d_printf(3, dev, "received %zu octet event\n", size);
+       d_dump(4, dev, whcrc->evt_buf, size > 32 ? 32 : size);
+
+       uwb_rc_neh_grok(whcrc->uwb_rc, whcrc->evt_buf, size);
+       whcrc_enable_events(whcrc);
+}
+
+/**
+ * Catch interrupts?
+ *
+ * We ack inmediately (and expect the hw to do the right thing and
+ * raise another IRQ if things have changed :)
+ */
+static
+irqreturn_t whcrc_irq_cb(int irq, void *_whcrc)
+{
+       struct whcrc *whcrc = _whcrc;
+       struct device *dev = &whcrc->umc_dev->dev;
+       u32 urcsts;
+
+       urcsts = le_readl(whcrc->rc_base + URCSTS);
+       if (!(urcsts & URCSTS_INT_MASK))
+               return IRQ_NONE;
+       le_writel(urcsts & URCSTS_INT_MASK, whcrc->rc_base + URCSTS);
+
+       d_printf(4, dev, "acked 0x%08x, urcsts 0x%08x\n",
+                le_readl(whcrc->rc_base + URCSTS), urcsts);
+
+       if (urcsts & URCSTS_HSE) {
+               dev_err(dev, "host system error -- hardware halted\n");
+               /* FIXME: do something sensible here */
+               goto out;
+       }
+       if (urcsts & URCSTS_ER) {
+               d_printf(3, dev, "ER: event ready\n");
+               schedule_work(&whcrc->event_work);
+       }
+       if (urcsts & URCSTS_RCI) {
+               d_printf(3, dev, "RCI: ready to execute another command\n");
+               wake_up_all(&whcrc->cmd_wq);
+       }
+out:
+       return IRQ_HANDLED;
+}
+
+
+/**
+ * Initialize a UMC RC interface: map regions, get (shared) IRQ
+ */
+static
+int whcrc_setup_rc_umc(struct whcrc *whcrc)
+{
+       int result = 0;
+       struct device *dev = &whcrc->umc_dev->dev;
+       struct umc_dev *umc_dev = whcrc->umc_dev;
+
+       whcrc->area = umc_dev->resource.start;
+       whcrc->rc_len = umc_dev->resource.end - umc_dev->resource.start + 1;
+       result = -EBUSY;
+       if (request_mem_region(whcrc->area, whcrc->rc_len, KBUILD_MODNAME)
+           == NULL) {
+               dev_err(dev, "can't request URC region (%zu bytes @ 0x%lx): %d\n",
+                       whcrc->rc_len, whcrc->area, result);
+               goto error_request_region;
+       }
+
+       whcrc->rc_base = ioremap_nocache(whcrc->area, whcrc->rc_len);
+       if (whcrc->rc_base == NULL) {
+               dev_err(dev, "can't ioremap registers (%zu bytes @ 0x%lx): %d\n",
+                       whcrc->rc_len, whcrc->area, result);
+               goto error_ioremap_nocache;
+       }
+
+       result = request_irq(umc_dev->irq, whcrc_irq_cb, IRQF_SHARED,
+                            KBUILD_MODNAME, whcrc);
+       if (result < 0) {
+               dev_err(dev, "can't allocate IRQ %d: %d\n",
+                       umc_dev->irq, result);
+               goto error_request_irq;
+       }
+
+       result = -ENOMEM;
+       whcrc->cmd_buf = dma_alloc_coherent(&umc_dev->dev, PAGE_SIZE,
+                                           &whcrc->cmd_dma_buf, GFP_KERNEL);
+       if (whcrc->cmd_buf == NULL) {
+               dev_err(dev, "Can't allocate cmd transfer buffer\n");
+               goto error_cmd_buffer;
+       }
+
+       whcrc->evt_buf = dma_alloc_coherent(&umc_dev->dev, PAGE_SIZE,
+                                           &whcrc->evt_dma_buf, GFP_KERNEL);
+       if (whcrc->evt_buf == NULL) {
+               dev_err(dev, "Can't allocate evt transfer buffer\n");
+               goto error_evt_buffer;
+       }
+       d_printf(3, dev, "UWB RC Interface: %zu bytes at 0x%p, irq %u\n",
+                whcrc->rc_len, whcrc->rc_base, umc_dev->irq);
+       return 0;
+
+error_evt_buffer:
+       dma_free_coherent(&umc_dev->dev, PAGE_SIZE, whcrc->cmd_buf,
+                         whcrc->cmd_dma_buf);
+error_cmd_buffer:
+       free_irq(umc_dev->irq, whcrc);
+error_request_irq:
+       iounmap(whcrc->rc_base);
+error_ioremap_nocache:
+       release_mem_region(whcrc->area, whcrc->rc_len);
+error_request_region:
+       return result;
+}
+
+
+/**
+ * Release RC's UMC resources
+ */
+static
+void whcrc_release_rc_umc(struct whcrc *whcrc)
+{
+       struct umc_dev *umc_dev = whcrc->umc_dev;
+
+       dma_free_coherent(&umc_dev->dev, PAGE_SIZE, whcrc->evt_buf,
+                         whcrc->evt_dma_buf);
+       dma_free_coherent(&umc_dev->dev, PAGE_SIZE, whcrc->cmd_buf,
+                         whcrc->cmd_dma_buf);
+       free_irq(umc_dev->irq, whcrc);
+       iounmap(whcrc->rc_base);
+       release_mem_region(whcrc->area, whcrc->rc_len);
+}
+
+
+/**
+ * whcrc_start_rc - start a WHCI radio controller
+ * @whcrc: the radio controller to start
+ *
+ * Reset the UMC device, start the radio controller, enable events and
+ * finally enable interrupts.
+ */
+static int whcrc_start_rc(struct uwb_rc *rc)
+{
+       struct whcrc *whcrc = rc->priv;
+       int result = 0;
+       struct device *dev = &whcrc->umc_dev->dev;
+       unsigned long start, duration;
+
+       /* Reset the thing */
+       le_writel(URCCMD_RESET, whcrc->rc_base + URCCMD);
+       if (d_test(3))
+               start = jiffies;
+       if (whci_wait_for(dev, whcrc->rc_base + URCCMD, URCCMD_RESET, 0,
+                         5000, "device to reset at init") < 0) {
+               result = -EBUSY;
+               goto error;
+       } else if (d_test(3)) {
+               duration = jiffies - start;
+               if (duration > msecs_to_jiffies(40))
+                       dev_err(dev, "Device took %ums to "
+                                    "reset. MAX expected: 40ms\n",
+                                    jiffies_to_msecs(duration));
+       }
+
+       /* Set the event buffer, start the controller (enable IRQs later) */
+       le_writel(0, whcrc->rc_base + URCINTR);
+       le_writel(URCCMD_RS, whcrc->rc_base + URCCMD);
+       result = -ETIMEDOUT;
+       if (d_test(3))
+               start = jiffies;
+       if (whci_wait_for(dev, whcrc->rc_base + URCSTS, URCSTS_HALTED, 0,
+                         5000, "device to start") < 0)
+               goto error;
+       if (d_test(3)) {
+               duration = jiffies - start;
+               if (duration > msecs_to_jiffies(40))
+                       dev_err(dev, "Device took %ums to start. "
+                                    "MAX expected: 40ms\n",
+                                    jiffies_to_msecs(duration));
+       }
+       whcrc_enable_events(whcrc);
+       result = 0;
+       le_writel(URCINTR_EN_ALL, whcrc->rc_base + URCINTR);
+error:
+       return result;
+}
+
+
+/**
+ * whcrc_stop_rc - stop a WHCI radio controller
+ * @whcrc: the radio controller to stop
+ *
+ * Disable interrupts and cancel any pending event processing work
+ * before clearing the Run/Stop bit.
+ */
+static
+void whcrc_stop_rc(struct uwb_rc *rc)
+{
+       struct whcrc *whcrc = rc->priv;
+       struct umc_dev *umc_dev = whcrc->umc_dev;
+
+       le_writel(0, whcrc->rc_base + URCINTR);
+       cancel_work_sync(&whcrc->event_work);
+
+       le_writel(0, whcrc->rc_base + URCCMD);
+       whci_wait_for(&umc_dev->dev, whcrc->rc_base + URCSTS,
+                     URCSTS_HALTED, 0, 40, "URCSTS.HALTED");
+}
+
+static void whcrc_init(struct whcrc *whcrc)
+{
+       spin_lock_init(&whcrc->irq_lock);
+       init_waitqueue_head(&whcrc->cmd_wq);
+       INIT_WORK(&whcrc->event_work, whcrc_event_work);
+}
+
+/**
+ * Initialize the radio controller.
+ *
+ * NOTE: we setup whcrc->uwb_rc before calling uwb_rc_add(); in the
+ *       IRQ handler we use that to determine if the hw is ready to
+ *       handle events. Looks like a race condition, but it really is
+ *       not.
+ */
+static
+int whcrc_probe(struct umc_dev *umc_dev)
+{
+       int result;
+       struct uwb_rc *uwb_rc;
+       struct whcrc *whcrc;
+       struct device *dev = &umc_dev->dev;
+
+       d_fnstart(3, dev, "(umc_dev %p)\n", umc_dev);
+       result = -ENOMEM;
+       uwb_rc = uwb_rc_alloc();
+       if (uwb_rc == NULL) {
+               dev_err(dev, "unable to allocate RC instance\n");
+               goto error_rc_alloc;
+       }
+       whcrc = kzalloc(sizeof(*whcrc), GFP_KERNEL);
+       if (whcrc == NULL) {
+               dev_err(dev, "unable to allocate WHC-RC instance\n");
+               goto error_alloc;
+       }
+       whcrc_init(whcrc);
+       whcrc->umc_dev = umc_dev;
+
+       result = whcrc_setup_rc_umc(whcrc);
+       if (result < 0) {
+               dev_err(dev, "Can't setup RC UMC interface: %d\n", result);
+               goto error_setup_rc_umc;
+       }
+       whcrc->uwb_rc = uwb_rc;
+
+       uwb_rc->owner = THIS_MODULE;
+       uwb_rc->cmd   = whcrc_cmd;
+       uwb_rc->reset = whcrc_reset;
+       uwb_rc->start = whcrc_start_rc;
+       uwb_rc->stop  = whcrc_stop_rc;
+
+       result = uwb_rc_add(uwb_rc, dev, whcrc);
+       if (result < 0)
+               goto error_rc_add;
+       umc_set_drvdata(umc_dev, whcrc);
+       d_fnend(3, dev, "(umc_dev %p) = 0\n", umc_dev);
+       return 0;
+
+error_rc_add:
+       whcrc_release_rc_umc(whcrc);
+error_setup_rc_umc:
+       kfree(whcrc);
+error_alloc:
+       uwb_rc_put(uwb_rc);
+error_rc_alloc:
+       d_fnend(3, dev, "(umc_dev %p) = %d\n", umc_dev, result);
+       return result;
+}
+
+/**
+ * Clean up the radio control resources
+ *
+ * When we up the command semaphore, everybody possibly held trying to
+ * execute a command should be granted entry and then they'll see the
+ * host is quiescing and up it (so it will chain to the next waiter).
+ * This should not happen (in any case), as we can only remove when
+ * there are no handles open...
+ */
+static void whcrc_remove(struct umc_dev *umc_dev)
+{
+       struct whcrc *whcrc = umc_get_drvdata(umc_dev);
+       struct uwb_rc *uwb_rc = whcrc->uwb_rc;
+
+       umc_set_drvdata(umc_dev, NULL);
+       uwb_rc_rm(uwb_rc);
+       whcrc_release_rc_umc(whcrc);
+       kfree(whcrc);
+       uwb_rc_put(uwb_rc);
+       d_printf(1, &umc_dev->dev, "freed whcrc %p\n", whcrc);
+}
+
+/* PCI device ID's that we handle [so it gets loaded] */
+static struct pci_device_id whcrc_id_table[] = {
+       { PCI_DEVICE_CLASS(PCI_CLASS_WIRELESS_WHCI, ~0) },
+       { /* empty last entry */ }
+};
+MODULE_DEVICE_TABLE(pci, whcrc_id_table);
+
+static struct umc_driver whcrc_driver = {
+       .name   = "whc-rc",
+       .cap_id = UMC_CAP_ID_WHCI_RC,
+       .probe  = whcrc_probe,
+       .remove = whcrc_remove,
+};
+
+static int __init whcrc_driver_init(void)
+{
+       return umc_driver_register(&whcrc_driver);
+}
+module_init(whcrc_driver_init);
+
+static void __exit whcrc_driver_exit(void)
+{
+       umc_driver_unregister(&whcrc_driver);
+}
+module_exit(whcrc_driver_exit);
+
+MODULE_AUTHOR("Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>");
+MODULE_DESCRIPTION("Wireless Host Controller Radio Control Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/uwb/whci.c b/drivers/uwb/whci.c
new file mode 100644 (file)
index 0000000..3df2388
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * WHCI UWB Multi-interface Controller enumerator.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * This file is released under the GNU GPL v2.
+ */
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/uwb/whci.h>
+#include <linux/uwb/umc.h>
+
+struct whci_card {
+       struct pci_dev *pci;
+       void __iomem *uwbbase;
+       u8 n_caps;
+       struct umc_dev *devs[0];
+};
+
+
+/* Fix faulty HW :( */
+static
+u64 whci_capdata_quirks(struct whci_card *card, u64 capdata)
+{
+       u64 capdata_orig = capdata;
+       struct pci_dev *pci_dev = card->pci;
+       if (pci_dev->vendor == PCI_VENDOR_ID_INTEL
+           && (pci_dev->device == 0x0c3b || pci_dev->device == 0004)
+           && pci_dev->class == 0x0d1010) {
+               switch (UWBCAPDATA_TO_CAP_ID(capdata)) {
+                       /* WLP capability has 0x100 bytes of aperture */
+               case 0x80:
+                       capdata |= 0x40 << 8; break;
+                       /* WUSB capability has 0x80 bytes of aperture
+                        * and ID is 1 */
+               case 0x02:
+                       capdata &= ~0xffff;
+                       capdata |= 0x2001;
+                       break;
+               }
+       }
+       if (capdata_orig != capdata)
+               dev_warn(&pci_dev->dev,
+                        "PCI v%04x d%04x c%06x#%02x: "
+                        "corrected capdata from %016Lx to %016Lx\n",
+                        pci_dev->vendor, pci_dev->device, pci_dev->class,
+                        (unsigned)UWBCAPDATA_TO_CAP_ID(capdata),
+                        (unsigned long long)capdata_orig,
+                        (unsigned long long)capdata);
+       return capdata;
+}
+
+
+/**
+ * whci_wait_for - wait for a WHCI register to be set
+ *
+ * Polls (for at most @max_ms ms) until '*@reg & @mask == @result'.
+ */
+int whci_wait_for(struct device *dev, u32 __iomem *reg, u32 mask, u32 result,
+       unsigned long max_ms, const char *tag)
+{
+       unsigned t = 0;
+       u32 val;
+       for (;;) {
+               val = le_readl(reg);
+               if ((val & mask) == result)
+                       break;
+               msleep(10);
+               if (t >= max_ms) {
+                       dev_err(dev, "timed out waiting for %s ", tag);
+                       return -ETIMEDOUT;
+               }
+               t += 10;
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(whci_wait_for);
+
+
+/*
+ * NOTE: the capinfo and capdata registers are slightly different
+ *       (size and cap-id fields). So for cap #0, we need to fill
+ *       in. Size comes from the size of the register block
+ *       (statically calculated); cap_id comes from nowhere, we use
+ *       zero, that is reserved, for the radio controller, because
+ *       none was defined at the spec level.
+ */
+static int whci_add_cap(struct whci_card *card, int n)
+{
+       struct umc_dev *umc;
+       u64 capdata;
+       int bar, err;
+
+       umc = umc_device_create(&card->pci->dev, n);
+       if (umc == NULL)
+               return -ENOMEM;
+
+       capdata = le_readq(card->uwbbase + UWBCAPDATA(n));
+
+       bar = UWBCAPDATA_TO_BAR(capdata) << 1;
+
+       capdata = whci_capdata_quirks(card, capdata);
+       /* Capability 0 is the radio controller. It's size is 32
+        * bytes (WHCI0.95[2.3, T2-9]). */
+       umc->version         = UWBCAPDATA_TO_VERSION(capdata);
+       umc->cap_id          = n == 0 ? 0 : UWBCAPDATA_TO_CAP_ID(capdata);
+       umc->bar             = bar;
+       umc->resource.start  = pci_resource_start(card->pci, bar)
+               + UWBCAPDATA_TO_OFFSET(capdata);
+       umc->resource.end    = umc->resource.start
+               + (n == 0 ? 0x20 : UWBCAPDATA_TO_SIZE(capdata)) - 1;
+       umc->resource.name   = umc->dev.bus_id;
+       umc->resource.flags  = card->pci->resource[bar].flags;
+       umc->resource.parent = &card->pci->resource[bar];
+       umc->irq             = card->pci->irq;
+
+       err = umc_device_register(umc);
+       if (err < 0)
+               goto error;
+       card->devs[n] = umc;
+       return 0;
+
+error:
+       kfree(umc);
+       return err;
+}
+
+static void whci_del_cap(struct whci_card *card, int n)
+{
+       struct umc_dev *umc = card->devs[n];
+
+       if (umc != NULL)
+               umc_device_unregister(umc);
+}
+
+static int whci_n_caps(struct pci_dev *pci)
+{
+       void __iomem *uwbbase;
+       u64 capinfo;
+
+       uwbbase = pci_iomap(pci, 0, 8);
+       if (!uwbbase)
+               return -ENOMEM;
+       capinfo = le_readq(uwbbase + UWBCAPINFO);
+       pci_iounmap(pci, uwbbase);
+
+       return UWBCAPINFO_TO_N_CAPS(capinfo);
+}
+
+static int whci_probe(struct pci_dev *pci, const struct pci_device_id *id)
+{
+       struct whci_card *card;
+       int err, n_caps, n;
+
+       err = pci_enable_device(pci);
+       if (err < 0)
+               goto error;
+       pci_enable_msi(pci);
+       pci_set_master(pci);
+       err = -ENXIO;
+       if (!pci_set_dma_mask(pci, DMA_64BIT_MASK))
+               pci_set_consistent_dma_mask(pci, DMA_64BIT_MASK);
+       else if (!pci_set_dma_mask(pci, DMA_32BIT_MASK))
+               pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK);
+       else
+               goto error_dma;
+
+       err = n_caps = whci_n_caps(pci);
+       if (n_caps < 0)
+               goto error_ncaps;
+
+       err = -ENOMEM;
+       card = kzalloc(sizeof(struct whci_card)
+                      + sizeof(struct whci_dev *) * (n_caps + 1),
+                      GFP_KERNEL);
+       if (card == NULL)
+               goto error_kzalloc;
+       card->pci = pci;
+       card->n_caps = n_caps;
+
+       err = -EBUSY;
+       if (!request_mem_region(pci_resource_start(pci, 0),
+                               UWBCAPDATA_SIZE(card->n_caps),
+                               "whci (capability data)"))
+               goto error_request_memregion;
+       err = -ENOMEM;
+       card->uwbbase = pci_iomap(pci, 0, UWBCAPDATA_SIZE(card->n_caps));
+       if (!card->uwbbase)
+               goto error_iomap;
+
+       /* Add each capability. */
+       for (n = 0; n <= card->n_caps; n++) {
+               err = whci_add_cap(card, n);
+               if (err < 0 && n == 0) {
+                       dev_err(&pci->dev, "cannot bind UWB radio controller:"
+                               " %d\n", err);
+                       goto error_bind;
+               }
+               if (err < 0)
+                       dev_warn(&pci->dev, "warning: cannot bind capability "
+                                "#%u: %d\n", n, err);
+       }
+       pci_set_drvdata(pci, card);
+       return 0;
+
+error_bind:
+       pci_iounmap(pci, card->uwbbase);
+error_iomap:
+       release_mem_region(pci_resource_start(pci, 0), UWBCAPDATA_SIZE(card->n_caps));
+error_request_memregion:
+       kfree(card);
+error_kzalloc:
+error_ncaps:
+error_dma:
+       pci_disable_msi(pci);
+       pci_disable_device(pci);
+error:
+       return err;
+}
+
+static void whci_remove(struct pci_dev *pci)
+{
+       struct whci_card *card = pci_get_drvdata(pci);
+       int n;
+
+       pci_set_drvdata(pci, NULL);
+       /* Unregister each capability in reverse (so the master device
+        * is unregistered last). */
+       for (n = card->n_caps; n >= 0 ; n--)
+               whci_del_cap(card, n);
+       pci_iounmap(pci, card->uwbbase);
+       release_mem_region(pci_resource_start(pci, 0), UWBCAPDATA_SIZE(card->n_caps));
+       kfree(card);
+       pci_disable_msi(pci);
+       pci_disable_device(pci);
+}
+
+static struct pci_device_id whci_id_table[] = {
+       { PCI_DEVICE_CLASS(PCI_CLASS_WIRELESS_WHCI, ~0) },
+       { 0 },
+};
+MODULE_DEVICE_TABLE(pci, whci_id_table);
+
+
+static struct pci_driver whci_driver = {
+       .name     = "whci",
+       .id_table = whci_id_table,
+       .probe    = whci_probe,
+       .remove   = whci_remove,
+};
+
+static int __init whci_init(void)
+{
+       return pci_register_driver(&whci_driver);
+}
+
+static void __exit whci_exit(void)
+{
+       pci_unregister_driver(&whci_driver);
+}
+
+module_init(whci_init);
+module_exit(whci_exit);
+
+MODULE_DESCRIPTION("WHCI UWB Multi-interface Controller enumerator");
+MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
+MODULE_LICENSE("GPL");
diff --git a/drivers/uwb/wlp/Makefile b/drivers/uwb/wlp/Makefile
new file mode 100644 (file)
index 0000000..c72c11d
--- /dev/null
@@ -0,0 +1,10 @@
+obj-$(CONFIG_UWB_WLP) := wlp.o
+
+wlp-objs :=    \
+       driver.o        \
+       eda.o           \
+       messages.o      \
+       sysfs.o         \
+       txrx.o          \
+       wlp-lc.o        \
+       wss-lc.o
diff --git a/drivers/uwb/wlp/driver.c b/drivers/uwb/wlp/driver.c
new file mode 100644 (file)
index 0000000..cb8d699
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * WiMedia Logical Link Control Protocol (WLP)
+ *
+ * Copyright (C) 2007 Intel Corporation
+ * Reinette Chatre <reinette.chatre@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * Life cycle of WLP substack
+ *
+ * FIXME: Docs
+ */
+
+#include <linux/module.h>
+
+static int __init wlp_subsys_init(void)
+{
+       return 0;
+}
+module_init(wlp_subsys_init);
+
+static void __exit wlp_subsys_exit(void)
+{
+       return;
+}
+module_exit(wlp_subsys_exit);
+
+MODULE_AUTHOR("Reinette Chatre <reinette.chatre@intel.com>");
+MODULE_DESCRIPTION("WiMedia Logical Link Control Protocol (WLP)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/uwb/wlp/eda.c b/drivers/uwb/wlp/eda.c
new file mode 100644 (file)
index 0000000..cdfe8df
--- /dev/null
@@ -0,0 +1,449 @@
+/*
+ * WUSB Wire Adapter: WLP interface
+ * Ethernet to device address cache
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * We need to be able to map ethernet addresses to device addresses
+ * and back because there is not explicit relationship between the eth
+ * addresses used in the ETH frames and the device addresses (no, it
+ * would not have been simpler to force as ETH address the MBOA MAC
+ * address...no, not at all :).
+ *
+ * A device has one MBOA MAC address and one device address. It is possible
+ * for a device to have more than one virtual MAC address (although a
+ * virtual address can be the same as the MBOA MAC address). The device
+ * address is guaranteed to be unique among the devices in the extended
+ * beacon group (see ECMA 17.1.1). We thus use the device address as index
+ * to this cache. We do allow searching based on virtual address as this
+ * is how Ethernet frames will be addressed.
+ *
+ * We need to support virtual EUI-48. Although, right now the virtual
+ * EUI-48 will always be the same as the MAC SAP address. The EDA cache
+ * entry thus contains a MAC SAP address as well as the virtual address
+ * (used to map the network stack address to a neighbor). When we move
+ * to support more than one virtual MAC on a host then this organization
+ * will have to change. Perhaps a neighbor has a list of WSSs, each with a
+ * tag and virtual EUI-48.
+ *
+ * On data transmission
+ * it is used to determine if the neighbor is connected and what WSS it
+ * belongs to. With this we know what tag to add to the WLP frame. Storing
+ * the WSS in the EDA cache may be overkill because we only support one
+ * WSS. Hopefully we will support more than one WSS at some point.
+ * On data reception it is used to determine the WSS based on
+ * the tag and address of the transmitting neighbor.
+ */
+
+#define D_LOCAL 5
+#include <linux/netdevice.h>
+#include <linux/uwb/debug.h>
+#include <linux/etherdevice.h>
+#include <linux/wlp.h>
+#include "wlp-internal.h"
+
+
+/* FIXME: cache is not purged, only on device close */
+
+/* FIXME: does not scale, change to dynamic array */
+
+/*
+ * Initialize the EDA cache
+ *
+ * @returns 0 if ok, < 0 errno code on error
+ *
+ * Call when the interface is being brought up
+ *
+ * NOTE: Keep it as a separate function as the implementation will
+ *       change and be more complex.
+ */
+void wlp_eda_init(struct wlp_eda *eda)
+{
+       INIT_LIST_HEAD(&eda->cache);
+       spin_lock_init(&eda->lock);
+}
+
+/*
+ * Release the EDA cache
+ *
+ * @returns 0 if ok, < 0 errno code on error
+ *
+ * Called when the interface is brought down
+ */
+void wlp_eda_release(struct wlp_eda *eda)
+{
+       unsigned long flags;
+       struct wlp_eda_node *itr, *next;
+
+       spin_lock_irqsave(&eda->lock, flags);
+       list_for_each_entry_safe(itr, next, &eda->cache, list_node) {
+               list_del(&itr->list_node);
+               kfree(itr);
+       }
+       spin_unlock_irqrestore(&eda->lock, flags);
+}
+
+/*
+ * Add an address mapping
+ *
+ * @returns 0 if ok, < 0 errno code on error
+ *
+ * An address mapping is initially created when the neighbor device is seen
+ * for the first time (it is "onair"). At this time the neighbor is not
+ * connected or associated with a WSS so we only populate the Ethernet and
+ * Device address fields.
+ *
+ */
+int wlp_eda_create_node(struct wlp_eda *eda,
+                       const unsigned char eth_addr[ETH_ALEN],
+                       const struct uwb_dev_addr *dev_addr)
+{
+       int result = 0;
+       struct wlp_eda_node *itr;
+       unsigned long flags;
+
+       BUG_ON(dev_addr == NULL || eth_addr == NULL);
+       spin_lock_irqsave(&eda->lock, flags);
+       list_for_each_entry(itr, &eda->cache, list_node) {
+               if (!memcmp(&itr->dev_addr, dev_addr, sizeof(itr->dev_addr))) {
+                       printk(KERN_ERR "EDA cache already contains entry "
+                              "for neighbor %02x:%02x\n",
+                              dev_addr->data[1], dev_addr->data[0]);
+                       result = -EEXIST;
+                       goto out_unlock;
+               }
+       }
+       itr = kzalloc(sizeof(*itr), GFP_ATOMIC);
+       if (itr != NULL) {
+               memcpy(itr->eth_addr, eth_addr, sizeof(itr->eth_addr));
+               itr->dev_addr = *dev_addr;
+               list_add(&itr->list_node, &eda->cache);
+       } else
+               result = -ENOMEM;
+out_unlock:
+       spin_unlock_irqrestore(&eda->lock, flags);
+       return result;
+}
+
+/*
+ * Remove entry from EDA cache
+ *
+ * This is done when the device goes off air.
+ */
+void wlp_eda_rm_node(struct wlp_eda *eda, const struct uwb_dev_addr *dev_addr)
+{
+       struct wlp_eda_node *itr, *next;
+       unsigned long flags;
+
+       spin_lock_irqsave(&eda->lock, flags);
+       list_for_each_entry_safe(itr, next, &eda->cache, list_node) {
+               if (!memcmp(&itr->dev_addr, dev_addr, sizeof(itr->dev_addr))) {
+                       list_del(&itr->list_node);
+                       kfree(itr);
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(&eda->lock, flags);
+}
+
+/*
+ * Update an address mapping
+ *
+ * @returns 0 if ok, < 0 errno code on error
+ */
+int wlp_eda_update_node(struct wlp_eda *eda,
+                       const struct uwb_dev_addr *dev_addr,
+                       struct wlp_wss *wss,
+                       const unsigned char virt_addr[ETH_ALEN],
+                       const u8 tag, const enum wlp_wss_connect state)
+{
+       int result = -ENOENT;
+       struct wlp_eda_node *itr;
+       unsigned long flags;
+
+       spin_lock_irqsave(&eda->lock, flags);
+       list_for_each_entry(itr, &eda->cache, list_node) {
+               if (!memcmp(&itr->dev_addr, dev_addr, sizeof(itr->dev_addr))) {
+                       /* Found it, update it */
+                       itr->wss = wss;
+                       memcpy(itr->virt_addr, virt_addr,
+                              sizeof(itr->virt_addr));
+                       itr->tag = tag;
+                       itr->state = state;
+                       result = 0;
+                       goto out_unlock;
+               }
+       }
+       /* Not found */
+out_unlock:
+       spin_unlock_irqrestore(&eda->lock, flags);
+       return result;
+}
+
+/*
+ * Update only state field of an address mapping
+ *
+ * @returns 0 if ok, < 0 errno code on error
+ */
+int wlp_eda_update_node_state(struct wlp_eda *eda,
+                             const struct uwb_dev_addr *dev_addr,
+                             const enum wlp_wss_connect state)
+{
+       int result = -ENOENT;
+       struct wlp_eda_node *itr;
+       unsigned long flags;
+
+       spin_lock_irqsave(&eda->lock, flags);
+       list_for_each_entry(itr, &eda->cache, list_node) {
+               if (!memcmp(&itr->dev_addr, dev_addr, sizeof(itr->dev_addr))) {
+                       /* Found it, update it */
+                       itr->state = state;
+                       result = 0;
+                       goto out_unlock;
+               }
+       }
+       /* Not found */
+out_unlock:
+       spin_unlock_irqrestore(&eda->lock, flags);
+       return result;
+}
+
+/*
+ * Return contents of EDA cache entry
+ *
+ * @dev_addr: index to EDA cache
+ * @eda_entry: pointer to where contents of EDA cache will be copied
+ */
+int wlp_copy_eda_node(struct wlp_eda *eda, struct uwb_dev_addr *dev_addr,
+                     struct wlp_eda_node *eda_entry)
+{
+       int result = -ENOENT;
+       struct wlp_eda_node *itr;
+       unsigned long flags;
+
+       spin_lock_irqsave(&eda->lock, flags);
+       list_for_each_entry(itr, &eda->cache, list_node) {
+               if (!memcmp(&itr->dev_addr, dev_addr, sizeof(itr->dev_addr))) {
+                       *eda_entry = *itr;
+                       result = 0;
+                       goto out_unlock;
+               }
+       }
+       /* Not found */
+out_unlock:
+       spin_unlock_irqrestore(&eda->lock, flags);
+       return result;
+}
+
+/*
+ * Execute function for every element in the cache
+ *
+ * @function: function to execute on element of cache (must be atomic)
+ * @priv:     private data of function
+ * @returns:  result of first function that failed, or last function
+ *            executed if no function failed.
+ *
+ * Stop executing when function returns error for any element in cache.
+ *
+ * IMPORTANT: We are using a spinlock here: the function executed on each
+ * element has to be atomic.
+ */
+int wlp_eda_for_each(struct wlp_eda *eda, wlp_eda_for_each_f function,
+                    void *priv)
+{
+       int result = 0;
+       struct wlp *wlp = container_of(eda, struct wlp, eda);
+       struct wlp_eda_node *entry;
+       unsigned long flags;
+
+       spin_lock_irqsave(&eda->lock, flags);
+       list_for_each_entry(entry, &eda->cache, list_node) {
+               result = (*function)(wlp, entry, priv);
+               if (result < 0)
+                       break;
+       }
+       spin_unlock_irqrestore(&eda->lock, flags);
+       return result;
+}
+
+/*
+ * Execute function for single element in the cache (return dev addr)
+ *
+ * @virt_addr: index into EDA cache used to determine which element to
+ *             execute the function on
+ * @dev_addr: device address of element in cache will be returned using
+ *            @dev_addr
+ * @function: function to execute on element of cache (must be atomic)
+ * @priv:     private data of function
+ * @returns:  result of function
+ *
+ * IMPORTANT: We are using a spinlock here: the function executed on the
+ * element has to be atomic.
+ */
+int wlp_eda_for_virtual(struct wlp_eda *eda,
+                       const unsigned char virt_addr[ETH_ALEN],
+                       struct uwb_dev_addr *dev_addr,
+                       wlp_eda_for_each_f function,
+                       void *priv)
+{
+       int result = 0;
+       struct wlp *wlp = container_of(eda, struct wlp, eda);
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       struct wlp_eda_node *itr;
+       unsigned long flags;
+       int found = 0;
+
+       spin_lock_irqsave(&eda->lock, flags);
+       list_for_each_entry(itr, &eda->cache, list_node) {
+               if (!memcmp(itr->virt_addr, virt_addr,
+                          sizeof(itr->virt_addr))) {
+                       d_printf(6, dev, "EDA: looking for "
+                              "%02x:%02x:%02x:%02x:%02x:%02x hit %02x:%02x "
+                              "wss %p tag 0x%02x state %u\n",
+                              virt_addr[0], virt_addr[1],
+                              virt_addr[2], virt_addr[3],
+                              virt_addr[4], virt_addr[5],
+                              itr->dev_addr.data[1],
+                              itr->dev_addr.data[0], itr->wss,
+                              itr->tag, itr->state);
+                       result = (*function)(wlp, itr, priv);
+                       *dev_addr = itr->dev_addr;
+                       found = 1;
+                       break;
+               } else
+                       d_printf(6, dev, "EDA: looking for "
+                              "%02x:%02x:%02x:%02x:%02x:%02x "
+                              "against "
+                              "%02x:%02x:%02x:%02x:%02x:%02x miss\n",
+                              virt_addr[0], virt_addr[1],
+                              virt_addr[2], virt_addr[3],
+                              virt_addr[4], virt_addr[5],
+                              itr->virt_addr[0], itr->virt_addr[1],
+                              itr->virt_addr[2], itr->virt_addr[3],
+                              itr->virt_addr[4], itr->virt_addr[5]);
+       }
+       if (!found) {
+               if (printk_ratelimit())
+                       dev_err(dev, "EDA: Eth addr %02x:%02x:%02x"
+                               ":%02x:%02x:%02x not found.\n",
+                               virt_addr[0], virt_addr[1],
+                               virt_addr[2], virt_addr[3],
+                               virt_addr[4], virt_addr[5]);
+               result = -ENODEV;
+       }
+       spin_unlock_irqrestore(&eda->lock, flags);
+       return result;
+}
+
+static const char *__wlp_wss_connect_state[] = { "WLP_WSS_UNCONNECTED",
+                                         "WLP_WSS_CONNECTED",
+                                         "WLP_WSS_CONNECT_FAILED",
+};
+
+static const char *wlp_wss_connect_state_str(unsigned id)
+{
+       if (id >= ARRAY_SIZE(__wlp_wss_connect_state))
+               return "unknown WSS connection state";
+       return __wlp_wss_connect_state[id];
+}
+
+/*
+ * View EDA cache from user space
+ *
+ * A debugging feature to give user visibility into the EDA cache. Also
+ * used to display members of WSS to user (called from wlp_wss_members_show())
+ */
+ssize_t wlp_eda_show(struct wlp *wlp, char *buf)
+{
+       ssize_t result = 0;
+       struct wlp_eda_node *entry;
+       unsigned long flags;
+       struct wlp_eda *eda = &wlp->eda;
+       spin_lock_irqsave(&eda->lock, flags);
+       result = scnprintf(buf, PAGE_SIZE, "#eth_addr dev_addr wss_ptr "
+                          "tag state virt_addr\n");
+       list_for_each_entry(entry, &eda->cache, list_node) {
+               result += scnprintf(buf + result, PAGE_SIZE - result,
+                                   "%02x:%02x:%02x:%02x:%02x:%02x %02x:%02x "
+                                   "%p 0x%02x %s "
+                                   "%02x:%02x:%02x:%02x:%02x:%02x\n",
+                                   entry->eth_addr[0], entry->eth_addr[1],
+                                   entry->eth_addr[2], entry->eth_addr[3],
+                                   entry->eth_addr[4], entry->eth_addr[5],
+                                   entry->dev_addr.data[1],
+                                   entry->dev_addr.data[0], entry->wss,
+                                   entry->tag,
+                                   wlp_wss_connect_state_str(entry->state),
+                                   entry->virt_addr[0], entry->virt_addr[1],
+                                   entry->virt_addr[2], entry->virt_addr[3],
+                                   entry->virt_addr[4], entry->virt_addr[5]);
+               if (result >= PAGE_SIZE)
+                       break;
+       }
+       spin_unlock_irqrestore(&eda->lock, flags);
+       return result;
+}
+EXPORT_SYMBOL_GPL(wlp_eda_show);
+
+/*
+ * Add new EDA cache entry based on user input in sysfs
+ *
+ * Should only be used for debugging.
+ *
+ * The WSS is assumed to be the only WSS supported. This needs to be
+ * redesigned when we support more than one WSS.
+ */
+ssize_t wlp_eda_store(struct wlp *wlp, const char *buf, size_t size)
+{
+       ssize_t result;
+       struct wlp_eda *eda = &wlp->eda;
+       u8 eth_addr[6];
+       struct uwb_dev_addr dev_addr;
+       u8 tag;
+       unsigned state;
+
+       result = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx "
+                       "%02hhx:%02hhx %02hhx %u\n",
+                       &eth_addr[0], &eth_addr[1],
+                       &eth_addr[2], &eth_addr[3],
+                       &eth_addr[4], &eth_addr[5],
+                       &dev_addr.data[1], &dev_addr.data[0], &tag, &state);
+       switch (result) {
+       case 6: /* no dev addr specified -- remove entry NOT IMPLEMENTED */
+               /*result = wlp_eda_rm(eda, eth_addr, &dev_addr);*/
+               result = -ENOSYS;
+               break;
+       case 10:
+               state = state >= 1 ? 1 : 0;
+               result = wlp_eda_create_node(eda, eth_addr, &dev_addr);
+               if (result < 0 && result != -EEXIST)
+                       goto error;
+               /* Set virtual addr to be same as MAC */
+               result = wlp_eda_update_node(eda, &dev_addr, &wlp->wss,
+                                            eth_addr, tag, state);
+               if (result < 0)
+                       goto error;
+               break;
+       default: /* bad format */
+               result = -EINVAL;
+       }
+error:
+       return result < 0 ? result : size;
+}
+EXPORT_SYMBOL_GPL(wlp_eda_store);
diff --git a/drivers/uwb/wlp/messages.c b/drivers/uwb/wlp/messages.c
new file mode 100644 (file)
index 0000000..a64cb82
--- /dev/null
@@ -0,0 +1,1946 @@
+/*
+ * WiMedia Logical Link Control Protocol (WLP)
+ * Message construction and parsing
+ *
+ * Copyright (C) 2007 Intel Corporation
+ * Reinette Chatre <reinette.chatre@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ */
+
+#include <linux/wlp.h>
+#define D_LOCAL 6
+#include <linux/uwb/debug.h>
+#include "wlp-internal.h"
+
+static
+const char *__wlp_assoc_frame[] = {
+       [WLP_ASSOC_D1] = "WLP_ASSOC_D1",
+       [WLP_ASSOC_D2] = "WLP_ASSOC_D2",
+       [WLP_ASSOC_M1] = "WLP_ASSOC_M1",
+       [WLP_ASSOC_M2] = "WLP_ASSOC_M2",
+       [WLP_ASSOC_M3] = "WLP_ASSOC_M3",
+       [WLP_ASSOC_M4] = "WLP_ASSOC_M4",
+       [WLP_ASSOC_M5] = "WLP_ASSOC_M5",
+       [WLP_ASSOC_M6] = "WLP_ASSOC_M6",
+       [WLP_ASSOC_M7] = "WLP_ASSOC_M7",
+       [WLP_ASSOC_M8] = "WLP_ASSOC_M8",
+       [WLP_ASSOC_F0] = "WLP_ASSOC_F0",
+       [WLP_ASSOC_E1] = "WLP_ASSOC_E1",
+       [WLP_ASSOC_E2] = "WLP_ASSOC_E2",
+       [WLP_ASSOC_C1] = "WLP_ASSOC_C1",
+       [WLP_ASSOC_C2] = "WLP_ASSOC_C2",
+       [WLP_ASSOC_C3] = "WLP_ASSOC_C3",
+       [WLP_ASSOC_C4] = "WLP_ASSOC_C4",
+};
+
+static const char *wlp_assoc_frame_str(unsigned id)
+{
+       if (id >= ARRAY_SIZE(__wlp_assoc_frame))
+               return "unknown association frame";
+       return __wlp_assoc_frame[id];
+}
+
+static const char *__wlp_assc_error[] = {
+       "none",
+       "Authenticator Failure",
+       "Rogue activity suspected",
+       "Device busy",
+       "Setup Locked",
+       "Registrar not ready",
+       "Invalid WSS selection",
+       "Message timeout",
+       "Enrollment session timeout",
+       "Device password invalid",
+       "Unsupported version",
+       "Internal error",
+       "Undefined error",
+       "Numeric comparison failure",
+       "Waiting for user input",
+};
+
+static const char *wlp_assc_error_str(unsigned id)
+{
+       if (id >= ARRAY_SIZE(__wlp_assc_error))
+               return "unknown WLP association error";
+       return __wlp_assc_error[id];
+}
+
+static inline void wlp_set_attr_hdr(struct wlp_attr_hdr *hdr, unsigned type,
+                                   size_t len)
+{
+       hdr->type = cpu_to_le16(type);
+       hdr->length = cpu_to_le16(len);
+}
+
+/*
+ * Populate fields of a constant sized attribute
+ *
+ * @returns: total size of attribute including size of new value
+ *
+ * We have two instances of this function (wlp_pset and wlp_set): one takes
+ * the value as a parameter, the other takes a pointer to the value as
+ * parameter. They thus only differ in how the value is assigned to the
+ * attribute.
+ *
+ * We use sizeof(*attr) - sizeof(struct wlp_attr_hdr) instead of
+ * sizeof(type) to be able to use this same code for the structures that
+ * contain 8bit enum values and be able to deal with pointer types.
+ */
+#define wlp_set(type, type_code, name)                                 \
+static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value) \
+{                                                                      \
+       d_fnstart(6, NULL, "(attribute %p)\n", attr);                   \
+       wlp_set_attr_hdr(&attr->hdr, type_code,                         \
+                        sizeof(*attr) - sizeof(struct wlp_attr_hdr));  \
+       attr->name = value;                                             \
+       d_dump(6, NULL, attr, sizeof(*attr));                           \
+       d_fnend(6, NULL, "(attribute %p)\n", attr);                     \
+       return sizeof(*attr);                                           \
+}
+
+#define wlp_pset(type, type_code, name)                                        \
+static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value) \
+{                                                                      \
+       d_fnstart(6, NULL, "(attribute %p)\n", attr);                   \
+       wlp_set_attr_hdr(&attr->hdr, type_code,                         \
+                        sizeof(*attr) - sizeof(struct wlp_attr_hdr));  \
+       attr->name = *value;                                            \
+       d_dump(6, NULL, attr, sizeof(*attr));                           \
+       d_fnend(6, NULL, "(attribute %p)\n", attr);                     \
+       return sizeof(*attr);                                           \
+}
+
+/**
+ * Populate fields of a variable attribute
+ *
+ * @returns: total size of attribute including size of new value
+ *
+ * Provided with a pointer to the memory area reserved for the
+ * attribute structure, the field is populated with the value. The
+ * reserved memory has to contain enough space for the value.
+ */
+#define wlp_vset(type, type_code, name)                                        \
+static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value, \
+                               size_t len)                             \
+{                                                                      \
+       d_fnstart(6, NULL, "(attribute %p)\n", attr);                   \
+       wlp_set_attr_hdr(&attr->hdr, type_code, len);                   \
+       memcpy(attr->name, value, len);                                 \
+       d_dump(6, NULL, attr, sizeof(*attr) + len);                     \
+       d_fnend(6, NULL, "(attribute %p)\n", attr);                     \
+       return sizeof(*attr) + len;                                     \
+}
+
+wlp_vset(char *, WLP_ATTR_DEV_NAME, dev_name)
+wlp_vset(char *, WLP_ATTR_MANUF, manufacturer)
+wlp_set(enum wlp_assoc_type, WLP_ATTR_MSG_TYPE, msg_type)
+wlp_vset(char *, WLP_ATTR_MODEL_NAME, model_name)
+wlp_vset(char *, WLP_ATTR_MODEL_NR, model_nr)
+wlp_vset(char *, WLP_ATTR_SERIAL, serial)
+wlp_vset(char *, WLP_ATTR_WSS_NAME, wss_name)
+wlp_pset(struct wlp_uuid *, WLP_ATTR_UUID_E, uuid_e)
+wlp_pset(struct wlp_uuid *, WLP_ATTR_UUID_R, uuid_r)
+wlp_pset(struct wlp_uuid *, WLP_ATTR_WSSID, wssid)
+wlp_pset(struct wlp_dev_type *, WLP_ATTR_PRI_DEV_TYPE, prim_dev_type)
+/*wlp_pset(struct wlp_dev_type *, WLP_ATTR_SEC_DEV_TYPE, sec_dev_type)*/
+wlp_set(u8, WLP_ATTR_WLP_VER, version)
+wlp_set(enum wlp_assc_error, WLP_ATTR_WLP_ASSC_ERR, wlp_assc_err)
+wlp_set(enum wlp_wss_sel_mthd, WLP_ATTR_WSS_SEL_MTHD, wss_sel_mthd)
+wlp_set(u8, WLP_ATTR_ACC_ENRL, accept_enrl)
+wlp_set(u8, WLP_ATTR_WSS_SEC_STAT, wss_sec_status)
+wlp_pset(struct uwb_mac_addr *, WLP_ATTR_WSS_BCAST, wss_bcast)
+wlp_pset(struct wlp_nonce *, WLP_ATTR_ENRL_NONCE, enonce)
+wlp_pset(struct wlp_nonce *, WLP_ATTR_REG_NONCE, rnonce)
+wlp_set(u8, WLP_ATTR_WSS_TAG, wss_tag)
+wlp_pset(struct uwb_mac_addr *, WLP_ATTR_WSS_VIRT, wss_virt)
+
+/**
+ * Fill in the WSS information attributes
+ *
+ * We currently only support one WSS, and this is assumed in this function
+ * that can populate only one WSS information attribute.
+ */
+static size_t wlp_set_wss_info(struct wlp_attr_wss_info *attr,
+                              struct wlp_wss *wss)
+{
+       size_t datalen;
+       void *ptr = attr->wss_info;
+       size_t used = sizeof(*attr);
+       d_fnstart(6, NULL, "(attribute %p)\n", attr);
+       datalen = sizeof(struct wlp_wss_info) + strlen(wss->name);
+       wlp_set_attr_hdr(&attr->hdr, WLP_ATTR_WSS_INFO, datalen);
+       used = wlp_set_wssid(ptr, &wss->wssid);
+       used += wlp_set_wss_name(ptr + used, wss->name, strlen(wss->name));
+       used += wlp_set_accept_enrl(ptr + used, wss->accept_enroll);
+       used += wlp_set_wss_sec_status(ptr + used, wss->secure_status);
+       used += wlp_set_wss_bcast(ptr + used, &wss->bcast);
+       d_dump(6, NULL, attr, sizeof(*attr) + datalen);
+       d_fnend(6, NULL, "(attribute %p, used %d)\n",
+               attr, (int)(sizeof(*attr) + used));
+       return sizeof(*attr) + used;
+}
+
+/**
+ * Verify attribute header
+ *
+ * @hdr:     Pointer to attribute header that will be verified.
+ * @type:    Expected attribute type.
+ * @len:     Expected length of attribute value (excluding header).
+ *
+ * Most attribute values have a known length even when they do have a
+ * length field. This knowledge can be used via this function to verify
+ * that the length field matches the expected value.
+ */
+static int wlp_check_attr_hdr(struct wlp *wlp, struct wlp_attr_hdr *hdr,
+                      enum wlp_attr_type type, unsigned len)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+
+       if (le16_to_cpu(hdr->type) != type) {
+               dev_err(dev, "WLP: unexpected header type. Expected "
+                       "%u, got %u.\n", type, le16_to_cpu(hdr->type));
+               return -EINVAL;
+       }
+       if (le16_to_cpu(hdr->length) != len) {
+               dev_err(dev, "WLP: unexpected length in header. Expected "
+                       "%u, got %u.\n", len, le16_to_cpu(hdr->length));
+               return -EINVAL;
+       }
+       return 0;
+}
+
+/**
+ * Check if header of WSS information attribute valid
+ *
+ * @returns: length of WSS attributes (value of length attribute field) if
+ *             valid WSS information attribute found
+ *           -ENODATA if no WSS information attribute found
+ *           -EIO other error occured
+ *
+ * The WSS information attribute is optional. The function will be provided
+ * with a pointer to data that could _potentially_ be a WSS information
+ * attribute. If a valid WSS information attribute is found it will return
+ * 0, if no WSS information attribute is found it will return -ENODATA, and
+ * another error will be returned if it is a WSS information attribute, but
+ * some parsing failure occured.
+ */
+static int wlp_check_wss_info_attr_hdr(struct wlp *wlp,
+                                      struct wlp_attr_hdr *hdr, size_t buflen)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       size_t len;
+       int result = 0;
+
+       if (buflen < sizeof(*hdr)) {
+               dev_err(dev, "WLP: Not enough space in buffer to parse"
+                       " WSS information attribute header.\n");
+               result = -EIO;
+               goto out;
+       }
+       if (le16_to_cpu(hdr->type) != WLP_ATTR_WSS_INFO) {
+               /* WSS information is optional */
+               result = -ENODATA;
+               goto out;
+       }
+       len = le16_to_cpu(hdr->length);
+       if (buflen < sizeof(*hdr) + len) {
+               dev_err(dev, "WLP: Not enough space in buffer to parse "
+                       "variable data. Got %d, expected %d.\n",
+                       (int)buflen, (int)(sizeof(*hdr) + len));
+               result = -EIO;
+               goto out;
+       }
+       result = len;
+out:
+       return result;
+}
+
+
+/**
+ * Get value of attribute from fixed size attribute field.
+ *
+ * @attr:    Pointer to attribute field.
+ * @value:   Pointer to variable in which attribute value will be placed.
+ * @buflen:  Size of buffer in which attribute field (including header)
+ *           can be found.
+ * @returns: Amount of given buffer consumed by parsing for this attribute.
+ *
+ * The size and type of the value is known by the type of the attribute.
+ */
+#define wlp_get(type, type_code, name)                                 \
+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);                                           \
+}
+
+#define wlp_get_sparse(type, type_code, name) \
+       static wlp_get(type, type_code, name)
+
+/**
+ * Get value of attribute from variable sized attribute field.
+ *
+ * @max:     The maximum size of this attribute. This value is dictated by
+ *           the maximum value from the WLP specification.
+ *
+ * @attr:    Pointer to attribute field.
+ * @value:   Pointer to variable that will contain the value. The memory
+ *           must already have been allocated for this value.
+ * @buflen:  Size of buffer in which attribute field (including header)
+ *           can be found.
+ * @returns: Amount of given bufferconsumed by parsing for this attribute.
+ */
+#define wlp_vget(type_val, type_code, name, max)                       \
+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;                                     \
+}
+
+wlp_get(u8, WLP_ATTR_WLP_VER, version)
+wlp_get_sparse(enum wlp_wss_sel_mthd, WLP_ATTR_WSS_SEL_MTHD, wss_sel_mthd)
+wlp_get_sparse(struct wlp_dev_type, WLP_ATTR_PRI_DEV_TYPE, prim_dev_type)
+wlp_get_sparse(enum wlp_assc_error, WLP_ATTR_WLP_ASSC_ERR, wlp_assc_err)
+wlp_get_sparse(struct wlp_uuid, WLP_ATTR_UUID_E, uuid_e)
+wlp_get_sparse(struct wlp_uuid, WLP_ATTR_UUID_R, uuid_r)
+wlp_get(struct wlp_uuid, WLP_ATTR_WSSID, wssid)
+wlp_get_sparse(u8, WLP_ATTR_ACC_ENRL, accept_enrl)
+wlp_get_sparse(u8, WLP_ATTR_WSS_SEC_STAT, wss_sec_status)
+wlp_get_sparse(struct uwb_mac_addr, WLP_ATTR_WSS_BCAST, wss_bcast)
+wlp_get_sparse(u8, WLP_ATTR_WSS_TAG, wss_tag)
+wlp_get_sparse(struct uwb_mac_addr, WLP_ATTR_WSS_VIRT, wss_virt)
+wlp_get_sparse(struct wlp_nonce, WLP_ATTR_ENRL_NONCE, enonce)
+wlp_get_sparse(struct wlp_nonce, WLP_ATTR_REG_NONCE, rnonce)
+
+/* The buffers for the device info attributes can be found in the
+ * wlp_device_info struct. These buffers contain one byte more than the
+ * max allowed by the spec - this is done to be able to add the
+ * terminating \0 for user display. This terminating byte is not required
+ * in the actual attribute field (because it has a length field) so the
+ * maximum allowed for this value is one less than its size in the
+ * structure.
+ */
+wlp_vget(char, WLP_ATTR_WSS_NAME, wss_name,
+        FIELD_SIZEOF(struct wlp_wss, name) - 1)
+wlp_vget(char, WLP_ATTR_DEV_NAME, dev_name,
+        FIELD_SIZEOF(struct wlp_device_info, name) - 1)
+wlp_vget(char, WLP_ATTR_MANUF, manufacturer,
+        FIELD_SIZEOF(struct wlp_device_info, manufacturer) - 1)
+wlp_vget(char, WLP_ATTR_MODEL_NAME, model_name,
+        FIELD_SIZEOF(struct wlp_device_info, model_name) - 1)
+wlp_vget(char, WLP_ATTR_MODEL_NR, model_nr,
+        FIELD_SIZEOF(struct wlp_device_info, model_nr) - 1)
+wlp_vget(char, WLP_ATTR_SERIAL, serial,
+        FIELD_SIZEOF(struct wlp_device_info, serial) - 1)
+
+/**
+ * Retrieve WSS Name, Accept enroll, Secure status, Broadcast from WSS info
+ *
+ * @attr: pointer to WSS name attribute in WSS information attribute field
+ * @info: structure that will be populated with data from WSS information
+ *        field (WSS name, Accept enroll, secure status, broadcast address)
+ * @buflen: size of buffer
+ *
+ * Although the WSSID attribute forms part of the WSS info attribute it is
+ * retrieved separately and stored in a different location.
+ */
+static ssize_t wlp_get_wss_info_attrs(struct wlp *wlp,
+                                     struct wlp_attr_hdr *attr,
+                                     struct wlp_wss_tmp_info *info,
+                                     ssize_t buflen)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       void *ptr = attr;
+       size_t used = 0;
+       ssize_t result = -EINVAL;
+
+       d_printf(6, dev, "WLP: WSS info: Retrieving WSS name\n");
+       result = wlp_get_wss_name(wlp, ptr, info->name, buflen);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain WSS name from "
+                       "WSS info in D2 message.\n");
+               goto error_parse;
+       }
+       used += result;
+       d_printf(6, dev, "WLP: WSS info: Retrieving accept enroll\n");
+       result = wlp_get_accept_enrl(wlp, ptr + used, &info->accept_enroll,
+                                    buflen - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain accepting "
+                       "enrollment from WSS info in D2 message.\n");
+               goto error_parse;
+       }
+       if (info->accept_enroll != 0 && info->accept_enroll != 1) {
+               dev_err(dev, "WLP: invalid value for accepting "
+                       "enrollment in D2 message.\n");
+               result = -EINVAL;
+               goto error_parse;
+       }
+       used += result;
+       d_printf(6, dev, "WLP: WSS info: Retrieving secure status\n");
+       result = wlp_get_wss_sec_status(wlp, ptr + used, &info->sec_status,
+                                       buflen - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain secure "
+                       "status from WSS info in D2 message.\n");
+               goto error_parse;
+       }
+       if (info->sec_status != 0 && info->sec_status != 1) {
+               dev_err(dev, "WLP: invalid value for secure "
+                       "status in D2 message.\n");
+               result = -EINVAL;
+               goto error_parse;
+       }
+       used += result;
+       d_printf(6, dev, "WLP: WSS info: Retrieving broadcast\n");
+       result = wlp_get_wss_bcast(wlp, ptr + used, &info->bcast,
+                                  buflen - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain broadcast "
+                       "address from WSS info in D2 message.\n");
+               goto error_parse;
+       }
+       used += result;
+       result = used;
+error_parse:
+       return result;
+}
+
+/**
+ * Create a new WSSID entry for the neighbor, allocate temporary storage
+ *
+ * Each neighbor can have many WSS active. We maintain a list of WSSIDs
+ * advertised by neighbor. During discovery we also cache information about
+ * these WSS in temporary storage.
+ *
+ * The temporary storage will be removed after it has been used (eg.
+ * displayed to user), the wssid element will be removed from the list when
+ * the neighbor is rediscovered or when it disappears.
+ */
+static struct wlp_wssid_e *wlp_create_wssid_e(struct wlp *wlp,
+                                             struct wlp_neighbor_e *neighbor)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       struct wlp_wssid_e *wssid_e;
+
+       wssid_e = kzalloc(sizeof(*wssid_e), GFP_KERNEL);
+       if (wssid_e == NULL) {
+               dev_err(dev, "WLP: unable to allocate memory "
+                       "for WSS information.\n");
+               goto error_alloc;
+       }
+       wssid_e->info = kzalloc(sizeof(struct wlp_wss_tmp_info), GFP_KERNEL);
+       if (wssid_e->info == NULL) {
+               dev_err(dev, "WLP: unable to allocate memory "
+                       "for temporary WSS information.\n");
+               kfree(wssid_e);
+               wssid_e = NULL;
+               goto error_alloc;
+       }
+       list_add(&wssid_e->node, &neighbor->wssid);
+error_alloc:
+       return wssid_e;
+}
+
+/**
+ * Parse WSS information attribute
+ *
+ * @attr: pointer to WSS information attribute header
+ * @buflen: size of buffer in which WSS information attribute appears
+ * @wssid: will place wssid from WSS info attribute in this location
+ * @wss_info: will place other information from WSS information attribute
+ * in this location
+ *
+ * memory for @wssid and @wss_info must be allocated when calling this
+ */
+static ssize_t wlp_get_wss_info(struct wlp *wlp, struct wlp_attr_wss_info *attr,
+                               size_t buflen, struct wlp_uuid *wssid,
+                               struct wlp_wss_tmp_info *wss_info)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       ssize_t result;
+       size_t len;
+       size_t used = 0;
+       void *ptr;
+
+       result = wlp_check_wss_info_attr_hdr(wlp, (struct wlp_attr_hdr *)attr,
+                                            buflen);
+       if (result < 0)
+               goto out;
+       len = result;
+       used = sizeof(*attr);
+       ptr = attr;
+       d_printf(6, dev, "WLP: WSS info: Retrieving WSSID\n");
+       result = wlp_get_wssid(wlp, ptr + used, wssid, buflen - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain WSSID from WSS info.\n");
+               goto out;
+       }
+       used += result;
+       result = wlp_get_wss_info_attrs(wlp, ptr + used, wss_info,
+                                       buflen - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain WSS information "
+                       "from WSS information attributes. \n");
+               goto out;
+       }
+       used += result;
+       if (len + sizeof(*attr) != used) {
+               dev_err(dev, "WLP: Amount of data parsed does not "
+                       "match length field. Parsed %zu, length "
+                       "field %zu. \n", used, len);
+               result = -EINVAL;
+               goto out;
+       }
+       result = used;
+       d_printf(6, dev, "WLP: Successfully parsed WLP information "
+                "attribute. used %zu bytes\n", used);
+out:
+       return result;
+}
+
+/**
+ * Retrieve WSS info from association frame
+ *
+ * @attr:     pointer to WSS information attribute
+ * @neighbor: ptr to neighbor being discovered, NULL if enrollment in
+ *            progress
+ * @wss:      ptr to WSS being enrolled in, NULL if discovery in progress
+ * @buflen:   size of buffer in which WSS information appears
+ *
+ * The WSS information attribute appears in the D2 association message.
+ * This message is used in two ways: to discover all neighbors or to enroll
+ * into a WSS activated by a neighbor. During discovery we only want to
+ * store the WSS info in a cache, to be deleted right after it has been
+ * used (eg. displayed to the user). During enrollment we store the WSS
+ * information for the lifetime of enrollment.
+ *
+ * During discovery we are interested in all WSS information, during
+ * enrollment we are only interested in the WSS being enrolled in. Even so,
+ * when in enrollment we keep parsing the message after finding the WSS of
+ * interest, this simplifies the calling routine in that it can be sure
+ * that all WSS information attributes have been parsed out of the message.
+ *
+ * Association frame is process with nbmutex held. The list access is safe.
+ */
+static ssize_t wlp_get_all_wss_info(struct wlp *wlp,
+                                   struct wlp_attr_wss_info *attr,
+                                   struct wlp_neighbor_e *neighbor,
+                                   struct wlp_wss *wss, ssize_t buflen)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       size_t used = 0;
+       ssize_t result = -EINVAL;
+       struct wlp_attr_wss_info *cur;
+       struct wlp_uuid wssid;
+       struct wlp_wss_tmp_info wss_info;
+       unsigned enroll; /* 0 - discovery to cache, 1 - enrollment */
+       struct wlp_wssid_e *wssid_e;
+       char buf[WLP_WSS_UUID_STRSIZE];
+
+       d_fnstart(6, dev, "wlp %p, attr %p, neighbor %p, wss %p, buflen %d \n",
+                 wlp, attr, neighbor, wss, (int)buflen);
+       if (buflen < 0)
+               goto out;
+
+       if (neighbor != NULL && wss == NULL)
+               enroll = 0; /* discovery */
+       else if (wss != NULL && neighbor == NULL)
+               enroll = 1; /* enrollment */
+       else
+               goto out;
+
+       cur = attr;
+       while (buflen - used > 0) {
+               memset(&wss_info, 0, sizeof(wss_info));
+               cur = (void *)cur + used;
+               result = wlp_get_wss_info(wlp, cur, buflen - used, &wssid,
+                                         &wss_info);
+               if (result == -ENODATA) {
+                       result = used;
+                       goto out;
+               } else if (result < 0) {
+                       dev_err(dev, "WLP: Unable to parse WSS information "
+                               "from WSS information attribute. \n");
+                       result = -EINVAL;
+                       goto error_parse;
+               }
+               if (enroll && !memcmp(&wssid, &wss->wssid, sizeof(wssid))) {
+                       if (wss_info.accept_enroll != 1) {
+                               dev_err(dev, "WLP: Requested WSS does "
+                                       "not accept enrollment.\n");
+                               result = -EINVAL;
+                               goto out;
+                       }
+                       memcpy(wss->name, wss_info.name, sizeof(wss->name));
+                       wss->bcast = wss_info.bcast;
+                       wss->secure_status = wss_info.sec_status;
+                       wss->accept_enroll = wss_info.accept_enroll;
+                       wss->state = WLP_WSS_STATE_PART_ENROLLED;
+                       wlp_wss_uuid_print(buf, sizeof(buf), &wssid);
+                       d_printf(2, dev, "WLP: Found WSS %s. Enrolling.\n",
+                                buf);
+               } else {
+                       wssid_e = wlp_create_wssid_e(wlp, neighbor);
+                       if (wssid_e == NULL) {
+                               dev_err(dev, "WLP: Cannot create new WSSID "
+                                       "entry for neighbor %02x:%02x.\n",
+                                       neighbor->uwb_dev->dev_addr.data[1],
+                                       neighbor->uwb_dev->dev_addr.data[0]);
+                               result = -ENOMEM;
+                               goto out;
+                       }
+                       wssid_e->wssid = wssid;
+                       *wssid_e->info = wss_info;
+               }
+               used += result;
+       }
+       result = used;
+error_parse:
+       if (result < 0 && !enroll) /* this was a discovery */
+               wlp_remove_neighbor_tmp_info(neighbor);
+out:
+       d_fnend(6, dev, "wlp %p, attr %p, neighbor %p, wss %p, buflen %d, "
+               "result %d \n", wlp, attr, neighbor, wss, (int)buflen,
+               (int)result);
+       return result;
+
+}
+
+/**
+ * Parse WSS information attributes into cache for discovery
+ *
+ * @attr: the first WSS information attribute in message
+ * @neighbor: the neighbor whose cache will be populated
+ * @buflen: size of the input buffer
+ */
+static ssize_t wlp_get_wss_info_to_cache(struct wlp *wlp,
+                                        struct wlp_attr_wss_info *attr,
+                                        struct wlp_neighbor_e *neighbor,
+                                        ssize_t buflen)
+{
+       return wlp_get_all_wss_info(wlp, attr, neighbor, NULL, buflen);
+}
+
+/**
+ * Parse WSS information attributes into WSS struct for enrollment
+ *
+ * @attr: the first WSS information attribute in message
+ * @wss: the WSS that will be enrolled
+ * @buflen: size of the input buffer
+ */
+static ssize_t wlp_get_wss_info_to_enroll(struct wlp *wlp,
+                                         struct wlp_attr_wss_info *attr,
+                                         struct wlp_wss *wss, ssize_t buflen)
+{
+       return wlp_get_all_wss_info(wlp, attr, NULL, wss, buflen);
+}
+
+/**
+ * Construct a D1 association frame
+ *
+ * We use the radio control functions to determine the values of the device
+ * properties. These are of variable length and the total space needed is
+ * tallied first before we start constructing the message. The radio
+ * control functions return strings that are terminated with \0. This
+ * character should not be included in the message (there is a length field
+ * accompanying it in the attribute).
+ */
+static int wlp_build_assoc_d1(struct wlp *wlp, struct wlp_wss *wss,
+                             struct sk_buff **skb)
+{
+
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       int result = 0;
+       struct wlp_device_info *info;
+       size_t used = 0;
+       struct wlp_frame_assoc *_d1;
+       struct sk_buff *_skb;
+       void *d1_itr;
+
+       d_fnstart(6, dev, "wlp %p\n", wlp);
+       if (wlp->dev_info == NULL) {
+               result = __wlp_setup_device_info(wlp);
+               if (result < 0) {
+                       dev_err(dev, "WLP: Unable to setup device "
+                               "information for D1 message.\n");
+                       goto error;
+               }
+       }
+       info = wlp->dev_info;
+       d_printf(6, dev, "Local properties:\n"
+                "Device name (%d bytes): %s\n"
+                "Model name (%d bytes): %s\n"
+                "Manufacturer (%d bytes): %s\n"
+                "Model number (%d bytes): %s\n"
+                "Serial number (%d bytes): %s\n"
+                "Primary device type: \n"
+                " Category: %d \n"
+                " OUI: %02x:%02x:%02x \n"
+                " OUI Subdivision: %u \n",
+                (int)strlen(info->name), info->name,
+                (int)strlen(info->model_name), info->model_name,
+                (int)strlen(info->manufacturer), info->manufacturer,
+                (int)strlen(info->model_nr),  info->model_nr,
+                (int)strlen(info->serial), info->serial,
+                info->prim_dev_type.category,
+                info->prim_dev_type.OUI[0], info->prim_dev_type.OUI[1],
+                info->prim_dev_type.OUI[2], info->prim_dev_type.OUIsubdiv);
+       _skb = dev_alloc_skb(sizeof(*_d1)
+                     + sizeof(struct wlp_attr_uuid_e)
+                     + sizeof(struct wlp_attr_wss_sel_mthd)
+                     + sizeof(struct wlp_attr_dev_name)
+                     + strlen(info->name)
+                     + sizeof(struct wlp_attr_manufacturer)
+                     + strlen(info->manufacturer)
+                     + sizeof(struct wlp_attr_model_name)
+                     + strlen(info->model_name)
+                     + sizeof(struct wlp_attr_model_nr)
+                     + strlen(info->model_nr)
+                     + sizeof(struct wlp_attr_serial)
+                     + strlen(info->serial)
+                     + sizeof(struct wlp_attr_prim_dev_type)
+                     + sizeof(struct wlp_attr_wlp_assc_err));
+       if (_skb == NULL) {
+               dev_err(dev, "WLP: Cannot allocate memory for association "
+                       "message.\n");
+               result = -ENOMEM;
+               goto error;
+       }
+       _d1 = (void *) _skb->data;
+       d_printf(6, dev, "D1 starts at %p \n", _d1);
+       _d1->hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID);
+       _d1->hdr.type = WLP_FRAME_ASSOCIATION;
+       _d1->type = WLP_ASSOC_D1;
+
+       wlp_set_version(&_d1->version, WLP_VERSION);
+       wlp_set_msg_type(&_d1->msg_type, WLP_ASSOC_D1);
+       d1_itr = _d1->attr;
+       used = wlp_set_uuid_e(d1_itr, &wlp->uuid);
+       used += wlp_set_wss_sel_mthd(d1_itr + used, WLP_WSS_REG_SELECT);
+       used += wlp_set_dev_name(d1_itr + used, info->name,
+                                strlen(info->name));
+       used += wlp_set_manufacturer(d1_itr + used, info->manufacturer,
+                                    strlen(info->manufacturer));
+       used += wlp_set_model_name(d1_itr + used, info->model_name,
+                                  strlen(info->model_name));
+       used += wlp_set_model_nr(d1_itr + used, info->model_nr,
+                                strlen(info->model_nr));
+       used += wlp_set_serial(d1_itr + used, info->serial,
+                              strlen(info->serial));
+       used += wlp_set_prim_dev_type(d1_itr + used, &info->prim_dev_type);
+       used += wlp_set_wlp_assc_err(d1_itr + used, WLP_ASSOC_ERROR_NONE);
+       skb_put(_skb, sizeof(*_d1) + used);
+       d_printf(6, dev, "D1 message:\n");
+       d_dump(6, dev, _d1, sizeof(*_d1)
+                    + sizeof(struct wlp_attr_uuid_e)
+                    + sizeof(struct wlp_attr_wss_sel_mthd)
+                    + sizeof(struct wlp_attr_dev_name)
+                    + strlen(info->name)
+                    + sizeof(struct wlp_attr_manufacturer)
+                    + strlen(info->manufacturer)
+                    + sizeof(struct wlp_attr_model_name)
+                    + strlen(info->model_name)
+                    + sizeof(struct wlp_attr_model_nr)
+                    + strlen(info->model_nr)
+                    + sizeof(struct wlp_attr_serial)
+                    + strlen(info->serial)
+                    + sizeof(struct wlp_attr_prim_dev_type)
+                    + sizeof(struct wlp_attr_wlp_assc_err));
+       *skb = _skb;
+error:
+       d_fnend(6, dev, "wlp %p, result = %d\n", wlp, result);
+       return result;
+}
+
+/**
+ * Construct a D2 association frame
+ *
+ * We use the radio control functions to determine the values of the device
+ * properties. These are of variable length and the total space needed is
+ * tallied first before we start constructing the message. The radio
+ * control functions return strings that are terminated with \0. This
+ * character should not be included in the message (there is a length field
+ * accompanying it in the attribute).
+ */
+static
+int wlp_build_assoc_d2(struct wlp *wlp, struct wlp_wss *wss,
+                      struct sk_buff **skb, struct wlp_uuid *uuid_e)
+{
+
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       int result = 0;
+       struct wlp_device_info *info;
+       size_t used = 0;
+       struct wlp_frame_assoc *_d2;
+       struct sk_buff *_skb;
+       void *d2_itr;
+       size_t mem_needed;
+
+       d_fnstart(6, dev, "wlp %p\n", wlp);
+       if (wlp->dev_info == NULL) {
+               result = __wlp_setup_device_info(wlp);
+               if (result < 0) {
+                       dev_err(dev, "WLP: Unable to setup device "
+                               "information for D2 message.\n");
+                       goto error;
+               }
+       }
+       info = wlp->dev_info;
+       d_printf(6, dev, "Local properties:\n"
+                "Device name (%d bytes): %s\n"
+                "Model name (%d bytes): %s\n"
+                "Manufacturer (%d bytes): %s\n"
+                "Model number (%d bytes): %s\n"
+                "Serial number (%d bytes): %s\n"
+                "Primary device type: \n"
+                " Category: %d \n"
+                " OUI: %02x:%02x:%02x \n"
+                " OUI Subdivision: %u \n",
+                (int)strlen(info->name), info->name,
+                (int)strlen(info->model_name), info->model_name,
+                (int)strlen(info->manufacturer), info->manufacturer,
+                (int)strlen(info->model_nr),  info->model_nr,
+                (int)strlen(info->serial), info->serial,
+                info->prim_dev_type.category,
+                info->prim_dev_type.OUI[0], info->prim_dev_type.OUI[1],
+                info->prim_dev_type.OUI[2], info->prim_dev_type.OUIsubdiv);
+       mem_needed = sizeof(*_d2)
+                     + sizeof(struct wlp_attr_uuid_e)
+                     + sizeof(struct wlp_attr_uuid_r)
+                     + sizeof(struct wlp_attr_dev_name)
+                     + strlen(info->name)
+                     + sizeof(struct wlp_attr_manufacturer)
+                     + strlen(info->manufacturer)
+                     + sizeof(struct wlp_attr_model_name)
+                     + strlen(info->model_name)
+                     + sizeof(struct wlp_attr_model_nr)
+                     + strlen(info->model_nr)
+                     + sizeof(struct wlp_attr_serial)
+                     + strlen(info->serial)
+                     + sizeof(struct wlp_attr_prim_dev_type)
+                     + sizeof(struct wlp_attr_wlp_assc_err);
+       if (wlp->wss.state >= WLP_WSS_STATE_ACTIVE)
+               mem_needed += sizeof(struct wlp_attr_wss_info)
+                             + sizeof(struct wlp_wss_info)
+                             + strlen(wlp->wss.name);
+       _skb = dev_alloc_skb(mem_needed);
+       if (_skb == NULL) {
+               dev_err(dev, "WLP: Cannot allocate memory for association "
+                       "message.\n");
+               result = -ENOMEM;
+               goto error;
+       }
+       _d2 = (void *) _skb->data;
+       d_printf(6, dev, "D2 starts at %p \n", _d2);
+       _d2->hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID);
+       _d2->hdr.type = WLP_FRAME_ASSOCIATION;
+       _d2->type = WLP_ASSOC_D2;
+
+       wlp_set_version(&_d2->version, WLP_VERSION);
+       wlp_set_msg_type(&_d2->msg_type, WLP_ASSOC_D2);
+       d2_itr = _d2->attr;
+       used = wlp_set_uuid_e(d2_itr, uuid_e);
+       used += wlp_set_uuid_r(d2_itr + used, &wlp->uuid);
+       if (wlp->wss.state >= WLP_WSS_STATE_ACTIVE)
+               used += wlp_set_wss_info(d2_itr + used, &wlp->wss);
+       used += wlp_set_dev_name(d2_itr + used, info->name,
+                                strlen(info->name));
+       used += wlp_set_manufacturer(d2_itr + used, info->manufacturer,
+                                    strlen(info->manufacturer));
+       used += wlp_set_model_name(d2_itr + used, info->model_name,
+                                  strlen(info->model_name));
+       used += wlp_set_model_nr(d2_itr + used, info->model_nr,
+                                strlen(info->model_nr));
+       used += wlp_set_serial(d2_itr + used, info->serial,
+                              strlen(info->serial));
+       used += wlp_set_prim_dev_type(d2_itr + used, &info->prim_dev_type);
+       used += wlp_set_wlp_assc_err(d2_itr + used, WLP_ASSOC_ERROR_NONE);
+       skb_put(_skb, sizeof(*_d2) + used);
+       d_printf(6, dev, "D2 message:\n");
+       d_dump(6, dev, _d2, mem_needed);
+       *skb = _skb;
+error:
+       d_fnend(6, dev, "wlp %p, result = %d\n", wlp, result);
+       return result;
+}
+
+/**
+ * Allocate memory for and populate fields of F0 association frame
+ *
+ * Currently (while focusing on unsecure enrollment) we ignore the
+ * nonce's that could be placed in the message. Only the error field is
+ * populated by the value provided by the caller.
+ */
+static
+int wlp_build_assoc_f0(struct wlp *wlp, struct sk_buff **skb,
+                      enum wlp_assc_error error)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       int result = -ENOMEM;
+       struct {
+               struct wlp_frame_assoc f0_hdr;
+               struct wlp_attr_enonce enonce;
+               struct wlp_attr_rnonce rnonce;
+               struct wlp_attr_wlp_assc_err assc_err;
+       } *f0;
+       struct sk_buff *_skb;
+       struct wlp_nonce tmp;
+
+       d_fnstart(6, dev, "wlp %p\n", wlp);
+       _skb = dev_alloc_skb(sizeof(*f0));
+       if (_skb == NULL) {
+               dev_err(dev, "WLP: Unable to allocate memory for F0 "
+                       "association frame. \n");
+               goto error_alloc;
+       }
+       f0 = (void *) _skb->data;
+       d_printf(6, dev, "F0 starts at %p \n", f0);
+       f0->f0_hdr.hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID);
+       f0->f0_hdr.hdr.type = WLP_FRAME_ASSOCIATION;
+       f0->f0_hdr.type = WLP_ASSOC_F0;
+       wlp_set_version(&f0->f0_hdr.version, WLP_VERSION);
+       wlp_set_msg_type(&f0->f0_hdr.msg_type, WLP_ASSOC_F0);
+       memset(&tmp, 0, sizeof(tmp));
+       wlp_set_enonce(&f0->enonce, &tmp);
+       wlp_set_rnonce(&f0->rnonce, &tmp);
+       wlp_set_wlp_assc_err(&f0->assc_err, error);
+       skb_put(_skb, sizeof(*f0));
+       *skb = _skb;
+       result = 0;
+error_alloc:
+       d_fnend(6, dev, "wlp %p, result %d \n", wlp, result);
+       return result;
+}
+
+/**
+ * Parse F0 frame
+ *
+ * We just retrieve the values and print it as an error to the user.
+ * Calling function already knows an error occured (F0 indicates error), so
+ * we just parse the content as debug for higher layers.
+ */
+int wlp_parse_f0(struct wlp *wlp, struct sk_buff *skb)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       struct wlp_frame_assoc *f0 = (void *) skb->data;
+       void *ptr = skb->data;
+       size_t len = skb->len;
+       size_t used;
+       ssize_t result;
+       struct wlp_nonce enonce, rnonce;
+       enum wlp_assc_error assc_err;
+       char enonce_buf[WLP_WSS_NONCE_STRSIZE];
+       char rnonce_buf[WLP_WSS_NONCE_STRSIZE];
+
+       used = sizeof(*f0);
+       result = wlp_get_enonce(wlp, ptr + used, &enonce, len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain Enrollee nonce "
+                       "attribute from F0 message.\n");
+               goto error_parse;
+       }
+       used += result;
+       result = wlp_get_rnonce(wlp, ptr + used, &rnonce, len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain Registrar nonce "
+                       "attribute from F0 message.\n");
+               goto error_parse;
+       }
+       used += result;
+       result = wlp_get_wlp_assc_err(wlp, ptr + used, &assc_err, len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain WLP Association error "
+                       "attribute from F0 message.\n");
+               goto error_parse;
+       }
+       wlp_wss_nonce_print(enonce_buf, sizeof(enonce_buf), &enonce);
+       wlp_wss_nonce_print(rnonce_buf, sizeof(rnonce_buf), &rnonce);
+       dev_err(dev, "WLP: Received F0 error frame from neighbor. Enrollee "
+               "nonce: %s, Registrar nonce: %s, WLP Association error: %s.\n",
+               enonce_buf, rnonce_buf, wlp_assc_error_str(assc_err));
+       result = 0;
+error_parse:
+       return result;
+}
+
+/**
+ * Retrieve variable device information from association message
+ *
+ * The device information parsed is not required in any message. This
+ * routine will thus not fail if an attribute is not present.
+ * The attributes are expected in a certain order, even if all are not
+ * present. The "attribute type" value is used to ensure the attributes
+ * are parsed in the correct order.
+ *
+ * If an error is encountered during parsing the function will return an
+ * error code, when this happens the given device_info structure may be
+ * partially filled.
+ */
+static
+int wlp_get_variable_info(struct wlp *wlp, void *data,
+                         struct wlp_device_info *dev_info, ssize_t len)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       size_t used = 0;
+       struct wlp_attr_hdr *hdr;
+       ssize_t result = 0;
+       unsigned last = 0;
+
+       while (len - used > 0) {
+               if (len - used < sizeof(*hdr)) {
+                       dev_err(dev, "WLP: Partial data in frame, cannot "
+                               "parse. \n");
+                       goto error_parse;
+               }
+               hdr = data + used;
+               switch (le16_to_cpu(hdr->type)) {
+               case WLP_ATTR_MANUF:
+                       if (last >= WLP_ATTR_MANUF) {
+                               dev_err(dev, "WLP: Incorrect order of "
+                                       "attribute values in D1 msg.\n");
+                               goto error_parse;
+                       }
+                       result = wlp_get_manufacturer(wlp, data + used,
+                                                     dev_info->manufacturer,
+                                                     len - used);
+                       if (result < 0) {
+                               dev_err(dev, "WLP: Unable to obtain "
+                                       "Manufacturer attribute from D1 "
+                                       "message.\n");
+                               goto error_parse;
+                       }
+                       last = WLP_ATTR_MANUF;
+                       used += result;
+                       break;
+               case WLP_ATTR_MODEL_NAME:
+                       if (last >= WLP_ATTR_MODEL_NAME) {
+                               dev_err(dev, "WLP: Incorrect order of "
+                                       "attribute values in D1 msg.\n");
+                               goto error_parse;
+                       }
+                       result = wlp_get_model_name(wlp, data + used,
+                                                   dev_info->model_name,
+                                                   len - used);
+                       if (result < 0) {
+                               dev_err(dev, "WLP: Unable to obtain Model "
+                                       "name attribute from D1 message.\n");
+                               goto error_parse;
+                       }
+                       last = WLP_ATTR_MODEL_NAME;
+                       used += result;
+                       break;
+               case WLP_ATTR_MODEL_NR:
+                       if (last >= WLP_ATTR_MODEL_NR) {
+                               dev_err(dev, "WLP: Incorrect order of "
+                                       "attribute values in D1 msg.\n");
+                               goto error_parse;
+                       }
+                       result = wlp_get_model_nr(wlp, data + used,
+                                                 dev_info->model_nr,
+                                                 len - used);
+                       if (result < 0) {
+                               dev_err(dev, "WLP: Unable to obtain Model "
+                                       "number attribute from D1 message.\n");
+                               goto error_parse;
+                       }
+                       last = WLP_ATTR_MODEL_NR;
+                       used += result;
+                       break;
+               case WLP_ATTR_SERIAL:
+                       if (last >= WLP_ATTR_SERIAL) {
+                               dev_err(dev, "WLP: Incorrect order of "
+                                       "attribute values in D1 msg.\n");
+                               goto error_parse;
+                       }
+                       result = wlp_get_serial(wlp, data + used,
+                                               dev_info->serial, len - used);
+                       if (result < 0) {
+                               dev_err(dev, "WLP: Unable to obtain Serial "
+                                       "number attribute from D1 message.\n");
+                               goto error_parse;
+                       }
+                       last = WLP_ATTR_SERIAL;
+                       used += result;
+                       break;
+               case WLP_ATTR_PRI_DEV_TYPE:
+                       if (last >= WLP_ATTR_PRI_DEV_TYPE) {
+                               dev_err(dev, "WLP: Incorrect order of "
+                                       "attribute values in D1 msg.\n");
+                               goto error_parse;
+                       }
+                       result = wlp_get_prim_dev_type(wlp, data + used,
+                                                      &dev_info->prim_dev_type,
+                                                      len - used);
+                       if (result < 0) {
+                               dev_err(dev, "WLP: Unable to obtain Primary "
+                                       "device type attribute from D1 "
+                                       "message.\n");
+                               goto error_parse;
+                       }
+                       dev_info->prim_dev_type.category =
+                               le16_to_cpu(dev_info->prim_dev_type.category);
+                       dev_info->prim_dev_type.subID =
+                               le16_to_cpu(dev_info->prim_dev_type.subID);
+                       last = WLP_ATTR_PRI_DEV_TYPE;
+                       used += result;
+                       break;
+               default:
+                       /* This is not variable device information. */
+                       goto out;
+                       break;
+               }
+       }
+out:
+       return used;
+error_parse:
+       return -EINVAL;
+}
+
+/**
+ * Parse incoming D1 frame, populate attribute values
+ *
+ * Caller provides pointers to memory already allocated for attributes
+ * expected in the D1 frame. These variables will be populated.
+ */
+static
+int wlp_parse_d1_frame(struct wlp *wlp, struct sk_buff *skb,
+                      struct wlp_uuid *uuid_e,
+                      enum wlp_wss_sel_mthd *sel_mthd,
+                      struct wlp_device_info *dev_info,
+                      enum wlp_assc_error *assc_err)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       struct wlp_frame_assoc *d1 = (void *) skb->data;
+       void *ptr = skb->data;
+       size_t len = skb->len;
+       size_t used;
+       ssize_t result;
+
+       used = sizeof(*d1);
+       result = wlp_get_uuid_e(wlp, ptr + used, uuid_e, len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain UUID-E attribute from D1 "
+                       "message.\n");
+               goto error_parse;
+       }
+       used += result;
+       result = wlp_get_wss_sel_mthd(wlp, ptr + used, sel_mthd, len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain WSS selection method "
+                       "from D1 message.\n");
+               goto error_parse;
+       }
+       used += result;
+       result = wlp_get_dev_name(wlp, ptr + used, dev_info->name,
+                                    len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain Device Name from D1 "
+                       "message.\n");
+               goto error_parse;
+       }
+       used += result;
+       result = wlp_get_variable_info(wlp, ptr + used, dev_info, len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain Device Information from "
+                       "D1 message.\n");
+               goto error_parse;
+       }
+       used += result;
+       result = wlp_get_wlp_assc_err(wlp, ptr + used, assc_err, len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain WLP Association Error "
+                       "Information from D1 message.\n");
+               goto error_parse;
+       }
+       result = 0;
+error_parse:
+       return result;
+}
+/**
+ * Handle incoming D1 frame
+ *
+ * The frame has already been verified to contain an Association header with
+ * the correct version number. Parse the incoming frame, construct and send
+ * a D2 frame in response.
+ *
+ * It is not clear what to do with most fields in the incoming D1 frame. We
+ * retrieve and discard the information here for now.
+ */
+void wlp_handle_d1_frame(struct work_struct *ws)
+{
+       struct wlp_assoc_frame_ctx *frame_ctx = container_of(ws,
+                                                 struct wlp_assoc_frame_ctx,
+                                                 ws);
+       struct wlp *wlp = frame_ctx->wlp;
+       struct wlp_wss *wss = &wlp->wss;
+       struct sk_buff *skb = frame_ctx->skb;
+       struct uwb_dev_addr *src = &frame_ctx->src;
+       int result;
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       struct wlp_uuid uuid_e;
+       enum wlp_wss_sel_mthd sel_mthd = 0;
+       struct wlp_device_info dev_info;
+       enum wlp_assc_error assc_err;
+       char uuid[WLP_WSS_UUID_STRSIZE];
+       struct sk_buff *resp = NULL;
+
+       /* Parse D1 frame */
+       d_fnstart(6, dev, "WLP: handle D1 frame. wlp = %p, skb = %p\n",
+                 wlp, skb);
+       mutex_lock(&wss->mutex);
+       mutex_lock(&wlp->mutex); /* to access wlp->uuid */
+       memset(&dev_info, 0, sizeof(dev_info));
+       result = wlp_parse_d1_frame(wlp, skb, &uuid_e, &sel_mthd, &dev_info,
+                                   &assc_err);
+       if (result < 0) {
+               dev_err(dev, "WLP: Unable to parse incoming D1 frame.\n");
+               kfree_skb(skb);
+               goto out;
+       }
+       wlp_wss_uuid_print(uuid, sizeof(uuid), &uuid_e);
+       d_printf(6, dev, "From D1 frame:\n"
+                "UUID-E: %s\n"
+                "Selection method: %d\n"
+                "Device name (%d bytes): %s\n"
+                "Model name (%d bytes): %s\n"
+                "Manufacturer (%d bytes): %s\n"
+                "Model number (%d bytes): %s\n"
+                "Serial number (%d bytes): %s\n"
+                "Primary device type: \n"
+                " Category: %d \n"
+                " OUI: %02x:%02x:%02x \n"
+                " OUI Subdivision: %u \n",
+                uuid, sel_mthd,
+                (int)strlen(dev_info.name), dev_info.name,
+                (int)strlen(dev_info.model_name), dev_info.model_name,
+                (int)strlen(dev_info.manufacturer), dev_info.manufacturer,
+                (int)strlen(dev_info.model_nr),  dev_info.model_nr,
+                (int)strlen(dev_info.serial), dev_info.serial,
+                dev_info.prim_dev_type.category,
+                dev_info.prim_dev_type.OUI[0],
+                dev_info.prim_dev_type.OUI[1],
+                dev_info.prim_dev_type.OUI[2],
+                dev_info.prim_dev_type.OUIsubdiv);
+
+       kfree_skb(skb);
+       if (!wlp_uuid_is_set(&wlp->uuid)) {
+               dev_err(dev, "WLP: UUID is not set. Set via sysfs to "
+                       "proceed. Respong to D1 message with error F0.\n");
+               result = wlp_build_assoc_f0(wlp, &resp,
+                                           WLP_ASSOC_ERROR_NOT_READY);
+               if (result < 0) {
+                       dev_err(dev, "WLP: Unable to construct F0 message.\n");
+                       goto out;
+               }
+       } else {
+               /* Construct D2 frame */
+               result = wlp_build_assoc_d2(wlp, wss, &resp, &uuid_e);
+               if (result < 0) {
+                       dev_err(dev, "WLP: Unable to construct D2 message.\n");
+                       goto out;
+               }
+       }
+       /* Send D2 frame */
+       BUG_ON(wlp->xmit_frame == NULL);
+       result = wlp->xmit_frame(wlp, resp, src);
+       if (result < 0) {
+               dev_err(dev, "WLP: Unable to transmit D2 association "
+                       "message: %d\n", result);
+               if (result == -ENXIO)
+                       dev_err(dev, "WLP: Is network interface up? \n");
+               /* We could try again ... */
+               dev_kfree_skb_any(resp); /* we need to free if tx fails */
+       }
+out:
+       kfree(frame_ctx);
+       mutex_unlock(&wlp->mutex);
+       mutex_unlock(&wss->mutex);
+       d_fnend(6, dev, "WLP: handle D1 frame. wlp = %p\n", wlp);
+}
+
+/**
+ * Parse incoming D2 frame, create and populate temporary cache
+ *
+ * @skb: socket buffer in which D2 frame can be found
+ * @neighbor: the neighbor that sent the D2 frame
+ *
+ * Will allocate memory for temporary storage of information learned during
+ * discovery.
+ */
+int wlp_parse_d2_frame_to_cache(struct wlp *wlp, struct sk_buff *skb,
+                               struct wlp_neighbor_e *neighbor)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       struct wlp_frame_assoc *d2 = (void *) skb->data;
+       void *ptr = skb->data;
+       size_t len = skb->len;
+       size_t used;
+       ssize_t result;
+       struct wlp_uuid uuid_e;
+       struct wlp_device_info *nb_info;
+       enum wlp_assc_error assc_err;
+
+       used = sizeof(*d2);
+       result = wlp_get_uuid_e(wlp, ptr + used, &uuid_e, len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain UUID-E attribute from D2 "
+                       "message.\n");
+               goto error_parse;
+       }
+       if (memcmp(&uuid_e, &wlp->uuid, sizeof(uuid_e))) {
+               dev_err(dev, "WLP: UUID-E in incoming D2 does not match "
+                       "local UUID sent in D1. \n");
+               goto error_parse;
+       }
+       used += result;
+       result = wlp_get_uuid_r(wlp, ptr + used, &neighbor->uuid, len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain UUID-R attribute from D2 "
+                       "message.\n");
+               goto error_parse;
+       }
+       used += result;
+       result = wlp_get_wss_info_to_cache(wlp, ptr + used, neighbor,
+                                          len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain WSS information "
+                       "from D2 message.\n");
+               goto error_parse;
+       }
+       used += result;
+       neighbor->info = kzalloc(sizeof(struct wlp_device_info), GFP_KERNEL);
+       if (neighbor->info == NULL) {
+               dev_err(dev, "WLP: cannot allocate memory to store device "
+                       "info.\n");
+               result = -ENOMEM;
+               goto error_parse;
+       }
+       nb_info = neighbor->info;
+       result = wlp_get_dev_name(wlp, ptr + used, nb_info->name,
+                                 len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain Device Name from D2 "
+                       "message.\n");
+               goto error_parse;
+       }
+       used += result;
+       result = wlp_get_variable_info(wlp, ptr + used, nb_info, len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain Device Information from "
+                       "D2 message.\n");
+               goto error_parse;
+       }
+       used += result;
+       result = wlp_get_wlp_assc_err(wlp, ptr + used, &assc_err, len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain WLP Association Error "
+                       "Information from D2 message.\n");
+               goto error_parse;
+       }
+       if (assc_err != WLP_ASSOC_ERROR_NONE) {
+               dev_err(dev, "WLP: neighbor device returned association "
+                       "error %d\n", assc_err);
+               result = -EINVAL;
+               goto error_parse;
+       }
+       result = 0;
+error_parse:
+       if (result < 0)
+               wlp_remove_neighbor_tmp_info(neighbor);
+       return result;
+}
+
+/**
+ * Parse incoming D2 frame, populate attribute values of WSS bein enrolled in
+ *
+ * @wss: our WSS that will be enrolled
+ * @skb: socket buffer in which D2 frame can be found
+ * @neighbor: the neighbor that sent the D2 frame
+ * @wssid: the wssid of the WSS in which we want to enroll
+ *
+ * Forms part of enrollment sequence. We are trying to enroll in WSS with
+ * @wssid by using @neighbor as registrar. A D1 message was sent to
+ * @neighbor and now we need to parse the D2 response. The neighbor's
+ * response is searched for the requested WSS and if found (and it accepts
+ * enrollment), we store the information.
+ */
+int wlp_parse_d2_frame_to_enroll(struct wlp_wss *wss, struct sk_buff *skb,
+                                struct wlp_neighbor_e *neighbor,
+                                struct wlp_uuid *wssid)
+{
+       struct wlp *wlp = container_of(wss, struct wlp, wss);
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       void *ptr = skb->data;
+       size_t len = skb->len;
+       size_t used;
+       ssize_t result;
+       struct wlp_uuid uuid_e;
+       struct wlp_uuid uuid_r;
+       struct wlp_device_info nb_info;
+       enum wlp_assc_error assc_err;
+       char uuid_bufA[WLP_WSS_UUID_STRSIZE];
+       char uuid_bufB[WLP_WSS_UUID_STRSIZE];
+
+       used = sizeof(struct wlp_frame_assoc);
+       result = wlp_get_uuid_e(wlp, ptr + used, &uuid_e, len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain UUID-E attribute from D2 "
+                       "message.\n");
+               goto error_parse;
+       }
+       if (memcmp(&uuid_e, &wlp->uuid, sizeof(uuid_e))) {
+               dev_err(dev, "WLP: UUID-E in incoming D2 does not match "
+                       "local UUID sent in D1. \n");
+               goto error_parse;
+       }
+       used += result;
+       result = wlp_get_uuid_r(wlp, ptr + used, &uuid_r, len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain UUID-R attribute from D2 "
+                       "message.\n");
+               goto error_parse;
+       }
+       if (memcmp(&uuid_r, &neighbor->uuid, sizeof(uuid_r))) {
+               wlp_wss_uuid_print(uuid_bufA, sizeof(uuid_bufA),
+                                  &neighbor->uuid);
+               wlp_wss_uuid_print(uuid_bufB, sizeof(uuid_bufB), &uuid_r);
+               dev_err(dev, "WLP: UUID of neighbor does not match UUID "
+                       "learned during discovery. Originally discovered: %s, "
+                       "now from D2 message: %s\n", uuid_bufA, uuid_bufB);
+               result = -EINVAL;
+               goto error_parse;
+       }
+       used += result;
+       wss->wssid = *wssid;
+       result = wlp_get_wss_info_to_enroll(wlp, ptr + used, wss, len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain WSS information "
+                       "from D2 message.\n");
+               goto error_parse;
+       }
+       if (wss->state != WLP_WSS_STATE_PART_ENROLLED) {
+               dev_err(dev, "WLP: D2 message did not contain information "
+                       "for successful enrollment. \n");
+               result = -EINVAL;
+               goto error_parse;
+       }
+       used += result;
+       /* Place device information on stack to continue parsing of message */
+       result = wlp_get_dev_name(wlp, ptr + used, nb_info.name,
+                                 len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain Device Name from D2 "
+                       "message.\n");
+               goto error_parse;
+       }
+       used += result;
+       result = wlp_get_variable_info(wlp, ptr + used, &nb_info, len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain Device Information from "
+                       "D2 message.\n");
+               goto error_parse;
+       }
+       used += result;
+       result = wlp_get_wlp_assc_err(wlp, ptr + used, &assc_err, len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain WLP Association Error "
+                       "Information from D2 message.\n");
+               goto error_parse;
+       }
+       if (assc_err != WLP_ASSOC_ERROR_NONE) {
+               dev_err(dev, "WLP: neighbor device returned association "
+                       "error %d\n", assc_err);
+               if (wss->state == WLP_WSS_STATE_PART_ENROLLED) {
+                       dev_err(dev, "WLP: Enrolled in WSS (should not "
+                               "happen according to spec). Undoing. \n");
+                       wlp_wss_reset(wss);
+               }
+               result = -EINVAL;
+               goto error_parse;
+       }
+       result = 0;
+error_parse:
+       return result;
+}
+
+/**
+ * Parse C3/C4 frame into provided variables
+ *
+ * @wssid: will point to copy of wssid retrieved from C3/C4 frame
+ * @tag:   will point to copy of tag retrieved from C3/C4 frame
+ * @virt_addr: will point to copy of virtual address retrieved from C3/C4
+ * frame.
+ *
+ * Calling function has to allocate memory for these values.
+ *
+ * skb contains a valid C3/C4 frame, return the individual fields of this
+ * frame in the provided variables.
+ */
+int wlp_parse_c3c4_frame(struct wlp *wlp, struct sk_buff *skb,
+                      struct wlp_uuid *wssid, u8 *tag,
+                      struct uwb_mac_addr *virt_addr)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       int result;
+       void *ptr = skb->data;
+       size_t len = skb->len;
+       size_t used;
+       char buf[WLP_WSS_UUID_STRSIZE];
+       struct wlp_frame_assoc *assoc = ptr;
+
+       d_fnstart(6, dev, "wlp %p, skb %p \n", wlp, skb);
+       used = sizeof(*assoc);
+       result = wlp_get_wssid(wlp, ptr + used, wssid, len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain WSSID attribute from "
+                       "%s message.\n", wlp_assoc_frame_str(assoc->type));
+               goto error_parse;
+       }
+       used += result;
+       result = wlp_get_wss_tag(wlp, ptr + used, tag, len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain WSS tag attribute from "
+                       "%s message.\n", wlp_assoc_frame_str(assoc->type));
+               goto error_parse;
+       }
+       used += result;
+       result = wlp_get_wss_virt(wlp, ptr + used, virt_addr, len - used);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain WSS virtual address "
+                       "attribute from %s message.\n",
+                       wlp_assoc_frame_str(assoc->type));
+               goto error_parse;
+       }
+       wlp_wss_uuid_print(buf, sizeof(buf), wssid);
+       d_printf(6, dev, "WLP: parsed: WSSID %s, tag 0x%02x, virt "
+                "%02x:%02x:%02x:%02x:%02x:%02x \n", buf, *tag,
+                virt_addr->data[0], virt_addr->data[1], virt_addr->data[2],
+                virt_addr->data[3], virt_addr->data[4], virt_addr->data[5]);
+
+error_parse:
+       d_fnend(6, dev, "wlp %p, skb %p, result = %d \n", wlp, skb, result);
+       return result;
+}
+
+/**
+ * Allocate memory for and populate fields of C1 or C2 association frame
+ *
+ * The C1 and C2 association frames appear identical - except for the type.
+ */
+static
+int wlp_build_assoc_c1c2(struct wlp *wlp, struct wlp_wss *wss,
+                        struct sk_buff **skb, enum wlp_assoc_type type)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       int result  = -ENOMEM;
+       struct {
+               struct wlp_frame_assoc c_hdr;
+               struct wlp_attr_wssid wssid;
+       } *c;
+       struct sk_buff *_skb;
+
+       d_fnstart(6, dev, "wlp %p, wss %p \n", wlp, wss);
+       _skb = dev_alloc_skb(sizeof(*c));
+       if (_skb == NULL) {
+               dev_err(dev, "WLP: Unable to allocate memory for C1/C2 "
+                       "association frame. \n");
+               goto error_alloc;
+       }
+       c = (void *) _skb->data;
+       d_printf(6, dev, "C1/C2 starts at %p \n", c);
+       c->c_hdr.hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID);
+       c->c_hdr.hdr.type = WLP_FRAME_ASSOCIATION;
+       c->c_hdr.type = type;
+       wlp_set_version(&c->c_hdr.version, WLP_VERSION);
+       wlp_set_msg_type(&c->c_hdr.msg_type, type);
+       wlp_set_wssid(&c->wssid, &wss->wssid);
+       skb_put(_skb, sizeof(*c));
+       d_printf(6, dev, "C1/C2 message:\n");
+       d_dump(6, dev, c, sizeof(*c));
+       *skb = _skb;
+       result = 0;
+error_alloc:
+       d_fnend(6, dev, "wlp %p, wss %p, result %d \n", wlp, wss, result);
+       return result;
+}
+
+
+static
+int wlp_build_assoc_c1(struct wlp *wlp, struct wlp_wss *wss,
+                      struct sk_buff **skb)
+{
+       return wlp_build_assoc_c1c2(wlp, wss, skb, WLP_ASSOC_C1);
+}
+
+static
+int wlp_build_assoc_c2(struct wlp *wlp, struct wlp_wss *wss,
+                      struct sk_buff **skb)
+{
+       return wlp_build_assoc_c1c2(wlp, wss, skb, WLP_ASSOC_C2);
+}
+
+
+/**
+ * Allocate memory for and populate fields of C3 or C4 association frame
+ *
+ * The C3 and C4 association frames appear identical - except for the type.
+ */
+static
+int wlp_build_assoc_c3c4(struct wlp *wlp, struct wlp_wss *wss,
+                        struct sk_buff **skb, enum wlp_assoc_type type)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       int result  = -ENOMEM;
+       struct {
+               struct wlp_frame_assoc c_hdr;
+               struct wlp_attr_wssid wssid;
+               struct wlp_attr_wss_tag wss_tag;
+               struct wlp_attr_wss_virt wss_virt;
+       } *c;
+       struct sk_buff *_skb;
+
+       d_fnstart(6, dev, "wlp %p, wss %p \n", wlp, wss);
+       _skb = dev_alloc_skb(sizeof(*c));
+       if (_skb == NULL) {
+               dev_err(dev, "WLP: Unable to allocate memory for C3/C4 "
+                       "association frame. \n");
+               goto error_alloc;
+       }
+       c = (void *) _skb->data;
+       d_printf(6, dev, "C3/C4 starts at %p \n", c);
+       c->c_hdr.hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID);
+       c->c_hdr.hdr.type = WLP_FRAME_ASSOCIATION;
+       c->c_hdr.type = type;
+       wlp_set_version(&c->c_hdr.version, WLP_VERSION);
+       wlp_set_msg_type(&c->c_hdr.msg_type, type);
+       wlp_set_wssid(&c->wssid, &wss->wssid);
+       wlp_set_wss_tag(&c->wss_tag, wss->tag);
+       wlp_set_wss_virt(&c->wss_virt, &wss->virtual_addr);
+       skb_put(_skb, sizeof(*c));
+       d_printf(6, dev, "C3/C4 message:\n");
+       d_dump(6, dev, c, sizeof(*c));
+       *skb = _skb;
+       result = 0;
+error_alloc:
+       d_fnend(6, dev, "wlp %p, wss %p, result %d \n", wlp, wss, result);
+       return result;
+}
+
+static
+int wlp_build_assoc_c3(struct wlp *wlp, struct wlp_wss *wss,
+                      struct sk_buff **skb)
+{
+       return wlp_build_assoc_c3c4(wlp, wss, skb, WLP_ASSOC_C3);
+}
+
+static
+int wlp_build_assoc_c4(struct wlp *wlp, struct wlp_wss *wss,
+                      struct sk_buff **skb)
+{
+       return wlp_build_assoc_c3c4(wlp, wss, skb, WLP_ASSOC_C4);
+}
+
+
+#define wlp_send_assoc(type, id)                                       \
+static int wlp_send_assoc_##type(struct wlp *wlp, struct wlp_wss *wss, \
+                                struct uwb_dev_addr *dev_addr)         \
+{                                                                      \
+       struct device *dev = &wlp->rc->uwb_dev.dev;                     \
+       int result;                                                     \
+       struct sk_buff *skb = NULL;                                     \
+       d_fnstart(6, dev, "wlp %p, wss %p, neighbor: %02x:%02x\n",      \
+                 wlp, wss, dev_addr->data[1], dev_addr->data[0]);      \
+       d_printf(6, dev, "WLP: Constructing %s frame. \n",              \
+                wlp_assoc_frame_str(id));                              \
+       /* Build the frame */                                           \
+       result = wlp_build_assoc_##type(wlp, wss, &skb);                \
+       if (result < 0) {                                               \
+               dev_err(dev, "WLP: Unable to construct %s association " \
+                       "frame: %d\n", wlp_assoc_frame_str(id), result);\
+               goto error_build_assoc;                                 \
+       }                                                               \
+       /* Send the frame */                                            \
+       d_printf(6, dev, "Transmitting %s frame to %02x:%02x \n",       \
+                wlp_assoc_frame_str(id),                               \
+                dev_addr->data[1], dev_addr->data[0]);                 \
+       BUG_ON(wlp->xmit_frame == NULL);                                \
+       result = wlp->xmit_frame(wlp, skb, dev_addr);                   \
+       if (result < 0) {                                               \
+               dev_err(dev, "WLP: Unable to transmit %s association "  \
+                       "message: %d\n", wlp_assoc_frame_str(id),       \
+                       result);                                        \
+               if (result == -ENXIO)                                   \
+                       dev_err(dev, "WLP: Is network interface "       \
+                               "up? \n");                              \
+               goto error_xmit;                                        \
+       }                                                               \
+       return 0;                                                       \
+error_xmit:                                                            \
+       /* We could try again ... */                                    \
+       dev_kfree_skb_any(skb);/*we need to free if tx fails*/          \
+error_build_assoc:                                                     \
+       d_fnend(6, dev, "wlp %p, wss %p, neighbor: %02x:%02x\n",        \
+               wlp, wss, dev_addr->data[1], dev_addr->data[0]);        \
+       return result;                                                  \
+}
+
+wlp_send_assoc(d1, WLP_ASSOC_D1)
+wlp_send_assoc(c1, WLP_ASSOC_C1)
+wlp_send_assoc(c3, WLP_ASSOC_C3)
+
+int wlp_send_assoc_frame(struct wlp *wlp, struct wlp_wss *wss,
+                        struct uwb_dev_addr *dev_addr,
+                        enum wlp_assoc_type type)
+{
+       int result = 0;
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       switch (type) {
+       case WLP_ASSOC_D1:
+               result = wlp_send_assoc_d1(wlp, wss, dev_addr);
+               break;
+       case WLP_ASSOC_C1:
+               result = wlp_send_assoc_c1(wlp, wss, dev_addr);
+               break;
+       case WLP_ASSOC_C3:
+               result = wlp_send_assoc_c3(wlp, wss, dev_addr);
+               break;
+       default:
+               dev_err(dev, "WLP: Received request to send unknown "
+                       "association message.\n");
+               result = -EINVAL;
+               break;
+       }
+       return result;
+}
+
+/**
+ * Handle incoming C1 frame
+ *
+ * The frame has already been verified to contain an Association header with
+ * the correct version number. Parse the incoming frame, construct and send
+ * a C2 frame in response.
+ */
+void wlp_handle_c1_frame(struct work_struct *ws)
+{
+       struct wlp_assoc_frame_ctx *frame_ctx = container_of(ws,
+                                                 struct wlp_assoc_frame_ctx,
+                                                 ws);
+       struct wlp *wlp = frame_ctx->wlp;
+       struct wlp_wss *wss = &wlp->wss;
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       struct wlp_frame_assoc *c1 = (void *) frame_ctx->skb->data;
+       unsigned int len = frame_ctx->skb->len;
+       struct uwb_dev_addr *src = &frame_ctx->src;
+       int result;
+       struct wlp_uuid wssid;
+       char buf[WLP_WSS_UUID_STRSIZE];
+       struct sk_buff *resp = NULL;
+
+       /* Parse C1 frame */
+       d_fnstart(6, dev, "WLP: handle C1 frame. wlp = %p, c1 = %p\n",
+                 wlp, c1);
+       mutex_lock(&wss->mutex);
+       result = wlp_get_wssid(wlp, (void *)c1 + sizeof(*c1), &wssid,
+                              len - sizeof(*c1));
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain WSSID from C1 frame.\n");
+               goto out;
+       }
+       wlp_wss_uuid_print(buf, sizeof(buf), &wssid);
+       d_printf(6, dev, "Received C1 frame with WSSID %s \n", buf);
+       if (!memcmp(&wssid, &wss->wssid, sizeof(wssid))
+           && wss->state == WLP_WSS_STATE_ACTIVE) {
+               d_printf(6, dev, "WSSID from C1 frame is known locally "
+                        "and is active\n");
+               /* Construct C2 frame */
+               result = wlp_build_assoc_c2(wlp, wss, &resp);
+               if (result < 0) {
+                       dev_err(dev, "WLP: Unable to construct C2 message.\n");
+                       goto out;
+               }
+       } else {
+               d_printf(6, dev, "WSSID from C1 frame is not known locally "
+                        "or is not active\n");
+               /* Construct F0 frame */
+               result = wlp_build_assoc_f0(wlp, &resp, WLP_ASSOC_ERROR_INV);
+               if (result < 0) {
+                       dev_err(dev, "WLP: Unable to construct F0 message.\n");
+                       goto out;
+               }
+       }
+       /* Send C2 frame */
+       d_printf(6, dev, "Transmitting response (C2/F0) frame to %02x:%02x \n",
+                src->data[1], src->data[0]);
+       BUG_ON(wlp->xmit_frame == NULL);
+       result = wlp->xmit_frame(wlp, resp, src);
+       if (result < 0) {
+               dev_err(dev, "WLP: Unable to transmit response association "
+                       "message: %d\n", result);
+               if (result == -ENXIO)
+                       dev_err(dev, "WLP: Is network interface up? \n");
+               /* We could try again ... */
+               dev_kfree_skb_any(resp); /* we need to free if tx fails */
+       }
+out:
+       kfree_skb(frame_ctx->skb);
+       kfree(frame_ctx);
+       mutex_unlock(&wss->mutex);
+       d_fnend(6, dev, "WLP: handle C1 frame. wlp = %p\n", wlp);
+}
+
+/**
+ * Handle incoming C3 frame
+ *
+ * The frame has already been verified to contain an Association header with
+ * the correct version number. Parse the incoming frame, construct and send
+ * a C4 frame in response. If the C3 frame identifies a WSS that is locally
+ * active then we connect to this neighbor (add it to our EDA cache).
+ */
+void wlp_handle_c3_frame(struct work_struct *ws)
+{
+       struct wlp_assoc_frame_ctx *frame_ctx = container_of(ws,
+                                                 struct wlp_assoc_frame_ctx,
+                                                 ws);
+       struct wlp *wlp = frame_ctx->wlp;
+       struct wlp_wss *wss = &wlp->wss;
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       struct sk_buff *skb = frame_ctx->skb;
+       struct uwb_dev_addr *src = &frame_ctx->src;
+       int result;
+       char buf[WLP_WSS_UUID_STRSIZE];
+       struct sk_buff *resp = NULL;
+       struct wlp_uuid wssid;
+       u8 tag;
+       struct uwb_mac_addr virt_addr;
+
+       /* Parse C3 frame */
+       d_fnstart(6, dev, "WLP: handle C3 frame. wlp = %p, skb = %p\n",
+                 wlp, skb);
+       mutex_lock(&wss->mutex);
+       result = wlp_parse_c3c4_frame(wlp, skb, &wssid, &tag, &virt_addr);
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain values from C3 frame.\n");
+               goto out;
+       }
+       wlp_wss_uuid_print(buf, sizeof(buf), &wssid);
+       d_printf(6, dev, "Received C3 frame with WSSID %s \n", buf);
+       if (!memcmp(&wssid, &wss->wssid, sizeof(wssid))
+           && wss->state >= WLP_WSS_STATE_ACTIVE) {
+               d_printf(6, dev, "WSSID from C3 frame is known locally "
+                        "and is active\n");
+               result = wlp_eda_update_node(&wlp->eda, src, wss,
+                                            (void *) virt_addr.data, tag,
+                                            WLP_WSS_CONNECTED);
+               if (result < 0) {
+                       dev_err(dev, "WLP: Unable to update EDA cache "
+                               "with new connected neighbor information.\n");
+                       result = wlp_build_assoc_f0(wlp, &resp,
+                                                   WLP_ASSOC_ERROR_INT);
+                       if (result < 0) {
+                               dev_err(dev, "WLP: Unable to construct F0 "
+                                       "message.\n");
+                               goto out;
+                       }
+               } else {
+                       wss->state = WLP_WSS_STATE_CONNECTED;
+                       /* Construct C4 frame */
+                       result = wlp_build_assoc_c4(wlp, wss, &resp);
+                       if (result < 0) {
+                               dev_err(dev, "WLP: Unable to construct C4 "
+                                       "message.\n");
+                               goto out;
+                       }
+               }
+       } else {
+               d_printf(6, dev, "WSSID from C3 frame is not known locally "
+                        "or is not active\n");
+               /* Construct F0 frame */
+               result = wlp_build_assoc_f0(wlp, &resp, WLP_ASSOC_ERROR_INV);
+               if (result < 0) {
+                       dev_err(dev, "WLP: Unable to construct F0 message.\n");
+                       goto out;
+               }
+       }
+       /* Send C4 frame */
+       d_printf(6, dev, "Transmitting response (C4/F0) frame to %02x:%02x \n",
+                src->data[1], src->data[0]);
+       BUG_ON(wlp->xmit_frame == NULL);
+       result = wlp->xmit_frame(wlp, resp, src);
+       if (result < 0) {
+               dev_err(dev, "WLP: Unable to transmit response association "
+                       "message: %d\n", result);
+               if (result == -ENXIO)
+                       dev_err(dev, "WLP: Is network interface up? \n");
+               /* We could try again ... */
+               dev_kfree_skb_any(resp); /* we need to free if tx fails */
+       }
+out:
+       kfree_skb(frame_ctx->skb);
+       kfree(frame_ctx);
+       mutex_unlock(&wss->mutex);
+       d_fnend(6, dev, "WLP: handle C3 frame. wlp = %p, skb = %p\n",
+               wlp, skb);
+}
+
+
diff --git a/drivers/uwb/wlp/sysfs.c b/drivers/uwb/wlp/sysfs.c
new file mode 100644 (file)
index 0000000..1bb9b1f
--- /dev/null
@@ -0,0 +1,709 @@
+/*
+ * WiMedia Logical Link Control Protocol (WLP)
+ * sysfs functions
+ *
+ * Copyright (C) 2007 Intel Corporation
+ * Reinette Chatre <reinette.chatre@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: Docs
+ *
+ */
+
+#include <linux/wlp.h>
+#include "wlp-internal.h"
+
+static
+size_t wlp_wss_wssid_e_print(char *buf, size_t bufsize,
+                            struct wlp_wssid_e *wssid_e)
+{
+       size_t used = 0;
+       used += scnprintf(buf, bufsize, " WSS: ");
+       used += wlp_wss_uuid_print(buf + used, bufsize - used,
+                                  &wssid_e->wssid);
+
+       if (wssid_e->info != NULL) {
+               used += scnprintf(buf + used, bufsize - used, " ");
+               used += uwb_mac_addr_print(buf + used, bufsize - used,
+                                          &wssid_e->info->bcast);
+               used += scnprintf(buf + used, bufsize - used, " %u %u %s\n",
+                                 wssid_e->info->accept_enroll,
+                                 wssid_e->info->sec_status,
+                                 wssid_e->info->name);
+       }
+       return used;
+}
+
+/**
+ * Print out information learned from neighbor discovery
+ *
+ * Some fields being printed may not be included in the device discovery
+ * information (it is not mandatory). We are thus careful how the
+ * information is printed to ensure it is clear to the user what field is
+ * being referenced.
+ * The information being printed is for one time use - temporary storage is
+ * cleaned after it is printed.
+ *
+ * Ideally sysfs output should be on one line. The information printed here
+ * contain a few strings so it will be hard to parse if they are all
+ * printed on the same line - without agreeing on a standard field
+ * separator.
+ */
+static
+ssize_t wlp_wss_neighborhood_print_remove(struct wlp *wlp, char *buf,
+                                  size_t bufsize)
+{
+       size_t used = 0;
+       struct wlp_neighbor_e *neighb;
+       struct wlp_wssid_e *wssid_e;
+
+       mutex_lock(&wlp->nbmutex);
+       used = scnprintf(buf, bufsize, "#Neighbor information\n"
+                        "#uuid dev_addr\n"
+                        "# Device Name:\n# Model Name:\n# Manufacturer:\n"
+                        "# Model Nr:\n# Serial:\n"
+                        "# Pri Dev type: CategoryID OUI OUISubdiv "
+                        "SubcategoryID\n"
+                        "# WSS: WSSID WSS_name accept_enroll sec_status "
+                        "bcast\n"
+                        "# WSS: WSSID WSS_name accept_enroll sec_status "
+                        "bcast\n\n");
+       list_for_each_entry(neighb, &wlp->neighbors, node) {
+               if (bufsize - used <= 0)
+                       goto out;
+               used += wlp_wss_uuid_print(buf + used, bufsize - used,
+                                          &neighb->uuid);
+               buf[used++] = ' ';
+               used += uwb_dev_addr_print(buf + used, bufsize - used,
+                                          &neighb->uwb_dev->dev_addr);
+               if (neighb->info != NULL)
+                       used += scnprintf(buf + used, bufsize - used,
+                                         "\n Device Name: %s\n"
+                                         " Model Name: %s\n"
+                                         " Manufacturer:%s \n"
+                                         " Model Nr: %s\n"
+                                         " Serial: %s\n"
+                                         " Pri Dev type: "
+                                         "%u %02x:%02x:%02x %u %u\n",
+                                         neighb->info->name,
+                                         neighb->info->model_name,
+                                         neighb->info->manufacturer,
+                                         neighb->info->model_nr,
+                                         neighb->info->serial,
+                                         neighb->info->prim_dev_type.category,
+                                         neighb->info->prim_dev_type.OUI[0],
+                                         neighb->info->prim_dev_type.OUI[1],
+                                         neighb->info->prim_dev_type.OUI[2],
+                                         neighb->info->prim_dev_type.OUIsubdiv,
+                                         neighb->info->prim_dev_type.subID);
+               list_for_each_entry(wssid_e, &neighb->wssid, node) {
+                       used += wlp_wss_wssid_e_print(buf + used,
+                                                     bufsize - used,
+                                                     wssid_e);
+               }
+               buf[used++] = '\n';
+               wlp_remove_neighbor_tmp_info(neighb);
+       }
+
+
+out:
+       mutex_unlock(&wlp->nbmutex);
+       return used;
+}
+
+
+/**
+ * Show properties of all WSS in neighborhood.
+ *
+ * Will trigger a complete discovery of WSS activated by this device and
+ * its neighbors.
+ */
+ssize_t wlp_neighborhood_show(struct wlp *wlp, char *buf)
+{
+       wlp_discover(wlp);
+       return wlp_wss_neighborhood_print_remove(wlp, buf, PAGE_SIZE);
+}
+EXPORT_SYMBOL_GPL(wlp_neighborhood_show);
+
+static
+ssize_t __wlp_wss_properties_show(struct wlp_wss *wss, char *buf,
+                                 size_t bufsize)
+{
+       ssize_t result;
+
+       result = wlp_wss_uuid_print(buf, bufsize, &wss->wssid);
+       result += scnprintf(buf + result, bufsize - result, " ");
+       result += uwb_mac_addr_print(buf + result, bufsize - result,
+                                    &wss->bcast);
+       result += scnprintf(buf + result, bufsize - result,
+                           " 0x%02x %u ", wss->hash, wss->secure_status);
+       result += wlp_wss_key_print(buf + result, bufsize - result,
+                                   wss->master_key);
+       result += scnprintf(buf + result, bufsize - result, " 0x%02x ",
+                           wss->tag);
+       result += uwb_mac_addr_print(buf + result, bufsize - result,
+                                    &wss->virtual_addr);
+       result += scnprintf(buf + result, bufsize - result, " %s", wss->name);
+       result += scnprintf(buf + result, bufsize - result,
+                           "\n\n#WSSID\n#WSS broadcast address\n"
+                           "#WSS hash\n#WSS secure status\n"
+                           "#WSS master key\n#WSS local tag\n"
+                           "#WSS local virtual EUI-48\n#WSS name\n");
+       return result;
+}
+
+/**
+ * Show which WSS is activated.
+ */
+ssize_t wlp_wss_activate_show(struct wlp_wss *wss, char *buf)
+{
+       int result = 0;
+
+       if (mutex_lock_interruptible(&wss->mutex))
+               goto out;
+       if (wss->state >= WLP_WSS_STATE_ACTIVE)
+               result = __wlp_wss_properties_show(wss, buf, PAGE_SIZE);
+       else
+               result = scnprintf(buf, PAGE_SIZE, "No local WSS active.\n");
+       result += scnprintf(buf + result, PAGE_SIZE - result,
+                       "\n\n"
+                       "# echo WSSID SECURE_STATUS ACCEPT_ENROLLMENT "
+                       "NAME #create new WSS\n"
+                       "# echo WSSID [DEV ADDR] #enroll in and activate "
+                       "existing WSS, can request registrar\n"
+                       "#\n"
+                       "# WSSID is a 16 byte hex array. Eg. 12 A3 3B ... \n"
+                       "# SECURE_STATUS 0 - unsecure, 1 - secure (default)\n"
+                       "# ACCEPT_ENROLLMENT 0 - no, 1 - yes (default)\n"
+                       "# NAME is the text string identifying the WSS\n"
+                       "# DEV ADDR is the device address of neighbor "
+                       "that should be registrar. Eg. 32:AB\n");
+
+       mutex_unlock(&wss->mutex);
+out:
+       return result;
+
+}
+EXPORT_SYMBOL_GPL(wlp_wss_activate_show);
+
+/**
+ * Create/activate a new WSS or enroll/activate in neighboring WSS
+ *
+ * The user can provide the WSSID of a WSS in which it wants to enroll.
+ * Only the WSSID is necessary if the WSS have been discovered before. If
+ * the WSS has not been discovered before, or the user wants to use a
+ * particular neighbor as its registrar, then the user can also provide a
+ * device address or the neighbor that will be used as registrar.
+ *
+ * A new WSS is created when the user provides a WSSID, secure status, and
+ * WSS name.
+ */
+ssize_t wlp_wss_activate_store(struct wlp_wss *wss,
+                              const char *buf, size_t size)
+{
+       ssize_t result = -EINVAL;
+       struct wlp_uuid wssid;
+       struct uwb_dev_addr dev;
+       struct uwb_dev_addr bcast = {.data = {0xff, 0xff} };
+       char name[65];
+       unsigned sec_status, accept;
+       memset(name, 0, sizeof(name));
+       result = sscanf(buf, "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx:%02hhx",
+                       &wssid.data[0] , &wssid.data[1],
+                       &wssid.data[2] , &wssid.data[3],
+                       &wssid.data[4] , &wssid.data[5],
+                       &wssid.data[6] , &wssid.data[7],
+                       &wssid.data[8] , &wssid.data[9],
+                       &wssid.data[10], &wssid.data[11],
+                       &wssid.data[12], &wssid.data[13],
+                       &wssid.data[14], &wssid.data[15],
+                       &dev.data[1], &dev.data[0]);
+       if (result == 16 || result == 17) {
+               result = sscanf(buf, "%02hhx %02hhx %02hhx %02hhx "
+                               "%02hhx %02hhx %02hhx %02hhx "
+                               "%02hhx %02hhx %02hhx %02hhx "
+                               "%02hhx %02hhx %02hhx %02hhx "
+                               "%u %u %64c",
+                               &wssid.data[0] , &wssid.data[1],
+                               &wssid.data[2] , &wssid.data[3],
+                               &wssid.data[4] , &wssid.data[5],
+                               &wssid.data[6] , &wssid.data[7],
+                               &wssid.data[8] , &wssid.data[9],
+                               &wssid.data[10], &wssid.data[11],
+                               &wssid.data[12], &wssid.data[13],
+                               &wssid.data[14], &wssid.data[15],
+                               &sec_status, &accept, name);
+               if (result == 16)
+                       result = wlp_wss_enroll_activate(wss, &wssid, &bcast);
+               else if (result == 19) {
+                       sec_status = sec_status == 0 ? 0 : 1;
+                       accept = accept == 0 ? 0 : 1;
+                       /* We read name using %c, so the newline needs to be
+                        * removed */
+                       if (strlen(name) != sizeof(name) - 1)
+                               name[strlen(name) - 1] = '\0';
+                       result = wlp_wss_create_activate(wss, &wssid, name,
+                                                        sec_status, accept);
+               } else
+                       result = -EINVAL;
+       } else if (result == 18)
+               result = wlp_wss_enroll_activate(wss, &wssid, &dev);
+       else
+               result = -EINVAL;
+       return result < 0 ? result : size;
+}
+EXPORT_SYMBOL_GPL(wlp_wss_activate_store);
+
+/**
+ * Show the UUID of this host
+ */
+ssize_t wlp_uuid_show(struct wlp *wlp, char *buf)
+{
+       ssize_t result = 0;
+
+       mutex_lock(&wlp->mutex);
+       result = wlp_wss_uuid_print(buf, PAGE_SIZE, &wlp->uuid);
+       buf[result++] = '\n';
+       mutex_unlock(&wlp->mutex);
+       return result;
+}
+EXPORT_SYMBOL_GPL(wlp_uuid_show);
+
+/**
+ * Store a new UUID for this host
+ *
+ * According to the spec this should be encoded as an octet string in the
+ * order the octets are shown in string representation in RFC 4122 (WLP
+ * 0.99 [Table 6])
+ *
+ * We do not check value provided by user.
+ */
+ssize_t wlp_uuid_store(struct wlp *wlp, const char *buf, size_t size)
+{
+       ssize_t result;
+       struct wlp_uuid uuid;
+
+       mutex_lock(&wlp->mutex);
+       result = sscanf(buf, "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx "
+                       "%02hhx %02hhx %02hhx %02hhx ",
+                       &uuid.data[0] , &uuid.data[1],
+                       &uuid.data[2] , &uuid.data[3],
+                       &uuid.data[4] , &uuid.data[5],
+                       &uuid.data[6] , &uuid.data[7],
+                       &uuid.data[8] , &uuid.data[9],
+                       &uuid.data[10], &uuid.data[11],
+                       &uuid.data[12], &uuid.data[13],
+                       &uuid.data[14], &uuid.data[15]);
+       if (result != 16) {
+               result = -EINVAL;
+               goto error;
+       }
+       wlp->uuid = uuid;
+error:
+       mutex_unlock(&wlp->mutex);
+       return result < 0 ? result : size;
+}
+EXPORT_SYMBOL_GPL(wlp_uuid_store);
+
+/**
+ * Show contents of members of device information structure
+ */
+#define wlp_dev_info_show(type)                                                \
+ssize_t wlp_dev_##type##_show(struct wlp *wlp, char *buf)              \
+{                                                                      \
+       ssize_t result = 0;                                             \
+       mutex_lock(&wlp->mutex);                                        \
+       if (wlp->dev_info == NULL) {                                    \
+               result = __wlp_setup_device_info(wlp);                  \
+               if (result < 0)                                         \
+                       goto out;                                       \
+       }                                                               \
+       result = scnprintf(buf, PAGE_SIZE, "%s\n", wlp->dev_info->type);\
+out:                                                                   \
+       mutex_unlock(&wlp->mutex);                                      \
+       return result;                                                  \
+}                                                                      \
+EXPORT_SYMBOL_GPL(wlp_dev_##type##_show);
+
+wlp_dev_info_show(name)
+wlp_dev_info_show(model_name)
+wlp_dev_info_show(model_nr)
+wlp_dev_info_show(manufacturer)
+wlp_dev_info_show(serial)
+
+/**
+ * Store contents of members of device information structure
+ */
+#define wlp_dev_info_store(type, len)                                  \
+ssize_t wlp_dev_##type##_store(struct wlp *wlp, const char *buf, size_t size)\
+{                                                                      \
+       ssize_t result;                                                 \
+       char format[10];                                                \
+       mutex_lock(&wlp->mutex);                                        \
+       if (wlp->dev_info == NULL) {                                    \
+               result = __wlp_alloc_device_info(wlp);                  \
+               if (result < 0)                                         \
+                       goto out;                                       \
+       }                                                               \
+       memset(wlp->dev_info->type, 0, sizeof(wlp->dev_info->type));    \
+       sprintf(format, "%%%uc", len);                                  \
+       result = sscanf(buf, format, wlp->dev_info->type);              \
+out:                                                                   \
+       mutex_unlock(&wlp->mutex);                                      \
+       return result < 0 ? result : size;                              \
+}                                                                      \
+EXPORT_SYMBOL_GPL(wlp_dev_##type##_store);
+
+wlp_dev_info_store(name, 32)
+wlp_dev_info_store(manufacturer, 64)
+wlp_dev_info_store(model_name, 32)
+wlp_dev_info_store(model_nr, 32)
+wlp_dev_info_store(serial, 32)
+
+static
+const char *__wlp_dev_category[] = {
+       [WLP_DEV_CAT_COMPUTER] = "Computer",
+       [WLP_DEV_CAT_INPUT] = "Input device",
+       [WLP_DEV_CAT_PRINT_SCAN_FAX_COPIER] = "Printer, scanner, FAX, or "
+                                             "Copier",
+       [WLP_DEV_CAT_CAMERA] = "Camera",
+       [WLP_DEV_CAT_STORAGE] = "Storage Network",
+       [WLP_DEV_CAT_INFRASTRUCTURE] = "Infrastructure",
+       [WLP_DEV_CAT_DISPLAY] = "Display",
+       [WLP_DEV_CAT_MULTIM] = "Multimedia device",
+       [WLP_DEV_CAT_GAMING] = "Gaming device",
+       [WLP_DEV_CAT_TELEPHONE] = "Telephone",
+       [WLP_DEV_CAT_OTHER] = "Other",
+};
+
+static
+const char *wlp_dev_category_str(unsigned cat)
+{
+       if ((cat >= WLP_DEV_CAT_COMPUTER && cat <= WLP_DEV_CAT_TELEPHONE)
+           || cat == WLP_DEV_CAT_OTHER)
+               return __wlp_dev_category[cat];
+       return "unknown category";
+}
+
+ssize_t wlp_dev_prim_category_show(struct wlp *wlp, char *buf)
+{
+       ssize_t result = 0;
+       mutex_lock(&wlp->mutex);
+       if (wlp->dev_info == NULL) {
+               result = __wlp_setup_device_info(wlp);
+               if (result < 0)
+                       goto out;
+       }
+       result = scnprintf(buf, PAGE_SIZE, "%s\n",
+                 wlp_dev_category_str(wlp->dev_info->prim_dev_type.category));
+out:
+       mutex_unlock(&wlp->mutex);
+       return result;
+}
+EXPORT_SYMBOL_GPL(wlp_dev_prim_category_show);
+
+ssize_t wlp_dev_prim_category_store(struct wlp *wlp, const char *buf,
+                                   size_t size)
+{
+       ssize_t result;
+       u16 cat;
+       mutex_lock(&wlp->mutex);
+       if (wlp->dev_info == NULL) {
+               result = __wlp_alloc_device_info(wlp);
+               if (result < 0)
+                       goto out;
+       }
+       result = sscanf(buf, "%hu", &cat);
+       if ((cat >= WLP_DEV_CAT_COMPUTER && cat <= WLP_DEV_CAT_TELEPHONE)
+           || cat == WLP_DEV_CAT_OTHER)
+               wlp->dev_info->prim_dev_type.category = cat;
+       else
+               result = -EINVAL;
+out:
+       mutex_unlock(&wlp->mutex);
+       return result < 0 ? result : size;
+}
+EXPORT_SYMBOL_GPL(wlp_dev_prim_category_store);
+
+ssize_t wlp_dev_prim_OUI_show(struct wlp *wlp, char *buf)
+{
+       ssize_t result = 0;
+       mutex_lock(&wlp->mutex);
+       if (wlp->dev_info == NULL) {
+               result = __wlp_setup_device_info(wlp);
+               if (result < 0)
+                       goto out;
+       }
+       result = scnprintf(buf, PAGE_SIZE, "%02x:%02x:%02x\n",
+                          wlp->dev_info->prim_dev_type.OUI[0],
+                          wlp->dev_info->prim_dev_type.OUI[1],
+                          wlp->dev_info->prim_dev_type.OUI[2]);
+out:
+       mutex_unlock(&wlp->mutex);
+       return result;
+}
+EXPORT_SYMBOL_GPL(wlp_dev_prim_OUI_show);
+
+ssize_t wlp_dev_prim_OUI_store(struct wlp *wlp, const char *buf, size_t size)
+{
+       ssize_t result;
+       u8 OUI[3];
+       mutex_lock(&wlp->mutex);
+       if (wlp->dev_info == NULL) {
+               result = __wlp_alloc_device_info(wlp);
+               if (result < 0)
+                       goto out;
+       }
+       result = sscanf(buf, "%hhx:%hhx:%hhx",
+                       &OUI[0], &OUI[1], &OUI[2]);
+       if (result != 3) {
+               result = -EINVAL;
+               goto out;
+       } else
+               memcpy(wlp->dev_info->prim_dev_type.OUI, OUI, sizeof(OUI));
+out:
+       mutex_unlock(&wlp->mutex);
+       return result < 0 ? result : size;
+}
+EXPORT_SYMBOL_GPL(wlp_dev_prim_OUI_store);
+
+
+ssize_t wlp_dev_prim_OUI_sub_show(struct wlp *wlp, char *buf)
+{
+       ssize_t result = 0;
+       mutex_lock(&wlp->mutex);
+       if (wlp->dev_info == NULL) {
+               result = __wlp_setup_device_info(wlp);
+               if (result < 0)
+                       goto out;
+       }
+       result = scnprintf(buf, PAGE_SIZE, "%u\n",
+                          wlp->dev_info->prim_dev_type.OUIsubdiv);
+out:
+       mutex_unlock(&wlp->mutex);
+       return result;
+}
+EXPORT_SYMBOL_GPL(wlp_dev_prim_OUI_sub_show);
+
+ssize_t wlp_dev_prim_OUI_sub_store(struct wlp *wlp, const char *buf,
+                                  size_t size)
+{
+       ssize_t result;
+       unsigned sub;
+       u8 max_sub = ~0;
+       mutex_lock(&wlp->mutex);
+       if (wlp->dev_info == NULL) {
+               result = __wlp_alloc_device_info(wlp);
+               if (result < 0)
+                       goto out;
+       }
+       result = sscanf(buf, "%u", &sub);
+       if (sub <= max_sub)
+               wlp->dev_info->prim_dev_type.OUIsubdiv = sub;
+       else
+               result = -EINVAL;
+out:
+       mutex_unlock(&wlp->mutex);
+       return result < 0 ? result : size;
+}
+EXPORT_SYMBOL_GPL(wlp_dev_prim_OUI_sub_store);
+
+ssize_t wlp_dev_prim_subcat_show(struct wlp *wlp, char *buf)
+{
+       ssize_t result = 0;
+       mutex_lock(&wlp->mutex);
+       if (wlp->dev_info == NULL) {
+               result = __wlp_setup_device_info(wlp);
+               if (result < 0)
+                       goto out;
+       }
+       result = scnprintf(buf, PAGE_SIZE, "%u\n",
+                          wlp->dev_info->prim_dev_type.subID);
+out:
+       mutex_unlock(&wlp->mutex);
+       return result;
+}
+EXPORT_SYMBOL_GPL(wlp_dev_prim_subcat_show);
+
+ssize_t wlp_dev_prim_subcat_store(struct wlp *wlp, const char *buf,
+                                 size_t size)
+{
+       ssize_t result;
+       unsigned sub;
+       __le16 max_sub = ~0;
+       mutex_lock(&wlp->mutex);
+       if (wlp->dev_info == NULL) {
+               result = __wlp_alloc_device_info(wlp);
+               if (result < 0)
+                       goto out;
+       }
+       result = sscanf(buf, "%u", &sub);
+       if (sub <= max_sub)
+               wlp->dev_info->prim_dev_type.subID = sub;
+       else
+               result = -EINVAL;
+out:
+       mutex_unlock(&wlp->mutex);
+       return result < 0 ? result : size;
+}
+EXPORT_SYMBOL_GPL(wlp_dev_prim_subcat_store);
+
+/**
+ * Subsystem implementation for interaction with individual WSS via sysfs
+ *
+ * Followed instructions for subsystem in Documentation/filesystems/sysfs.txt
+ */
+
+#define kobj_to_wlp_wss(obj) container_of(obj, struct wlp_wss, kobj)
+#define attr_to_wlp_wss_attr(_attr) \
+       container_of(_attr, struct wlp_wss_attribute, attr)
+
+/**
+ * Sysfs subsystem: forward read calls
+ *
+ * Sysfs operation for forwarding read call to the show method of the
+ * attribute owner
+ */
+static
+ssize_t wlp_wss_attr_show(struct kobject *kobj, struct attribute *attr,
+                         char *buf)
+{
+       struct wlp_wss_attribute *wss_attr = attr_to_wlp_wss_attr(attr);
+       struct wlp_wss *wss = kobj_to_wlp_wss(kobj);
+       ssize_t ret = -EIO;
+
+       if (wss_attr->show)
+               ret = wss_attr->show(wss, buf);
+       return ret;
+}
+/**
+ * Sysfs subsystem: forward write calls
+ *
+ * Sysfs operation for forwarding write call to the store method of the
+ * attribute owner
+ */
+static
+ssize_t wlp_wss_attr_store(struct kobject *kobj, struct attribute *attr,
+                          const char *buf, size_t count)
+{
+       struct wlp_wss_attribute *wss_attr = attr_to_wlp_wss_attr(attr);
+       struct wlp_wss *wss = kobj_to_wlp_wss(kobj);
+       ssize_t ret = -EIO;
+
+       if (wss_attr->store)
+               ret = wss_attr->store(wss, buf, count);
+       return ret;
+}
+
+static
+struct sysfs_ops wss_sysfs_ops = {
+       .show   = wlp_wss_attr_show,
+       .store  = wlp_wss_attr_store,
+};
+
+struct kobj_type wss_ktype = {
+       .release        = wlp_wss_release,
+       .sysfs_ops      = &wss_sysfs_ops,
+};
+
+
+/**
+ * Sysfs files for individual WSS
+ */
+
+/**
+ * Print static properties of this WSS
+ *
+ * The name of a WSS may not be null teminated. It's max size is 64 bytes
+ * so we copy it to a larger array just to make sure we print sane data.
+ */
+static ssize_t wlp_wss_properties_show(struct wlp_wss *wss, char *buf)
+{
+       int result = 0;
+
+       if (mutex_lock_interruptible(&wss->mutex))
+               goto out;
+       result = __wlp_wss_properties_show(wss, buf, PAGE_SIZE);
+       mutex_unlock(&wss->mutex);
+out:
+       return result;
+}
+WSS_ATTR(properties, S_IRUGO, wlp_wss_properties_show, NULL);
+
+/**
+ * Print all connected members of this WSS
+ * The EDA cache contains all members of WSS neighborhood.
+ */
+static ssize_t wlp_wss_members_show(struct wlp_wss *wss, char *buf)
+{
+       struct wlp *wlp = container_of(wss, struct wlp, wss);
+       return wlp_eda_show(wlp, buf);
+}
+WSS_ATTR(members, S_IRUGO, wlp_wss_members_show, NULL);
+
+static
+const char *__wlp_strstate[] = {
+       "none",
+       "partially enrolled",
+       "enrolled",
+       "active",
+       "connected",
+};
+
+static const char *wlp_wss_strstate(unsigned state)
+{
+       if (state >= ARRAY_SIZE(__wlp_strstate))
+               return "unknown state";
+       return __wlp_strstate[state];
+}
+
+/*
+ * Print current state of this WSS
+ */
+static ssize_t wlp_wss_state_show(struct wlp_wss *wss, char *buf)
+{
+       int result = 0;
+
+       if (mutex_lock_interruptible(&wss->mutex))
+               goto out;
+       result = scnprintf(buf, PAGE_SIZE, "%s\n",
+                          wlp_wss_strstate(wss->state));
+       mutex_unlock(&wss->mutex);
+out:
+       return result;
+}
+WSS_ATTR(state, S_IRUGO, wlp_wss_state_show, NULL);
+
+
+static
+struct attribute *wss_attrs[] = {
+       &wss_attr_properties.attr,
+       &wss_attr_members.attr,
+       &wss_attr_state.attr,
+       NULL,
+};
+
+struct attribute_group wss_attr_group = {
+       .name = NULL,   /* we want them in the same directory */
+       .attrs = wss_attrs,
+};
diff --git a/drivers/uwb/wlp/txrx.c b/drivers/uwb/wlp/txrx.c
new file mode 100644 (file)
index 0000000..c701bd1
--- /dev/null
@@ -0,0 +1,374 @@
+/*
+ * WiMedia Logical Link Control Protocol (WLP)
+ * Message exchange infrastructure
+ *
+ * Copyright (C) 2007 Intel Corporation
+ * Reinette Chatre <reinette.chatre@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: Docs
+ *
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/wlp.h>
+#define D_LOCAL 5
+#include <linux/uwb/debug.h>
+#include "wlp-internal.h"
+
+
+/**
+ * Direct incoming association msg to correct parsing routine
+ *
+ * We only expect D1, E1, C1, C3 messages as new. All other incoming
+ * association messages should form part of an established session that is
+ * handled elsewhere.
+ * The handling of these messages often require calling sleeping functions
+ * - this cannot be done in interrupt context. We use the kernel's
+ * workqueue to handle these messages.
+ */
+static
+void wlp_direct_assoc_frame(struct wlp *wlp, struct sk_buff *skb,
+                          struct uwb_dev_addr *src)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       struct wlp_frame_assoc *assoc = (void *) skb->data;
+       struct wlp_assoc_frame_ctx *frame_ctx;
+       d_fnstart(5, dev, "wlp %p, skb %p\n", wlp, skb);
+       frame_ctx = kmalloc(sizeof(*frame_ctx), GFP_ATOMIC);
+       if (frame_ctx == NULL) {
+               dev_err(dev, "WLP: Unable to allocate memory for association "
+                       "frame handling.\n");
+               kfree_skb(skb);
+               goto out;
+       }
+       frame_ctx->wlp = wlp;
+       frame_ctx->skb = skb;
+       frame_ctx->src = *src;
+       switch (assoc->type) {
+       case WLP_ASSOC_D1:
+               d_printf(5, dev, "Received a D1 frame.\n");
+               INIT_WORK(&frame_ctx->ws, wlp_handle_d1_frame);
+               schedule_work(&frame_ctx->ws);
+               break;
+       case WLP_ASSOC_E1:
+               d_printf(5, dev, "Received a E1 frame. FIXME?\n");
+               kfree_skb(skb); /* Temporary until we handle it */
+               kfree(frame_ctx); /* Temporary until we handle it */
+               break;
+       case WLP_ASSOC_C1:
+               d_printf(5, dev, "Received a C1 frame.\n");
+               INIT_WORK(&frame_ctx->ws, wlp_handle_c1_frame);
+               schedule_work(&frame_ctx->ws);
+               break;
+       case WLP_ASSOC_C3:
+               d_printf(5, dev, "Received a C3 frame.\n");
+               INIT_WORK(&frame_ctx->ws, wlp_handle_c3_frame);
+               schedule_work(&frame_ctx->ws);
+               break;
+       default:
+               dev_err(dev, "Received unexpected association frame. "
+                       "Type = %d \n", assoc->type);
+               kfree_skb(skb);
+               kfree(frame_ctx);
+               break;
+       }
+out:
+       d_fnend(5, dev, "wlp %p\n", wlp);
+}
+
+/**
+ * Process incoming association frame
+ *
+ * Although it could be possible to deal with some incoming association
+ * messages without creating a new session we are keeping things simple. We
+ * do not accept new association messages if there is a session in progress
+ * and the messages do not belong to that session.
+ *
+ * If an association message arrives that causes the creation of a session
+ * (WLP_ASSOC_E1) while we are in the process of creating a session then we
+ * rely on the neighbor mutex to protect the data. That is, the new session
+ * will not be started until the previous is completed.
+ */
+static
+void wlp_receive_assoc_frame(struct wlp *wlp, struct sk_buff *skb,
+                            struct uwb_dev_addr *src)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       struct wlp_frame_assoc *assoc = (void *) skb->data;
+       struct wlp_session *session = wlp->session;
+       u8 version;
+       d_fnstart(5, dev, "wlp %p, skb %p\n", wlp, skb);
+
+       if (wlp_get_version(wlp, &assoc->version, &version,
+                           sizeof(assoc->version)) < 0)
+               goto error;
+       if (version != WLP_VERSION) {
+               dev_err(dev, "Unsupported WLP version in association "
+                       "message.\n");
+               goto error;
+       }
+       if (session != NULL) {
+               /* Function that created this session is still holding the
+                * &wlp->mutex to protect this session. */
+               if (assoc->type == session->exp_message ||
+                   assoc->type == WLP_ASSOC_F0) {
+                       if (!memcmp(&session->neighbor_addr, src,
+                                  sizeof(*src))) {
+                               session->data = skb;
+                               (session->cb)(wlp);
+                       } else {
+                               dev_err(dev, "Received expected message from "
+                                       "unexpected source.  Expected message "
+                                       "%d or F0 from %02x:%02x, but received "
+                                       "it from %02x:%02x. Dropping.\n",
+                                       session->exp_message,
+                                       session->neighbor_addr.data[1],
+                                       session->neighbor_addr.data[0],
+                                       src->data[1], src->data[0]);
+                               goto error;
+                       }
+               } else {
+                       dev_err(dev, "Association already in progress. "
+                               "Dropping.\n");
+                       goto error;
+               }
+       } else {
+               wlp_direct_assoc_frame(wlp, skb, src);
+       }
+       d_fnend(5, dev, "wlp %p\n", wlp);
+       return;
+error:
+       kfree_skb(skb);
+       d_fnend(5, dev, "wlp %p\n", wlp);
+}
+
+/**
+ * Verify incoming frame is from connected neighbor, prep to pass to WLP client
+ *
+ * Verification proceeds according to WLP 0.99 [7.3.1]. The source address
+ * is used to determine which neighbor is sending the frame and the WSS tag
+ * is used to know to which WSS the frame belongs (we only support one WSS
+ * so this test is straight forward).
+ * With the WSS found we need to ensure that we are connected before
+ * allowing the exchange of data frames.
+ */
+static
+int wlp_verify_prep_rx_frame(struct wlp *wlp, struct sk_buff *skb,
+                            struct uwb_dev_addr *src)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       int result = -EINVAL;
+       struct wlp_eda_node eda_entry;
+       struct wlp_frame_std_abbrv_hdr *hdr = (void *) skb->data;
+
+       d_fnstart(6, dev, "wlp %p, skb %p \n", wlp, skb);
+       /*verify*/
+       result = wlp_copy_eda_node(&wlp->eda, src, &eda_entry);
+       if (result < 0) {
+               if (printk_ratelimit())
+                       dev_err(dev, "WLP: Incoming frame is from unknown "
+                               "neighbor %02x:%02x.\n", src->data[1],
+                               src->data[0]);
+               goto out;
+       }
+       if (hdr->tag != eda_entry.tag) {
+               if (printk_ratelimit())
+                       dev_err(dev, "WLP: Tag of incoming frame from "
+                               "%02x:%02x does not match expected tag. "
+                               "Received 0x%02x, expected 0x%02x. \n",
+                               src->data[1], src->data[0], hdr->tag,
+                               eda_entry.tag);
+               result = -EINVAL;
+               goto out;
+       }
+       if (eda_entry.state != WLP_WSS_CONNECTED) {
+               if (printk_ratelimit())
+                       dev_err(dev, "WLP: Incoming frame from "
+                               "%02x:%02x does is not from connected WSS.\n",
+                               src->data[1], src->data[0]);
+               result = -EINVAL;
+               goto out;
+       }
+       /*prep*/
+       skb_pull(skb, sizeof(*hdr));
+out:
+       d_fnend(6, dev, "wlp %p, skb %p, result = %d \n", wlp, skb, result);
+       return result;
+}
+
+/**
+ * Receive a WLP frame from device
+ *
+ * @returns: 1 if calling function should free the skb
+ *           0 if it successfully handled skb and freed it
+ *           0 if error occured, will free skb in this case
+ */
+int wlp_receive_frame(struct device *dev, struct wlp *wlp, struct sk_buff *skb,
+                     struct uwb_dev_addr *src)
+{
+       unsigned len = skb->len;
+       void *ptr = skb->data;
+       struct wlp_frame_hdr *hdr;
+       int result = 0;
+
+       d_fnstart(6, dev, "skb (%p), len (%u)\n", skb, len);
+       if (len < sizeof(*hdr)) {
+               dev_err(dev, "Not enough data to parse WLP header.\n");
+               result = -EINVAL;
+               goto out;
+       }
+       hdr = ptr;
+       d_dump(6, dev, hdr, sizeof(*hdr));
+       if (le16_to_cpu(hdr->mux_hdr) != WLP_PROTOCOL_ID) {
+               dev_err(dev, "Not a WLP frame type.\n");
+               result = -EINVAL;
+               goto out;
+       }
+       switch (hdr->type) {
+       case WLP_FRAME_STANDARD:
+               if (len < sizeof(struct wlp_frame_std_abbrv_hdr)) {
+                       dev_err(dev, "Not enough data to parse Standard "
+                               "WLP header.\n");
+                       goto out;
+               }
+               result = wlp_verify_prep_rx_frame(wlp, skb, src);
+               if (result < 0) {
+                       if (printk_ratelimit())
+                               dev_err(dev, "WLP: Verification of frame "
+                                       "from neighbor %02x:%02x failed.\n",
+                                       src->data[1], src->data[0]);
+                       goto out;
+               }
+               result = 1;
+               break;
+       case WLP_FRAME_ABBREVIATED:
+               dev_err(dev, "Abbreviated frame received. FIXME?\n");
+               kfree_skb(skb);
+               break;
+       case WLP_FRAME_CONTROL:
+               dev_err(dev, "Control frame received. FIXME?\n");
+               kfree_skb(skb);
+               break;
+       case WLP_FRAME_ASSOCIATION:
+               if (len < sizeof(struct wlp_frame_assoc)) {
+                       dev_err(dev, "Not enough data to parse Association "
+                               "WLP header.\n");
+                       goto out;
+               }
+               d_printf(5, dev, "Association frame received.\n");
+               wlp_receive_assoc_frame(wlp, skb, src);
+               break;
+       default:
+               dev_err(dev, "Invalid frame received.\n");
+               result = -EINVAL;
+               break;
+       }
+out:
+       if (result < 0) {
+               kfree_skb(skb);
+               result = 0;
+       }
+       d_fnend(6, dev, "skb (%p)\n", skb);
+       return result;
+}
+EXPORT_SYMBOL_GPL(wlp_receive_frame);
+
+
+/**
+ * Verify frame from network stack, prepare for further transmission
+ *
+ * @skb:   the socket buffer that needs to be prepared for transmission (it
+ *         is in need of a WLP header). If this is a broadcast frame we take
+ *         over the entire transmission.
+ *         If it is a unicast the WSS connection should already be established
+ *         and transmission will be done by the calling function.
+ * @dst:   On return this will contain the device address to which the
+ *         frame is destined.
+ * @returns: 0 on success no tx : WLP header sucessfully applied to skb buffer,
+ *                                calling function can proceed with tx
+ *           1 on success with tx : WLP will take over transmission of this
+ *                                  frame
+ *           <0 on error
+ *
+ * The network stack (WLP client) is attempting to transmit a frame. We can
+ * only transmit data if a local WSS is at least active (connection will be
+ * done here if this is a broadcast frame and neighbor also has the WSS
+ * active).
+ *
+ * The frame can be either broadcast or unicast. Broadcast in a WSS is
+ * supported via multicast, but we don't support multicast yet (until
+ * devices start to support MAB IEs). If a broadcast frame needs to be
+ * transmitted it is treated as a unicast frame to each neighbor. In this
+ * case the WLP takes over transmission of the skb and returns 1
+ * to the caller to indicate so. Also, in this case, if a neighbor has the
+ * same WSS activated but is not connected then the WSS connection will be
+ * done at this time. The neighbor's virtual address will be learned at
+ * this time.
+ *
+ * The destination address in a unicast frame is the virtual address of the
+ * neighbor. This address only becomes known when a WSS connection is
+ * established. We thus rely on a broadcast frame to trigger the setup of
+ * WSS connections to all neighbors before we are able to send unicast
+ * frames to them. This seems reasonable as IP would usually use ARP first
+ * before any unicast frames are sent.
+ *
+ * If we are already connected to the neighbor (neighbor's virtual address
+ * is known) we just prepare the WLP header and the caller will continue to
+ * send the frame.
+ *
+ * A failure in this function usually indicates something that cannot be
+ * fixed automatically. So, if this function fails (@return < 0) the calling
+ * function should not retry to send the frame as it will very likely keep
+ * failing.
+ *
+ */
+int wlp_prepare_tx_frame(struct device *dev, struct wlp *wlp,
+                        struct sk_buff *skb, struct uwb_dev_addr *dst)
+{
+       int result = -EINVAL;
+       struct ethhdr *eth_hdr = (void *) skb->data;
+
+       d_fnstart(6, dev, "wlp (%p), skb (%p) \n", wlp, skb);
+       if (is_broadcast_ether_addr(eth_hdr->h_dest)) {
+               d_printf(6, dev, "WLP: handling broadcast frame. \n");
+               result = wlp_eda_for_each(&wlp->eda, wlp_wss_send_copy, skb);
+               if (result < 0) {
+                       if (printk_ratelimit())
+                               dev_err(dev, "Unable to handle broadcast "
+                                       "frame from WLP client.\n");
+                       goto out;
+               }
+               dev_kfree_skb_irq(skb);
+               result = 1;
+               /* Frame will be transmitted by WLP. */
+       } else {
+               d_printf(6, dev, "WLP: handling unicast frame. \n");
+               result = wlp_eda_for_virtual(&wlp->eda, eth_hdr->h_dest, dst,
+                                            wlp_wss_prep_hdr, skb);
+               if (unlikely(result < 0)) {
+                       if (printk_ratelimit())
+                               dev_err(dev, "Unable to prepare "
+                                       "skb for transmission. \n");
+                       goto out;
+               }
+       }
+out:
+       d_fnend(6, dev, "wlp (%p), skb (%p). result = %d \n", wlp, skb, result);
+       return result;
+}
+EXPORT_SYMBOL_GPL(wlp_prepare_tx_frame);
diff --git a/drivers/uwb/wlp/wlp-internal.h b/drivers/uwb/wlp/wlp-internal.h
new file mode 100644 (file)
index 0000000..1c94fab
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * WiMedia Logical Link Control Protocol (WLP)
+ * Internal API
+ *
+ * Copyright (C) 2007 Intel Corporation
+ * Reinette Chatre <reinette.chatre@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#ifndef __WLP_INTERNAL_H__
+#define __WLP_INTERNAL_H__
+
+/**
+ * State of WSS connection
+ *
+ * A device needs to connect to a neighbor in an activated WSS before data
+ * can be transmitted. The spec also distinguishes between a new connection
+ * attempt and a connection attempt after previous connection attempts. The
+ * state WLP_WSS_CONNECT_FAILED is used for this scenario. See WLP 0.99
+ * [7.2.6]
+ */
+enum wlp_wss_connect {
+       WLP_WSS_UNCONNECTED = 0,
+       WLP_WSS_CONNECTED,
+       WLP_WSS_CONNECT_FAILED,
+};
+
+extern struct kobj_type wss_ktype;
+extern struct attribute_group wss_attr_group;
+
+extern int uwb_rc_ie_add(struct uwb_rc *, const struct uwb_ie_hdr *, size_t);
+extern int uwb_rc_ie_rm(struct uwb_rc *, enum uwb_ie);
+
+
+/* This should be changed to a dynamic array where entries are sorted
+ * by eth_addr and search is done in a binary form
+ *
+ * Although thinking twice about it: this technologie's maximum reach
+ * is 10 meters...unless you want to pack too much stuff in around
+ * your radio controller/WLP device, the list will probably not be
+ * too big.
+ *
+ * In any case, there is probably some data structure in the kernel
+ * than we could reused for that already.
+ *
+ * The below structure is really just good while we support one WSS per
+ * host.
+ */
+struct wlp_eda_node {
+       struct list_head list_node;
+       unsigned char eth_addr[ETH_ALEN];
+       struct uwb_dev_addr dev_addr;
+       struct wlp_wss *wss;
+       unsigned char virt_addr[ETH_ALEN];
+       u8 tag;
+       enum wlp_wss_connect state;
+};
+
+typedef int (*wlp_eda_for_each_f)(struct wlp *, struct wlp_eda_node *, void *);
+
+extern void wlp_eda_init(struct wlp_eda *);
+extern void wlp_eda_release(struct wlp_eda *);
+extern int wlp_eda_create_node(struct wlp_eda *,
+                              const unsigned char eth_addr[ETH_ALEN],
+                              const struct uwb_dev_addr *);
+extern void wlp_eda_rm_node(struct wlp_eda *, const struct uwb_dev_addr *);
+extern int wlp_eda_update_node(struct wlp_eda *,
+                              const struct uwb_dev_addr *,
+                              struct wlp_wss *,
+                              const unsigned char virt_addr[ETH_ALEN],
+                              const u8, const enum wlp_wss_connect);
+extern int wlp_eda_update_node_state(struct wlp_eda *,
+                                    const struct uwb_dev_addr *,
+                                    const enum wlp_wss_connect);
+
+extern int wlp_copy_eda_node(struct wlp_eda *, struct uwb_dev_addr *,
+                            struct wlp_eda_node *);
+extern int wlp_eda_for_each(struct wlp_eda *, wlp_eda_for_each_f , void *);
+extern int wlp_eda_for_virtual(struct wlp_eda *,
+                              const unsigned char eth_addr[ETH_ALEN],
+                              struct uwb_dev_addr *,
+                              wlp_eda_for_each_f , void *);
+
+
+extern void wlp_remove_neighbor_tmp_info(struct wlp_neighbor_e *);
+
+extern size_t wlp_wss_key_print(char *, size_t, u8 *);
+
+/* Function called when no more references to WSS exists */
+extern void wlp_wss_release(struct kobject *);
+
+extern void wlp_wss_reset(struct wlp_wss *);
+extern int wlp_wss_create_activate(struct wlp_wss *, struct wlp_uuid *,
+                                  char *, unsigned, unsigned);
+extern int wlp_wss_enroll_activate(struct wlp_wss *, struct wlp_uuid *,
+                                  struct uwb_dev_addr *);
+extern ssize_t wlp_discover(struct wlp *);
+
+extern int wlp_enroll_neighbor(struct wlp *, struct wlp_neighbor_e *,
+                              struct wlp_wss *, struct wlp_uuid *);
+extern int wlp_wss_is_active(struct wlp *, struct wlp_wss *,
+                            struct uwb_dev_addr *);
+
+struct wlp_assoc_conn_ctx {
+       struct work_struct ws;
+       struct wlp *wlp;
+       struct sk_buff *skb;
+       struct wlp_eda_node eda_entry;
+};
+
+
+extern int wlp_wss_connect_prep(struct wlp *, struct wlp_eda_node *, void *);
+extern int wlp_wss_send_copy(struct wlp *, struct wlp_eda_node *, void *);
+
+
+/* Message handling */
+struct wlp_assoc_frame_ctx {
+       struct work_struct ws;
+       struct wlp *wlp;
+       struct sk_buff *skb;
+       struct uwb_dev_addr src;
+};
+
+extern int wlp_wss_prep_hdr(struct wlp *, struct wlp_eda_node *, void *);
+extern void wlp_handle_d1_frame(struct work_struct *);
+extern int wlp_parse_d2_frame_to_cache(struct wlp *, struct sk_buff *,
+                                      struct wlp_neighbor_e *);
+extern int wlp_parse_d2_frame_to_enroll(struct wlp_wss *, struct sk_buff *,
+                                       struct wlp_neighbor_e *,
+                                       struct wlp_uuid *);
+extern void wlp_handle_c1_frame(struct work_struct *);
+extern void wlp_handle_c3_frame(struct work_struct *);
+extern int wlp_parse_c3c4_frame(struct wlp *, struct sk_buff *,
+                               struct wlp_uuid *, u8 *,
+                               struct uwb_mac_addr *);
+extern int wlp_parse_f0(struct wlp *, struct sk_buff *);
+extern int wlp_send_assoc_frame(struct wlp *, struct wlp_wss *,
+                               struct uwb_dev_addr *, enum wlp_assoc_type);
+extern ssize_t wlp_get_version(struct wlp *, struct wlp_attr_version *,
+                              u8 *, ssize_t);
+extern ssize_t wlp_get_wssid(struct wlp *, struct wlp_attr_wssid *,
+                            struct wlp_uuid *, ssize_t);
+extern int __wlp_alloc_device_info(struct wlp *);
+extern int __wlp_setup_device_info(struct wlp *);
+
+extern struct wlp_wss_attribute wss_attribute_properties;
+extern struct wlp_wss_attribute wss_attribute_members;
+extern struct wlp_wss_attribute wss_attribute_state;
+
+static inline
+size_t wlp_wss_uuid_print(char *buf, size_t bufsize, struct wlp_uuid *uuid)
+{
+       size_t result;
+
+       result = scnprintf(buf, bufsize,
+                         "%02x:%02x:%02x:%02x:%02x:%02x:"
+                         "%02x:%02x:%02x:%02x:%02x:%02x:"
+                         "%02x:%02x:%02x:%02x",
+                         uuid->data[0], uuid->data[1],
+                         uuid->data[2], uuid->data[3],
+                         uuid->data[4], uuid->data[5],
+                         uuid->data[6], uuid->data[7],
+                         uuid->data[8], uuid->data[9],
+                         uuid->data[10], uuid->data[11],
+                         uuid->data[12], uuid->data[13],
+                         uuid->data[14], uuid->data[15]);
+       return result;
+}
+
+/**
+ * FIXME: How should a nonce be displayed?
+ */
+static inline
+size_t wlp_wss_nonce_print(char *buf, size_t bufsize, struct wlp_nonce *nonce)
+{
+       size_t result;
+
+       result = scnprintf(buf, bufsize,
+                         "%02x %02x %02x %02x %02x %02x "
+                         "%02x %02x %02x %02x %02x %02x "
+                         "%02x %02x %02x %02x",
+                         nonce->data[0], nonce->data[1],
+                         nonce->data[2], nonce->data[3],
+                         nonce->data[4], nonce->data[5],
+                         nonce->data[6], nonce->data[7],
+                         nonce->data[8], nonce->data[9],
+                         nonce->data[10], nonce->data[11],
+                         nonce->data[12], nonce->data[13],
+                         nonce->data[14], nonce->data[15]);
+       return result;
+}
+
+
+static inline
+void wlp_session_cb(struct wlp *wlp)
+{
+       struct completion *completion = wlp->session->cb_priv;
+       complete(completion);
+}
+
+static inline
+int wlp_uuid_is_set(struct wlp_uuid *uuid)
+{
+       struct wlp_uuid zero_uuid = { .data = { 0x00, 0x00, 0x00, 0x00,
+                                               0x00, 0x00, 0x00, 0x00,
+                                               0x00, 0x00, 0x00, 0x00,
+                                               0x00, 0x00, 0x00, 0x00} };
+
+       if (!memcmp(uuid, &zero_uuid, sizeof(*uuid)))
+               return 0;
+       return 1;
+}
+
+#endif /* __WLP_INTERNAL_H__ */
diff --git a/drivers/uwb/wlp/wlp-lc.c b/drivers/uwb/wlp/wlp-lc.c
new file mode 100644 (file)
index 0000000..0799402
--- /dev/null
@@ -0,0 +1,585 @@
+/*
+ * WiMedia Logical Link Control Protocol (WLP)
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Reinette Chatre <reinette.chatre@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ */
+
+#include <linux/wlp.h>
+#define D_LOCAL 6
+#include <linux/uwb/debug.h>
+#include "wlp-internal.h"
+
+
+static
+void wlp_neighbor_init(struct wlp_neighbor_e *neighbor)
+{
+       INIT_LIST_HEAD(&neighbor->wssid);
+}
+
+/**
+ * Create area for device information storage
+ *
+ * wlp->mutex must be held
+ */
+int __wlp_alloc_device_info(struct wlp *wlp)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       BUG_ON(wlp->dev_info != NULL);
+       wlp->dev_info = kzalloc(sizeof(struct wlp_device_info), GFP_KERNEL);
+       if (wlp->dev_info == NULL) {
+               dev_err(dev, "WLP: Unable to allocate memory for "
+                       "device information.\n");
+               return -ENOMEM;
+       }
+       return 0;
+}
+
+
+/**
+ * Fill in device information using function provided by driver
+ *
+ * wlp->mutex must be held
+ */
+static
+void __wlp_fill_device_info(struct wlp *wlp)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+
+       BUG_ON(wlp->fill_device_info == NULL);
+       d_printf(6, dev, "Retrieving device information "
+                        "from device driver.\n");
+       wlp->fill_device_info(wlp, wlp->dev_info);
+}
+
+/**
+ * Setup device information
+ *
+ * Allocate area for device information and populate it.
+ *
+ * wlp->mutex must be held
+ */
+int __wlp_setup_device_info(struct wlp *wlp)
+{
+       int result;
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+
+       result = __wlp_alloc_device_info(wlp);
+       if (result < 0) {
+               dev_err(dev, "WLP: Unable to allocate area for "
+                       "device information.\n");
+               return result;
+       }
+       __wlp_fill_device_info(wlp);
+       return 0;
+}
+
+/**
+ * Remove information about neighbor stored temporarily
+ *
+ * Information learned during discovey should only be stored when the
+ * device enrolls in the neighbor's WSS. We do need to store this
+ * information temporarily in order to present it to the user.
+ *
+ * We are only interested in keeping neighbor WSS information if that
+ * neighbor is accepting enrollment.
+ *
+ * should be called with wlp->nbmutex held
+ */
+void wlp_remove_neighbor_tmp_info(struct wlp_neighbor_e *neighbor)
+{
+       struct wlp_wssid_e *wssid_e, *next;
+       u8 keep;
+       if (!list_empty(&neighbor->wssid)) {
+               list_for_each_entry_safe(wssid_e, next, &neighbor->wssid,
+                                        node) {
+                       if (wssid_e->info != NULL) {
+                               keep = wssid_e->info->accept_enroll;
+                               kfree(wssid_e->info);
+                               wssid_e->info = NULL;
+                               if (!keep) {
+                                       list_del(&wssid_e->node);
+                                       kfree(wssid_e);
+                               }
+                       }
+               }
+       }
+       if (neighbor->info != NULL) {
+               kfree(neighbor->info);
+               neighbor->info = NULL;
+       }
+}
+
+/**
+ * Populate WLP neighborhood cache with neighbor information
+ *
+ * A new neighbor is found. If it is discoverable then we add it to the
+ * neighborhood cache.
+ *
+ */
+static
+int wlp_add_neighbor(struct wlp *wlp, struct uwb_dev *dev)
+{
+       int result = 0;
+       int discoverable;
+       struct wlp_neighbor_e *neighbor;
+
+       d_fnstart(6, &dev->dev, "uwb %p \n", dev);
+       d_printf(6, &dev->dev, "Found neighbor device %02x:%02x \n",
+                dev->dev_addr.data[1], dev->dev_addr.data[0]);
+       /**
+        * FIXME:
+        * Use contents of WLP IE found in beacon cache to determine if
+        * neighbor is discoverable.
+        * The device does not support WLP IE yet so this still needs to be
+        * done. Until then we assume all devices are discoverable.
+        */
+       discoverable = 1; /* will be changed when FIXME disappears */
+       if (discoverable) {
+               /* Add neighbor to cache for discovery */
+               neighbor = kzalloc(sizeof(*neighbor), GFP_KERNEL);
+               if (neighbor == NULL) {
+                       dev_err(&dev->dev, "Unable to create memory for "
+                               "new neighbor. \n");
+                       result = -ENOMEM;
+                       goto error_no_mem;
+               }
+               wlp_neighbor_init(neighbor);
+               uwb_dev_get(dev);
+               neighbor->uwb_dev = dev;
+               list_add(&neighbor->node, &wlp->neighbors);
+       }
+error_no_mem:
+       d_fnend(6, &dev->dev, "uwb %p, result = %d \n", dev, result);
+       return result;
+}
+
+/**
+ * Remove one neighbor from cache
+ */
+static
+void __wlp_neighbor_release(struct wlp_neighbor_e *neighbor)
+{
+       struct wlp_wssid_e *wssid_e, *next_wssid_e;
+
+       list_for_each_entry_safe(wssid_e, next_wssid_e,
+                                &neighbor->wssid, node) {
+               list_del(&wssid_e->node);
+               kfree(wssid_e);
+       }
+       uwb_dev_put(neighbor->uwb_dev);
+       list_del(&neighbor->node);
+       kfree(neighbor);
+}
+
+/**
+ * Clear entire neighborhood cache.
+ */
+static
+void __wlp_neighbors_release(struct wlp *wlp)
+{
+       struct wlp_neighbor_e *neighbor, *next;
+       if (list_empty(&wlp->neighbors))
+               return;
+       list_for_each_entry_safe(neighbor, next, &wlp->neighbors, node) {
+               __wlp_neighbor_release(neighbor);
+       }
+}
+
+static
+void wlp_neighbors_release(struct wlp *wlp)
+{
+       mutex_lock(&wlp->nbmutex);
+       __wlp_neighbors_release(wlp);
+       mutex_unlock(&wlp->nbmutex);
+}
+
+
+
+/**
+ * Send D1 message to neighbor, receive D2 message
+ *
+ * @neighbor: neighbor to which D1 message will be sent
+ * @wss:      if not NULL, it is an enrollment request for this WSS
+ * @wssid:    if wss not NULL, this is the wssid of the WSS in which we
+ *            want to enroll
+ *
+ * A D1/D2 exchange is done for one of two reasons: discovery or
+ * enrollment. If done for discovery the D1 message is sent to the neighbor
+ * and the contents of the D2 response is stored in a temporary cache.
+ * If done for enrollment the @wss and @wssid are provided also. In this
+ * case the D1 message is sent to the neighbor, the D2 response is parsed
+ * for enrollment of the WSS with wssid.
+ *
+ * &wss->mutex is held
+ */
+static
+int wlp_d1d2_exchange(struct wlp *wlp, struct wlp_neighbor_e *neighbor,
+                     struct wlp_wss *wss, struct wlp_uuid *wssid)
+{
+       int result;
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       DECLARE_COMPLETION_ONSTACK(completion);
+       struct wlp_session session;
+       struct sk_buff  *skb;
+       struct wlp_frame_assoc *resp;
+       struct uwb_dev_addr *dev_addr = &neighbor->uwb_dev->dev_addr;
+
+       mutex_lock(&wlp->mutex);
+       if (!wlp_uuid_is_set(&wlp->uuid)) {
+               dev_err(dev, "WLP: UUID is not set. Set via sysfs to "
+                       "proceed.\n");
+               result = -ENXIO;
+               goto out;
+       }
+       /* Send D1 association frame */
+       result = wlp_send_assoc_frame(wlp, wss, dev_addr, WLP_ASSOC_D1);
+       if (result < 0) {
+               dev_err(dev, "Unable to send D1 frame to neighbor "
+                       "%02x:%02x (%d)\n", dev_addr->data[1],
+                       dev_addr->data[0], result);
+               d_printf(6, dev, "Add placeholders into buffer next to "
+                        "neighbor information we have (dev address).\n");
+               goto out;
+       }
+       /* Create session, wait for response */
+       session.exp_message = WLP_ASSOC_D2;
+       session.cb = wlp_session_cb;
+       session.cb_priv = &completion;
+       session.neighbor_addr = *dev_addr;
+       BUG_ON(wlp->session != NULL);
+       wlp->session = &session;
+       /* Wait for D2/F0 frame */
+       result = wait_for_completion_interruptible_timeout(&completion,
+                                                  WLP_PER_MSG_TIMEOUT * HZ);
+       if (result == 0) {
+               result = -ETIMEDOUT;
+               dev_err(dev, "Timeout while sending D1 to neighbor "
+                            "%02x:%02x.\n", dev_addr->data[1],
+                            dev_addr->data[0]);
+               goto error_session;
+       }
+       if (result < 0) {
+               dev_err(dev, "Unable to discover/enroll neighbor %02x:%02x.\n",
+                       dev_addr->data[1], dev_addr->data[0]);
+               goto error_session;
+       }
+       /* Parse message in session->data: it will be either D2 or F0 */
+       skb = session.data;
+       resp = (void *) skb->data;
+       d_printf(6, dev, "Received response to D1 frame. \n");
+       d_dump(6, dev, skb->data, skb->len > 72 ? 72 : skb->len);
+
+       if (resp->type == WLP_ASSOC_F0) {
+               result = wlp_parse_f0(wlp, skb);
+               if (result < 0)
+                       dev_err(dev, "WLP: Unable to parse F0 from neighbor "
+                               "%02x:%02x.\n", dev_addr->data[1],
+                               dev_addr->data[0]);
+               result = -EINVAL;
+               goto error_resp_parse;
+       }
+       if (wss == NULL) {
+               /* Discovery */
+               result = wlp_parse_d2_frame_to_cache(wlp, skb, neighbor);
+               if (result < 0) {
+                       dev_err(dev, "WLP: Unable to parse D2 message from "
+                               "neighbor %02x:%02x for discovery.\n",
+                               dev_addr->data[1], dev_addr->data[0]);
+                       goto error_resp_parse;
+               }
+       } else {
+               /* Enrollment */
+               result = wlp_parse_d2_frame_to_enroll(wss, skb, neighbor,
+                                                     wssid);
+               if (result < 0) {
+                       dev_err(dev, "WLP: Unable to parse D2 message from "
+                               "neighbor %02x:%02x for enrollment.\n",
+                               dev_addr->data[1], dev_addr->data[0]);
+                       goto error_resp_parse;
+               }
+       }
+error_resp_parse:
+       kfree_skb(skb);
+error_session:
+       wlp->session = NULL;
+out:
+       mutex_unlock(&wlp->mutex);
+       return result;
+}
+
+/**
+ * Enroll into WSS of provided WSSID by using neighbor as registrar
+ *
+ * &wss->mutex is held
+ */
+int wlp_enroll_neighbor(struct wlp *wlp, struct wlp_neighbor_e *neighbor,
+                       struct wlp_wss *wss, struct wlp_uuid *wssid)
+{
+       int result = 0;
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       char buf[WLP_WSS_UUID_STRSIZE];
+       struct uwb_dev_addr *dev_addr = &neighbor->uwb_dev->dev_addr;
+       wlp_wss_uuid_print(buf, sizeof(buf), wssid);
+       d_fnstart(6, dev, "wlp %p, neighbor %p, wss %p, wssid %p (%s)\n",
+                 wlp, neighbor, wss, wssid, buf);
+       d_printf(6, dev, "Complete me.\n");
+       result =  wlp_d1d2_exchange(wlp, neighbor, wss, wssid);
+       if (result < 0) {
+               dev_err(dev, "WLP: D1/D2 message exchange for enrollment "
+                       "failed. result = %d \n", result);
+               goto out;
+       }
+       if (wss->state != WLP_WSS_STATE_PART_ENROLLED) {
+               dev_err(dev, "WLP: Unable to enroll into WSS %s using "
+                       "neighbor %02x:%02x. \n", buf,
+                       dev_addr->data[1], dev_addr->data[0]);
+               result = -EINVAL;
+               goto out;
+       }
+       if (wss->secure_status == WLP_WSS_SECURE) {
+               dev_err(dev, "FIXME: need to complete secure enrollment.\n");
+               result = -EINVAL;
+               goto error;
+       } else {
+               wss->state = WLP_WSS_STATE_ENROLLED;
+               d_printf(2, dev, "WLP: Success Enrollment into unsecure WSS "
+                        "%s using neighbor %02x:%02x. \n", buf,
+                        dev_addr->data[1], dev_addr->data[0]);
+       }
+
+       d_fnend(6, dev, "wlp %p, neighbor %p, wss %p, wssid %p (%s)\n",
+                 wlp, neighbor, wss, wssid, buf);
+out:
+       return result;
+error:
+       wlp_wss_reset(wss);
+       return result;
+}
+
+/**
+ * Discover WSS information of neighbor's active WSS
+ */
+static
+int wlp_discover_neighbor(struct wlp *wlp,
+                         struct wlp_neighbor_e *neighbor)
+{
+       return wlp_d1d2_exchange(wlp, neighbor, NULL, NULL);
+}
+
+
+/**
+ * Each neighbor in the neighborhood cache is discoverable. Discover it.
+ *
+ * Discovery is done through sending of D1 association frame and parsing
+ * the D2 association frame response. Only wssid from D2 will be included
+ * in neighbor cache, rest is just displayed to user and forgotten.
+ *
+ * The discovery is not done in parallel. This is simple and enables us to
+ * maintain only one association context.
+ *
+ * The discovery of one neighbor does not affect the other, but if the
+ * discovery of a neighbor fails it is removed from the neighborhood cache.
+ */
+static
+int wlp_discover_all_neighbors(struct wlp *wlp)
+{
+       int result = 0;
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       struct wlp_neighbor_e *neighbor, *next;
+
+       list_for_each_entry_safe(neighbor, next, &wlp->neighbors, node) {
+               result = wlp_discover_neighbor(wlp, neighbor);
+               if (result < 0) {
+                       dev_err(dev, "WLP: Unable to discover neighbor "
+                               "%02x:%02x, removing from neighborhood. \n",
+                               neighbor->uwb_dev->dev_addr.data[1],
+                               neighbor->uwb_dev->dev_addr.data[0]);
+                       __wlp_neighbor_release(neighbor);
+               }
+       }
+       return result;
+}
+
+static int wlp_add_neighbor_helper(struct device *dev, void *priv)
+{
+       struct wlp *wlp = priv;
+       struct uwb_dev *uwb_dev = to_uwb_dev(dev);
+
+       return wlp_add_neighbor(wlp, uwb_dev);
+}
+
+/**
+ * Discover WLP neighborhood
+ *
+ * Will send D1 association frame to all devices in beacon group that have
+ * discoverable bit set in WLP IE. D2 frames will be received, information
+ * displayed to user in @buf. Partial information (from D2 association
+ * frame) will be cached to assist with future association
+ * requests.
+ *
+ * The discovery of the WLP neighborhood is triggered by the user. This
+ * should occur infrequently and we thus free current cache and re-allocate
+ * memory if needed.
+ *
+ * If one neighbor fails during initial discovery (determining if it is a
+ * neighbor or not), we fail all - note that interaction with neighbor has
+ * not occured at this point so if a failure occurs we know something went wrong
+ * locally. We thus undo everything.
+ */
+ssize_t wlp_discover(struct wlp *wlp)
+{
+       int result = 0;
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+
+       d_fnstart(6, dev, "wlp %p \n", wlp);
+       mutex_lock(&wlp->nbmutex);
+       /* Clear current neighborhood cache. */
+       __wlp_neighbors_release(wlp);
+       /* Determine which devices in neighborhood. Repopulate cache. */
+       result = uwb_dev_for_each(wlp->rc, wlp_add_neighbor_helper, wlp);
+       if (result < 0) {
+               /* May have partial neighbor information, release all. */
+               __wlp_neighbors_release(wlp);
+               goto error_dev_for_each;
+       }
+       /* Discover the properties of devices in neighborhood. */
+       result = wlp_discover_all_neighbors(wlp);
+       /* In case of failure we still print our partial results. */
+       if (result < 0) {
+               dev_err(dev, "Unable to fully discover neighborhood. \n");
+               result = 0;
+       }
+error_dev_for_each:
+       mutex_unlock(&wlp->nbmutex);
+       d_fnend(6, dev, "wlp %p \n", wlp);
+       return result;
+}
+
+/**
+ * Handle events from UWB stack
+ *
+ * We handle events conservatively. If a neighbor goes off the air we
+ * remove it from the neighborhood. If an association process is in
+ * progress this function will block waiting for the nbmutex to become
+ * free. The association process will thus be allowed to complete before it
+ * is removed.
+ */
+static
+void wlp_uwb_notifs_cb(void *_wlp, struct uwb_dev *uwb_dev,
+                      enum uwb_notifs event)
+{
+       struct wlp *wlp = _wlp;
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       struct wlp_neighbor_e *neighbor, *next;
+       int result;
+       switch (event) {
+       case UWB_NOTIF_ONAIR:
+               d_printf(6, dev, "UWB device %02x:%02x is onair\n",
+                               uwb_dev->dev_addr.data[1],
+                               uwb_dev->dev_addr.data[0]);
+               result = wlp_eda_create_node(&wlp->eda,
+                                            uwb_dev->mac_addr.data,
+                                            &uwb_dev->dev_addr);
+               if (result < 0)
+                       dev_err(dev, "WLP: Unable to add new neighbor "
+                               "%02x:%02x to EDA cache.\n",
+                               uwb_dev->dev_addr.data[1],
+                               uwb_dev->dev_addr.data[0]);
+               break;
+       case UWB_NOTIF_OFFAIR:
+               d_printf(6, dev, "UWB device %02x:%02x is offair\n",
+                               uwb_dev->dev_addr.data[1],
+                               uwb_dev->dev_addr.data[0]);
+               wlp_eda_rm_node(&wlp->eda, &uwb_dev->dev_addr);
+               mutex_lock(&wlp->nbmutex);
+               list_for_each_entry_safe(neighbor, next, &wlp->neighbors,
+                                        node) {
+                       if (neighbor->uwb_dev == uwb_dev) {
+                               d_printf(6, dev, "Removing device from "
+                                        "neighborhood.\n");
+                               __wlp_neighbor_release(neighbor);
+                       }
+               }
+               mutex_unlock(&wlp->nbmutex);
+               break;
+       default:
+               dev_err(dev, "don't know how to handle event %d from uwb\n",
+                               event);
+       }
+}
+
+int wlp_setup(struct wlp *wlp, struct uwb_rc *rc)
+{
+       struct device *dev = &rc->uwb_dev.dev;
+       int result;
+
+       d_fnstart(6, dev, "wlp %p\n", wlp);
+       BUG_ON(wlp->fill_device_info == NULL);
+       BUG_ON(wlp->xmit_frame == NULL);
+       BUG_ON(wlp->stop_queue == NULL);
+       BUG_ON(wlp->start_queue == NULL);
+       wlp->rc = rc;
+       wlp_eda_init(&wlp->eda);/* Set up address cache */
+       wlp->uwb_notifs_handler.cb = wlp_uwb_notifs_cb;
+       wlp->uwb_notifs_handler.data = wlp;
+       uwb_notifs_register(rc, &wlp->uwb_notifs_handler);
+
+       uwb_pal_init(&wlp->pal);
+       result = uwb_pal_register(rc, &wlp->pal);
+       if (result < 0)
+               uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler);
+
+       d_fnend(6, dev, "wlp %p, result = %d\n", wlp, result);
+       return result;
+}
+EXPORT_SYMBOL_GPL(wlp_setup);
+
+void wlp_remove(struct wlp *wlp)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       d_fnstart(6, dev, "wlp %p\n", wlp);
+       wlp_neighbors_release(wlp);
+       uwb_pal_unregister(wlp->rc, &wlp->pal);
+       uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler);
+       wlp_eda_release(&wlp->eda);
+       mutex_lock(&wlp->mutex);
+       if (wlp->dev_info != NULL)
+               kfree(wlp->dev_info);
+       mutex_unlock(&wlp->mutex);
+       wlp->rc = NULL;
+       /* We have to use NULL here because this function can be called
+        * when the device disappeared. */
+       d_fnend(6, NULL, "wlp %p\n", wlp);
+}
+EXPORT_SYMBOL_GPL(wlp_remove);
+
+/**
+ * wlp_reset_all - reset the WLP hardware
+ * @wlp: the WLP device to reset.
+ *
+ * This schedules a full hardware reset of the WLP device.  The radio
+ * controller and any other PALs will also be reset.
+ */
+void wlp_reset_all(struct wlp *wlp)
+{
+       uwb_rc_reset_all(wlp->rc);
+}
+EXPORT_SYMBOL_GPL(wlp_reset_all);
diff --git a/drivers/uwb/wlp/wss-lc.c b/drivers/uwb/wlp/wss-lc.c
new file mode 100644 (file)
index 0000000..96b18c9
--- /dev/null
@@ -0,0 +1,1055 @@
+/*
+ * WiMedia Logical Link Control Protocol (WLP)
+ *
+ * Copyright (C) 2007 Intel Corporation
+ * Reinette Chatre <reinette.chatre@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * Implementation of the WLP association protocol.
+ *
+ * FIXME: Docs
+ *
+ * A UWB network interface will configure a WSS through wlp_wss_setup() after
+ * the interface has been assigned a MAC address, typically after
+ * "ifconfig" has been called. When the interface goes down it should call
+ * wlp_wss_remove().
+ *
+ * When the WSS is ready for use the user interacts via sysfs to create,
+ * discover, and activate WSS.
+ *
+ * wlp_wss_enroll_activate()
+ *
+ * wlp_wss_create_activate()
+ *     wlp_wss_set_wssid_hash()
+ *             wlp_wss_comp_wssid_hash()
+ *     wlp_wss_sel_bcast_addr()
+ *     wlp_wss_sysfs_add()
+ *
+ * Called when no more references to WSS exist:
+ *     wlp_wss_release()
+ *             wlp_wss_reset()
+ */
+
+#include <linux/etherdevice.h> /* for is_valid_ether_addr */
+#include <linux/skbuff.h>
+#include <linux/wlp.h>
+#define D_LOCAL 5
+#include <linux/uwb/debug.h>
+#include "wlp-internal.h"
+
+
+size_t wlp_wss_key_print(char *buf, size_t bufsize, u8 *key)
+{
+       size_t result;
+
+       result = scnprintf(buf, bufsize,
+                         "%02x %02x %02x %02x %02x %02x "
+                         "%02x %02x %02x %02x %02x %02x "
+                         "%02x %02x %02x %02x",
+                         key[0], key[1], key[2], key[3],
+                         key[4], key[5], key[6], key[7],
+                         key[8], key[9], key[10], key[11],
+                         key[12], key[13], key[14], key[15]);
+       return result;
+}
+
+/**
+ * Compute WSSID hash
+ * WLP Draft 0.99 [7.2.1]
+ *
+ * The WSSID hash for a WSSID is the result of an octet-wise exclusive-OR
+ * of all octets in the WSSID.
+ */
+static
+u8 wlp_wss_comp_wssid_hash(struct wlp_uuid *wssid)
+{
+       return wssid->data[0]  ^ wssid->data[1]  ^ wssid->data[2]
+              ^ wssid->data[3]  ^ wssid->data[4]  ^ wssid->data[5]
+              ^ wssid->data[6]  ^ wssid->data[7]  ^ wssid->data[8]
+              ^ wssid->data[9]  ^ wssid->data[10] ^ wssid->data[11]
+              ^ wssid->data[12] ^ wssid->data[13] ^ wssid->data[14]
+              ^ wssid->data[15];
+}
+
+/**
+ * Select a multicast EUI-48 for the WSS broadcast address.
+ * WLP Draft 0.99 [7.2.1]
+ *
+ * Selected based on the WiMedia Alliance OUI, 00-13-88, within the WLP
+ * range, [01-13-88-00-01-00, 01-13-88-00-01-FF] inclusive.
+ *
+ * This address is currently hardcoded.
+ * FIXME?
+ */
+static
+struct uwb_mac_addr wlp_wss_sel_bcast_addr(struct wlp_wss *wss)
+{
+       struct uwb_mac_addr bcast = {
+               .data = { 0x01, 0x13, 0x88, 0x00, 0x01, 0x00 }
+       };
+       return bcast;
+}
+
+/**
+ * Clear the contents of the WSS structure - all except kobj, mutex, virtual
+ *
+ * We do not want to reinitialize - the internal kobj should not change as
+ * it still points to the parent received during setup. The mutex should
+ * remain also. We thus just reset values individually.
+ * The virutal address assigned to WSS will remain the same for the
+ * lifetime of the WSS. We only reset the fields that can change during its
+ * lifetime.
+ */
+void wlp_wss_reset(struct wlp_wss *wss)
+{
+       struct wlp *wlp = container_of(wss, struct wlp, wss);
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       d_fnstart(5, dev, "wss (%p) \n", wss);
+       memset(&wss->wssid, 0, sizeof(wss->wssid));
+       wss->hash = 0;
+       memset(&wss->name[0], 0, sizeof(wss->name));
+       memset(&wss->bcast, 0, sizeof(wss->bcast));
+       wss->secure_status = WLP_WSS_UNSECURE;
+       memset(&wss->master_key[0], 0, sizeof(wss->master_key));
+       wss->tag = 0;
+       wss->state = WLP_WSS_STATE_NONE;
+       d_fnend(5, dev, "wss (%p) \n", wss);
+}
+
+/**
+ * Create sysfs infrastructure for WSS
+ *
+ * The WSS is configured to have the interface as parent (see wlp_wss_setup())
+ * a new sysfs directory that includes wssid as its name is created in the
+ * interface's sysfs directory. The group of files interacting with WSS are
+ * created also.
+ */
+static
+int wlp_wss_sysfs_add(struct wlp_wss *wss, char *wssid_str)
+{
+       struct wlp *wlp = container_of(wss, struct wlp, wss);
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       int result;
+
+       d_fnstart(5, dev, "wss (%p), wssid: %s\n", wss, wssid_str);
+       result = kobject_set_name(&wss->kobj, "wss-%s", wssid_str);
+       if (result < 0)
+               return result;
+       wss->kobj.ktype = &wss_ktype;
+       result = kobject_init_and_add(&wss->kobj,
+                       &wss_ktype, wss->kobj.parent, "wlp");
+       if (result < 0) {
+               dev_err(dev, "WLP: Cannot register WSS kobject.\n");
+               goto error_kobject_register;
+       }
+       result = sysfs_create_group(&wss->kobj, &wss_attr_group);
+       if (result < 0) {
+               dev_err(dev, "WLP: Cannot register WSS attributes: %d\n",
+                       result);
+               goto error_sysfs_create_group;
+       }
+       d_fnend(5, dev, "Completed. result = %d \n", result);
+       return 0;
+error_sysfs_create_group:
+
+       kobject_put(&wss->kobj); /* will free name if needed */
+       return result;
+error_kobject_register:
+       kfree(wss->kobj.name);
+       wss->kobj.name = NULL;
+       wss->kobj.ktype = NULL;
+       return result;
+}
+
+
+/**
+ * Release WSS
+ *
+ * No more references exist to this WSS. We should undo everything that was
+ * done in wlp_wss_create_activate() except removing the group. The group
+ * is not removed because an object can be unregistered before the group is
+ * created. We also undo any additional operations on the WSS after this
+ * (addition of members).
+ *
+ * If memory was allocated for the kobject's name then it will
+ * be freed by the kobject system during this time.
+ *
+ * The EDA cache is removed and reinitilized when the WSS is removed. We
+ * thus loose knowledge of members of this WSS at that time and need not do
+ * it here.
+ */
+void wlp_wss_release(struct kobject *kobj)
+{
+       struct wlp_wss *wss = container_of(kobj, struct wlp_wss, kobj);
+
+       wlp_wss_reset(wss);
+}
+
+/**
+ * Enroll into a WSS using provided neighbor as registrar
+ *
+ * First search the neighborhood information to learn which neighbor is
+ * referred to, next proceed with enrollment.
+ *
+ * &wss->mutex is held
+ */
+static
+int wlp_wss_enroll_target(struct wlp_wss *wss, struct wlp_uuid *wssid,
+                         struct uwb_dev_addr *dest)
+{
+       struct wlp *wlp = container_of(wss, struct wlp, wss);
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       struct wlp_neighbor_e *neighbor;
+       char buf[WLP_WSS_UUID_STRSIZE];
+       int result = -ENXIO;
+       struct uwb_dev_addr *dev_addr;
+
+       wlp_wss_uuid_print(buf, sizeof(buf), wssid);
+       d_fnstart(5, dev, "wss %p, wssid %s, registrar %02x:%02x \n",
+                 wss, buf, dest->data[1], dest->data[0]);
+       mutex_lock(&wlp->nbmutex);
+       list_for_each_entry(neighbor, &wlp->neighbors, node) {
+               dev_addr = &neighbor->uwb_dev->dev_addr;
+               if (!memcmp(dest, dev_addr, sizeof(*dest))) {
+                       d_printf(5, dev, "Neighbor %02x:%02x is valid, "
+                                "enrolling. \n",
+                                dev_addr->data[1], dev_addr->data[0]);
+                       result = wlp_enroll_neighbor(wlp, neighbor, wss,
+                                                    wssid);
+                       break;
+               }
+       }
+       if (result == -ENXIO)
+               dev_err(dev, "WLP: Cannot find neighbor %02x:%02x. \n",
+                       dest->data[1], dest->data[0]);
+       mutex_unlock(&wlp->nbmutex);
+       d_fnend(5, dev, "wss %p, wssid %s, registrar %02x:%02x, result %d \n",
+                 wss, buf, dest->data[1], dest->data[0], result);
+       return result;
+}
+
+/**
+ * Enroll into a WSS previously discovered
+ *
+ * User provides WSSID of WSS, search for neighbor that has this WSS
+ * activated and attempt to enroll.
+ *
+ * &wss->mutex is held
+ */
+static
+int wlp_wss_enroll_discovered(struct wlp_wss *wss, struct wlp_uuid *wssid)
+{
+       struct wlp *wlp = container_of(wss, struct wlp, wss);
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       struct wlp_neighbor_e *neighbor;
+       struct wlp_wssid_e *wssid_e;
+       char buf[WLP_WSS_UUID_STRSIZE];
+       int result = -ENXIO;
+
+       wlp_wss_uuid_print(buf, sizeof(buf), wssid);
+       d_fnstart(5, dev, "wss %p, wssid %s \n", wss, buf);
+       mutex_lock(&wlp->nbmutex);
+       list_for_each_entry(neighbor, &wlp->neighbors, node) {
+               list_for_each_entry(wssid_e, &neighbor->wssid, node) {
+                       if (!memcmp(wssid, &wssid_e->wssid, sizeof(*wssid))) {
+                               d_printf(5, dev, "Found WSSID %s in neighbor "
+                                        "%02x:%02x cache. \n", buf,
+                                        neighbor->uwb_dev->dev_addr.data[1],
+                                        neighbor->uwb_dev->dev_addr.data[0]);
+                               result = wlp_enroll_neighbor(wlp, neighbor,
+                                                            wss, wssid);
+                               if (result == 0) /* enrollment success */
+                                       goto out;
+                               break;
+                       }
+               }
+       }
+out:
+       if (result == -ENXIO)
+               dev_err(dev, "WLP: Cannot find WSSID %s in cache. \n", buf);
+       mutex_unlock(&wlp->nbmutex);
+       d_fnend(5, dev, "wss %p, wssid %s, result %d \n", wss, buf, result);
+       return result;
+}
+
+/**
+ * Enroll into WSS with provided WSSID, registrar may be provided
+ *
+ * @wss: out WSS that will be enrolled
+ * @wssid: wssid of neighboring WSS that we want to enroll in
+ * @devaddr: registrar can be specified, will be broadcast (ff:ff) if any
+ *           neighbor can be used as registrar.
+ *
+ * &wss->mutex is held
+ */
+static
+int wlp_wss_enroll(struct wlp_wss *wss, struct wlp_uuid *wssid,
+                  struct uwb_dev_addr *devaddr)
+{
+       int result;
+       struct wlp *wlp = container_of(wss, struct wlp, wss);
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       char buf[WLP_WSS_UUID_STRSIZE];
+       struct uwb_dev_addr bcast = {.data = {0xff, 0xff} };
+
+       wlp_wss_uuid_print(buf, sizeof(buf), wssid);
+       if (wss->state != WLP_WSS_STATE_NONE) {
+               dev_err(dev, "WLP: Already enrolled in WSS %s.\n", buf);
+               result = -EEXIST;
+               goto error;
+       }
+       if (!memcmp(&bcast, devaddr, sizeof(bcast))) {
+               d_printf(5, dev, "Request to enroll in discovered WSS "
+                        "with WSSID %s \n", buf);
+               result = wlp_wss_enroll_discovered(wss, wssid);
+       } else {
+               d_printf(5, dev, "Request to enroll in WSSID %s with "
+                        "registrar %02x:%02x\n", buf, devaddr->data[1],
+                        devaddr->data[0]);
+               result = wlp_wss_enroll_target(wss, wssid, devaddr);
+       }
+       if (result < 0) {
+               dev_err(dev, "WLP: Unable to enroll into WSS %s, result %d \n",
+                       buf, result);
+               goto error;
+       }
+       d_printf(2, dev, "Successfully enrolled into WSS %s \n", buf);
+       result = wlp_wss_sysfs_add(wss, buf);
+       if (result < 0) {
+               dev_err(dev, "WLP: Unable to set up sysfs for WSS kobject.\n");
+               wlp_wss_reset(wss);
+       }
+error:
+       return result;
+
+}
+
+/**
+ * Activate given WSS
+ *
+ * Prior to activation a WSS must be enrolled. To activate a WSS a device
+ * includes the WSS hash in the WLP IE in its beacon in each superframe.
+ * WLP 0.99 [7.2.5].
+ *
+ * The WSS tag is also computed at this time. We only support one activated
+ * WSS so we can use the hash as a tag - there will never be a conflict.
+ *
+ * We currently only support one activated WSS so only one WSS hash is
+ * included in the WLP IE.
+ */
+static
+int wlp_wss_activate(struct wlp_wss *wss)
+{
+       struct wlp *wlp = container_of(wss, struct wlp, wss);
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       struct uwb_rc *uwb_rc = wlp->rc;
+       int result;
+       struct {
+               struct wlp_ie wlp_ie;
+               u8 hash; /* only include one hash */
+       } ie_data;
+
+       d_fnstart(5, dev, "Activating WSS %p. \n", wss);
+       BUG_ON(wss->state != WLP_WSS_STATE_ENROLLED);
+       wss->hash = wlp_wss_comp_wssid_hash(&wss->wssid);
+       wss->tag = wss->hash;
+       memset(&ie_data, 0, sizeof(ie_data));
+       ie_data.wlp_ie.hdr.element_id = UWB_IE_WLP;
+       ie_data.wlp_ie.hdr.length = sizeof(ie_data) - sizeof(struct uwb_ie_hdr);
+       wlp_ie_set_hash_length(&ie_data.wlp_ie, sizeof(ie_data.hash));
+       ie_data.hash = wss->hash;
+       result = uwb_rc_ie_add(uwb_rc, &ie_data.wlp_ie.hdr,
+                              sizeof(ie_data));
+       if (result < 0) {
+               dev_err(dev, "WLP: Unable to add WLP IE to beacon. "
+                       "result = %d.\n", result);
+               goto error_wlp_ie;
+       }
+       wss->state = WLP_WSS_STATE_ACTIVE;
+       result = 0;
+error_wlp_ie:
+       d_fnend(5, dev, "Activating WSS %p, result = %d \n", wss, result);
+       return result;
+}
+
+/**
+ * Enroll in and activate WSS identified by provided WSSID
+ *
+ * The neighborhood cache should contain a list of all neighbors and the
+ * WSS they have activated. Based on that cache we search which neighbor we
+ * can perform the association process with. The user also has option to
+ * specify which neighbor it prefers as registrar.
+ * Successful enrollment is followed by activation.
+ * Successful activation will create the sysfs directory containing
+ * specific information regarding this WSS.
+ */
+int wlp_wss_enroll_activate(struct wlp_wss *wss, struct wlp_uuid *wssid,
+                           struct uwb_dev_addr *devaddr)
+{
+       struct wlp *wlp = container_of(wss, struct wlp, wss);
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       int result = 0;
+       char buf[WLP_WSS_UUID_STRSIZE];
+
+       d_fnstart(5, dev, "Enrollment and activation requested. \n");
+       mutex_lock(&wss->mutex);
+       result = wlp_wss_enroll(wss, wssid, devaddr);
+       if (result < 0) {
+               wlp_wss_uuid_print(buf, sizeof(buf), &wss->wssid);
+               dev_err(dev, "WLP: Enrollment into WSS %s failed.\n", buf);
+               goto error_enroll;
+       }
+       result = wlp_wss_activate(wss);
+       if (result < 0) {
+               dev_err(dev, "WLP: Unable to activate WSS. Undoing enrollment "
+                       "result = %d \n", result);
+               /* Undo enrollment */
+               wlp_wss_reset(wss);
+               goto error_activate;
+       }
+error_activate:
+error_enroll:
+       mutex_unlock(&wss->mutex);
+       d_fnend(5, dev, "Completed. result = %d \n", result);
+       return result;
+}
+
+/**
+ * Create, enroll, and activate a new WSS
+ *
+ * @wssid: new wssid provided by user
+ * @name:  WSS name requested by used.
+ * @sec_status: security status requested by user
+ *
+ * A user requested the creation of a new WSS. All operations are done
+ * locally. The new WSS will be stored locally, the hash will be included
+ * in the WLP IE, and the sysfs infrastructure for this WSS will be
+ * created.
+ */
+int wlp_wss_create_activate(struct wlp_wss *wss, struct wlp_uuid *wssid,
+                           char *name, unsigned sec_status, unsigned accept)
+{
+       struct wlp *wlp = container_of(wss, struct wlp, wss);
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       int result = 0;
+       char buf[WLP_WSS_UUID_STRSIZE];
+       d_fnstart(5, dev, "Request to create new WSS.\n");
+       result = wlp_wss_uuid_print(buf, sizeof(buf), wssid);
+       d_printf(5, dev, "Request to create WSS: WSSID=%s, name=%s, "
+                "sec_status=%u, accepting enrollment=%u \n",
+                buf, name, sec_status, accept);
+       if (!mutex_trylock(&wss->mutex)) {
+               dev_err(dev, "WLP: WLP association session in progress.\n");
+               return -EBUSY;
+       }
+       if (wss->state != WLP_WSS_STATE_NONE) {
+               dev_err(dev, "WLP: WSS already exists. Not creating new.\n");
+               result = -EEXIST;
+               goto out;
+       }
+       if (wss->kobj.parent == NULL) {
+               dev_err(dev, "WLP: WSS parent not ready. Is network interface "
+                      "up?\n");
+               result = -ENXIO;
+               goto out;
+       }
+       if (sec_status == WLP_WSS_SECURE) {
+               dev_err(dev, "WLP: FIXME Creation of secure WSS not "
+                       "supported yet.\n");
+               result = -EINVAL;
+               goto out;
+       }
+       wss->wssid = *wssid;
+       memcpy(wss->name, name, sizeof(wss->name));
+       wss->bcast = wlp_wss_sel_bcast_addr(wss);
+       wss->secure_status = sec_status;
+       wss->accept_enroll = accept;
+       /*wss->virtual_addr is initialized in call to wlp_wss_setup*/
+       /* sysfs infrastructure */
+       result = wlp_wss_sysfs_add(wss, buf);
+       if (result < 0) {
+               dev_err(dev, "Cannot set up sysfs for WSS kobject.\n");
+               wlp_wss_reset(wss);
+               goto out;
+       } else
+               result = 0;
+       wss->state = WLP_WSS_STATE_ENROLLED;
+       result = wlp_wss_activate(wss);
+       if (result < 0) {
+               dev_err(dev, "WLP: Unable to activate WSS. Undoing "
+                       "enrollment\n");
+               wlp_wss_reset(wss);
+               goto out;
+       }
+       result = 0;
+out:
+       mutex_unlock(&wss->mutex);
+       d_fnend(5, dev, "Completed. result = %d \n", result);
+       return result;
+}
+
+/**
+ * Determine if neighbor has WSS activated
+ *
+ * @returns: 1 if neighbor has WSS activated, zero otherwise
+ *
+ * This can be done in two ways:
+ * - send a C1 frame, parse C2/F0 response
+ * - examine the WLP IE sent by the neighbor
+ *
+ * The WLP IE is not fully supported in hardware so we use the C1/C2 frame
+ * exchange to determine if a WSS is activated. Using the WLP IE should be
+ * faster and should be used when it becomes possible.
+ */
+int wlp_wss_is_active(struct wlp *wlp, struct wlp_wss *wss,
+                     struct uwb_dev_addr *dev_addr)
+{
+       int result = 0;
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       char buf[WLP_WSS_UUID_STRSIZE];
+       DECLARE_COMPLETION_ONSTACK(completion);
+       struct wlp_session session;
+       struct sk_buff  *skb;
+       struct wlp_frame_assoc *resp;
+       struct wlp_uuid wssid;
+
+       wlp_wss_uuid_print(buf, sizeof(buf), &wss->wssid);
+       d_fnstart(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n",
+                 wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]);
+       mutex_lock(&wlp->mutex);
+       /* Send C1 association frame */
+       result = wlp_send_assoc_frame(wlp, wss, dev_addr, WLP_ASSOC_C1);
+       if (result < 0) {
+               dev_err(dev, "Unable to send C1 frame to neighbor "
+                       "%02x:%02x (%d)\n", dev_addr->data[1],
+                       dev_addr->data[0], result);
+               result = 0;
+               goto out;
+       }
+       /* Create session, wait for response */
+       session.exp_message = WLP_ASSOC_C2;
+       session.cb = wlp_session_cb;
+       session.cb_priv = &completion;
+       session.neighbor_addr = *dev_addr;
+       BUG_ON(wlp->session != NULL);
+       wlp->session = &session;
+       /* Wait for C2/F0 frame */
+       result = wait_for_completion_interruptible_timeout(&completion,
+                                                  WLP_PER_MSG_TIMEOUT * HZ);
+       if (result == 0) {
+               dev_err(dev, "Timeout while sending C1 to neighbor "
+                            "%02x:%02x.\n", dev_addr->data[1],
+                            dev_addr->data[0]);
+               goto out;
+       }
+       if (result < 0) {
+               dev_err(dev, "Unable to send C1 to neighbor %02x:%02x.\n",
+                       dev_addr->data[1], dev_addr->data[0]);
+               result = 0;
+               goto out;
+       }
+       /* Parse message in session->data: it will be either C2 or F0 */
+       skb = session.data;
+       resp = (void *) skb->data;
+       d_printf(5, dev, "Received response to C1 frame. \n");
+       d_dump(5, dev, skb->data, skb->len > 72 ? 72 : skb->len);
+       if (resp->type == WLP_ASSOC_F0) {
+               result = wlp_parse_f0(wlp, skb);
+               if (result < 0)
+                       dev_err(dev, "WLP:  unable to parse incoming F0 "
+                               "frame from neighbor %02x:%02x.\n",
+                               dev_addr->data[1], dev_addr->data[0]);
+               result = 0;
+               goto error_resp_parse;
+       }
+       /* WLP version and message type fields have already been parsed */
+       result = wlp_get_wssid(wlp, (void *)resp + sizeof(*resp), &wssid,
+                              skb->len - sizeof(*resp));
+       if (result < 0) {
+               dev_err(dev, "WLP: unable to obtain WSSID from C2 frame.\n");
+               result = 0;
+               goto error_resp_parse;
+       }
+       if (!memcmp(&wssid, &wss->wssid, sizeof(wssid))) {
+               d_printf(5, dev, "WSSID in C2 frame matches local "
+                        "active WSS.\n");
+               result = 1;
+       } else {
+               dev_err(dev, "WLP: Received a C2 frame without matching "
+                       "WSSID.\n");
+               result = 0;
+       }
+error_resp_parse:
+       kfree_skb(skb);
+out:
+       wlp->session = NULL;
+       mutex_unlock(&wlp->mutex);
+       d_fnend(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n",
+                 wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]);
+       return result;
+}
+
+/**
+ * Activate connection with neighbor by updating EDA cache
+ *
+ * @wss:       local WSS to which neighbor wants to connect
+ * @dev_addr:  neighbor's address
+ * @wssid:     neighbor's WSSID - must be same as our WSS's WSSID
+ * @tag:       neighbor's WSS tag used to identify frames transmitted by it
+ * @virt_addr: neighbor's virtual EUI-48
+ */
+static
+int wlp_wss_activate_connection(struct wlp *wlp, struct wlp_wss *wss,
+                               struct uwb_dev_addr *dev_addr,
+                               struct wlp_uuid *wssid, u8 *tag,
+                               struct uwb_mac_addr *virt_addr)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       int result = 0;
+       char buf[WLP_WSS_UUID_STRSIZE];
+       wlp_wss_uuid_print(buf, sizeof(buf), wssid);
+       d_fnstart(5, dev, "wlp %p, wss %p, wssid %s, tag %u, virtual "
+                 "%02x:%02x:%02x:%02x:%02x:%02x \n", wlp, wss, buf, *tag,
+                 virt_addr->data[0], virt_addr->data[1], virt_addr->data[2],
+                 virt_addr->data[3], virt_addr->data[4], virt_addr->data[5]);
+
+       if (!memcmp(wssid, &wss->wssid, sizeof(*wssid))) {
+               d_printf(5, dev, "WSSID from neighbor frame matches local "
+                        "active WSS.\n");
+               /* Update EDA cache */
+               result = wlp_eda_update_node(&wlp->eda, dev_addr, wss,
+                                            (void *) virt_addr->data, *tag,
+                                            WLP_WSS_CONNECTED);
+               if (result < 0)
+                       dev_err(dev, "WLP: Unable to update EDA cache "
+                               "with new connected neighbor information.\n");
+       } else {
+               dev_err(dev, "WLP: Neighbor does not have matching "
+                       "WSSID.\n");
+               result = -EINVAL;
+       }
+
+       d_fnend(5, dev, "wlp %p, wss %p, wssid %s, tag %u, virtual "
+                 "%02x:%02x:%02x:%02x:%02x:%02x, result = %d \n",
+                 wlp, wss, buf, *tag,
+                 virt_addr->data[0], virt_addr->data[1], virt_addr->data[2],
+                 virt_addr->data[3], virt_addr->data[4], virt_addr->data[5],
+                 result);
+
+       return result;
+}
+
+/**
+ * Connect to WSS neighbor
+ *
+ * Use C3/C4 exchange to determine if neighbor has WSS activated and
+ * retrieve the WSS tag and virtual EUI-48 of the neighbor.
+ */
+static
+int wlp_wss_connect_neighbor(struct wlp *wlp, struct wlp_wss *wss,
+                            struct uwb_dev_addr *dev_addr)
+{
+       int result;
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       char buf[WLP_WSS_UUID_STRSIZE];
+       struct wlp_uuid wssid;
+       u8 tag;
+       struct uwb_mac_addr virt_addr;
+       DECLARE_COMPLETION_ONSTACK(completion);
+       struct wlp_session session;
+       struct wlp_frame_assoc *resp;
+       struct sk_buff *skb;
+
+       wlp_wss_uuid_print(buf, sizeof(buf), &wss->wssid);
+       d_fnstart(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n",
+                 wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]);
+       mutex_lock(&wlp->mutex);
+       /* Send C3 association frame */
+       result = wlp_send_assoc_frame(wlp, wss, dev_addr, WLP_ASSOC_C3);
+       if (result < 0) {
+               dev_err(dev, "Unable to send C3 frame to neighbor "
+                       "%02x:%02x (%d)\n", dev_addr->data[1],
+                       dev_addr->data[0], result);
+               goto out;
+       }
+       /* Create session, wait for response */
+       session.exp_message = WLP_ASSOC_C4;
+       session.cb = wlp_session_cb;
+       session.cb_priv = &completion;
+       session.neighbor_addr = *dev_addr;
+       BUG_ON(wlp->session != NULL);
+       wlp->session = &session;
+       /* Wait for C4/F0 frame */
+       result = wait_for_completion_interruptible_timeout(&completion,
+                                                  WLP_PER_MSG_TIMEOUT * HZ);
+       if (result == 0) {
+               dev_err(dev, "Timeout while sending C3 to neighbor "
+                            "%02x:%02x.\n", dev_addr->data[1],
+                            dev_addr->data[0]);
+               result = -ETIMEDOUT;
+               goto out;
+       }
+       if (result < 0) {
+               dev_err(dev, "Unable to send C3 to neighbor %02x:%02x.\n",
+                       dev_addr->data[1], dev_addr->data[0]);
+               goto out;
+       }
+       /* Parse message in session->data: it will be either C4 or F0 */
+       skb = session.data;
+       resp = (void *) skb->data;
+       d_printf(5, dev, "Received response to C3 frame. \n");
+       d_dump(5, dev, skb->data, skb->len > 72 ? 72 : skb->len);
+       if (resp->type == WLP_ASSOC_F0) {
+               result = wlp_parse_f0(wlp, skb);
+               if (result < 0)
+                       dev_err(dev, "WLP: unable to parse incoming F0 "
+                               "frame from neighbor %02x:%02x.\n",
+                               dev_addr->data[1], dev_addr->data[0]);
+               result = -EINVAL;
+               goto error_resp_parse;
+       }
+       result = wlp_parse_c3c4_frame(wlp, skb, &wssid, &tag, &virt_addr);
+       if (result < 0) {
+               dev_err(dev, "WLP: Unable to parse C4 frame from neighbor.\n");
+               goto error_resp_parse;
+       }
+       result = wlp_wss_activate_connection(wlp, wss, dev_addr, &wssid, &tag,
+                                            &virt_addr);
+       if (result < 0) {
+               dev_err(dev, "WLP: Unable to activate connection to "
+                       "neighbor %02x:%02x.\n", dev_addr->data[1],
+                       dev_addr->data[0]);
+               goto error_resp_parse;
+       }
+error_resp_parse:
+       kfree_skb(skb);
+out:
+       /* Record that we unsuccessfully tried to connect to this neighbor */
+       if (result < 0)
+               wlp_eda_update_node_state(&wlp->eda, dev_addr,
+                                         WLP_WSS_CONNECT_FAILED);
+       wlp->session = NULL;
+       mutex_unlock(&wlp->mutex);
+       d_fnend(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n",
+                 wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]);
+       return result;
+}
+
+/**
+ * Connect to neighbor with common WSS, send pending frame
+ *
+ * This function is scheduled when a frame is destined to a neighbor with
+ * which we do not have a connection. A copy of the EDA cache entry is
+ * provided - not the actual cache entry (because it is protected by a
+ * spinlock).
+ *
+ * First determine if neighbor has the same WSS activated, connect if it
+ * does. The C3/C4 exchange is dual purpose to determine if neighbor has
+ * WSS activated and proceed with the connection.
+ *
+ * The frame that triggered the connection setup is sent after connection
+ * setup.
+ *
+ * network queue is stopped - we need to restart when done
+ *
+ */
+static
+void wlp_wss_connect_send(struct work_struct *ws)
+{
+       struct wlp_assoc_conn_ctx *conn_ctx = container_of(ws,
+                                                 struct wlp_assoc_conn_ctx,
+                                                 ws);
+       struct wlp *wlp = conn_ctx->wlp;
+       struct sk_buff *skb = conn_ctx->skb;
+       struct wlp_eda_node *eda_entry = &conn_ctx->eda_entry;
+       struct uwb_dev_addr *dev_addr = &eda_entry->dev_addr;
+       struct wlp_wss *wss = &wlp->wss;
+       int result;
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       char buf[WLP_WSS_UUID_STRSIZE];
+
+       mutex_lock(&wss->mutex);
+       wlp_wss_uuid_print(buf, sizeof(buf), &wss->wssid);
+       d_fnstart(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n",
+                 wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]);
+       if (wss->state < WLP_WSS_STATE_ACTIVE) {
+               if (printk_ratelimit())
+                       dev_err(dev, "WLP: Attempting to connect with "
+                               "WSS that is not active or connected.\n");
+               dev_kfree_skb(skb);
+               goto out;
+       }
+       /* Establish connection - send C3 rcv C4 */
+       result = wlp_wss_connect_neighbor(wlp, wss, dev_addr);
+       if (result < 0) {
+               if (printk_ratelimit())
+                       dev_err(dev, "WLP: Unable to establish connection "
+                               "with neighbor %02x:%02x.\n",
+                               dev_addr->data[1], dev_addr->data[0]);
+               dev_kfree_skb(skb);
+               goto out;
+       }
+       /* EDA entry changed, update the local copy being used */
+       result = wlp_copy_eda_node(&wlp->eda, dev_addr, eda_entry);
+       if (result < 0) {
+               if (printk_ratelimit())
+                       dev_err(dev, "WLP: Cannot find EDA entry for "
+                               "neighbor %02x:%02x \n",
+                               dev_addr->data[1], dev_addr->data[0]);
+       }
+       result = wlp_wss_prep_hdr(wlp, eda_entry, skb);
+       if (result < 0) {
+               if (printk_ratelimit())
+                       dev_err(dev, "WLP: Unable to prepare frame header for "
+                               "transmission (neighbor %02x:%02x). \n",
+                               dev_addr->data[1], dev_addr->data[0]);
+               dev_kfree_skb(skb);
+               goto out;
+       }
+       BUG_ON(wlp->xmit_frame == NULL);
+       result = wlp->xmit_frame(wlp, skb, dev_addr);
+       if (result < 0) {
+               if (printk_ratelimit())
+                       dev_err(dev, "WLP: Unable to transmit frame: %d\n",
+                               result);
+               if (result == -ENXIO)
+                       dev_err(dev, "WLP: Is network interface up? \n");
+               /* We could try again ... */
+               dev_kfree_skb(skb);/*we need to free if tx fails */
+       }
+out:
+       kfree(conn_ctx);
+       BUG_ON(wlp->start_queue == NULL);
+       wlp->start_queue(wlp);
+       mutex_unlock(&wss->mutex);
+       d_fnend(5, dev, "wlp %p, wss %p (wssid %s)\n", wlp, wss, buf);
+}
+
+/**
+ * Add WLP header to outgoing skb
+ *
+ * @eda_entry: pointer to neighbor's entry in the EDA cache
+ * @_skb:      skb containing data destined to the neighbor
+ */
+int wlp_wss_prep_hdr(struct wlp *wlp, struct wlp_eda_node *eda_entry,
+                    void *_skb)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       int result = 0;
+       unsigned char *eth_addr = eda_entry->eth_addr;
+       struct uwb_dev_addr *dev_addr = &eda_entry->dev_addr;
+       struct sk_buff *skb = _skb;
+       struct wlp_frame_std_abbrv_hdr *std_hdr;
+
+       d_fnstart(6, dev, "wlp %p \n", wlp);
+       if (eda_entry->state == WLP_WSS_CONNECTED) {
+               /* Add WLP header */
+               BUG_ON(skb_headroom(skb) < sizeof(*std_hdr));
+               std_hdr = (void *) __skb_push(skb, sizeof(*std_hdr));
+               std_hdr->hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID);
+               std_hdr->hdr.type = WLP_FRAME_STANDARD;
+               std_hdr->tag = eda_entry->wss->tag;
+       } else {
+               if (printk_ratelimit())
+                       dev_err(dev, "WLP: Destination neighbor (Ethernet: "
+                               "%02x:%02x:%02x:%02x:%02x:%02x, Dev: "
+                               "%02x:%02x) is not connected. \n", eth_addr[0],
+                               eth_addr[1], eth_addr[2], eth_addr[3],
+                               eth_addr[4], eth_addr[5], dev_addr->data[1],
+                               dev_addr->data[0]);
+               result = -EINVAL;
+       }
+       d_fnend(6, dev, "wlp %p \n", wlp);
+       return result;
+}
+
+
+/**
+ * Prepare skb for neighbor: connect if not already and prep WLP header
+ *
+ * This function is called in interrupt context, but it needs to sleep. We
+ * temporarily stop the net queue to establish the WLP connection.
+ * Setup of the WLP connection and restart of queue is scheduled
+ * on the default work queue.
+ *
+ * run with eda->lock held (spinlock)
+ */
+int wlp_wss_connect_prep(struct wlp *wlp, struct wlp_eda_node *eda_entry,
+                        void *_skb)
+{
+       int result = 0;
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       struct uwb_dev_addr *dev_addr = &eda_entry->dev_addr;
+       unsigned char *eth_addr = eda_entry->eth_addr;
+       struct sk_buff *skb = _skb;
+       struct wlp_assoc_conn_ctx *conn_ctx;
+
+       d_fnstart(5, dev, "wlp %p\n", wlp);
+       d_printf(5, dev, "To neighbor %02x:%02x with eth "
+                 "%02x:%02x:%02x:%02x:%02x:%02x\n", dev_addr->data[1],
+                 dev_addr->data[0], eth_addr[0], eth_addr[1], eth_addr[2],
+                 eth_addr[3], eth_addr[4], eth_addr[5]);
+       if (eda_entry->state == WLP_WSS_UNCONNECTED) {
+               /* We don't want any more packets while we set up connection */
+               BUG_ON(wlp->stop_queue == NULL);
+               wlp->stop_queue(wlp);
+               conn_ctx = kmalloc(sizeof(*conn_ctx), GFP_ATOMIC);
+               if (conn_ctx == NULL) {
+                       if (printk_ratelimit())
+                               dev_err(dev, "WLP: Unable to allocate memory "
+                                       "for connection handling.\n");
+                       result = -ENOMEM;
+                       goto out;
+               }
+               conn_ctx->wlp = wlp;
+               conn_ctx->skb = skb;
+               conn_ctx->eda_entry = *eda_entry;
+               INIT_WORK(&conn_ctx->ws, wlp_wss_connect_send);
+               schedule_work(&conn_ctx->ws);
+               result = 1;
+       } else if (eda_entry->state == WLP_WSS_CONNECT_FAILED) {
+               /* Previous connection attempts failed, don't retry - see
+                * conditions for connection in WLP 0.99 [7.6.2] */
+               if (printk_ratelimit())
+                       dev_err(dev, "Could not connect to neighbor "
+                        "previously. Not retrying. \n");
+               result = -ENONET;
+               goto out;
+       } else { /* eda_entry->state == WLP_WSS_CONNECTED */
+               d_printf(5, dev, "Neighbor is connected, preparing frame.\n");
+               result = wlp_wss_prep_hdr(wlp, eda_entry, skb);
+       }
+out:
+       d_fnend(5, dev, "wlp %p, result = %d \n", wlp, result);
+       return result;
+}
+
+/**
+ * Emulate broadcast: copy skb, send copy to neighbor (connect if not already)
+ *
+ * We need to copy skbs in the case where we emulate broadcast through
+ * unicast. We copy instead of clone because we are modifying the data of
+ * the frame after copying ... clones share data so we cannot emulate
+ * broadcast using clones.
+ *
+ * run with eda->lock held (spinlock)
+ */
+int wlp_wss_send_copy(struct wlp *wlp, struct wlp_eda_node *eda_entry,
+                     void *_skb)
+{
+       int result = -ENOMEM;
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       struct sk_buff *skb = _skb;
+       struct sk_buff *copy;
+       struct uwb_dev_addr *dev_addr = &eda_entry->dev_addr;
+
+       d_fnstart(5, dev, "to neighbor %02x:%02x, skb (%p) \n",
+                 dev_addr->data[1], dev_addr->data[0], skb);
+       copy = skb_copy(skb, GFP_ATOMIC);
+       if (copy == NULL) {
+               if (printk_ratelimit())
+                       dev_err(dev, "WLP: Unable to copy skb for "
+                               "transmission.\n");
+               goto out;
+       }
+       result = wlp_wss_connect_prep(wlp, eda_entry, copy);
+       if (result < 0) {
+               if (printk_ratelimit())
+                       dev_err(dev, "WLP: Unable to connect/send skb "
+                               "to neighbor.\n");
+               dev_kfree_skb_irq(copy);
+               goto out;
+       } else if (result == 1)
+               /* Frame will be transmitted separately */
+               goto out;
+       BUG_ON(wlp->xmit_frame == NULL);
+       result = wlp->xmit_frame(wlp, copy, dev_addr);
+       if (result < 0) {
+               if (printk_ratelimit())
+                       dev_err(dev, "WLP: Unable to transmit frame: %d\n",
+                               result);
+               if ((result == -ENXIO) && printk_ratelimit())
+                       dev_err(dev, "WLP: Is network interface up? \n");
+               /* We could try again ... */
+               dev_kfree_skb_irq(copy);/*we need to free if tx fails */
+       }
+out:
+       d_fnend(5, dev, "to neighbor %02x:%02x \n", dev_addr->data[1],
+                 dev_addr->data[0]);
+       return result;
+}
+
+
+/**
+ * Setup WSS
+ *
+ * Should be called by network driver after the interface has been given a
+ * MAC address.
+ */
+int wlp_wss_setup(struct net_device *net_dev, struct wlp_wss *wss)
+{
+       struct wlp *wlp = container_of(wss, struct wlp, wss);
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       int result = 0;
+       d_fnstart(5, dev, "wss (%p) \n", wss);
+       mutex_lock(&wss->mutex);
+       wss->kobj.parent = &net_dev->dev.kobj;
+       if (!is_valid_ether_addr(net_dev->dev_addr)) {
+               dev_err(dev, "WLP: Invalid MAC address. Cannot use for"
+                      "virtual.\n");
+               result = -EINVAL;
+               goto out;
+       }
+       memcpy(wss->virtual_addr.data, net_dev->dev_addr,
+              sizeof(wss->virtual_addr.data));
+out:
+       mutex_unlock(&wss->mutex);
+       d_fnend(5, dev, "wss (%p) \n", wss);
+       return result;
+}
+EXPORT_SYMBOL_GPL(wlp_wss_setup);
+
+/**
+ * Remove WSS
+ *
+ * Called by client that configured WSS through wlp_wss_setup(). This
+ * function is called when client no longer needs WSS, eg. client shuts
+ * down.
+ *
+ * We remove the WLP IE from the beacon before initiating local cleanup.
+ */
+void wlp_wss_remove(struct wlp_wss *wss)
+{
+       struct wlp *wlp = container_of(wss, struct wlp, wss);
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       d_fnstart(5, dev, "wss (%p) \n", wss);
+       mutex_lock(&wss->mutex);
+       if (wss->state == WLP_WSS_STATE_ACTIVE)
+               uwb_rc_ie_rm(wlp->rc, UWB_IE_WLP);
+       if (wss->state != WLP_WSS_STATE_NONE) {
+               sysfs_remove_group(&wss->kobj, &wss_attr_group);
+               kobject_put(&wss->kobj);
+       }
+       wss->kobj.parent = NULL;
+       memset(&wss->virtual_addr, 0, sizeof(wss->virtual_addr));
+       /* Cleanup EDA cache */
+       wlp_eda_release(&wlp->eda);
+       wlp_eda_init(&wlp->eda);
+       mutex_unlock(&wss->mutex);
+       d_fnend(5, dev, "wss (%p) \n", wss);
+}
+EXPORT_SYMBOL_GPL(wlp_wss_remove);
index c72a13562954d2d404bea84f810fc1d1a590dd4d..4a4dd9adc328cfc63f797cd2d785c14ed8082259 100644 (file)
@@ -75,6 +75,15 @@ config LCD_PLATFORM
          This driver provides a platform-device registered LCD power
          control interface.
 
+config LCD_TOSA
+       tristate "Sharp SL-6000 LCD Driver"
+       depends on LCD_CLASS_DEVICE && SPI
+       depends on MACH_TOSA
+       default n
+       help
+         If you have an Sharp SL-6000 Zaurus say Y to enable a driver
+         for its LCD.
+
 #
 # Backlight
 #
@@ -115,7 +124,7 @@ config BACKLIGHT_ATMEL_PWM
          called atmel-pwm-bl.
 
 config BACKLIGHT_CORGI
-       tristate "Generic (aka Sharp Corgi) Backlight Driver"
+       tristate "Generic (aka Sharp Corgi) Backlight Driver (DEPRECATED)"
        depends on BACKLIGHT_CLASS_DEVICE
        default n
        help
@@ -123,6 +132,9 @@ config BACKLIGHT_CORGI
          known as the Corgi backlight driver. If you have a Sharp Zaurus
          SL-C7xx, SL-Cxx00 or SL-6000x say y. Most users can say n.
 
+         Note: this driver is marked as deprecated, try enable SPI and
+         use the new corgi_lcd driver with integrated backlight control
+
 config BACKLIGHT_LOCOMO
        tristate "Sharp LOCOMO LCD/Backlight Driver"
        depends on BACKLIGHT_CLASS_DEVICE && SHARP_LOCOMO
@@ -171,6 +183,13 @@ config BACKLIGHT_PWM
          If you have a LCD backlight adjustable by PWM, say Y to enable
          this driver.
 
+config BACKLIGHT_DA903X
+       tristate "Backlight Driver for DA9030/DA9034 using WLED"
+       depends on BACKLIGHT_CLASS_DEVICE && PMIC_DA903X
+       help
+         If you have a LCD backlight connected to the WLED output of DA9030
+         or DA9034 WLED output, say Y here to enable this driver.
+
 config BACKLIGHT_MBP_NVIDIA
        tristate "MacBook Pro Nvidia Backlight Driver"
        depends on BACKLIGHT_CLASS_DEVICE && X86
@@ -179,3 +198,19 @@ config BACKLIGHT_MBP_NVIDIA
          If you have an Apple Macbook Pro with Nvidia graphics hardware say Y
         to enable a driver for its backlight
 
+config BACKLIGHT_TOSA
+       tristate "Sharp SL-6000 Backlight Driver"
+       depends on BACKLIGHT_CLASS_DEVICE && I2C
+       depends on MACH_TOSA && LCD_TOSA
+       default n
+       help
+         If you have an Sharp SL-6000 Zaurus say Y to enable a driver
+         for its backlight
+
+config BACKLIGHT_SAHARA
+       tristate "Tabletkiosk Sahara Touch-iT Backlight Driver"
+       depends on BACKLIGHT_CLASS_DEVICE && X86
+       default n
+       help
+         If you have a Tabletkiosk Sahara Touch-iT, say y to enable the
+         backlight driver.
index 3ec551eb472ce6d46c0a446f22badd1eda586def..103427de670357f4f974fd598b37ee41cd5f6ef2 100644 (file)
@@ -7,6 +7,7 @@ obj-$(CONFIG_LCD_ILI9320)          += ili9320.o
 obj-$(CONFIG_LCD_PLATFORM)        += platform_lcd.o
 obj-$(CONFIG_LCD_VGG2432A4)       += vgg2432a4.o
 obj-$(CONFIG_LCD_TDO24M)          += tdo24m.o
+obj-$(CONFIG_LCD_TOSA)            += tosa_lcd.o
 
 obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
 obj-$(CONFIG_BACKLIGHT_ATMEL_PWM)    += atmel-pwm-bl.o
@@ -17,5 +18,8 @@ obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o
 obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
 obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
 obj-$(CONFIG_BACKLIGHT_PWM)    += pwm_bl.o
+obj-$(CONFIG_BACKLIGHT_DA903X) += da903x.o
 obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o
+obj-$(CONFIG_BACKLIGHT_TOSA)   += tosa_bl.o
+obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
 
diff --git a/drivers/video/backlight/da903x.c b/drivers/video/backlight/da903x.c
new file mode 100644 (file)
index 0000000..242c382
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Backlight driver for Dialog Semiconductor DA9030/DA9034
+ *
+ * Copyright (C) 2008 Compulab, Ltd.
+ *     Mike Rapoport <mike@compulab.co.il>
+ *
+ * Copyright (C) 2006-2008 Marvell International Ltd.
+ *     Eric Miao <eric.miao@marvell.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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/mfd/da903x.h>
+
+#define DA9030_WLED_CONTROL    0x25
+#define DA9030_WLED_CP_EN      (1 << 6)
+#define DA9030_WLED_TRIM(x)    ((x) & 0x7)
+
+#define DA9034_WLED_CONTROL1   0x3C
+#define DA9034_WLED_CONTROL2   0x3D
+
+#define DA9034_WLED_BOOST_EN   (1 << 5)
+
+#define DA9030_MAX_BRIGHTNESS  7
+#define DA9034_MAX_BRIGHTNESS  0x7f
+
+struct da903x_backlight_data {
+       struct device *da903x_dev;
+       int id;
+       int current_brightness;
+};
+
+static int da903x_backlight_set(struct backlight_device *bl, int brightness)
+{
+       struct da903x_backlight_data *data = bl_get_data(bl);
+       struct device *dev = data->da903x_dev;
+       uint8_t val;
+       int ret = 0;
+
+       switch (data->id) {
+       case DA9034_ID_WLED:
+               ret = da903x_update(dev, DA9034_WLED_CONTROL1,
+                               brightness, 0x7f);
+               if (ret)
+                       return ret;
+
+               if (data->current_brightness && brightness == 0)
+                       ret = da903x_clr_bits(dev,
+                                       DA9034_WLED_CONTROL2,
+                                       DA9034_WLED_BOOST_EN);
+
+               if (data->current_brightness == 0 && brightness)
+                       ret = da903x_set_bits(dev,
+                                       DA9034_WLED_CONTROL2,
+                                       DA9034_WLED_BOOST_EN);
+               break;
+       case DA9030_ID_WLED:
+               val = DA9030_WLED_TRIM(brightness);
+               val |= brightness ? DA9030_WLED_CP_EN : 0;
+               ret = da903x_write(dev, DA9030_WLED_CONTROL, val);
+               break;
+       }
+
+       if (ret)
+               return ret;
+
+       data->current_brightness = brightness;
+       return 0;
+}
+
+static int da903x_backlight_update_status(struct backlight_device *bl)
+{
+       int brightness = bl->props.brightness;
+
+       if (bl->props.power != FB_BLANK_UNBLANK)
+               brightness = 0;
+
+       if (bl->props.fb_blank != FB_BLANK_UNBLANK)
+               brightness = 0;
+
+       return da903x_backlight_set(bl, brightness);
+}
+
+static int da903x_backlight_get_brightness(struct backlight_device *bl)
+{
+       struct da903x_backlight_data *data = bl_get_data(bl);
+       return data->current_brightness;
+}
+
+static struct backlight_ops da903x_backlight_ops = {
+       .update_status  = da903x_backlight_update_status,
+       .get_brightness = da903x_backlight_get_brightness,
+};
+
+static int da903x_backlight_probe(struct platform_device *pdev)
+{
+       struct da903x_backlight_data *data;
+       struct backlight_device *bl;
+       int max_brightness;
+
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       if (data == NULL)
+               return -ENOMEM;
+
+       switch (pdev->id) {
+       case DA9030_ID_WLED:
+               max_brightness = DA9030_MAX_BRIGHTNESS;
+               break;
+       case DA9034_ID_WLED:
+               max_brightness = DA9034_MAX_BRIGHTNESS;
+               break;
+       default:
+               dev_err(&pdev->dev, "invalid backlight device ID(%d)\n",
+                               pdev->id);
+               return -EINVAL;
+       }
+
+       data->id = pdev->id;
+       data->da903x_dev = pdev->dev.parent;
+       data->current_brightness = 0;
+
+       bl = backlight_device_register(pdev->name, data->da903x_dev,
+                       data, &da903x_backlight_ops);
+       if (IS_ERR(bl)) {
+               dev_err(&pdev->dev, "failed to register backlight\n");
+               return PTR_ERR(bl);
+       }
+
+       bl->props.max_brightness = max_brightness;
+       bl->props.brightness = max_brightness;
+
+       platform_set_drvdata(pdev, bl);
+       backlight_update_status(bl);
+       return 0;
+}
+
+static int da903x_backlight_remove(struct platform_device *pdev)
+{
+       struct backlight_device *bl = platform_get_drvdata(pdev);
+       struct da903x_backlight_data *data = bl_get_data(bl);
+
+       backlight_device_unregister(bl);
+       kfree(data);
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int da903x_backlight_suspend(struct platform_device *pdev,
+                                pm_message_t state)
+{
+       struct backlight_device *bl = platform_get_drvdata(pdev);
+       return da903x_backlight_set(bl, 0);
+}
+
+static int da903x_backlight_resume(struct platform_device *pdev)
+{
+       struct backlight_device *bl = platform_get_drvdata(pdev);
+
+       backlight_update_status(bl);
+       return 0;
+}
+#else
+#define da903x_backlight_suspend       NULL
+#define da903x_backlight_resume                NULL
+#endif
+
+static struct platform_driver da903x_backlight_driver = {
+       .driver         = {
+               .name   = "da903x-backlight",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = da903x_backlight_probe,
+       .remove         = da903x_backlight_remove,
+       .suspend        = da903x_backlight_suspend,
+       .resume         = da903x_backlight_resume,
+};
+
+static int __init da903x_backlight_init(void)
+{
+       return platform_driver_register(&da903x_backlight_driver);
+}
+module_init(da903x_backlight_init);
+
+static void __exit da903x_backlight_exit(void)
+{
+       platform_driver_unregister(&da903x_backlight_driver);
+}
+module_exit(da903x_backlight_exit);
+
+MODULE_DESCRIPTION("Backlight Driver for Dialog Semiconductor DA9030/DA9034");
+MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"
+             "Mike Rapoport <mike@compulab.co.il>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:da903x-backlight");
diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c
new file mode 100644 (file)
index 0000000..a38fda1
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ *  Backlight Driver for the KB3886 Backlight
+ *
+ *  Copyright (c) 2007-2008 Claudio Nieder
+ *
+ *  Based on corgi_bl.c by Richard Purdie and kb3886 driver by Robert Woerle
+ *
+ *  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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/dmi.h>
+
+#define KB3886_PARENT 0x64
+#define KB3886_IO 0x60
+#define KB3886_ADC_DAC_PWM 0xC4
+#define KB3886_PWM0_WRITE 0x81
+#define KB3886_PWM0_READ 0x41
+
+static DEFINE_MUTEX(bl_mutex);
+
+static void kb3886_bl_set_intensity(int intensity)
+{
+       mutex_lock(&bl_mutex);
+       intensity = intensity&0xff;
+       outb(KB3886_ADC_DAC_PWM, KB3886_PARENT);
+       msleep(10);
+       outb(KB3886_PWM0_WRITE, KB3886_IO);
+       msleep(10);
+       outb(intensity, KB3886_IO);
+       mutex_unlock(&bl_mutex);
+}
+
+struct kb3886bl_machinfo {
+       int max_intensity;
+       int default_intensity;
+       int limit_mask;
+       void (*set_bl_intensity)(int intensity);
+};
+
+static struct kb3886bl_machinfo kb3886_bl_machinfo = {
+       .max_intensity = 0xff,
+       .default_intensity = 0xa0,
+       .limit_mask = 0x7f,
+       .set_bl_intensity = kb3886_bl_set_intensity,
+};
+
+static struct platform_device kb3886bl_device = {
+       .name           = "kb3886-bl",
+       .dev            = {
+               .platform_data  = &kb3886_bl_machinfo,
+       },
+       .id             = -1,
+};
+
+static struct platform_device *devices[] __initdata = {
+       &kb3886bl_device,
+};
+
+/*
+ * Back to driver
+ */
+
+static int kb3886bl_intensity;
+static struct backlight_device *kb3886_backlight_device;
+static struct kb3886bl_machinfo *bl_machinfo;
+
+static unsigned long kb3886bl_flags;
+#define KB3886BL_SUSPENDED     0x01
+
+static struct dmi_system_id __initdata kb3886bl_device_table[] = {
+       {
+               .ident = "Sahara Touch-iT",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "SDV"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "iTouch T201"),
+               },
+       },
+       { }
+};
+
+static int kb3886bl_send_intensity(struct backlight_device *bd)
+{
+       int intensity = bd->props.brightness;
+
+       if (bd->props.power != FB_BLANK_UNBLANK)
+               intensity = 0;
+       if (bd->props.fb_blank != FB_BLANK_UNBLANK)
+               intensity = 0;
+       if (kb3886bl_flags & KB3886BL_SUSPENDED)
+               intensity = 0;
+
+       bl_machinfo->set_bl_intensity(intensity);
+
+       kb3886bl_intensity = intensity;
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int kb3886bl_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       struct backlight_device *bd = platform_get_drvdata(pdev);
+
+       kb3886bl_flags |= KB3886BL_SUSPENDED;
+       backlight_update_status(bd);
+       return 0;
+}
+
+static int kb3886bl_resume(struct platform_device *pdev)
+{
+       struct backlight_device *bd = platform_get_drvdata(pdev);
+
+       kb3886bl_flags &= ~KB3886BL_SUSPENDED;
+       backlight_update_status(bd);
+       return 0;
+}
+#else
+#define kb3886bl_suspend       NULL
+#define kb3886bl_resume                NULL
+#endif
+
+static int kb3886bl_get_intensity(struct backlight_device *bd)
+{
+       return kb3886bl_intensity;
+}
+
+static struct backlight_ops kb3886bl_ops = {
+       .get_brightness = kb3886bl_get_intensity,
+       .update_status  = kb3886bl_send_intensity,
+};
+
+static int kb3886bl_probe(struct platform_device *pdev)
+{
+       struct kb3886bl_machinfo *machinfo = pdev->dev.platform_data;
+
+       bl_machinfo = machinfo;
+       if (!machinfo->limit_mask)
+               machinfo->limit_mask = -1;
+
+       kb3886_backlight_device = backlight_device_register("kb3886-bl",
+               &pdev->dev, NULL, &kb3886bl_ops);
+       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);
+
+       return 0;
+}
+
+static int kb3886bl_remove(struct platform_device *pdev)
+{
+       struct backlight_device *bd = platform_get_drvdata(pdev);
+
+       backlight_device_unregister(bd);
+
+       return 0;
+}
+
+static struct platform_driver kb3886bl_driver = {
+       .probe          = kb3886bl_probe,
+       .remove         = kb3886bl_remove,
+       .suspend        = kb3886bl_suspend,
+       .resume         = kb3886bl_resume,
+       .driver         = {
+               .name   = "kb3886-bl",
+       },
+};
+
+static int __init kb3886_init(void)
+{
+       if (!dmi_check_system(kb3886bl_device_table))
+               return -ENODEV;
+
+       platform_add_devices(devices, ARRAY_SIZE(devices));
+       return platform_driver_register(&kb3886bl_driver);
+}
+
+static void __exit kb3886_exit(void)
+{
+       platform_driver_unregister(&kb3886bl_driver);
+}
+
+module_init(kb3886_init);
+module_exit(kb3886_exit);
+
+MODULE_AUTHOR("Claudio Nieder <private@claudio.ch>");
+MODULE_DESCRIPTION("Tabletkiosk Sahara Touch-iT Backlight Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("dmi:*:svnSDV:pniTouchT201:*");
diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c
new file mode 100644 (file)
index 0000000..43edbad
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ *  LCD / Backlight control code for Sharp SL-6000x (tosa)
+ *
+ *  Copyright (c) 2005         Dirk Opfer
+ *  Copyright (c) 2007,2008    Dmitry Baryshkov
+ *
+ *  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/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+
+#include <asm/mach/sharpsl_param.h>
+
+#include <mach/tosa.h>
+
+#define COMADJ_DEFAULT 97
+
+#define DAC_CH1                0
+#define DAC_CH2                1
+
+struct tosa_bl_data {
+       struct i2c_client *i2c;
+       struct backlight_device *bl;
+
+       int comadj;
+};
+
+static void tosa_bl_set_backlight(struct tosa_bl_data *data, int brightness)
+{
+       struct spi_device *spi = data->i2c->dev.platform_data;
+
+       i2c_smbus_write_byte_data(data->i2c, DAC_CH1, data->comadj);
+
+       /* SetBacklightDuty */
+       i2c_smbus_write_byte_data(data->i2c, DAC_CH2, (u8)(brightness & 0xff));
+
+       /* SetBacklightVR */
+       gpio_set_value(TOSA_GPIO_BL_C20MA, brightness & 0x100);
+
+       tosa_bl_enable(spi, brightness);
+}
+
+static int tosa_bl_update_status(struct backlight_device *dev)
+{
+       struct backlight_properties *props = &dev->props;
+       struct tosa_bl_data *data = dev_get_drvdata(&dev->dev);
+       int power = max(props->power, props->fb_blank);
+       int brightness = props->brightness;
+
+       if (power)
+               brightness = 0;
+
+       tosa_bl_set_backlight(data, brightness);
+
+       return 0;
+}
+
+static int tosa_bl_get_brightness(struct backlight_device *dev)
+{
+       struct backlight_properties *props = &dev->props;
+
+       return props->brightness;
+}
+
+static struct backlight_ops bl_ops = {
+       .get_brightness         = tosa_bl_get_brightness,
+       .update_status          = tosa_bl_update_status,
+};
+
+static int __devinit tosa_bl_probe(struct i2c_client *client,
+               const struct i2c_device_id *id)
+{
+       struct tosa_bl_data *data = kzalloc(sizeof(struct tosa_bl_data), GFP_KERNEL);
+       int ret = 0;
+       if (!data)
+               return -ENOMEM;
+
+       data->comadj = sharpsl_param.comadj == -1 ? COMADJ_DEFAULT : sharpsl_param.comadj;
+
+       ret = gpio_request(TOSA_GPIO_BL_C20MA, "backlight");
+       if (ret) {
+               dev_dbg(&data->bl->dev, "Unable to request gpio!\n");
+               goto err_gpio_bl;
+       }
+       ret = gpio_direction_output(TOSA_GPIO_BL_C20MA, 0);
+       if (ret)
+               goto err_gpio_dir;
+
+       i2c_set_clientdata(client, data);
+       data->i2c = client;
+
+       data->bl = backlight_device_register("tosa-bl", &client->dev,
+                       data, &bl_ops);
+       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);
+
+       return 0;
+
+err_reg:
+       data->bl = NULL;
+       i2c_set_clientdata(client, NULL);
+err_gpio_dir:
+       gpio_free(TOSA_GPIO_BL_C20MA);
+err_gpio_bl:
+       kfree(data);
+       return ret;
+}
+
+static int __devexit tosa_bl_remove(struct i2c_client *client)
+{
+       struct tosa_bl_data *data = i2c_get_clientdata(client);
+
+       backlight_device_unregister(data->bl);
+       data->bl = NULL;
+       i2c_set_clientdata(client, NULL);
+
+       gpio_free(TOSA_GPIO_BL_C20MA);
+
+       kfree(data);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int tosa_bl_suspend(struct i2c_client *client, pm_message_t pm)
+{
+       struct tosa_bl_data *data = i2c_get_clientdata(client);
+
+       tosa_bl_set_backlight(data, 0);
+
+       return 0;
+}
+
+static int tosa_bl_resume(struct i2c_client *client)
+{
+       struct tosa_bl_data *data = i2c_get_clientdata(client);
+
+       backlight_update_status(data->bl);
+       return 0;
+}
+#else
+#define tosa_bl_suspend NULL
+#define tosa_bl_resume NULL
+#endif
+
+static const struct i2c_device_id tosa_bl_id[] = {
+       { "tosa-bl", 0 },
+       { },
+};
+
+
+static struct i2c_driver tosa_bl_driver = {
+       .driver = {
+               .name           = "tosa-bl",
+               .owner          = THIS_MODULE,
+       },
+       .probe          = tosa_bl_probe,
+       .remove         = __devexit_p(tosa_bl_remove),
+       .suspend        = tosa_bl_suspend,
+       .resume         = tosa_bl_resume,
+       .id_table       = tosa_bl_id,
+};
+
+static int __init tosa_bl_init(void)
+{
+       return i2c_add_driver(&tosa_bl_driver);
+}
+
+static void __exit tosa_bl_exit(void)
+{
+       i2c_del_driver(&tosa_bl_driver);
+}
+
+module_init(tosa_bl_init);
+module_exit(tosa_bl_exit);
+
+MODULE_AUTHOR("Dmitry Baryshkov");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("LCD/Backlight control for Sharp SL-6000 PDA");
+
diff --git a/drivers/video/backlight/tosa_lcd.c b/drivers/video/backlight/tosa_lcd.c
new file mode 100644 (file)
index 0000000..57a2664
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ *  LCD / Backlight control code for Sharp SL-6000x (tosa)
+ *
+ *  Copyright (c) 2005         Dirk Opfer
+ *  Copyright (c) 2007,2008    Dmitry Baryshkov
+ *
+ *  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/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/lcd.h>
+#include <linux/fb.h>
+
+#include <asm/mach/sharpsl_param.h>
+
+#include <mach/tosa.h>
+
+#define POWER_IS_ON(pwr)       ((pwr) <= FB_BLANK_NORMAL)
+
+#define TG_REG0_VQV    0x0001
+#define TG_REG0_COLOR  0x0002
+#define TG_REG0_UD     0x0004
+#define TG_REG0_LR     0x0008
+
+#define        DAC_BASE        0x4e
+
+struct tosa_lcd_data {
+       struct spi_device *spi;
+       struct lcd_device *lcd;
+       struct i2c_client *i2c;
+
+       int lcd_power;
+};
+
+static int tosa_tg_send(struct spi_device *spi, int adrs, uint8_t data)
+{
+       u8 buf[1];
+       struct spi_message msg;
+       struct spi_transfer xfer = {
+               .len            = 1,
+               .cs_change      = 1,
+               .tx_buf         = buf,
+       };
+
+       buf[0] = ((adrs & 0x07) << 5) | (data & 0x1f);
+       spi_message_init(&msg);
+       spi_message_add_tail(&xfer, &msg);
+
+       return spi_sync(spi, &msg);
+}
+
+int tosa_bl_enable(struct spi_device *spi, int enable)
+{
+       /* bl_enable GP04=1 otherwise GP04=0*/
+       return tosa_tg_send(spi, TG_GPODR2, enable? 0x01 : 0x00);
+}
+EXPORT_SYMBOL(tosa_bl_enable);
+
+static void tosa_lcd_tg_init(struct tosa_lcd_data *data)
+{
+       /* TG on */
+       gpio_set_value(TOSA_GPIO_TG_ON, 0);
+
+       mdelay(60);
+
+       /* delayed 0clk TCTL signal for VGA */
+       tosa_tg_send(data->spi, TG_TPOSCTL, 0x00);
+       /* GPOS0=powercontrol, GPOS1=GPIO, GPOS2=TCTL */
+       tosa_tg_send(data->spi, TG_GPOSR, 0x02);
+}
+
+static void tosa_lcd_tg_on(struct tosa_lcd_data *data)
+{
+       struct spi_device *spi = data->spi;
+       const int value = TG_REG0_COLOR | TG_REG0_UD | TG_REG0_LR;
+       tosa_tg_send(spi, TG_PNLCTL, value | TG_REG0_VQV); /* this depends on mode */
+
+       /* TG LCD pannel power up */
+       tosa_tg_send(spi, TG_PINICTL,0x4);
+       mdelay(50);
+
+       /* TG LCD GVSS */
+       tosa_tg_send(spi, TG_PINICTL,0x0);
+
+       if (!data->i2c) {
+               /* after the pannel is powered up the first time, we can access the i2c bus */
+               /* so probe for the DAC */
+               struct i2c_adapter *adap = i2c_get_adapter(0);
+               struct i2c_board_info info = {
+                       .type   = "tosa-bl",
+                       .addr   = DAC_BASE,
+                       .platform_data = data->spi,
+               };
+               data->i2c = i2c_new_device(adap, &info);
+       }
+}
+
+static void tosa_lcd_tg_off(struct tosa_lcd_data *data)
+{
+       struct spi_device *spi = data->spi;
+
+       /* TG LCD VHSA off */
+       tosa_tg_send(spi, TG_PINICTL,0x4);
+       mdelay(50);
+
+       /* TG LCD signal off */
+       tosa_tg_send(spi, TG_PINICTL,0x6);
+       mdelay(50);
+
+       /* TG Off */
+       gpio_set_value(TOSA_GPIO_TG_ON, 1);
+       mdelay(100);
+}
+
+int tosa_lcd_set_power(struct lcd_device *lcd, int power)
+{
+       struct tosa_lcd_data *data = lcd_get_data(lcd);
+
+       if (POWER_IS_ON(power) && !POWER_IS_ON(data->lcd_power))
+               tosa_lcd_tg_on(data);
+
+       if (!POWER_IS_ON(power) && POWER_IS_ON(data->lcd_power))
+               tosa_lcd_tg_off(data);
+
+       data->lcd_power = power;
+       return 0;
+}
+
+static int tosa_lcd_get_power(struct lcd_device *lcd)
+{
+       struct tosa_lcd_data *data = lcd_get_data(lcd);
+
+       return data->lcd_power;
+}
+
+static struct lcd_ops tosa_lcd_ops = {
+       .set_power = tosa_lcd_set_power,
+       .get_power = tosa_lcd_get_power,
+};
+
+static int __devinit tosa_lcd_probe(struct spi_device *spi)
+{
+       int ret;
+       struct tosa_lcd_data *data;
+
+       data = kzalloc(sizeof(struct tosa_lcd_data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       /*
+        * bits_per_word cannot be configured in platform data
+        */
+       spi->bits_per_word = 8;
+
+       ret = spi_setup(spi);
+       if (ret < 0)
+               goto err_spi;
+
+       data->spi = spi;
+       dev_set_drvdata(&spi->dev, data);
+
+       ret = gpio_request(TOSA_GPIO_TG_ON, "tg #pwr");
+       if (ret < 0)
+               goto err_gpio_tg;
+
+       mdelay(60);
+
+       ret = gpio_direction_output(TOSA_GPIO_TG_ON, 0);
+       if (ret < 0)
+               goto err_gpio_dir;
+
+       mdelay(60);
+       tosa_lcd_tg_init(data);
+
+       tosa_lcd_tg_on(data);
+
+       data->lcd = lcd_device_register("tosa-lcd", &spi->dev, data,
+                       &tosa_lcd_ops);
+
+       if (IS_ERR(data->lcd)) {
+               ret = PTR_ERR(data->lcd);
+               data->lcd = NULL;
+               goto err_register;
+       }
+
+       return 0;
+
+err_register:
+       tosa_lcd_tg_off(data);
+err_gpio_dir:
+       gpio_free(TOSA_GPIO_TG_ON);
+err_gpio_tg:
+       dev_set_drvdata(&spi->dev, NULL);
+err_spi:
+       kfree(data);
+       return ret;
+}
+
+static int __devexit tosa_lcd_remove(struct spi_device *spi)
+{
+       struct tosa_lcd_data *data = dev_get_drvdata(&spi->dev);
+
+       lcd_device_unregister(data->lcd);
+
+       if (data->i2c)
+               i2c_unregister_device(data->i2c);
+
+       tosa_lcd_tg_off(data);
+
+       gpio_free(TOSA_GPIO_TG_ON);
+       dev_set_drvdata(&spi->dev, NULL);
+       kfree(data);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int tosa_lcd_suspend(struct spi_device *spi, pm_message_t state)
+{
+       struct tosa_lcd_data *data = dev_get_drvdata(&spi->dev);
+
+       tosa_lcd_tg_off(data);
+
+       return 0;
+}
+
+static int tosa_lcd_resume(struct spi_device *spi)
+{
+       struct tosa_lcd_data *data = dev_get_drvdata(&spi->dev);
+
+       tosa_lcd_tg_init(data);
+       if (POWER_IS_ON(data->lcd_power))
+               tosa_lcd_tg_on(data);
+       else
+               tosa_lcd_tg_off(data);
+
+       return 0;
+}
+#else
+#define tosa_lcd_suspend       NULL
+#define tosa_lcd_reume NULL
+#endif
+
+static struct spi_driver tosa_lcd_driver = {
+       .driver = {
+               .name           = "tosa-lcd",
+               .owner          = THIS_MODULE,
+       },
+       .probe          = tosa_lcd_probe,
+       .remove         = __devexit_p(tosa_lcd_remove),
+       .suspend        = tosa_lcd_suspend,
+       .resume         = tosa_lcd_resume,
+};
+
+static int __init tosa_lcd_init(void)
+{
+       return spi_register_driver(&tosa_lcd_driver);
+}
+
+static void __exit tosa_lcd_exit(void)
+{
+       spi_unregister_driver(&tosa_lcd_driver);
+}
+
+module_init(tosa_lcd_init);
+module_exit(tosa_lcd_exit);
+
+MODULE_AUTHOR("Dmitry Baryshkov");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("LCD/Backlight control for Sharp SL-6000 PDA");
+
index 05a28106e8eb7f8fdef5dfb35f0b61d6cd34226e..8782ec1f5aa05f3ef1713992ef09788d78b3fd6c 100644 (file)
@@ -154,7 +154,7 @@ static int ibwdt_set_heartbeat(int t)
                return -EINVAL;
 
        for (i = 0x0F; i > -1; i--)
-               if (wd_times[i] > t)
+               if (wd_times[i] >= t)
                        break;
        wd_margin = i;
        return 0;
index c73b5e2919c6abfddfc11e7290e121ee4d6765b7..ada8ad82d993a43b0e5e928148a9bd65919e536a 100644 (file)
@@ -102,7 +102,7 @@ static void w83697ug_select_wd_register(void)
 
        } else {
                printk(KERN_ERR PFX "No W83697UG/UF could be found\n");
-               return -EIO;
+               return;
        }
 
        outb_p(0x07, WDT_EFER); /* point to logical device number reg */
index 565280ec1c6a221dd3cc3c2652c21548d9d58600..974f56d1ebe1fa6ba67a4998f96f63e1fbdc96e9 100644 (file)
@@ -2,7 +2,7 @@
 
 #include <xen/xenbus.h>
 
-#include <asm-x86/xen/hypervisor.h>
+#include <asm/xen/hypervisor.h>
 #include <asm/cpu.h>
 
 static void enable_hotplug_cpu(int cpu)
index c3290bc186a0e62c36db12cd8ef44c58f0a4f4b0..9ce1ab6c268d7e0c23d2223cc09b74ababae1b7f 100644 (file)
@@ -125,7 +125,7 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
 
        BUG_ON(irq == -1);
 #ifdef CONFIG_SMP
-       irq_desc[irq].affinity = cpumask_of_cpu(cpu);
+       irq_to_desc(irq)->affinity = cpumask_of_cpu(cpu);
 #endif
 
        __clear_bit(chn, cpu_evtchn_mask[cpu_evtchn[chn]]);
@@ -137,10 +137,12 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
 static void init_evtchn_cpu_bindings(void)
 {
 #ifdef CONFIG_SMP
+       struct irq_desc *desc;
        int i;
+
        /* By default all event channels notify CPU#0. */
-       for (i = 0; i < NR_IRQS; i++)
-               irq_desc[i].affinity = cpumask_of_cpu(0);
+       for_each_irq_desc(i, desc)
+               desc->affinity = cpumask_of_cpu(0);
 #endif
 
        memset(cpu_evtchn, 0, sizeof(cpu_evtchn));
@@ -229,12 +231,12 @@ static int find_unbound_irq(void)
        int irq;
 
        /* Only allocate from dynirq range */
-       for (irq = 0; irq < NR_IRQS; irq++)
+       for_each_irq_nr(irq)
                if (irq_bindcount[irq] == 0)
                        break;
 
-       if (irq == NR_IRQS)
-               panic("No available IRQ to bind to: increase NR_IRQS!\n");
+       if (irq == nr_irqs)
+               panic("No available IRQ to bind to: increase nr_irqs!\n");
 
        return irq;
 }
@@ -790,7 +792,7 @@ void xen_irq_resume(void)
                mask_evtchn(evtchn);
 
        /* No IRQ <-> event-channel mappings. */
-       for (irq = 0; irq < NR_IRQS; irq++)
+       for_each_irq_nr(irq)
                irq_info[irq].evtchn = 0; /* zap event-channel binding */
 
        for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++)
@@ -822,7 +824,7 @@ void __init xen_init_IRQ(void)
                mask_evtchn(i);
 
        /* Dynamic IRQ space is currently unbound. Zero the refcnts. */
-       for (i = 0; i < NR_IRQS; i++)
+       for_each_irq_nr(i)
                irq_bindcount[i] = 0;
 
        irq_ctx_init(smp_processor_id());
index 041c526922845433c5a871f3afed75be7f35b0bd..68bf2af6c389568fcbbca52ed3c17a68934cc057 100644 (file)
@@ -178,7 +178,7 @@ v9fs_file_read(struct file *filp, char __user *udata, size_t count,
        int ret;
        struct p9_fid *fid;
 
-       P9_DPRINTK(P9_DEBUG_VFS, "count %d offset %lld\n", count, *offset);
+       P9_DPRINTK(P9_DEBUG_VFS, "count %zu offset %lld\n", count, *offset);
        fid = filp->private_data;
 
        if (count > (fid->clnt->msize - P9_IOHDRSZ))
index e282002b94d23f5e5025bf3344d8f5e0b35f812d..522469a7eca391e51f5b0648027785dff24d3569 100644 (file)
@@ -22,9 +22,10 @@ source "fs/jbd2/Kconfig"
 config FS_MBCACHE
 # Meta block cache for Extended Attributes (ext2/ext3/ext4)
        tristate
-       depends on EXT2_FS_XATTR || EXT3_FS_XATTR || EXT4_FS_XATTR
-       default y if EXT2_FS=y || EXT3_FS=y || EXT4_FS=y
-       default m if EXT2_FS=m || EXT3_FS=m || EXT4_FS=m
+       default y if EXT2_FS=y && EXT2_FS_XATTR
+       default y if EXT3_FS=y && EXT3_FS_XATTR
+       default y if EXT4_FS=y && EXT4_FS_XATTR
+       default m if EXT2_FS_XATTR || EXT3_FS_XATTR || EXT4_FS_XATTR
 
 config REISERFS_FS
        tristate "Reiserfs support"
@@ -403,7 +404,7 @@ config AUTOFS4_FS
          N here.
 
 config FUSE_FS
-       tristate "Filesystem in Userspace support"
+       tristate "FUSE (Filesystem in Userspace) support"
        help
          With FUSE it is possible to implement a fully functional filesystem
          in a userspace program.
index dfda03d4397d03862ae9b64d0832d4d9463010c5..99cf390641f74ee198e5f37d53b9a821b2268f50 100644 (file)
@@ -45,6 +45,7 @@ const struct file_operations afs_dir_file_operations = {
        .release        = afs_release,
        .readdir        = afs_readdir,
        .lock           = afs_lock,
+       .llseek         = generic_file_llseek,
 };
 
 const struct inode_operations afs_dir_inode_operations = {
index 26c71ba1eed49d2f500c9e8044e68693492a47ee..7a83819f6ba29144364f0f5769125d0ecb8f03f3 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -159,17 +159,17 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
        if (!(attr->ia_valid & ~(ATTR_KILL_SUID | ATTR_KILL_SGID)))
                return 0;
 
+       error = security_inode_setattr(dentry, attr);
+       if (error)
+               return error;
+
        if (ia_valid & ATTR_SIZE)
                down_write(&dentry->d_inode->i_alloc_sem);
 
        if (inode->i_op && inode->i_op->setattr) {
-               error = security_inode_setattr(dentry, attr);
-               if (!error)
-                       error = inode->i_op->setattr(dentry, attr);
+               error = inode->i_op->setattr(dentry, attr);
        } else {
                error = inode_change_ok(inode, attr);
-               if (!error)
-                       error = security_inode_setattr(dentry, attr);
                if (!error) {
                        if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
                            (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
index ed8feb052df978fff85f0edaabee9fa17ce9609d..daae463068e4e45615ba4c2ef03000f99fdfed96 100644 (file)
@@ -80,6 +80,7 @@ const struct file_operations bfs_dir_operations = {
        .read           = generic_read_dir,
        .readdir        = bfs_readdir,
        .fsync          = file_fsync,
+       .llseek         = generic_file_llseek,
 };
 
 extern void dump_imap(const char *, struct super_block *);
index e2159063198a072ef75545130ced4eb21e56accf..8fcfa398d35075e1e149b70d62226a6095524ad3 100644 (file)
@@ -1341,20 +1341,15 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
        prstatus->pr_pgrp = task_pgrp_vnr(p);
        prstatus->pr_sid = task_session_vnr(p);
        if (thread_group_leader(p)) {
+               struct task_cputime cputime;
+
                /*
-                * This is the record for the group leader.  Add in the
-                * cumulative times of previous dead threads.  This total
-                * won't include the time of each live thread whose state
-                * is included in the core dump.  The final total reported
-                * to our parent process when it calls wait4 will include
-                * those sums as well as the little bit more time it takes
-                * this and each other thread to finish dying after the
-                * core dump synchronization phase.
+                * This is the record for the group leader.  It shows the
+                * group-wide total, not its individual thread total.
                 */
-               cputime_to_timeval(cputime_add(p->utime, p->signal->utime),
-                                  &prstatus->pr_utime);
-               cputime_to_timeval(cputime_add(p->stime, p->signal->stime),
-                                  &prstatus->pr_stime);
+               thread_group_cputime(p, &cputime);
+               cputime_to_timeval(cputime.utime, &prstatus->pr_utime);
+               cputime_to_timeval(cputime.stime, &prstatus->pr_stime);
        } else {
                cputime_to_timeval(p->utime, &prstatus->pr_utime);
                cputime_to_timeval(p->stime, &prstatus->pr_stime);
index 0e8367c546248987418191c6ab7b14c5be61bec9..5b5424cb339151db85754685f00e2c168ff37908 100644 (file)
@@ -1390,20 +1390,15 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
        prstatus->pr_pgrp = task_pgrp_vnr(p);
        prstatus->pr_sid = task_session_vnr(p);
        if (thread_group_leader(p)) {
+               struct task_cputime cputime;
+
                /*
-                * This is the record for the group leader.  Add in the
-                * cumulative times of previous dead threads.  This total
-                * won't include the time of each live thread whose state
-                * is included in the core dump.  The final total reported
-                * to our parent process when it calls wait4 will include
-                * those sums as well as the little bit more time it takes
-                * this and each other thread to finish dying after the
-                * core dump synchronization phase.
+                * This is the record for the group leader.  It shows the
+                * group-wide total, not its individual thread total.
                 */
-               cputime_to_timeval(cputime_add(p->utime, p->signal->utime),
-                                  &prstatus->pr_utime);
-               cputime_to_timeval(cputime_add(p->stime, p->signal->stime),
-                                  &prstatus->pr_stime);
+               thread_group_cputime(p, &cputime);
+               cputime_to_timeval(cputime.utime, &prstatus->pr_utime);
+               cputime_to_timeval(cputime.stime, &prstatus->pr_stime);
        } else {
                cputime_to_timeval(p->utime, &prstatus->pr_utime);
                cputime_to_timeval(p->stime, &prstatus->pr_stime);
index 218408eed1bb1c4d77f2dd4a04fc9f3101bcb331..88a776fa0ef6e29bc67322f3184cb04f31b2248d 100644 (file)
@@ -840,13 +840,12 @@ EXPORT_SYMBOL_GPL(bd_release_from_disk);
  * to be used for internal purposes.  If you ever need it - reconsider
  * your API.
  */
-struct block_device *open_by_devnum(dev_t dev, unsigned mode)
+struct block_device *open_by_devnum(dev_t dev, fmode_t mode)
 {
        struct block_device *bdev = bdget(dev);
        int err = -ENOMEM;
-       int flags = mode & FMODE_WRITE ? O_RDWR : O_RDONLY;
        if (bdev)
-               err = blkdev_get(bdev, mode, flags);
+               err = blkdev_get(bdev, mode);
        return err ? ERR_PTR(err) : bdev;
 }
 
@@ -975,9 +974,7 @@ void bd_set_size(struct block_device *bdev, loff_t size)
 }
 EXPORT_SYMBOL(bd_set_size);
 
-static int __blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags,
-                       int for_part);
-static int __blkdev_put(struct block_device *bdev, int for_part);
+static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part);
 
 /*
  * bd_mutex locking:
@@ -986,7 +983,7 @@ static int __blkdev_put(struct block_device *bdev, int for_part);
  *    mutex_lock_nested(whole->bd_mutex, 1)
  */
 
-static int do_open(struct block_device *bdev, struct file *file, int for_part)
+static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
 {
        struct gendisk *disk;
        struct hd_struct *part = NULL;
@@ -994,9 +991,9 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
        int partno;
        int perm = 0;
 
-       if (file->f_mode & FMODE_READ)
+       if (mode & FMODE_READ)
                perm |= MAY_READ;
-       if (file->f_mode & FMODE_WRITE)
+       if (mode & FMODE_WRITE)
                perm |= MAY_WRITE;
        /*
         * hooks: /n/, see "layering violations".
@@ -1008,7 +1005,6 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
        }
 
        ret = -ENXIO;
-       file->f_mapping = bdev->bd_inode->i_mapping;
 
        lock_kernel();
 
@@ -1027,7 +1023,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
                if (!partno) {
                        struct backing_dev_info *bdi;
                        if (disk->fops->open) {
-                               ret = disk->fops->open(bdev->bd_inode, file);
+                               ret = disk->fops->open(bdev, mode);
                                if (ret)
                                        goto out_clear;
                        }
@@ -1047,7 +1043,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
                        if (!whole)
                                goto out_clear;
                        BUG_ON(for_part);
-                       ret = __blkdev_get(whole, file->f_mode, file->f_flags, 1);
+                       ret = __blkdev_get(whole, mode, 1);
                        if (ret)
                                goto out_clear;
                        bdev->bd_contains = whole;
@@ -1068,7 +1064,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
                disk = NULL;
                if (bdev->bd_contains == bdev) {
                        if (bdev->bd_disk->fops->open) {
-                               ret = bdev->bd_disk->fops->open(bdev->bd_inode, file);
+                               ret = bdev->bd_disk->fops->open(bdev, mode);
                                if (ret)
                                        goto out_unlock_bdev;
                        }
@@ -1088,7 +1084,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
        bdev->bd_part = NULL;
        bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;
        if (bdev != bdev->bd_contains)
-               __blkdev_put(bdev->bd_contains, 1);
+               __blkdev_put(bdev->bd_contains, mode, 1);
        bdev->bd_contains = NULL;
  out_unlock_bdev:
        mutex_unlock(&bdev->bd_mutex);
@@ -1104,28 +1100,9 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
        return ret;
 }
 
-static int __blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags,
-                       int for_part)
+int blkdev_get(struct block_device *bdev, fmode_t mode)
 {
-       /*
-        * This crockload is due to bad choice of ->open() type.
-        * It will go away.
-        * For now, block device ->open() routine must _not_
-        * examine anything in 'inode' argument except ->i_rdev.
-        */
-       struct file fake_file = {};
-       struct dentry fake_dentry = {};
-       fake_file.f_mode = mode;
-       fake_file.f_flags = flags;
-       fake_file.f_path.dentry = &fake_dentry;
-       fake_dentry.d_inode = bdev->bd_inode;
-
-       return do_open(bdev, &fake_file, for_part);
-}
-
-int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags)
-{
-       return __blkdev_get(bdev, mode, flags, 0);
+       return __blkdev_get(bdev, mode, 0);
 }
 EXPORT_SYMBOL(blkdev_get);
 
@@ -1142,28 +1119,36 @@ static int blkdev_open(struct inode * inode, struct file * filp)
         */
        filp->f_flags |= O_LARGEFILE;
 
+       if (filp->f_flags & O_NDELAY)
+               filp->f_mode |= FMODE_NDELAY;
+       if (filp->f_flags & O_EXCL)
+               filp->f_mode |= FMODE_EXCL;
+       if ((filp->f_flags & O_ACCMODE) == 3)
+               filp->f_mode |= FMODE_WRITE_IOCTL;
+
        bdev = bd_acquire(inode);
        if (bdev == NULL)
                return -ENOMEM;
 
-       res = do_open(bdev, filp, 0);
+       filp->f_mapping = bdev->bd_inode->i_mapping;
+
+       res = blkdev_get(bdev, filp->f_mode);
        if (res)
                return res;
 
-       if (!(filp->f_flags & O_EXCL) )
+       if (!(filp->f_mode & FMODE_EXCL))
                return 0;
 
        if (!(res = bd_claim(bdev, filp)))
                return 0;
 
-       blkdev_put(bdev);
+       blkdev_put(bdev, filp->f_mode);
        return res;
 }
 
-static int __blkdev_put(struct block_device *bdev, int for_part)
+static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
 {
        int ret = 0;
-       struct inode *bd_inode = bdev->bd_inode;
        struct gendisk *disk = bdev->bd_disk;
        struct block_device *victim = NULL;
 
@@ -1178,7 +1163,7 @@ static int __blkdev_put(struct block_device *bdev, int for_part)
        }
        if (bdev->bd_contains == bdev) {
                if (disk->fops->release)
-                       ret = disk->fops->release(bd_inode, NULL);
+                       ret = disk->fops->release(disk, mode);
        }
        if (!bdev->bd_openers) {
                struct module *owner = disk->fops->owner;
@@ -1197,13 +1182,13 @@ static int __blkdev_put(struct block_device *bdev, int for_part)
        mutex_unlock(&bdev->bd_mutex);
        bdput(bdev);
        if (victim)
-               __blkdev_put(victim, 1);
+               __blkdev_put(victim, mode, 1);
        return ret;
 }
 
-int blkdev_put(struct block_device *bdev)
+int blkdev_put(struct block_device *bdev, fmode_t mode)
 {
-       return __blkdev_put(bdev, 0);
+       return __blkdev_put(bdev, mode, 0);
 }
 EXPORT_SYMBOL(blkdev_put);
 
@@ -1212,12 +1197,16 @@ static int blkdev_close(struct inode * inode, struct file * filp)
        struct block_device *bdev = I_BDEV(filp->f_mapping->host);
        if (bdev->bd_holder == filp)
                bd_release(bdev);
-       return blkdev_put(bdev);
+       return blkdev_put(bdev, filp->f_mode);
 }
 
 static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg)
 {
-       return blkdev_ioctl(file->f_mapping->host, file, cmd, arg);
+       struct block_device *bdev = I_BDEV(file->f_mapping->host);
+       fmode_t mode = file->f_mode;
+       if (file->f_flags & O_NDELAY)
+               mode |= FMODE_NDELAY_NOW;
+       return blkdev_ioctl(bdev, mode, cmd, arg);
 }
 
 static const struct address_space_operations def_blk_aops = {
@@ -1253,7 +1242,7 @@ int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg)
        int res;
        mm_segment_t old_fs = get_fs();
        set_fs(KERNEL_DS);
-       res = blkdev_ioctl(bdev->bd_inode, NULL, cmd, arg);
+       res = blkdev_ioctl(bdev, 0, cmd, arg);
        set_fs(old_fs);
        return res;
 }
@@ -1268,33 +1257,33 @@ EXPORT_SYMBOL(ioctl_by_bdev);
  * namespace if possible and return it.  Return ERR_PTR(error)
  * otherwise.
  */
-struct block_device *lookup_bdev(const char *path)
+struct block_device *lookup_bdev(const char *pathname)
 {
        struct block_device *bdev;
        struct inode *inode;
-       struct nameidata nd;
+       struct path path;
        int error;
 
-       if (!path || !*path)
+       if (!pathname || !*pathname)
                return ERR_PTR(-EINVAL);
 
-       error = path_lookup(path, LOOKUP_FOLLOW, &nd);
+       error = kern_path(pathname, LOOKUP_FOLLOW, &path);
        if (error)
                return ERR_PTR(error);
 
-       inode = nd.path.dentry->d_inode;
+       inode = path.dentry->d_inode;
        error = -ENOTBLK;
        if (!S_ISBLK(inode->i_mode))
                goto fail;
        error = -EACCES;
-       if (nd.path.mnt->mnt_flags & MNT_NODEV)
+       if (path.mnt->mnt_flags & MNT_NODEV)
                goto fail;
        error = -ENOMEM;
        bdev = bd_acquire(inode);
        if (!bdev)
                goto fail;
 out:
-       path_put(&nd.path);
+       path_put(&path);
        return bdev;
 fail:
        bdev = ERR_PTR(error);
@@ -1303,32 +1292,29 @@ fail:
 EXPORT_SYMBOL(lookup_bdev);
 
 /**
- * open_bdev_excl  -  open a block device by name and set it up for use
+ * open_bdev_exclusive  -  open a block device by name and set it up for use
  *
  * @path:      special file representing the block device
- * @flags:     %MS_RDONLY for opening read-only
+ * @mode:      FMODE_... combination to pass be used
  * @holder:    owner for exclusion
  *
  * Open the blockdevice described by the special file at @path, claim it
  * for the @holder.
  */
-struct block_device *open_bdev_excl(const char *path, int flags, void *holder)
+struct block_device *open_bdev_exclusive(const char *path, fmode_t mode, void *holder)
 {
        struct block_device *bdev;
-       mode_t mode = FMODE_READ;
        int error = 0;
 
        bdev = lookup_bdev(path);
        if (IS_ERR(bdev))
                return bdev;
 
-       if (!(flags & MS_RDONLY))
-               mode |= FMODE_WRITE;
-       error = blkdev_get(bdev, mode, 0);
+       error = blkdev_get(bdev, mode);
        if (error)
                return ERR_PTR(error);
        error = -EACCES;
-       if (!(flags & MS_RDONLY) && bdev_read_only(bdev))
+       if ((mode & FMODE_WRITE) && bdev_read_only(bdev))
                goto blkdev_put;
        error = bd_claim(bdev, holder);
        if (error)
@@ -1337,26 +1323,27 @@ struct block_device *open_bdev_excl(const char *path, int flags, void *holder)
        return bdev;
        
 blkdev_put:
-       blkdev_put(bdev);
+       blkdev_put(bdev, mode);
        return ERR_PTR(error);
 }
 
-EXPORT_SYMBOL(open_bdev_excl);
+EXPORT_SYMBOL(open_bdev_exclusive);
 
 /**
- * close_bdev_excl  -  release a blockdevice openen by open_bdev_excl()
+ * close_bdev_exclusive  -  close a blockdevice opened by open_bdev_exclusive()
  *
  * @bdev:      blockdevice to close
+ * @mode:      mode, must match that used to open.
  *
- * This is the counterpart to open_bdev_excl().
+ * This is the counterpart to open_bdev_exclusive().
  */
-void close_bdev_excl(struct block_device *bdev)
+void close_bdev_exclusive(struct block_device *bdev, fmode_t mode)
 {
        bd_release(bdev);
-       blkdev_put(bdev);
+       blkdev_put(bdev, mode);
 }
 
-EXPORT_SYMBOL(close_bdev_excl);
+EXPORT_SYMBOL(close_bdev_exclusive);
 
 int __invalidate_device(struct block_device *bdev)
 {
index 262fa10e213d571c4d14e1c6b08a3c5861e55e03..700697a726187863a3d4557b27410192ad7d45d9 100644 (file)
@@ -386,15 +386,22 @@ static int chrdev_open(struct inode *inode, struct file *filp)
        cdev_put(new);
        if (ret)
                return ret;
+
+       ret = -ENXIO;
        filp->f_op = fops_get(p->ops);
-       if (!filp->f_op) {
-               cdev_put(p);
-               return -ENXIO;
-       }
-       if (filp->f_op->open)
+       if (!filp->f_op)
+               goto out_cdev_put;
+
+       if (filp->f_op->open) {
                ret = filp->f_op->open(inode,filp);
-       if (ret)
-               cdev_put(p);
+               if (ret)
+                       goto out_cdev_put;
+       }
+
+       return 0;
+
+ out_cdev_put:
+       cdev_put(p);
        return ret;
 }
 
index 06e521a945c33494130c7f1ab637d5ecfbef234c..8f528ea24c4813fc9c780d2c600262210383db6f 100644 (file)
@@ -1,3 +1,11 @@
+Version 1.55
+------------
+Various fixes to make delete of open files behavior more predictable
+(when delete of an open file fails we mark the file as "delete-on-close"
+in a way that more servers accept, but only if we can first rename the
+file to a temporary name).  Add experimental support for more safely
+handling fcntl(F_SETLEASE).
+
 Version 1.54
 ------------
 Fix premature write failure on congested networks (we would give up
@@ -13,6 +21,7 @@ on dns_upcall (resolving DFS referralls).  Fix plain text password
 authentication (requires setting SecurityFlags to 0x30030 to enable
 lanman and plain text though).  Fix writes to be at correct offset when
 file is open with O_APPEND and file is on a directio (forcediretio) mount.
+Fix bug in rewinding readdir directory searches.  Add nodfs mount option.
 
 Version 1.53
 ------------
index bd2343d4c6a638218d50c80a9091ef3dd8205a14..a439dc1739b3ac7790dd9684cd0837298f5dd5a8 100644 (file)
@@ -463,6 +463,9 @@ A partial list of the supported mount options follows:
                with cifs style mandatory byte range locks (and most
                cifs servers do not yet support requesting advisory
                byte range locks).
+ nodfs          Disable DFS (global name space support) even if the
+               server claims to support it.  This can help work around
+               a problem with parsing of DFS paths with Samba 3.0.24 server.
  remount        remount the share (often used to change from ro to rw mounts
                or vice versa)
  cifsacl        Report mode bits (e.g. on stat) based on the Windows ACL for
@@ -488,6 +491,19 @@ A partial list of the supported mount options follows:
                Note that this differs from the sign mount option in that it
                causes encryption of data sent over this mounted share but other
                shares mounted to the same server are unaffected.
+ locallease     This option is rarely needed. Fcntl F_SETLEASE is
+               used by some applications such as Samba and NFSv4 server to
+               check to see whether a file is cacheable.  CIFS has no way
+               to explicitly request a lease, but can check whether a file
+               is cacheable (oplocked).  Unfortunately, even if a file
+               is not oplocked, it could still be cacheable (ie cifs client
+               could grant fcntl leases if no other local processes are using
+               the file) for cases for example such as when the server does not
+               support oplocks and the user is sure that the only updates to
+               the file will be from this client. Specifying this mount option
+               will allow the cifs client to check for leases (only) locally
+               for files which are not oplocked instead of denying leases
+               in that case. (EXPERIMENTAL)
  sec            Security mode.  Allowed values are:
                        none    attempt to connection as a null user (no name)
                        krb5    Use Kerberos version 5 authentication
@@ -638,6 +654,9 @@ requires enabling CONFIG_CIFS_EXPERIMENTAL
        cifsacl support needed to retrieve approximated mode bits based on
                the contents on the CIFS ACL.
 
+       lease support: cifs will check the oplock state before calling into
+       the vfs to see if we can grant a lease on a file.
+
        DNOTIFY fcntl: needed for support of directory change 
                            notification and perhaps later for file leases)
 
index 25ecbd5b040476bf13716ccfbebc5e8032905bd2..ac5915d61dca768d4f71d689c5948712e2bf012f 100644 (file)
@@ -275,9 +275,12 @@ static int cifs_permission(struct inode *inode, int mask)
 
        cifs_sb = CIFS_SB(inode->i_sb);
 
-       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
-               return 0;
-       else /* file mode might have been restricted at mount time
+       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
+               if ((mask & MAY_EXEC) && !execute_ok(inode))
+                       return -EACCES;
+               else
+                       return 0;
+       } else /* file mode might have been restricted at mount time
                on the client (above and beyond ACL on servers) for
                servers which do not support setting and viewing mode bits,
                so allowing client to check permissions is useful */
@@ -309,6 +312,7 @@ cifs_alloc_inode(struct super_block *sb)
        file data or metadata */
        cifs_inode->clientCanCacheRead = false;
        cifs_inode->clientCanCacheAll = false;
+       cifs_inode->delete_pending = false;
        cifs_inode->vfs_inode.i_blkbits = 14;  /* 2**14 = CIFS_MAX_MSGSIZE */
 
        /* Can not set i_flags here - they get immediately overwritten
@@ -617,6 +621,37 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
        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
+          although I doubt that BKL is needed here in cifs */
+       struct inode *inode = file->f_path.dentry->d_inode;
+
+       if (!(S_ISREG(inode->i_mode)))
+               return -EINVAL;
+
+       /* check if file is oplocked */
+       if (((arg == F_RDLCK) &&
+               (CIFS_I(inode)->clientCanCacheRead)) ||
+           ((arg == F_WRLCK) &&
+               (CIFS_I(inode)->clientCanCacheAll)))
+               return generic_setlease(file, arg, lease);
+       else if (CIFS_SB(inode->i_sb)->tcon->local_lease &&
+                       !CIFS_I(inode)->clientCanCacheRead)
+               /* If the server claims to support oplock on this
+                  file, then we still need to check oplock even
+                  if the local_lease mount option is set, but there
+                  are servers which do not support oplock for which
+                  this mount option may be useful if the user
+                  knows that the file won't be changed on the server
+                  by anyone else */
+               return generic_setlease(file, arg, lease);
+       else
+               return -EAGAIN;
+}
+#endif
+
 struct file_system_type cifs_fs_type = {
        .owner = THIS_MODULE,
        .name = "cifs",
@@ -695,6 +730,7 @@ const struct file_operations cifs_file_ops = {
 
 #ifdef CONFIG_CIFS_EXPERIMENTAL
        .dir_notify = cifs_dir_notify,
+       .setlease = cifs_setlease,
 #endif /* CONFIG_CIFS_EXPERIMENTAL */
 };
 
@@ -715,6 +751,7 @@ const struct file_operations cifs_file_direct_ops = {
        .llseek = cifs_llseek,
 #ifdef CONFIG_CIFS_EXPERIMENTAL
        .dir_notify = cifs_dir_notify,
+       .setlease = cifs_setlease,
 #endif /* CONFIG_CIFS_EXPERIMENTAL */
 };
 const struct file_operations cifs_file_nobrl_ops = {
@@ -735,6 +772,7 @@ const struct file_operations cifs_file_nobrl_ops = {
 
 #ifdef CONFIG_CIFS_EXPERIMENTAL
        .dir_notify = cifs_dir_notify,
+       .setlease = cifs_setlease,
 #endif /* CONFIG_CIFS_EXPERIMENTAL */
 };
 
@@ -754,6 +792,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = {
        .llseek = cifs_llseek,
 #ifdef CONFIG_CIFS_EXPERIMENTAL
        .dir_notify = cifs_dir_notify,
+       .setlease = cifs_setlease,
 #endif /* CONFIG_CIFS_EXPERIMENTAL */
 };
 
@@ -765,6 +804,7 @@ const struct file_operations cifs_dir_ops = {
        .dir_notify = cifs_dir_notify,
 #endif /* CONFIG_CIFS_EXPERIMENTAL */
        .unlocked_ioctl  = cifs_ioctl,
+       .llseek = generic_file_llseek,
 };
 
 static void
@@ -945,6 +985,12 @@ static int cifs_oplock_thread(void *dummyarg)
                                the call */
                        /* mutex_lock(&inode->i_mutex);*/
                        if (S_ISREG(inode->i_mode)) {
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+                               if (CIFS_I(inode)->clientCanCacheAll == 0)
+                                       break_lease(inode, FMODE_READ);
+                               else if (CIFS_I(inode)->clientCanCacheRead == 0)
+                                       break_lease(inode, FMODE_WRITE);
+#endif
                                rc = filemap_fdatawrite(inode->i_mapping);
                                if (CIFS_I(inode)->clientCanCacheRead == 0) {
                                        waitrc = filemap_fdatawait(
index f7b4a5cd837b98184cc35aa4ea9d7163b4f36cb7..074de0b5064d094c620b6a60de53cd08ce143565 100644 (file)
@@ -101,5 +101,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.54"
+#define CIFS_VERSION   "1.55"
 #endif                         /* _CIFSFS_H */
index 0d22479d99b7c0de7a145b84ee1f246136fde8f8..c791e5b5a914e087fa5c5a20a3a48d58f7fa4cc0 100644 (file)
@@ -285,6 +285,7 @@ struct cifsTconInfo {
        bool seal:1;      /* transport encryption for this mounted share */
        bool unix_ext:1;  /* if false disable Linux extensions to CIFS protocol
                                for this mount even if server would support */
+       bool local_lease:1; /* check leases (only) on local system not remote */
        /* BB add field for back pointer to sb struct(s)? */
 };
 
@@ -353,6 +354,7 @@ struct cifsInodeInfo {
        bool clientCanCacheRead:1;      /* read oplock */
        bool clientCanCacheAll:1;       /* read and writebehind oplock */
        bool oplockPending:1;
+       bool delete_pending:1;          /* DELETE_ON_CLOSE is set */
        struct inode vfs_inode;
 };
 
index 6f4ffe15d68df73f79d822498264bb4958434a3c..843a85fb8b9ac8a1189016be9ac59f6b0b8767f4 100644 (file)
@@ -1309,6 +1309,7 @@ OldOpenRetry:
                                cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
                        pfile_info->EndOfFile = pfile_info->AllocationSize;
                        pfile_info->NumberOfLinks = cpu_to_le32(1);
+                       pfile_info->DeletePending = 0;
                }
        }
 
@@ -1410,6 +1411,7 @@ openRetry:
                    pfile_info->AllocationSize = pSMBr->AllocationSize;
                    pfile_info->EndOfFile = pSMBr->EndOfFile;
                    pfile_info->NumberOfLinks = cpu_to_le32(1);
+                   pfile_info->DeletePending = 0;
                }
        }
 
index 4c13bcdb92a5f4800cbd9f1a1d8bb844e6844a5c..71b7661e2260229efc1fa8eadd7ebf187a5ec8a7 100644 (file)
@@ -90,6 +90,8 @@ struct smb_vol {
        bool nocase:1;     /* request case insensitive filenames */
        bool nobrl:1;      /* disable sending byte range locks to srv */
        bool seal:1;       /* request transport encryption on share */
+       bool nodfs:1;      /* Do not request DFS, even if available */
+       bool local_lease:1; /* check leases only on local system, not remote */
        unsigned int rsize;
        unsigned int wsize;
        unsigned int sockopt;
@@ -124,7 +126,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
        struct mid_q_entry *mid_entry;
 
        spin_lock(&GlobalMid_Lock);
-       if (kthread_should_stop()) {
+       if (server->tcpStatus == CifsExiting) {
                /* the demux thread will exit normally
                next time through the loop */
                spin_unlock(&GlobalMid_Lock);
@@ -184,7 +186,8 @@ cifs_reconnect(struct TCP_Server_Info *server)
        spin_unlock(&GlobalMid_Lock);
        up(&server->tcpSem);
 
-       while ((!kthread_should_stop()) && (server->tcpStatus != CifsGood)) {
+       while ((server->tcpStatus != CifsExiting) &&
+              (server->tcpStatus != CifsGood)) {
                try_to_freeze();
                if (server->protocolType == IPV6) {
                        rc = ipv6_connect(&server->addr.sockAddr6,
@@ -201,7 +204,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
                } else {
                        atomic_inc(&tcpSesReconnectCount);
                        spin_lock(&GlobalMid_Lock);
-                       if (!kthread_should_stop())
+                       if (server->tcpStatus != CifsExiting)
                                server->tcpStatus = CifsGood;
                        server->sequence_number = 0;
                        spin_unlock(&GlobalMid_Lock);
@@ -356,7 +359,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                                GFP_KERNEL);
 
        set_freezable();
-       while (!kthread_should_stop()) {
+       while (server->tcpStatus != CifsExiting) {
                if (try_to_freeze())
                        continue;
                if (bigbuf == NULL) {
@@ -397,7 +400,7 @@ incomplete_rcv:
                    kernel_recvmsg(csocket, &smb_msg,
                                &iov, 1, pdu_length, 0 /* BB other flags? */);
 
-               if (kthread_should_stop()) {
+               if (server->tcpStatus == CifsExiting) {
                        break;
                } else if (server->tcpStatus == CifsNeedReconnect) {
                        cFYI(1, ("Reconnect after server stopped responding"));
@@ -522,7 +525,7 @@ incomplete_rcv:
                     total_read += length) {
                        length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
                                                pdu_length - total_read, 0);
-                       if (kthread_should_stop() ||
+                       if ((server->tcpStatus == CifsExiting) ||
                            (length == -EINTR)) {
                                /* then will exit */
                                reconnect = 2;
@@ -651,14 +654,6 @@ multi_t2_fnd:
        spin_unlock(&GlobalMid_Lock);
        wake_up_all(&server->response_q);
 
-       /* don't exit until kthread_stop is called */
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       while (!kthread_should_stop()) {
-               schedule();
-               set_current_state(TASK_UNINTERRUPTIBLE);
-       }
-       set_current_state(TASK_RUNNING);
-
        /* check if we have blocked requests that need to free */
        /* Note that cifs_max_pending is normally 50, but
        can be set at module install time to as little as two */
@@ -755,6 +750,7 @@ multi_t2_fnd:
        write_unlock(&GlobalSMBSeslock);
 
        kfree(server->hostname);
+       task_to_wake = xchg(&server->tsk, NULL);
        kfree(server);
 
        length = atomic_dec_return(&tcpSesAllocCount);
@@ -762,6 +758,16 @@ multi_t2_fnd:
                mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
                                GFP_KERNEL);
 
+       /* if server->tsk was NULL then wait for a signal before exiting */
+       if (!task_to_wake) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               while (!signal_pending(current)) {
+                       schedule();
+                       set_current_state(TASK_INTERRUPTIBLE);
+               }
+               set_current_state(TASK_RUNNING);
+       }
+
        return 0;
 }
 
@@ -1218,6 +1224,8 @@ cifs_parse_mount_options(char *options, const char *devname,
                        vol->sfu_emul = 1;
                } else if (strnicmp(data, "nosfu", 5) == 0) {
                        vol->sfu_emul = 0;
+               } else if (strnicmp(data, "nodfs", 5) == 0) {
+                       vol->nodfs = 1;
                } else if (strnicmp(data, "posixpaths", 10) == 0) {
                        vol->posix_paths = 1;
                } else if (strnicmp(data, "noposixpaths", 12) == 0) {
@@ -1268,6 +1276,10 @@ cifs_parse_mount_options(char *options, const char *devname,
                        vol->no_psx_acl = 0;
                } else if (strnicmp(data, "noacl", 5) == 0) {
                        vol->no_psx_acl = 1;
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+               } else if (strnicmp(data, "locallease", 6) == 0) {
+                       vol->local_lease = 1;
+#endif
                } else if (strnicmp(data, "sign", 4) == 0) {
                        vol->secFlg |= CIFSSEC_MUST_SIGN;
                } else if (strnicmp(data, "seal", 4) == 0) {
@@ -1845,6 +1857,16 @@ convert_delimiter(char *path, char delim)
        }
 }
 
+static void
+kill_cifsd(struct TCP_Server_Info *server)
+{
+       struct task_struct *task;
+
+       task = xchg(&server->tsk, NULL);
+       if (task)
+               force_sig(SIGKILL, task);
+}
+
 int
 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
           char *mount_data, const char *devname)
@@ -2166,6 +2188,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                           for the retry flag is used */
                        tcon->retry = volume_info.retry;
                        tcon->nocase = volume_info.nocase;
+                       tcon->local_lease = volume_info.local_lease;
                        if (tcon->seal != volume_info.seal)
                                cERROR(1, ("transport encryption setting "
                                           "conflicts with existing tid"));
@@ -2197,6 +2220,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                                                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) {
                                        atomic_inc(&pSesInfo->inUse);
@@ -2225,14 +2254,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                        spin_lock(&GlobalMid_Lock);
                        srvTcp->tcpStatus = CifsExiting;
                        spin_unlock(&GlobalMid_Lock);
-                       if (srvTcp->tsk) {
-                               /* If we could verify that kthread_stop would
-                                  always wake up processes blocked in
-                                  tcp in recv_mesg then we could remove the
-                                  send_sig call */
-                               force_sig(SIGKILL, srvTcp->tsk);
-                               kthread_stop(srvTcp->tsk);
-                       }
+                       kill_cifsd(srvTcp);
                }
                 /* If find_unc succeeded then rc == 0 so we can not end */
                if (tcon)  /* up accidently freeing someone elses tcon struct */
@@ -2245,19 +2267,15 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                                        temp_rc = CIFSSMBLogoff(xid, pSesInfo);
                                        /* if the socketUseCount is now zero */
                                        if ((temp_rc == -ESHUTDOWN) &&
-                                           (pSesInfo->server) &&
-                                           (pSesInfo->server->tsk)) {
-                                               force_sig(SIGKILL,
-                                                       pSesInfo->server->tsk);
-                                               kthread_stop(pSesInfo->server->tsk);
-                                       }
+                                           (pSesInfo->server))
+                                               kill_cifsd(pSesInfo->server);
                                } else {
                                        cFYI(1, ("No session or bad tcon"));
-                                       if ((pSesInfo->server) &&
-                                           (pSesInfo->server->tsk)) {
-                                               force_sig(SIGKILL,
-                                                       pSesInfo->server->tsk);
-                                               kthread_stop(pSesInfo->server->tsk);
+                                       if (pSesInfo->server) {
+                                               spin_lock(&GlobalMid_Lock);
+                                               srvTcp->tcpStatus = CifsExiting;
+                                               spin_unlock(&GlobalMid_Lock);
+                                               kill_cifsd(pSesInfo->server);
                                        }
                                }
                                sesInfoFree(pSesInfo);
@@ -3544,7 +3562,6 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
        int rc = 0;
        int xid;
        struct cifsSesInfo *ses = NULL;
-       struct task_struct *cifsd_task;
        char *tmp;
 
        xid = GetXid();
@@ -3560,7 +3577,6 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
                tconInfoFree(cifs_sb->tcon);
                if ((ses) && (ses->server)) {
                        /* save off task so we do not refer to ses later */
-                       cifsd_task = ses->server->tsk;
                        cFYI(1, ("About to do SMBLogoff "));
                        rc = CIFSSMBLogoff(xid, ses);
                        if (rc == -EBUSY) {
@@ -3568,10 +3584,8 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
                                return 0;
                        } else if (rc == -ESHUTDOWN) {
                                cFYI(1, ("Waking up socket by sending signal"));
-                               if (cifsd_task) {
-                                       force_sig(SIGKILL, cifsd_task);
-                                       kthread_stop(cifsd_task);
-                               }
+                               if (ses->server)
+                                       kill_cifsd(ses->server);
                                rc = 0;
                        } /* else - we have an smb session
                                left on this socket do not kill cifsd */
@@ -3701,7 +3715,9 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
                cERROR(1, ("Send error in SessSetup = %d", rc));
        } else {
                cFYI(1, ("CIFS Session Established successfully"));
+                       spin_lock(&GlobalMid_Lock);
                        pSesInfo->status = CifsGood;
+                       spin_unlock(&GlobalMid_Lock);
        }
 
 ss_err_exit:
index a8c833345fc98ad8442c70457ca654a881595883..d54fa8aeaea9fda413091776021cbee00cccc4f8 100644 (file)
@@ -506,6 +506,7 @@ int cifs_get_inode_info(struct inode **pinode,
        inode = *pinode;
        cifsInfo = CIFS_I(inode);
        cifsInfo->cifsAttrs = attr;
+       cifsInfo->delete_pending = pfindData->DeletePending ? true : false;
        cFYI(1, ("Old time %ld", cifsInfo->time));
        cifsInfo->time = jiffies;
        cFYI(1, ("New time %ld", cifsInfo->time));
@@ -772,63 +773,106 @@ out:
  * anything else.
  */
 static int
-cifs_rename_pending_delete(char *full_path, struct inode *inode, int xid)
+cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
 {
        int oplock = 0;
        int rc;
        __u16 netfid;
+       struct inode *inode = dentry->d_inode;
        struct cifsInodeInfo *cifsInode = CIFS_I(inode);
        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
        struct cifsTconInfo *tcon = cifs_sb->tcon;
-       __u32 dosattr;
-       FILE_BASIC_INFO *info_buf;
+       __u32 dosattr, origattr;
+       FILE_BASIC_INFO *info_buf = NULL;
 
        rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN,
-                        DELETE|FILE_WRITE_ATTRIBUTES,
-                        CREATE_NOT_DIR|CREATE_DELETE_ON_CLOSE,
+                        DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR,
                         &netfid, &oplock, NULL, cifs_sb->local_nls,
                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
        if (rc != 0)
                goto out;
 
-       /* set ATTR_HIDDEN and clear ATTR_READONLY */
-       cifsInode = CIFS_I(inode);
-       dosattr = cifsInode->cifsAttrs & ~ATTR_READONLY;
+       origattr = cifsInode->cifsAttrs;
+       if (origattr == 0)
+               origattr |= ATTR_NORMAL;
+
+       dosattr = origattr & ~ATTR_READONLY;
        if (dosattr == 0)
                dosattr |= ATTR_NORMAL;
        dosattr |= ATTR_HIDDEN;
 
-       info_buf = kzalloc(sizeof(*info_buf), GFP_KERNEL);
-       if (info_buf == NULL) {
-               rc = -ENOMEM;
-               goto out_close;
+       /* set ATTR_HIDDEN and clear ATTR_READONLY, but only if needed */
+       if (dosattr != origattr) {
+               info_buf = kzalloc(sizeof(*info_buf), GFP_KERNEL);
+               if (info_buf == NULL) {
+                       rc = -ENOMEM;
+                       goto out_close;
+               }
+               info_buf->Attributes = cpu_to_le32(dosattr);
+               rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid,
+                                       current->tgid);
+               /* although we would like to mark the file hidden
+                  if that fails we will still try to rename it */
+               if (rc != 0)
+                       cifsInode->cifsAttrs = dosattr;
+               else
+                       dosattr = origattr; /* since not able to change them */
        }
-       info_buf->Attributes = cpu_to_le32(dosattr);
-       rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid, current->tgid);
-       kfree(info_buf);
-       if (rc != 0)
-               goto out_close;
-       cifsInode->cifsAttrs = dosattr;
 
-       /* silly-rename the file */
-       CIFSSMBRenameOpenFile(xid, tcon, netfid, NULL, cifs_sb->local_nls,
+       /* rename the file */
+       rc = CIFSSMBRenameOpenFile(xid, tcon, netfid, NULL, cifs_sb->local_nls,
                                   cifs_sb->mnt_cifs_flags &
                                            CIFS_MOUNT_MAP_SPECIAL_CHR);
+       if (rc != 0) {
+               rc = -ETXTBSY;
+               goto undo_setattr;
+       }
 
-       /* set DELETE_ON_CLOSE */
-       rc = CIFSSMBSetFileDisposition(xid, tcon, true, netfid, current->tgid);
-
-       /*
-        * some samba versions return -ENOENT when we try to set the file
-        * disposition here. Likely a samba bug, but work around it for now
-        */
-       if (rc == -ENOENT)
-               rc = 0;
+       /* try to set DELETE_ON_CLOSE */
+       if (!cifsInode->delete_pending) {
+               rc = CIFSSMBSetFileDisposition(xid, tcon, true, netfid,
+                                              current->tgid);
+               /*
+                * some samba versions return -ENOENT when we try to set the
+                * file disposition here. Likely a samba bug, but work around
+                * it for now. This means that some cifsXXX files may hang
+                * around after they shouldn't.
+                *
+                * BB: remove this hack after more servers have the fix
+                */
+               if (rc == -ENOENT)
+                       rc = 0;
+               else if (rc != 0) {
+                       rc = -ETXTBSY;
+                       goto undo_rename;
+               }
+               cifsInode->delete_pending = true;
+       }
 
 out_close:
        CIFSSMBClose(xid, tcon, netfid);
 out:
+       kfree(info_buf);
        return rc;
+
+       /*
+        * reset everything back to the original state. Don't bother
+        * dealing with errors here since we can't do anything about
+        * them anyway.
+        */
+undo_rename:
+       CIFSSMBRenameOpenFile(xid, tcon, netfid, dentry->d_name.name,
+                               cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
+                                           CIFS_MOUNT_MAP_SPECIAL_CHR);
+undo_setattr:
+       if (dosattr != origattr) {
+               info_buf->Attributes = cpu_to_le32(origattr);
+               if (!CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid,
+                                       current->tgid))
+                       cifsInode->cifsAttrs = origattr;
+       }
+
+       goto out_close;
 }
 
 int cifs_unlink(struct inode *dir, struct dentry *dentry)
@@ -878,7 +922,7 @@ psx_del_no_retry:
        } else if (rc == -ENOENT) {
                d_drop(dentry);
        } else if (rc == -ETXTBSY) {
-               rc = cifs_rename_pending_delete(full_path, inode, xid);
+               rc = cifs_rename_pending_delete(full_path, dentry, xid);
                if (rc == 0)
                        drop_nlink(inode);
        } else if (rc == -EACCES && dosattr == 0) {
@@ -1241,22 +1285,21 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
        return rc;
 }
 
-int cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
-       struct inode *target_inode, struct dentry *target_direntry)
+int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
+       struct inode *target_dir, struct dentry *target_dentry)
 {
        char *fromName = NULL;
        char *toName = NULL;
        struct cifs_sb_info *cifs_sb_source;
        struct cifs_sb_info *cifs_sb_target;
-       struct cifsTconInfo *pTcon;
+       struct cifsTconInfo *tcon;
        FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
        FILE_UNIX_BASIC_INFO *info_buf_target;
-       int xid;
-       int rc;
+       int xid, rc, tmprc;
 
-       cifs_sb_target = CIFS_SB(target_inode->i_sb);
-       cifs_sb_source = CIFS_SB(source_inode->i_sb);
-       pTcon = cifs_sb_source->tcon;
+       cifs_sb_target = CIFS_SB(target_dir->i_sb);
+       cifs_sb_source = CIFS_SB(source_dir->i_sb);
+       tcon = cifs_sb_source->tcon;
 
        xid = GetXid();
 
@@ -1264,7 +1307,7 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
         * BB: this might be allowed if same server, but different share.
         * Consider adding support for this
         */
-       if (pTcon != cifs_sb_target->tcon) {
+       if (tcon != cifs_sb_target->tcon) {
                rc = -EXDEV;
                goto cifs_rename_exit;
        }
@@ -1273,65 +1316,65 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
         * we already have the rename sem so we do not need to
         * grab it again here to protect the path integrity
         */
-       fromName = build_path_from_dentry(source_direntry);
+       fromName = build_path_from_dentry(source_dentry);
        if (fromName == NULL) {
                rc = -ENOMEM;
                goto cifs_rename_exit;
        }
 
-       toName = build_path_from_dentry(target_direntry);
+       toName = build_path_from_dentry(target_dentry);
        if (toName == NULL) {
                rc = -ENOMEM;
                goto cifs_rename_exit;
        }
 
-       rc = cifs_do_rename(xid, source_direntry, fromName,
-                           target_direntry, toName);
+       rc = cifs_do_rename(xid, source_dentry, fromName,
+                           target_dentry, toName);
 
-       if (rc == -EEXIST) {
-               if (pTcon->unix_ext) {
-                       /*
-                        * Are src and dst hardlinks of same inode? We can
-                        * only tell with unix extensions enabled
-                        */
-                       info_buf_source =
-                               kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO),
-                                               GFP_KERNEL);
-                       if (info_buf_source == NULL)
-                               goto unlink_target;
-
-                       info_buf_target = info_buf_source + 1;
-                       rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName,
-                                               info_buf_source,
-                                               cifs_sb_source->local_nls,
-                                               cifs_sb_source->mnt_cifs_flags &
-                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
-                       if (rc != 0)
-                               goto unlink_target;
-
-                       rc = CIFSSMBUnixQPathInfo(xid, pTcon,
-                                               toName, info_buf_target,
-                                               cifs_sb_target->local_nls,
-                                               /* remap based on source sb */
-                                               cifs_sb_source->mnt_cifs_flags &
-                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
+       if (rc == -EEXIST && tcon->unix_ext) {
+               /*
+                * Are src and dst hardlinks of same inode? We can
+                * only tell with unix extensions enabled
+                */
+               info_buf_source =
+                       kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO),
+                                       GFP_KERNEL);
+               if (info_buf_source == NULL) {
+                       rc = -ENOMEM;
+                       goto cifs_rename_exit;
+               }
 
-                       if (rc == 0 && (info_buf_source->UniqueId ==
-                                       info_buf_target->UniqueId))
-                               /* same file, POSIX says that this is a noop */
-                               goto cifs_rename_exit;
-               } /* else ... BB we could add the same check for Windows by
+               info_buf_target = info_buf_source + 1;
+               tmprc = CIFSSMBUnixQPathInfo(xid, tcon, fromName,
+                                       info_buf_source,
+                                       cifs_sb_source->local_nls,
+                                       cifs_sb_source->mnt_cifs_flags &
+                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
+               if (tmprc != 0)
+                       goto unlink_target;
+
+               tmprc = CIFSSMBUnixQPathInfo(xid, tcon,
+                                       toName, info_buf_target,
+                                       cifs_sb_target->local_nls,
+                                       /* remap based on source sb */
+                                       cifs_sb_source->mnt_cifs_flags &
+                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
+
+               if (tmprc == 0 && (info_buf_source->UniqueId ==
+                                  info_buf_target->UniqueId))
+                       /* same file, POSIX says that this is a noop */
+                       goto cifs_rename_exit;
+       } /* else ... BB we could add the same check for Windows by
                     checking the UniqueId via FILE_INTERNAL_INFO */
+
 unlink_target:
-               /*
-                * we either can not tell the files are hardlinked (as with
-                * Windows servers) or files are not hardlinked. Delete the
-                * target manually before renaming to follow POSIX rather than
-                * Windows semantics
-                */
-               cifs_unlink(target_inode, target_direntry);
-               rc = cifs_do_rename(xid, source_direntry, fromName,
-                                   target_direntry, toName);
+       if ((rc == -EACCES) || (rc == -EEXIST)) {
+               tmprc = cifs_unlink(target_dir, target_dentry);
+               if (tmprc)
+                       goto cifs_rename_exit;
+
+               rc = cifs_do_rename(xid, source_dentry, fromName,
+                                   target_dentry, toName);
        }
 
 cifs_rename_exit:
index 765adf12d54fa635d594b0ea25033aa51f186b7f..58d57299f2a08c432625f9be298e731e2fa7bae0 100644 (file)
@@ -762,14 +762,15 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
                                 rc));
                        return rc;
                }
+               cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
        }
 
        while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
              (rc == 0) && !cifsFile->srch_inf.endOfSearch) {
                cFYI(1, ("calling findnext2"));
-               cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
                rc = CIFSFindNext(xid, pTcon, cifsFile->netfid,
                                  &cifsFile->srch_inf);
+               cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
                if (rc)
                        return -ENOENT;
        }
index c5916228243c1516b2d62e6b06cea208523a09ac..75b1fa90b2cb8ee205efc96bbbb8a7c71fc9a1e1 100644 (file)
@@ -146,6 +146,9 @@ int coda_permission(struct inode *inode, int mask)
        if (!mask)
                return 0; 
 
+       if ((mask & MAY_EXEC) && !execute_ok(inode))
+               return -EACCES;
+
        lock_kernel();
 
        if (coda_cache_check(inode, mask))
index c51365422aa8da4311133c3b0ff773421efbc723..773f2ce9aa068e48a865c677cf07c717d408777b 100644 (file)
@@ -43,7 +43,7 @@ const struct file_operations coda_ioctl_operations = {
 /* the coda pioctl inode ops */
 static int coda_ioctl_permission(struct inode *inode, int mask)
 {
-        return 0;
+       return (mask & MAY_EXEC) ? -EACCES : 0;
 }
 
 static int coda_pioctl(struct inode * inode, struct file * filp, 
index 5f9ec449c799854e19a9190b489ccf4a23fc0b03..fe3c9bf876089f1d71f7b45b92fb5110693eb599 100644 (file)
@@ -869,7 +869,7 @@ asmlinkage long compat_sys_old_readdir(unsigned int fd,
        buf.dirent = dirent;
 
        error = vfs_readdir(file, compat_fillonedir, &buf);
-       if (error >= 0)
+       if (buf.result)
                error = buf.result;
 
        fput(file);
@@ -956,9 +956,8 @@ asmlinkage long compat_sys_getdents(unsigned int fd,
        buf.error = 0;
 
        error = vfs_readdir(file, compat_filldir, &buf);
-       if (error < 0)
-               goto out_putf;
-       error = buf.error;
+       if (error >= 0)
+               error = buf.error;
        lastdirent = buf.previous;
        if (lastdirent) {
                if (put_user(file->f_pos, &lastdirent->d_off))
@@ -966,8 +965,6 @@ asmlinkage long compat_sys_getdents(unsigned int fd,
                else
                        error = count - buf.count;
        }
-
-out_putf:
        fput(file);
 out:
        return error;
@@ -1047,19 +1044,16 @@ asmlinkage long compat_sys_getdents64(unsigned int fd,
        buf.error = 0;
 
        error = vfs_readdir(file, compat_filldir64, &buf);
-       if (error < 0)
-               goto out_putf;
-       error = buf.error;
+       if (error >= 0)
+               error = buf.error;
        lastdirent = buf.previous;
        if (lastdirent) {
                typeof(lastdirent->d_off) d_off = file->f_pos;
-               error = -EFAULT;
                if (__put_user_unaligned(d_off, &lastdirent->d_off))
-                       goto out_putf;
-               error = count - buf.count;
+                       error = -EFAULT;
+               else
+                       error = count - buf.count;
        }
-
-out_putf:
        fput(file);
 out:
        return error;
@@ -1475,6 +1469,57 @@ out_ret:
 
 #define __COMPAT_NFDBITS       (8 * sizeof(compat_ulong_t))
 
+static int poll_select_copy_remaining(struct timespec *end_time, void __user *p,
+                                     int timeval, int ret)
+{
+       struct timespec ts;
+
+       if (!p)
+               return ret;
+
+       if (current->personality & STICKY_TIMEOUTS)
+               goto sticky;
+
+       /* No update for zero timeout */
+       if (!end_time->tv_sec && !end_time->tv_nsec)
+               return ret;
+
+       ktime_get_ts(&ts);
+       ts = timespec_sub(*end_time, ts);
+       if (ts.tv_sec < 0)
+               ts.tv_sec = ts.tv_nsec = 0;
+
+       if (timeval) {
+               struct compat_timeval rtv;
+
+               rtv.tv_sec = ts.tv_sec;
+               rtv.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
+
+               if (!copy_to_user(p, &rtv, sizeof(rtv)))
+                       return ret;
+       } else {
+               struct compat_timespec rts;
+
+               rts.tv_sec = ts.tv_sec;
+               rts.tv_nsec = ts.tv_nsec;
+
+               if (!copy_to_user(p, &rts, sizeof(rts)))
+                       return ret;
+       }
+       /*
+        * If an application puts its timeval in read-only memory, we
+        * don't want the Linux-specific update to the timeval to
+        * cause a fault after the select has completed
+        * successfully. However, because we're not updating the
+        * timeval, we can't restart the system call.
+        */
+
+sticky:
+       if (ret == -ERESTARTNOHAND)
+               ret = -EINTR;
+       return ret;
+}
+
 /*
  * Ooo, nasty.  We need here to frob 32-bit unsigned longs to
  * 64-bit unsigned longs.
@@ -1556,7 +1601,8 @@ int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
        ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
 
 int compat_core_sys_select(int n, compat_ulong_t __user *inp,
-       compat_ulong_t __user *outp, compat_ulong_t __user *exp, s64 *timeout)
+       compat_ulong_t __user *outp, compat_ulong_t __user *exp,
+       struct timespec *end_time)
 {
        fd_set_bits fds;
        void *bits;
@@ -1603,7 +1649,7 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp,
        zero_fd_set(n, fds.res_out);
        zero_fd_set(n, fds.res_ex);
 
-       ret = do_select(n, &fds, timeout);
+       ret = do_select(n, &fds, end_time);
 
        if (ret < 0)
                goto out;
@@ -1629,7 +1675,7 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
        compat_ulong_t __user *outp, compat_ulong_t __user *exp,
        struct compat_timeval __user *tvp)
 {
-       s64 timeout = -1;
+       struct timespec end_time, *to = NULL;
        struct compat_timeval tv;
        int ret;
 
@@ -1637,43 +1683,14 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
                if (copy_from_user(&tv, tvp, sizeof(tv)))
                        return -EFAULT;
 
-               if (tv.tv_sec < 0 || tv.tv_usec < 0)
+               to = &end_time;
+               if (poll_select_set_timeout(to, tv.tv_sec,
+                                           tv.tv_usec * NSEC_PER_USEC))
                        return -EINVAL;
-
-               /* Cast to u64 to make GCC stop complaining */
-               if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS)
-                       timeout = -1;   /* infinite */
-               else {
-                       timeout = DIV_ROUND_UP(tv.tv_usec, 1000000/HZ);
-                       timeout += tv.tv_sec * HZ;
-               }
        }
 
-       ret = compat_core_sys_select(n, inp, outp, exp, &timeout);
-
-       if (tvp) {
-               struct compat_timeval rtv;
-
-               if (current->personality & STICKY_TIMEOUTS)
-                       goto sticky;
-               rtv.tv_usec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ));
-               rtv.tv_sec = timeout;
-               if (compat_timeval_compare(&rtv, &tv) >= 0)
-                       rtv = tv;
-               if (copy_to_user(tvp, &rtv, sizeof(rtv))) {
-sticky:
-                       /*
-                        * If an application puts its timeval in read-only
-                        * memory, we don't want the Linux-specific update to
-                        * the timeval to cause a fault after the select has
-                        * completed successfully. However, because we're not
-                        * updating the timeval, we can't restart the system
-                        * call.
-                        */
-                       if (ret == -ERESTARTNOHAND)
-                               ret = -EINTR;
-               }
-       }
+       ret = compat_core_sys_select(n, inp, outp, exp, to);
+       ret = poll_select_copy_remaining(&end_time, tvp, 1, ret);
 
        return ret;
 }
@@ -1686,15 +1703,16 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp,
 {
        compat_sigset_t ss32;
        sigset_t ksigmask, sigsaved;
-       s64 timeout = MAX_SCHEDULE_TIMEOUT;
        struct compat_timespec ts;
+       struct timespec end_time, *to = NULL;
        int ret;
 
        if (tsp) {
                if (copy_from_user(&ts, tsp, sizeof(ts)))
                        return -EFAULT;
 
-               if (ts.tv_sec < 0 || ts.tv_nsec < 0)
+               to = &end_time;
+               if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
                        return -EINVAL;
        }
 
@@ -1709,51 +1727,8 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp,
                sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
        }
 
-       do {
-               if (tsp) {
-                       if ((unsigned long)ts.tv_sec < MAX_SELECT_SECONDS) {
-                               timeout = DIV_ROUND_UP(ts.tv_nsec, 1000000000/HZ);
-                               timeout += ts.tv_sec * (unsigned long)HZ;
-                               ts.tv_sec = 0;
-                               ts.tv_nsec = 0;
-                       } else {
-                               ts.tv_sec -= MAX_SELECT_SECONDS;
-                               timeout = MAX_SELECT_SECONDS * HZ;
-                       }
-               }
-
-               ret = compat_core_sys_select(n, inp, outp, exp, &timeout);
-
-       } while (!ret && !timeout && tsp && (ts.tv_sec || ts.tv_nsec));
-
-       if (tsp) {
-               struct compat_timespec rts;
-
-               if (current->personality & STICKY_TIMEOUTS)
-                       goto sticky;
-
-               rts.tv_sec = timeout / HZ;
-               rts.tv_nsec = (timeout % HZ) * (NSEC_PER_SEC/HZ);
-               if (rts.tv_nsec >= NSEC_PER_SEC) {
-                       rts.tv_sec++;
-                       rts.tv_nsec -= NSEC_PER_SEC;
-               }
-               if (compat_timespec_compare(&rts, &ts) >= 0)
-                       rts = ts;
-               if (copy_to_user(tsp, &rts, sizeof(rts))) {
-sticky:
-                       /*
-                        * If an application puts its timeval in read-only
-                        * memory, we don't want the Linux-specific update to
-                        * the timeval to cause a fault after the select has
-                        * completed successfully. However, because we're not
-                        * updating the timeval, we can't restart the system
-                        * call.
-                        */
-                       if (ret == -ERESTARTNOHAND)
-                               ret = -EINTR;
-               }
-       }
+       ret = compat_core_sys_select(n, inp, outp, exp, to);
+       ret = poll_select_copy_remaining(&end_time, tsp, 0, ret);
 
        if (ret == -ERESTARTNOHAND) {
                /*
@@ -1798,18 +1773,16 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
        compat_sigset_t ss32;
        sigset_t ksigmask, sigsaved;
        struct compat_timespec ts;
-       s64 timeout = -1;
+       struct timespec end_time, *to = NULL;
        int ret;
 
        if (tsp) {
                if (copy_from_user(&ts, tsp, sizeof(ts)))
                        return -EFAULT;
 
-               /* We assume that ts.tv_sec is always lower than
-                  the number of seconds that can be expressed in
-                  an s64. Otherwise the compiler bitches at us */
-               timeout = DIV_ROUND_UP(ts.tv_nsec, 1000000000/HZ);
-               timeout += ts.tv_sec * HZ;
+               to = &end_time;
+               if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
+                       return -EINVAL;
        }
 
        if (sigmask) {
@@ -1823,7 +1796,7 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
                sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
        }
 
-       ret = do_sys_poll(ufds, nfds, &timeout);
+       ret = do_sys_poll(ufds, nfds, to);
 
        /* We can restart this syscall, usually */
        if (ret == -EINTR) {
@@ -1841,31 +1814,7 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
        } else if (sigmask)
                sigprocmask(SIG_SETMASK, &sigsaved, NULL);
 
-       if (tsp && timeout >= 0) {
-               struct compat_timespec rts;
-
-               if (current->personality & STICKY_TIMEOUTS)
-                       goto sticky;
-               /* Yes, we know it's actually an s64, but it's also positive. */
-               rts.tv_nsec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)) *
-                                       1000;
-               rts.tv_sec = timeout;
-               if (compat_timespec_compare(&rts, &ts) >= 0)
-                       rts = ts;
-               if (copy_to_user(tsp, &rts, sizeof(rts))) {
-sticky:
-                       /*
-                        * If an application puts its timeval in read-only
-                        * memory, we don't want the Linux-specific update to
-                        * the timeval to cause a fault after the select has
-                        * completed successfully. However, because we're not
-                        * updating the timeval, we can't restart the system
-                        * call.
-                        */
-                       if (ret == -ERESTARTNOHAND && timeout >= 0)
-                               ret = -EINTR;
-               }
-       }
+       ret = poll_select_copy_remaining(&end_time, tsp, 0, ret);
 
        return ret;
 }
index bf74973b0492372d65aafaeb0fa8af496979c54c..932a92b31483053c85b66343c1dfc6481c7f7f32 100644 (file)
@@ -108,18 +108,18 @@ out:
 }
 
 
-static int get_target(const char *symname, struct nameidata *nd,
+static int get_target(const char *symname, struct path *path,
                      struct config_item **target)
 {
        int ret;
 
-       ret = path_lookup(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, nd);
+       ret = kern_path(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, path);
        if (!ret) {
-               if (nd->path.dentry->d_sb == configfs_sb) {
-                       *target = configfs_get_config_item(nd->path.dentry);
+               if (path->dentry->d_sb == configfs_sb) {
+                       *target = configfs_get_config_item(path->dentry);
                        if (!*target) {
                                ret = -ENOENT;
-                               path_put(&nd->path);
+                               path_put(path);
                        }
                } else
                        ret = -EPERM;
@@ -132,7 +132,7 @@ static int get_target(const char *symname, struct nameidata *nd,
 int configfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
 {
        int ret;
-       struct nameidata nd;
+       struct path path;
        struct configfs_dirent *sd;
        struct config_item *parent_item;
        struct config_item *target_item;
@@ -159,7 +159,7 @@ int configfs_symlink(struct inode *dir, struct dentry *dentry, const char *symna
            !type->ct_item_ops->allow_link)
                goto out_put;
 
-       ret = get_target(symname, &nd, &target_item);
+       ret = get_target(symname, &path, &target_item);
        if (ret)
                goto out_put;
 
@@ -174,7 +174,7 @@ int configfs_symlink(struct inode *dir, struct dentry *dentry, const char *symna
        }
 
        config_item_put(target_item);
-       path_put(&nd.path);
+       path_put(&path);
 
 out_put:
        config_item_put(parent_item);
index e7a1a99b7464ef442a8af4ed20b0d45a4db25a65..a1d86c7f3e6644c8914edeae67a0ba02b3df6ada 100644 (file)
@@ -69,6 +69,7 @@ struct dentry_stat_t dentry_stat = {
 
 static void __d_free(struct dentry *dentry)
 {
+       WARN_ON(!list_empty(&dentry->d_alias));
        if (dname_external(dentry))
                kfree(dentry->d_name.name);
        kmem_cache_free(dentry_cache, dentry); 
@@ -174,9 +175,12 @@ static struct dentry *d_kill(struct dentry *dentry)
        dentry_stat.nr_dentry--;        /* For d_free, below */
        /*drops the locks, at that point nobody can reach this dentry */
        dentry_iput(dentry);
-       parent = dentry->d_parent;
+       if (IS_ROOT(dentry))
+               parent = NULL;
+       else
+               parent = dentry->d_parent;
        d_free(dentry);
-       return dentry == parent ? NULL : parent;
+       return parent;
 }
 
 /* 
@@ -666,11 +670,12 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
                                BUG();
                        }
 
-                       parent = dentry->d_parent;
-                       if (parent == dentry)
+                       if (IS_ROOT(dentry))
                                parent = NULL;
-                       else
+                       else {
+                               parent = dentry->d_parent;
                                atomic_dec(&parent->d_count);
+                       }
 
                        list_del(&dentry->d_u.d_child);
                        detached++;
@@ -977,6 +982,15 @@ struct dentry *d_alloc_name(struct dentry *parent, const char *name)
        return d_alloc(parent, &q);
 }
 
+/* the caller must hold dcache_lock */
+static void __d_instantiate(struct dentry *dentry, struct inode *inode)
+{
+       if (inode)
+               list_add(&dentry->d_alias, &inode->i_dentry);
+       dentry->d_inode = inode;
+       fsnotify_d_instantiate(dentry, inode);
+}
+
 /**
  * d_instantiate - fill in inode information for a dentry
  * @entry: dentry to complete
@@ -996,10 +1010,7 @@ void d_instantiate(struct dentry *entry, struct inode * inode)
 {
        BUG_ON(!list_empty(&entry->d_alias));
        spin_lock(&dcache_lock);
-       if (inode)
-               list_add(&entry->d_alias, &inode->i_dentry);
-       entry->d_inode = inode;
-       fsnotify_d_instantiate(entry, inode);
+       __d_instantiate(entry, inode);
        spin_unlock(&dcache_lock);
        security_d_instantiate(entry, inode);
 }
@@ -1029,7 +1040,7 @@ static struct dentry *__d_instantiate_unique(struct dentry *entry,
        unsigned int hash = entry->d_name.hash;
 
        if (!inode) {
-               entry->d_inode = NULL;
+               __d_instantiate(entry, NULL);
                return NULL;
        }
 
@@ -1048,9 +1059,7 @@ static struct dentry *__d_instantiate_unique(struct dentry *entry,
                return alias;
        }
 
-       list_add(&entry->d_alias, &inode->i_dentry);
-       entry->d_inode = inode;
-       fsnotify_d_instantiate(entry, inode);
+       __d_instantiate(entry, inode);
        return NULL;
 }
 
@@ -1111,69 +1120,71 @@ static inline struct hlist_head *d_hash(struct dentry *parent,
 }
 
 /**
- * d_alloc_anon - allocate an anonymous dentry
+ * d_obtain_alias - find or allocate a dentry for a given inode
  * @inode: inode to allocate the dentry for
  *
- * This is similar to d_alloc_root.  It is used by filesystems when
- * creating a dentry for a given inode, often in the process of 
- * mapping a filehandle to a dentry.  The returned dentry may be
- * anonymous, or may have a full name (if the inode was already
- * in the cache).  The file system may need to make further
- * efforts to connect this dentry into the dcache properly.
+ * Obtain a dentry for an inode resulting from NFS filehandle conversion or
+ * similar open by handle operations.  The returned dentry may be anonymous,
+ * or may have a full name (if the inode was already in the cache).
  *
- * When called on a directory inode, we must ensure that
- * the inode only ever has one dentry.  If a dentry is
- * found, that is returned instead of allocating a new one.
+ * When called on a directory inode, we must ensure that the inode only ever
+ * has one dentry.  If a dentry is found, that is returned instead of
+ * allocating a new one.
  *
  * On successful return, the reference to the inode has been transferred
- * to the dentry.  If %NULL is returned (indicating kmalloc failure),
- * the reference on the inode has not been released.
+ * to the dentry.  In case of an error the reference on the inode is released.
+ * To make it easier to use in export operations a %NULL or IS_ERR inode may
+ * be passed in and will be the error will be propagate to the return value,
+ * with a %NULL @inode replaced by ERR_PTR(-ESTALE).
  */
-
-struct dentry * d_alloc_anon(struct inode *inode)
+struct dentry *d_obtain_alias(struct inode *inode)
 {
        static const struct qstr anonstring = { .name = "" };
        struct dentry *tmp;
        struct dentry *res;
 
-       if ((res = d_find_alias(inode))) {
-               iput(inode);
-               return res;
-       }
+       if (!inode)
+               return ERR_PTR(-ESTALE);
+       if (IS_ERR(inode))
+               return ERR_CAST(inode);
 
-       tmp = d_alloc(NULL, &anonstring);
-       if (!tmp)
-               return NULL;
+       res = d_find_alias(inode);
+       if (res)
+               goto out_iput;
 
+       tmp = d_alloc(NULL, &anonstring);
+       if (!tmp) {
+               res = ERR_PTR(-ENOMEM);
+               goto out_iput;
+       }
        tmp->d_parent = tmp; /* make sure dput doesn't croak */
-       
+
        spin_lock(&dcache_lock);
        res = __d_find_alias(inode, 0);
-       if (!res) {
-               /* attach a disconnected dentry */
-               res = tmp;
-               tmp = NULL;
-               spin_lock(&res->d_lock);
-               res->d_sb = inode->i_sb;
-               res->d_parent = res;
-               res->d_inode = inode;
-               res->d_flags |= DCACHE_DISCONNECTED;
-               res->d_flags &= ~DCACHE_UNHASHED;
-               list_add(&res->d_alias, &inode->i_dentry);
-               hlist_add_head(&res->d_hash, &inode->i_sb->s_anon);
-               spin_unlock(&res->d_lock);
-
-               inode = NULL; /* don't drop reference */
+       if (res) {
+               spin_unlock(&dcache_lock);
+               dput(tmp);
+               goto out_iput;
        }
+
+       /* attach a disconnected dentry */
+       spin_lock(&tmp->d_lock);
+       tmp->d_sb = inode->i_sb;
+       tmp->d_inode = inode;
+       tmp->d_flags |= DCACHE_DISCONNECTED;
+       tmp->d_flags &= ~DCACHE_UNHASHED;
+       list_add(&tmp->d_alias, &inode->i_dentry);
+       hlist_add_head(&tmp->d_hash, &inode->i_sb->s_anon);
+       spin_unlock(&tmp->d_lock);
+
        spin_unlock(&dcache_lock);
+       return tmp;
 
-       if (inode)
-               iput(inode);
-       if (tmp)
-               dput(tmp);
+ out_iput:
+       iput(inode);
        return res;
 }
-
+EXPORT_SYMBOL_GPL(d_obtain_alias);
 
 /**
  * d_splice_alias - splice a disconnected dentry into the tree if one exists
@@ -1200,17 +1211,14 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
                new = __d_find_alias(inode, 1);
                if (new) {
                        BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED));
-                       fsnotify_d_instantiate(new, inode);
                        spin_unlock(&dcache_lock);
                        security_d_instantiate(new, inode);
                        d_rehash(dentry);
                        d_move(new, dentry);
                        iput(inode);
                } else {
-                       /* d_instantiate takes dcache_lock, so we do it by hand */
-                       list_add(&dentry->d_alias, &inode->i_dentry);
-                       dentry->d_inode = inode;
-                       fsnotify_d_instantiate(dentry, inode);
+                       /* already taking dcache_lock, so d_add() by hand */
+                       __d_instantiate(dentry, inode);
                        spin_unlock(&dcache_lock);
                        security_d_instantiate(dentry, inode);
                        d_rehash(dentry);
@@ -1293,8 +1301,7 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
                 * d_instantiate() by hand because it takes dcache_lock which
                 * we already hold.
                 */
-               list_add(&found->d_alias, &inode->i_dentry);
-               found->d_inode = inode;
+               __d_instantiate(found, inode);
                spin_unlock(&dcache_lock);
                security_d_instantiate(found, inode);
                return found;
@@ -1456,8 +1463,6 @@ out:
  * d_validate - verify dentry provided from insecure source
  * @dentry: The dentry alleged to be valid child of @dparent
  * @dparent: The parent dentry (known to be valid)
- * @hash: Hash of the dentry
- * @len: Length of the name
  *
  * An insecure source has sent us a dentry, here we verify it and dget() it.
  * This is used by ncpfs in its readdir implementation.
@@ -1714,18 +1719,23 @@ void d_move(struct dentry * dentry, struct dentry * target)
        spin_unlock(&dcache_lock);
 }
 
-/*
- * Helper that returns 1 if p1 is a parent of p2, else 0
+/**
+ * d_ancestor - search for an ancestor
+ * @p1: ancestor dentry
+ * @p2: child dentry
+ *
+ * Returns the ancestor dentry of p2 which is a child of p1, if p1 is
+ * an ancestor of p2, else NULL.
  */
-static int d_isparent(struct dentry *p1, struct dentry *p2)
+struct dentry *d_ancestor(struct dentry *p1, struct dentry *p2)
 {
        struct dentry *p;
 
-       for (p = p2; p->d_parent != p; p = p->d_parent) {
+       for (p = p2; !IS_ROOT(p); p = p->d_parent) {
                if (p->d_parent == p1)
-                       return 1;
+                       return p;
        }
-       return 0;
+       return NULL;
 }
 
 /*
@@ -1749,7 +1759,7 @@ static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias)
 
        /* Check for loops */
        ret = ERR_PTR(-ELOOP);
-       if (d_isparent(alias, dentry))
+       if (d_ancestor(alias, dentry))
                goto out_err;
 
        /* See lock_rename() */
@@ -1822,7 +1832,7 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
 
        if (!inode) {
                actual = dentry;
-               dentry->d_inode = NULL;
+               __d_instantiate(dentry, NULL);
                goto found_lock;
        }
 
@@ -2149,32 +2159,27 @@ out:
  * Caller must ensure that "new_dentry" is pinned before calling is_subdir()
  */
   
-int is_subdir(struct dentry * new_dentry, struct dentry * old_dentry)
+int is_subdir(struct dentry *new_dentry, struct dentry *old_dentry)
 {
        int result;
-       struct dentry * saved = new_dentry;
        unsigned long seq;
 
-       /* need rcu_readlock to protect against the d_parent trashing due to
-        * d_move
+       /* FIXME: This is old behavior, needed? Please check callers. */
+       if (new_dentry == old_dentry)
+               return 1;
+
+       /*
+        * Need rcu_readlock to protect against the d_parent trashing
+        * due to d_move
         */
        rcu_read_lock();
-        do {
+       do {
                /* for restarting inner loop in case of seq retry */
-               new_dentry = saved;
-               result = 0;
                seq = read_seqbegin(&rename_lock);
-               for (;;) {
-                       if (new_dentry != old_dentry) {
-                               struct dentry * parent = new_dentry->d_parent;
-                               if (parent == new_dentry)
-                                       break;
-                               new_dentry = parent;
-                               continue;
-                       }
+               if (d_ancestor(old_dentry, new_dentry))
                        result = 1;
-                       break;
-               }
+               else
+                       result = 0;
        } while (read_seqretry(&rename_lock, seq));
        rcu_read_unlock();
 
@@ -2344,7 +2349,6 @@ void __init vfs_caches_init(unsigned long mempages)
 }
 
 EXPORT_SYMBOL(d_alloc);
-EXPORT_SYMBOL(d_alloc_anon);
 EXPORT_SYMBOL(d_alloc_root);
 EXPORT_SYMBOL(d_delete);
 EXPORT_SYMBOL(d_find_alias);
index da30a27f2242c7e2e844b630ea02d12474ce7fdd..5e95261005b2ac68f2103ae7468f257c57ba89da 100644 (file)
@@ -1805,19 +1805,19 @@ int vfs_quota_on_path(struct super_block *sb, int type, int format_id,
 }
 
 /* Actual function called from quotactl() */
-int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path,
+int vfs_quota_on(struct super_block *sb, int type, int format_id, char *name,
                 int remount)
 {
-       struct nameidata nd;
+       struct path path;
        int error;
 
        if (remount)
                return vfs_quota_on_remount(sb, type);
 
-       error = path_lookup(path, LOOKUP_FOLLOW, &nd);
+       error = kern_path(name, LOOKUP_FOLLOW, &path);
        if (!error) {
-               error = vfs_quota_on_path(sb, type, format_id, &nd.path);
-               path_put(&nd.path);
+               error = vfs_quota_on_path(sb, type, format_id, &path);
+               path_put(&path);
        }
        return error;
 }
index 046e027a4cb192705a49caf27048ac79cf35badb..64d2ba980df43b28d646fb18efc9842e9b380488 100644 (file)
@@ -471,31 +471,26 @@ out:
  */
 static int ecryptfs_read_super(struct super_block *sb, const char *dev_name)
 {
+       struct path path;
        int rc;
-       struct nameidata nd;
-       struct dentry *lower_root;
-       struct vfsmount *lower_mnt;
 
-       memset(&nd, 0, sizeof(struct nameidata));
-       rc = path_lookup(dev_name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &nd);
+       rc = kern_path(dev_name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
        if (rc) {
                ecryptfs_printk(KERN_WARNING, "path_lookup() failed\n");
                goto out;
        }
-       lower_root = nd.path.dentry;
-       lower_mnt = nd.path.mnt;
-       ecryptfs_set_superblock_lower(sb, lower_root->d_sb);
-       sb->s_maxbytes = lower_root->d_sb->s_maxbytes;
-       sb->s_blocksize = lower_root->d_sb->s_blocksize;
-       ecryptfs_set_dentry_lower(sb->s_root, lower_root);
-       ecryptfs_set_dentry_lower_mnt(sb->s_root, lower_mnt);
-       rc = ecryptfs_interpose(lower_root, sb->s_root, sb, 0);
+       ecryptfs_set_superblock_lower(sb, path.dentry->d_sb);
+       sb->s_maxbytes = path.dentry->d_sb->s_maxbytes;
+       sb->s_blocksize = path.dentry->d_sb->s_blocksize;
+       ecryptfs_set_dentry_lower(sb->s_root, path.dentry);
+       ecryptfs_set_dentry_lower_mnt(sb->s_root, path.mnt);
+       rc = ecryptfs_interpose(path.dentry, sb->s_root, sb, 0);
        if (rc)
                goto out_free;
        rc = 0;
        goto out;
 out_free:
-       path_put(&nd.path);
+       path_put(&path);
 out:
        return rc;
 }
index 291abb11e20ef8668fe9799b32b1342d04ece6cc..c3fb5f9c4a441d44fab690b43c8b9a0549fe844e 100644 (file)
@@ -112,35 +112,14 @@ struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid,
 
 struct dentry *efs_get_parent(struct dentry *child)
 {
-       struct dentry *parent;
-       struct inode *inode;
+       struct dentry *parent = ERR_PTR(-ENOENT);
        efs_ino_t ino;
-       long error;
 
        lock_kernel();
-
-       error = -ENOENT;
        ino = efs_find_entry(child->d_inode, "..", 2);
-       if (!ino)
-               goto fail;
-
-       inode = efs_iget(child->d_inode->i_sb, ino);
-       if (IS_ERR(inode)) {
-               error = PTR_ERR(inode);
-               goto fail;
-       }
-
-       error = -ENOMEM;
-       parent = d_alloc_anon(inode);
-       if (!parent)
-               goto fail_iput;
-
+       if (ino)
+               parent = d_obtain_alias(efs_iget(child->d_inode->i_sb, ino));
        unlock_kernel();
-       return parent;
 
- fail_iput:
-       iput(inode);
- fail:
-       unlock_kernel();
-       return ERR_PTR(error);
+       return parent;
 }
index cc91227d3bb88dcdce06b83806baf6dd7f912225..80246bad1b7fe513a7da15f4d6ac057cad3d7e54 100644 (file)
@@ -94,9 +94,8 @@ find_disconnected_root(struct dentry *dentry)
  * It may already be, as the flag isn't always updated when connection happens.
  */
 static int
-reconnect_path(struct vfsmount *mnt, struct dentry *target_dir)
+reconnect_path(struct vfsmount *mnt, struct dentry *target_dir, char *nbuf)
 {
-       char nbuf[NAME_MAX+1];
        int noprogress = 0;
        int err = -ESTALE;
 
@@ -281,13 +280,14 @@ static int get_name(struct vfsmount *mnt, struct dentry *dentry,
                int old_seq = buffer.sequence;
 
                error = vfs_readdir(file, filldir_one, &buffer);
+               if (buffer.found) {
+                       error = 0;
+                       break;
+               }
 
                if (error < 0)
                        break;
 
-               error = 0;
-               if (buffer.found)
-                       break;
                error = -ENOENT;
                if (old_seq == buffer.sequence)
                        break;
@@ -360,14 +360,13 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
 {
        const struct export_operations *nop = mnt->mnt_sb->s_export_op;
        struct dentry *result, *alias;
+       char nbuf[NAME_MAX+1];
        int err;
 
        /*
         * Try to get any dentry for the given file handle from the filesystem.
         */
        result = nop->fh_to_dentry(mnt->mnt_sb, fid, fh_len, fileid_type);
-       if (!result)
-               result = ERR_PTR(-ESTALE);
        if (IS_ERR(result))
                return result;
 
@@ -381,7 +380,7 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
                 * filesystem root.
                 */
                if (result->d_flags & DCACHE_DISCONNECTED) {
-                       err = reconnect_path(mnt, result);
+                       err = reconnect_path(mnt, result, nbuf);
                        if (err)
                                goto err_result;
                }
@@ -397,7 +396,6 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
                 * It's not a directory.  Life is a little more complicated.
                 */
                struct dentry *target_dir, *nresult;
-               char nbuf[NAME_MAX+1];
 
                /*
                 * See if either the dentry we just got from the filesystem
@@ -422,8 +420,6 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
 
                target_dir = nop->fh_to_parent(mnt->mnt_sb, fid,
                                fh_len, fileid_type);
-               if (!target_dir)
-                       goto err_result;
                err = PTR_ERR(target_dir);
                if (IS_ERR(target_dir))
                        goto err_result;
@@ -433,7 +429,7 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
                 * connected to the filesystem root.  The VFS really doesn't
                 * like disconnected directories..
                 */
-               err = reconnect_path(mnt, target_dir);
+               err = reconnect_path(mnt, target_dir, nbuf);
                if (err) {
                        dput(target_dir);
                        goto err_result;
index 11a49ce84392a1e39bc1c335273c4f1ab2ee0d8f..9a0fc400f91cf606bdd9bfc7c9b14e136243a1c7 100644 (file)
@@ -354,11 +354,11 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
  * (as a parameter - res_dir). Page is returned mapped and unlocked.
  * Entry is guaranteed to be valid.
  */
-struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
-                       struct dentry *dentry, struct page ** res_page)
+struct ext2_dir_entry_2 *ext2_find_entry (struct inode * dir,
+                       struct qstr *child, struct page ** res_page)
 {
-       const char *name = dentry->d_name.name;
-       int namelen = dentry->d_name.len;
+       const char *name = child->name;
+       int namelen = child->len;
        unsigned reclen = EXT2_DIR_REC_LEN(namelen);
        unsigned long start, n;
        unsigned long npages = dir_pages(dir);
@@ -431,13 +431,13 @@ struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p)
        return de;
 }
 
-ino_t ext2_inode_by_name(struct inode * dir, struct dentry *dentry)
+ino_t ext2_inode_by_name(struct inode *dir, struct qstr *child)
 {
        ino_t res = 0;
-       struct ext2_dir_entry_2 * de;
+       struct ext2_dir_entry_2 *de;
        struct page *page;
        
-       de = ext2_find_entry (dir, dentry, &page);
+       de = ext2_find_entry (dir, child, &page);
        if (de) {
                res = le32_to_cpu(de->inode);
                ext2_put_page(page);
index bae998c1e44eea3afef4a2e834d75d08ca5c472e..3203042b36efa055e456d2c45a37e968ad58034f 100644 (file)
@@ -105,9 +105,9 @@ extern void ext2_rsv_window_add(struct super_block *sb, struct ext2_reserve_wind
 
 /* dir.c */
 extern int ext2_add_link (struct dentry *, struct inode *);
-extern ino_t ext2_inode_by_name(struct inode *, struct dentry *);
+extern ino_t ext2_inode_by_name(struct inode *, struct qstr *);
 extern int ext2_make_empty(struct inode *, struct inode *);
-extern struct ext2_dir_entry_2 * ext2_find_entry (struct inode *,struct dentry *, struct page **);
+extern struct ext2_dir_entry_2 * ext2_find_entry (struct inode *,struct qstr *, struct page **);
 extern int ext2_delete_entry (struct ext2_dir_entry_2 *, struct page *);
 extern int ext2_empty_dir (struct inode *);
 extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **);
index 80c97fd8c571311280042d45343c9c220e458dd9..2a747252ec1204776d7ba99d9b7147872c060743 100644 (file)
@@ -60,7 +60,7 @@ static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, str
        if (dentry->d_name.len > EXT2_NAME_LEN)
                return ERR_PTR(-ENAMETOOLONG);
 
-       ino = ext2_inode_by_name(dir, dentry);
+       ino = ext2_inode_by_name(dir, &dentry->d_name);
        inode = NULL;
        if (ino) {
                inode = ext2_iget(dir->i_sb, ino);
@@ -72,27 +72,11 @@ static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, str
 
 struct dentry *ext2_get_parent(struct dentry *child)
 {
-       unsigned long ino;
-       struct dentry *parent;
-       struct inode *inode;
-       struct dentry dotdot;
-
-       dotdot.d_name.name = "..";
-       dotdot.d_name.len = 2;
-
-       ino = ext2_inode_by_name(child->d_inode, &dotdot);
+       struct qstr dotdot = {.name = "..", .len = 2};
+       unsigned long ino = ext2_inode_by_name(child->d_inode, &dotdot);
        if (!ino)
                return ERR_PTR(-ENOENT);
-       inode = ext2_iget(child->d_inode->i_sb, ino);
-
-       if (IS_ERR(inode))
-               return ERR_CAST(inode);
-       parent = d_alloc_anon(inode);
-       if (!parent) {
-               iput(inode);
-               parent = ERR_PTR(-ENOMEM);
-       }
-       return parent;
+       return d_obtain_alias(ext2_iget(child->d_inode->i_sb, ino));
 } 
 
 /*
@@ -257,7 +241,7 @@ static int ext2_unlink(struct inode * dir, struct dentry *dentry)
        struct page * page;
        int err = -ENOENT;
 
-       de = ext2_find_entry (dir, dentry, &page);
+       de = ext2_find_entry (dir, &dentry->d_name, &page);
        if (!de)
                goto out;
 
@@ -299,7 +283,7 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
        struct ext2_dir_entry_2 * old_de;
        int err = -ENOENT;
 
-       old_de = ext2_find_entry (old_dir, old_dentry, &old_page);
+       old_de = ext2_find_entry (old_dir, &old_dentry->d_name, &old_page);
        if (!old_de)
                goto out;
 
@@ -319,7 +303,7 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
                        goto out_dir;
 
                err = -ENOENT;
-               new_de = ext2_find_entry (new_dir, new_dentry, &new_page);
+               new_de = ext2_find_entry (new_dir, &new_dentry->d_name, &new_page);
                if (!new_de)
                        goto out_dir;
                inode_inc_link_count(old_inode);
index 4fb94c20041b5e44c5ee2152a151bf65e486daa9..b72b85884223fc3761208f6bc891b39e3213d034 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/buffer_head.h>
 #include <linux/ext2_fs_sb.h>
 #include <linux/ext2_fs.h>
+#include <linux/blkdev.h>
 #include "ext2.h"
 #include "xip.h"
 
index 0d0c70151642faf026c98d53b4179c6395e1b645..b7394d05ee8e9e8261d2a6e8be983b83781d2211 100644 (file)
@@ -239,7 +239,7 @@ setrsvsz_out:
        case EXT3_IOC_GROUP_EXTEND: {
                ext3_fsblk_t n_blocks_count;
                struct super_block *sb = inode->i_sb;
-               int err;
+               int err, err2;
 
                if (!capable(CAP_SYS_RESOURCE))
                        return -EPERM;
@@ -254,8 +254,10 @@ setrsvsz_out:
                }
                err = ext3_group_extend(sb, EXT3_SB(sb)->s_es, n_blocks_count);
                journal_lock_updates(EXT3_SB(sb)->s_journal);
-               journal_flush(EXT3_SB(sb)->s_journal);
+               err2 = journal_flush(EXT3_SB(sb)->s_journal);
                journal_unlock_updates(EXT3_SB(sb)->s_journal);
+               if (err == 0)
+                       err = err2;
 group_extend_out:
                mnt_drop_write(filp->f_path.mnt);
                return err;
@@ -263,7 +265,7 @@ group_extend_out:
        case EXT3_IOC_GROUP_ADD: {
                struct ext3_new_group_data input;
                struct super_block *sb = inode->i_sb;
-               int err;
+               int err, err2;
 
                if (!capable(CAP_SYS_RESOURCE))
                        return -EPERM;
@@ -280,8 +282,10 @@ group_extend_out:
 
                err = ext3_group_add(sb, &input);
                journal_lock_updates(EXT3_SB(sb)->s_journal);
-               journal_flush(EXT3_SB(sb)->s_journal);
+               err2 = journal_flush(EXT3_SB(sb)->s_journal);
                journal_unlock_updates(EXT3_SB(sb)->s_journal);
+               if (err == 0)
+                       err = err2;
 group_add_out:
                mnt_drop_write(filp->f_path.mnt);
                return err;
index de13e919cd8106fac1012c162699cc5604da90f4..3e5edc92aa0b088071d1711c4bcf620d585e0416 100644 (file)
@@ -159,7 +159,7 @@ static void dx_set_count (struct dx_entry *entries, unsigned value);
 static void dx_set_limit (struct dx_entry *entries, unsigned value);
 static unsigned dx_root_limit (struct inode *dir, unsigned infosize);
 static unsigned dx_node_limit (struct inode *dir);
-static struct dx_frame *dx_probe(struct dentry *dentry,
+static struct dx_frame *dx_probe(struct qstr *entry,
                                 struct inode *dir,
                                 struct dx_hash_info *hinfo,
                                 struct dx_frame *frame,
@@ -176,8 +176,9 @@ static int ext3_htree_next_block(struct inode *dir, __u32 hash,
                                 struct dx_frame *frame,
                                 struct dx_frame *frames,
                                 __u32 *start_hash);
-static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
-                      struct ext3_dir_entry_2 **res_dir, int *err);
+static struct buffer_head * ext3_dx_find_entry(struct inode *dir,
+                       struct qstr *entry, struct ext3_dir_entry_2 **res_dir,
+                       int *err);
 static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
                             struct inode *inode);
 
@@ -342,7 +343,7 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
  * back to userspace.
  */
 static struct dx_frame *
-dx_probe(struct dentry *dentry, struct inode *dir,
+dx_probe(struct qstr *entry, struct inode *dir,
         struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err)
 {
        unsigned count, indirect;
@@ -353,8 +354,6 @@ dx_probe(struct dentry *dentry, struct inode *dir,
        u32 hash;
 
        frame->bh = NULL;
-       if (dentry)
-               dir = dentry->d_parent->d_inode;
        if (!(bh = ext3_bread (NULL,dir, 0, 0, err)))
                goto fail;
        root = (struct dx_root *) bh->b_data;
@@ -370,8 +369,8 @@ dx_probe(struct dentry *dentry, struct inode *dir,
        }
        hinfo->hash_version = root->info.hash_version;
        hinfo->seed = EXT3_SB(dir->i_sb)->s_hash_seed;
-       if (dentry)
-               ext3fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo);
+       if (entry)
+               ext3fs_dirhash(entry->name, entry->len, hinfo);
        hash = hinfo->hash;
 
        if (root->info.unused_flags & 1) {
@@ -803,15 +802,15 @@ static inline int ext3_match (int len, const char * const name,
  */
 static inline int search_dirblock(struct buffer_head * bh,
                                  struct inode *dir,
-                                 struct dentry *dentry,
+                                 struct qstr *child,
                                  unsigned long offset,
                                  struct ext3_dir_entry_2 ** res_dir)
 {
        struct ext3_dir_entry_2 * de;
        char * dlimit;
        int de_len;
-       const char *name = dentry->d_name.name;
-       int namelen = dentry->d_name.len;
+       const char *name = child->name;
+       int namelen = child->len;
 
        de = (struct ext3_dir_entry_2 *) bh->b_data;
        dlimit = bh->b_data + dir->i_sb->s_blocksize;
@@ -850,8 +849,9 @@ static inline int search_dirblock(struct buffer_head * bh,
  * The returned buffer_head has ->b_count elevated.  The caller is expected
  * to brelse() it when appropriate.
  */
-static struct buffer_head * ext3_find_entry (struct dentry *dentry,
-                                       struct ext3_dir_entry_2 ** res_dir)
+static struct buffer_head *ext3_find_entry(struct inode *dir,
+                                       struct qstr *entry,
+                                       struct ext3_dir_entry_2 **res_dir)
 {
        struct super_block * sb;
        struct buffer_head * bh_use[NAMEI_RA_SIZE];
@@ -863,16 +863,15 @@ static struct buffer_head * ext3_find_entry (struct dentry *dentry,
                                   buffer */
        int num = 0;
        int nblocks, i, err;
-       struct inode *dir = dentry->d_parent->d_inode;
        int namelen;
 
        *res_dir = NULL;
        sb = dir->i_sb;
-       namelen = dentry->d_name.len;
+       namelen = entry->len;
        if (namelen > EXT3_NAME_LEN)
                return NULL;
        if (is_dx(dir)) {
-               bh = ext3_dx_find_entry(dentry, res_dir, &err);
+               bh = ext3_dx_find_entry(dir, entry, res_dir, &err);
                /*
                 * On success, or if the error was file not found,
                 * return.  Otherwise, fall back to doing a search the
@@ -923,7 +922,7 @@ restart:
                        brelse(bh);
                        goto next;
                }
-               i = search_dirblock(bh, dir, dentry,
+               i = search_dirblock(bh, dir, entry,
                            block << EXT3_BLOCK_SIZE_BITS(sb), res_dir);
                if (i == 1) {
                        EXT3_I(dir)->i_dir_start_lookup = block;
@@ -957,8 +956,9 @@ cleanup_and_exit:
        return ret;
 }
 
-static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
-                      struct ext3_dir_entry_2 **res_dir, int *err)
+static struct buffer_head * ext3_dx_find_entry(struct inode *dir,
+                       struct qstr *entry, struct ext3_dir_entry_2 **res_dir,
+                       int *err)
 {
        struct super_block * sb;
        struct dx_hash_info     hinfo;
@@ -968,14 +968,13 @@ static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
        struct buffer_head *bh;
        unsigned long block;
        int retval;
-       int namelen = dentry->d_name.len;
-       const u8 *name = dentry->d_name.name;
-       struct inode *dir = dentry->d_parent->d_inode;
+       int namelen = entry->len;
+       const u8 *name = entry->name;
 
        sb = dir->i_sb;
        /* NFS may look up ".." - look at dx_root directory block */
-       if (namelen > 2 || name[0] != '.'||(name[1] != '.' && name[1] != '\0')){
-               if (!(frame = dx_probe(dentry, NULL, &hinfo, frames, err)))
+       if (namelen > 2 || name[0] != '.'|| (namelen == 2 && name[1] != '.')) {
+               if (!(frame = dx_probe(entry, dir, &hinfo, frames, err)))
                        return NULL;
        } else {
                frame = frames;
@@ -1036,7 +1035,7 @@ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, str
        if (dentry->d_name.len > EXT3_NAME_LEN)
                return ERR_PTR(-ENAMETOOLONG);
 
-       bh = ext3_find_entry(dentry, &de);
+       bh = ext3_find_entry(dir, &dentry->d_name, &de);
        inode = NULL;
        if (bh) {
                unsigned long ino = le32_to_cpu(de->inode);
@@ -1057,18 +1056,11 @@ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, str
 struct dentry *ext3_get_parent(struct dentry *child)
 {
        unsigned long ino;
-       struct dentry *parent;
-       struct inode *inode;
-       struct dentry dotdot;
+       struct qstr dotdot = {.name = "..", .len = 2};
        struct ext3_dir_entry_2 * de;
        struct buffer_head *bh;
 
-       dotdot.d_name.name = "..";
-       dotdot.d_name.len = 2;
-       dotdot.d_parent = child; /* confusing, isn't it! */
-
-       bh = ext3_find_entry(&dotdot, &de);
-       inode = NULL;
+       bh = ext3_find_entry(child->d_inode, &dotdot, &de);
        if (!bh)
                return ERR_PTR(-ENOENT);
        ino = le32_to_cpu(de->inode);
@@ -1080,16 +1072,7 @@ struct dentry *ext3_get_parent(struct dentry *child)
                return ERR_PTR(-EIO);
        }
 
-       inode = ext3_iget(child->d_inode->i_sb, ino);
-       if (IS_ERR(inode))
-               return ERR_CAST(inode);
-
-       parent = d_alloc_anon(inode);
-       if (!parent) {
-               iput(inode);
-               parent = ERR_PTR(-ENOMEM);
-       }
-       return parent;
+       return d_obtain_alias(ext3_iget(child->d_inode->i_sb, ino));
 }
 
 #define S_SHIFT 12
@@ -1503,7 +1486,7 @@ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
        struct ext3_dir_entry_2 *de;
        int err;
 
-       frame = dx_probe(dentry, NULL, &hinfo, frames, &err);
+       frame = dx_probe(&dentry->d_name, dir, &hinfo, frames, &err);
        if (!frame)
                return err;
        entries = frame->entries;
@@ -2056,7 +2039,7 @@ static int ext3_rmdir (struct inode * dir, struct dentry *dentry)
                return PTR_ERR(handle);
 
        retval = -ENOENT;
-       bh = ext3_find_entry (dentry, &de);
+       bh = ext3_find_entry(dir, &dentry->d_name, &de);
        if (!bh)
                goto end_rmdir;
 
@@ -2118,7 +2101,7 @@ static int ext3_unlink(struct inode * dir, struct dentry *dentry)
                handle->h_sync = 1;
 
        retval = -ENOENT;
-       bh = ext3_find_entry (dentry, &de);
+       bh = ext3_find_entry(dir, &dentry->d_name, &de);
        if (!bh)
                goto end_unlink;
 
@@ -2276,7 +2259,7 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
        if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
                handle->h_sync = 1;
 
-       old_bh = ext3_find_entry (old_dentry, &old_de);
+       old_bh = ext3_find_entry(old_dir, &old_dentry->d_name, &old_de);
        /*
         *  Check for inode number is _not_ due to possible IO errors.
         *  We might rmdir the source, keep it as pwd of some process
@@ -2289,7 +2272,7 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
                goto end_rename;
 
        new_inode = new_dentry->d_inode;
-       new_bh = ext3_find_entry (new_dentry, &new_de);
+       new_bh = ext3_find_entry(new_dir, &new_dentry->d_name, &new_de);
        if (new_bh) {
                if (!new_inode) {
                        brelse (new_bh);
@@ -2355,7 +2338,8 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
                struct buffer_head *old_bh2;
                struct ext3_dir_entry_2 *old_de2;
 
-               old_bh2 = ext3_find_entry(old_dentry, &old_de2);
+               old_bh2 = ext3_find_entry(old_dir, &old_dentry->d_name,
+                                         &old_de2);
                if (old_bh2) {
                        retval = ext3_delete_entry(handle, old_dir,
                                                   old_de2, old_bh2);
index 3a260af5544d24dfc85f0dffc03b42771c322295..18eaa78ecb4ec53d4d65170ccfd28a362ae703f9 100644 (file)
@@ -347,7 +347,7 @@ fail:
 static int ext3_blkdev_put(struct block_device *bdev)
 {
        bd_release(bdev);
-       return blkdev_put(bdev);
+       return blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
 }
 
 static int ext3_blkdev_remove(struct ext3_sb_info *sbi)
@@ -393,7 +393,8 @@ static void ext3_put_super (struct super_block * sb)
        int i;
 
        ext3_xattr_put_super(sb);
-       journal_destroy(sbi->s_journal);
+       if (journal_destroy(sbi->s_journal) < 0)
+               ext3_abort(sb, __func__, "Couldn't clean up the journal");
        if (!(sb->s_flags & MS_RDONLY)) {
                EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
                es->s_state = cpu_to_le16(sbi->s_mount_state);
@@ -2066,7 +2067,7 @@ static journal_t *ext3_get_dev_journal(struct super_block *sb,
        if (bd_claim(bdev, sb)) {
                printk(KERN_ERR
                        "EXT3: failed to claim external journal device.\n");
-               blkdev_put(bdev);
+               blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
                return NULL;
        }
 
@@ -2296,7 +2297,9 @@ static void ext3_mark_recovery_complete(struct super_block * sb,
        journal_t *journal = EXT3_SB(sb)->s_journal;
 
        journal_lock_updates(journal);
-       journal_flush(journal);
+       if (journal_flush(journal) < 0)
+               goto out;
+
        lock_super(sb);
        if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER) &&
            sb->s_flags & MS_RDONLY) {
@@ -2305,6 +2308,8 @@ static void ext3_mark_recovery_complete(struct super_block * sb,
                ext3_commit_super(sb, es, 1);
        }
        unlock_super(sb);
+
+out:
        journal_unlock_updates(journal);
 }
 
@@ -2404,7 +2409,13 @@ static void ext3_write_super_lockfs(struct super_block *sb)
 
                /* Now we set up the journal barrier. */
                journal_lock_updates(journal);
-               journal_flush(journal);
+
+               /*
+                * We don't want to clear needs_recovery flag when we failed
+                * to flush the journal.
+                */
+               if (journal_flush(journal) < 0)
+                       return;
 
                /* Journal blocked and flushed, clear needs_recovery flag. */
                EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
@@ -2783,30 +2794,30 @@ static int ext3_quota_on_mount(struct super_block *sb, int type)
  * Standard function to be called on quota_on
  */
 static int ext3_quota_on(struct super_block *sb, int type, int format_id,
-                        char *path, int remount)
+                        char *name, int remount)
 {
        int err;
-       struct nameidata nd;
+       struct path path;
 
        if (!test_opt(sb, QUOTA))
                return -EINVAL;
-       /* When remounting, no checks are needed and in fact, path is NULL */
+       /* When remounting, no checks are needed and in fact, name is NULL */
        if (remount)
-               return vfs_quota_on(sb, type, format_id, path, remount);
+               return vfs_quota_on(sb, type, format_id, name, remount);
 
-       err = path_lookup(path, LOOKUP_FOLLOW, &nd);
+       err = kern_path(name, LOOKUP_FOLLOW, &path);
        if (err)
                return err;
 
        /* Quotafile not on the same filesystem? */
-       if (nd.path.mnt->mnt_sb != sb) {
-               path_put(&nd.path);
+       if (path.mnt->mnt_sb != sb) {
+               path_put(&path);
                return -EXDEV;
        }
        /* Journaling quota? */
        if (EXT3_SB(sb)->s_qf_names[type]) {
                /* Quotafile not of fs root? */
-               if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode)
+               if (path.dentry->d_parent != sb->s_root)
                        printk(KERN_WARNING
                                "EXT3-fs: Quota file not on filesystem root. "
                                "Journaled quota will not work.\n");
@@ -2816,18 +2827,22 @@ static int ext3_quota_on(struct super_block *sb, int type, int format_id,
         * When we journal data on quota file, we have to flush journal to see
         * all updates to the file when we bypass pagecache...
         */
-       if (ext3_should_journal_data(nd.path.dentry->d_inode)) {
+       if (ext3_should_journal_data(path.dentry->d_inode)) {
                /*
                 * We don't need to lock updates but journal_flush() could
                 * otherwise be livelocked...
                 */
                journal_lock_updates(EXT3_SB(sb)->s_journal);
-               journal_flush(EXT3_SB(sb)->s_journal);
+               err = journal_flush(EXT3_SB(sb)->s_journal);
                journal_unlock_updates(EXT3_SB(sb)->s_journal);
+               if (err) {
+                       path_put(&path);
+                       return err;
+               }
        }
 
-       err = vfs_quota_on_path(sb, type, format_id, &nd.path);
-       path_put(&nd.path);
+       err = vfs_quota_on_path(sb, type, format_id, &path);
+       path_put(&path);
        return err;
 }
 
index 92db9e94514779dce3d0cdccdcc78bc4e12ea465..63adcb792988016d642a6e341bcbca2f694b68d1 100644 (file)
@@ -1061,7 +1061,6 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, stru
 struct dentry *ext4_get_parent(struct dentry *child)
 {
        unsigned long ino;
-       struct dentry *parent;
        struct inode *inode;
        static const struct qstr dotdot = {
                .name = "..",
@@ -1083,16 +1082,7 @@ struct dentry *ext4_get_parent(struct dentry *child)
                return ERR_PTR(-EIO);
        }
 
-       inode = ext4_iget(child->d_inode->i_sb, ino);
-       if (IS_ERR(inode))
-               return ERR_CAST(inode);
-
-       parent = d_alloc_anon(inode);
-       if (!parent) {
-               iput(inode);
-               parent = ERR_PTR(-ENOMEM);
-       }
-       return parent;
+       return d_obtain_alias(ext4_iget(child->d_inode->i_sb, ino));
 }
 
 #define S_SHIFT 12
index 9b2b2bc4ec175e2ac43bf43113866e1c5dde38e5..bdddea14e782f041381837d1488506fd951cbc99 100644 (file)
@@ -399,7 +399,7 @@ fail:
 static int ext4_blkdev_put(struct block_device *bdev)
 {
        bd_release(bdev);
-       return blkdev_put(bdev);
+       return blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
 }
 
 static int ext4_blkdev_remove(struct ext4_sb_info *sbi)
@@ -2553,7 +2553,7 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb,
        if (bd_claim(bdev, sb)) {
                printk(KERN_ERR
                        "EXT4: failed to claim external journal device.\n");
-               blkdev_put(bdev);
+               blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
                return NULL;
        }
 
@@ -3328,30 +3328,30 @@ static int ext4_quota_on_mount(struct super_block *sb, int type)
  * Standard function to be called on quota_on
  */
 static int ext4_quota_on(struct super_block *sb, int type, int format_id,
-                        char *path, int remount)
+                        char *name, int remount)
 {
        int err;
-       struct nameidata nd;
+       struct path path;
 
        if (!test_opt(sb, QUOTA))
                return -EINVAL;
-       /* When remounting, no checks are needed and in fact, path is NULL */
+       /* When remounting, no checks are needed and in fact, name is NULL */
        if (remount)
-               return vfs_quota_on(sb, type, format_id, path, remount);
+               return vfs_quota_on(sb, type, format_id, name, remount);
 
-       err = path_lookup(path, LOOKUP_FOLLOW, &nd);
+       err = kern_path(name, LOOKUP_FOLLOW, &path);
        if (err)
                return err;
 
        /* Quotafile not on the same filesystem? */
-       if (nd.path.mnt->mnt_sb != sb) {
-               path_put(&nd.path);
+       if (path.mnt->mnt_sb != sb) {
+               path_put(&path);
                return -EXDEV;
        }
        /* Journaling quota? */
        if (EXT4_SB(sb)->s_qf_names[type]) {
                /* Quotafile not in fs root? */
-               if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode)
+               if (path.dentry->d_parent != sb->s_root)
                        printk(KERN_WARNING
                                "EXT4-fs: Quota file not on filesystem root. "
                                "Journaled quota will not work.\n");
@@ -3361,7 +3361,7 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
         * When we journal data on quota file, we have to flush journal to see
         * all updates to the file when we bypass pagecache...
         */
-       if (ext4_should_journal_data(nd.path.dentry->d_inode)) {
+       if (ext4_should_journal_data(path.dentry->d_inode)) {
                /*
                 * We don't need to lock updates but journal_flush() could
                 * otherwise be livelocked...
@@ -3370,13 +3370,13 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
                err = jbd2_journal_flush(EXT4_SB(sb)->s_journal);
                jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
                if (err) {
-                       path_put(&nd.path);
+                       path_put(&path);
                        return err;
                }
        }
 
-       err = vfs_quota_on_path(sb, type, format_id, &nd.path);
-       path_put(&nd.path);
+       err = vfs_quota_on_path(sb, type, format_id, &path);
+       path_put(&path);
        return err;
 }
 
index cd4a0162e10d6dea7507507cf25a13fd93d93f04..bae1c3292522eddbb744bcf6e6f84bc56da349e3 100644 (file)
@@ -839,6 +839,7 @@ const struct file_operations fat_dir_operations = {
        .compat_ioctl   = fat_compat_dir_ioctl,
 #endif
        .fsync          = file_fsync,
+       .llseek         = generic_file_llseek,
 };
 
 static int fat_get_short_entry(struct inode *dir, loff_t *pos,
index d12cdf2a0406695b43a85e8db5b7f0990d7d2c5a..19eafbe3c379ae685c8f6f018ab5d152ef1ed9bd 100644 (file)
@@ -681,33 +681,24 @@ static struct dentry *fat_fh_to_dentry(struct super_block *sb,
                        inode = NULL;
                }
        }
-       if (!inode) {
-               /* For now, do nothing
-                * What we could do is:
-                * follow the file starting at fh[4], and record
-                * the ".." entry, and the name of the fh[2] entry.
-                * The follow the ".." file finding the next step up.
-                * This way we build a path to the root of
-                * the tree. If this works, we lookup the path and so
-                * get this inode into the cache.
-                * Finally try the fat_iget lookup again
-                * If that fails, then weare totally out of luck
-                * But all that is for another day
-                */
-       }
-       if (!inode)
-               return ERR_PTR(-ESTALE);
-
 
-       /* now to find a dentry.
-        * If possible, get a well-connected one
+       /*
+        * For now, do nothing if the inode is not found.
+        *
+        * What we could do is:
+        *
+        *      - follow the file starting at fh[4], and record the ".." entry,
+        *        and the name of the fh[2] entry.
+        *      - then follow the ".." file finding the next step up.
+        *
+        * This way we build a path to the root of the tree. If this works, we
+        * lookup the path and so get this inode into the cache.  Finally try
+        * the fat_iget lookup again.  If that fails, then we are totally out
+        * of luck.  But all that is for another day
         */
-       result = d_alloc_anon(inode);
-       if (result == NULL) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
-       }
-       result->d_op = sb->s_root->d_op;
+       result = d_obtain_alias(inode);
+       if (!IS_ERR(result))
+               result->d_op = sb->s_root->d_op;
        return result;
 }
 
@@ -754,15 +745,8 @@ static struct dentry *fat_get_parent(struct dentry *child)
        }
        inode = fat_build_inode(sb, de, i_pos);
        brelse(bh);
-       if (IS_ERR(inode)) {
-               parent = ERR_CAST(inode);
-               goto out;
-       }
-       parent = d_alloc_anon(inode);
-       if (!parent) {
-               iput(inode);
-               parent = ERR_PTR(-ENOMEM);
-       }
+
+       parent = d_obtain_alias(inode);
 out:
        unlock_super(sb);
 
index 987bf94114957beca2250a221778f3f93c20d6d2..f8f97b8b6d44c82056a970b549eb3272d457263d 100644 (file)
--- a/fs/fifo.c
+++ b/fs/fifo.c
@@ -51,7 +51,7 @@ static int fifo_open(struct inode *inode, struct file *filp)
        filp->f_mode &= (FMODE_READ | FMODE_WRITE);
 
        switch (filp->f_mode) {
-       case 1:
+       case FMODE_READ:
        /*
         *  O_RDONLY
         *  POSIX.1 says that O_NONBLOCK means return with the FIFO
@@ -76,7 +76,7 @@ static int fifo_open(struct inode *inode, struct file *filp)
                }
                break;
        
-       case 2:
+       case FMODE_WRITE:
        /*
         *  O_WRONLY
         *  POSIX.1 says that O_NONBLOCK means return -1 with
@@ -98,7 +98,7 @@ static int fifo_open(struct inode *inode, struct file *filp)
                }
                break;
        
-       case 3:
+       case FMODE_READ | FMODE_WRITE:
        /*
         *  O_RDWR
         *  POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
index f45a4493f9e71b5afe52640f453a33bce0603c70..efc06faede6c3d6c27c324da2042b7d324e53f8e 100644 (file)
@@ -161,7 +161,7 @@ EXPORT_SYMBOL(get_empty_filp);
  * code should be moved into this function.
  */
 struct file *alloc_file(struct vfsmount *mnt, struct dentry *dentry,
-               mode_t mode, const struct file_operations *fop)
+               fmode_t mode, const struct file_operations *fop)
 {
        struct file *file;
        struct path;
@@ -193,7 +193,7 @@ EXPORT_SYMBOL(alloc_file);
  * of this should be moving to alloc_file().
  */
 int init_file(struct file *file, struct vfsmount *mnt, struct dentry *dentry,
-          mode_t mode, const struct file_operations *fop)
+          fmode_t mode, const struct file_operations *fop)
 {
        int error = 0;
        file->f_path.dentry = dentry;
index f37f87262837aaf6e47526d4895a000f1f9024c2..d0e20ced62ddd73fafdd6dec830d53fa479189bf 100644 (file)
@@ -8,6 +8,8 @@
 
 #include <linux/syscalls.h>
 #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>
@@ -214,6 +216,43 @@ int get_filesystem_list(char * buf)
        return len;
 }
 
+#ifdef CONFIG_PROC_FS
+static int filesystems_proc_show(struct seq_file *m, void *v)
+{
+       struct file_system_type * tmp;
+
+       read_lock(&file_systems_lock);
+       tmp = file_systems;
+       while (tmp) {
+               seq_printf(m, "%s\t%s\n",
+                       (tmp->fs_flags & FS_REQUIRES_DEV) ? "" : "nodev",
+                       tmp->name);
+               tmp = tmp->next;
+       }
+       read_unlock(&file_systems_lock);
+       return 0;
+}
+
+static int filesystems_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, filesystems_proc_show, NULL);
+}
+
+static const struct file_operations filesystems_proc_fops = {
+       .open           = filesystems_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int __init proc_filesystems_init(void)
+{
+       proc_create("filesystems", 0, NULL, &filesystems_proc_fops);
+       return 0;
+}
+module_init(proc_filesystems_init);
+#endif
+
 struct file_system_type *get_fs_type(const char *name)
 {
        struct file_system_type *fs;
index 2bada6bbc317dbeab3887fbcd26ed9fe630b6148..34930a964b8258067ec957f9e5ff2a974c09cc58 100644 (file)
@@ -101,6 +101,8 @@ void fuse_finish_open(struct inode *inode, struct file *file,
                file->f_op = &fuse_direct_io_file_operations;
        if (!(outarg->open_flags & FOPEN_KEEP_CACHE))
                invalidate_inode_pages2(inode->i_mapping);
+       if (outarg->open_flags & FOPEN_NONSEEKABLE)
+               nonseekable_open(inode, file);
        ff->fh = outarg->fh;
        file->private_data = fuse_file_get(ff);
 }
@@ -1448,6 +1450,9 @@ static loff_t fuse_file_llseek(struct file *file, loff_t offset, int origin)
        mutex_lock(&inode->i_mutex);
        switch (origin) {
        case SEEK_END:
+               retval = fuse_update_attributes(inode, NULL, file, NULL);
+               if (retval)
+                       return retval;
                offset += i_size_read(inode);
                break;
        case SEEK_CUR:
index 3a876076bdd1392c93b6a838af53eef104f8461d..35accfdd747f9fde9c561c4fc081939efadd5497 100644 (file)
@@ -6,6 +6,9 @@
   See the file COPYING.
 */
 
+#ifndef _FS_FUSE_I_H
+#define _FS_FUSE_I_H
+
 #include <linux/fuse.h>
 #include <linux/fs.h>
 #include <linux/mount.h>
@@ -655,3 +658,5 @@ void fuse_set_nowrite(struct inode *inode);
 void fuse_release_nowrite(struct inode *inode);
 
 u64 fuse_get_attr_version(struct fuse_conn *fc);
+
+#endif /* _FS_FUSE_I_H */
index 6a84388cacff6f3e0cf5a5d9e307bad71610d5df..2e99f34b44350d4791602ff3ff979fafabc9ad86 100644 (file)
@@ -596,12 +596,8 @@ static struct dentry *fuse_get_dentry(struct super_block *sb,
        if (inode->i_generation != handle->generation)
                goto out_iput;
 
-       entry = d_alloc_anon(inode);
-       err = -ENOMEM;
-       if (!entry)
-               goto out_iput;
-
-       if (get_node_id(inode) != FUSE_ROOT_ID) {
+       entry = d_obtain_alias(inode);
+       if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID) {
                entry->d_op = &fuse_dentry_operations;
                fuse_invalidate_entry_cache(entry);
        }
@@ -696,17 +692,14 @@ static struct dentry *fuse_get_parent(struct dentry *child)
        name.name = "..";
        err = fuse_lookup_name(child_inode->i_sb, get_node_id(child_inode),
                               &name, &outarg, &inode);
-       if (err && err != -ENOENT)
+       if (err) {
+               if (err == -ENOENT)
+                       return ERR_PTR(-ESTALE);
                return ERR_PTR(err);
-       if (err || !inode)
-               return ERR_PTR(-ESTALE);
-
-       parent = d_alloc_anon(inode);
-       if (!parent) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
        }
-       if (get_node_id(inode) != FUSE_ROOT_ID) {
+
+       parent = d_obtain_alias(inode);
+       if (!IS_ERR(parent) && get_node_id(inode) != FUSE_ROOT_ID) {
                parent->d_op = &fuse_dentry_operations;
                fuse_invalidate_entry_cache(parent);
        }
@@ -865,7 +858,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
        if (is_bdev) {
                fc->destroy_req = fuse_request_alloc();
                if (!fc->destroy_req)
-                       goto err_put_root;
+                       goto err_free_init_req;
        }
 
        mutex_lock(&fuse_mutex);
@@ -895,6 +888,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
 
  err_unlock:
        mutex_unlock(&fuse_mutex);
+ err_free_init_req:
        fuse_request_free(init_req);
  err_put_root:
        dput(root_dentry);
index 9cda8536530cb04d40a3a1e85ccc128c1f3baba1..bbb8c36403a96b8b341ea34c742bcb5285023406 100644 (file)
@@ -130,28 +130,17 @@ static int gfs2_get_name(struct dentry *parent, char *name,
 static struct dentry *gfs2_get_parent(struct dentry *child)
 {
        struct qstr dotdot;
-       struct inode *inode;
        struct dentry *dentry;
 
-       gfs2_str2qstr(&dotdot, "..");
-       inode = gfs2_lookupi(child->d_inode, &dotdot, 1);
-
-       if (!inode)
-               return ERR_PTR(-ENOENT);
        /*
-        * In case of an error, @inode carries the error value, and we
-        * have to return that as a(n invalid) pointer to dentry.
+        * XXX(hch): it would be a good idea to keep this around as a
+        *           static variable.
         */
-       if (IS_ERR(inode))
-               return ERR_CAST(inode);
-
-       dentry = d_alloc_anon(inode);
-       if (!dentry) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
-       }
+       gfs2_str2qstr(&dotdot, "..");
 
-       dentry->d_op = &gfs2_dops;
+       dentry = d_obtain_alias(gfs2_lookupi(child->d_inode, &dotdot, 1));
+       if (!IS_ERR(dentry))
+               dentry->d_op = &gfs2_dops;
        return dentry;
 }
 
@@ -233,13 +222,9 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb,
        gfs2_glock_dq_uninit(&i_gh);
 
 out_inode:
-       dentry = d_alloc_anon(inode);
-       if (!dentry) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
-       }
-
-       dentry->d_op = &gfs2_dops;
+       dentry = d_obtain_alias(inode);
+       if (!IS_ERR(dentry))
+               dentry->d_op = &gfs2_dops;
        return dentry;
 
 fail_rgd:
index 534e1e2c65ca63b3303cbeef81789ad82d893ea2..d232991b9046bf6888964c330b8c9abf0bb82723 100644 (file)
@@ -69,7 +69,7 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry,
                        mark_inode_dirty(inode);
                        break;
                } else if (PTR_ERR(inode) != -EEXIST ||
-                          (nd && (nd->intent.open.flags & O_EXCL))) {
+                          (nd && nd->flags & LOOKUP_EXCL)) {
                        gfs2_holder_uninit(ghs);
                        return PTR_ERR(inode);
                }
index 7e19835efa2ea91675980a18e963281a02d46bb8..c69b7ac75bf7d16bb53f6f1603e9a47019a2071b 100644 (file)
@@ -511,13 +511,6 @@ void hfs_clear_inode(struct inode *inode)
        }
 }
 
-static int hfs_permission(struct inode *inode, int mask)
-{
-       if (S_ISREG(inode->i_mode) && mask & MAY_EXEC)
-               return 0;
-       return generic_permission(inode, mask, NULL);
-}
-
 static int hfs_file_open(struct inode *inode, struct file *file)
 {
        if (HFS_IS_RSRC(inode))
@@ -616,7 +609,6 @@ static const struct inode_operations hfs_file_inode_operations = {
        .lookup         = hfs_file_lookup,
        .truncate       = hfs_file_truncate,
        .setattr        = hfs_inode_setattr,
-       .permission     = hfs_permission,
        .setxattr       = hfs_setxattr,
        .getxattr       = hfs_getxattr,
        .listxattr      = hfs_listxattr,
index 963be644297aeb45c2d376721c5cc70ee8ce28f5..b207f0e6fc22cec1feb87b127016f622b169656d 100644 (file)
@@ -238,18 +238,6 @@ static void hfsplus_set_perms(struct inode *inode, struct hfsplus_perm *perms)
        perms->dev = cpu_to_be32(HFSPLUS_I(inode).dev);
 }
 
-static int hfsplus_permission(struct inode *inode, int mask)
-{
-       /* MAY_EXEC is also used for lookup, if no x bit is set allow lookup,
-        * open_exec has the same test, so it's still not executable, if a x bit
-        * is set fall back to standard permission check.
-        */
-       if (S_ISREG(inode->i_mode) && mask & MAY_EXEC && !(inode->i_mode & 0111))
-               return 0;
-       return generic_permission(inode, mask, NULL);
-}
-
-
 static int hfsplus_file_open(struct inode *inode, struct file *file)
 {
        if (HFSPLUS_IS_RSRC(inode))
@@ -281,7 +269,6 @@ static int hfsplus_file_release(struct inode *inode, struct file *file)
 static const struct inode_operations hfsplus_file_inode_operations = {
        .lookup         = hfsplus_file_lookup,
        .truncate       = hfsplus_file_truncate,
-       .permission     = hfsplus_permission,
        .setxattr       = hfsplus_setxattr,
        .getxattr       = hfsplus_getxattr,
        .listxattr      = hfsplus_listxattr,
index d6ecabf4d231f2a9aa9f1cf5b5e1c061ea28cf6c..7f34f4385de00dbcca17d9d3bf7c45bd0aedc1d7 100644 (file)
@@ -20,7 +20,7 @@
 struct hostfs_inode_info {
        char *host_filename;
        int fd;
-       int mode;
+       fmode_t mode;
        struct inode vfs_inode;
 };
 
@@ -373,7 +373,8 @@ int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
 int hostfs_file_open(struct inode *ino, struct file *file)
 {
        char *name;
-       int mode = 0, r = 0, w = 0, fd;
+       fmode_t mode = 0;
+       int r = 0, w = 0, fd;
 
        mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
        if ((mode & HOSTFS_I(ino)->mode) == mode)
index be8be5040e073f81b4e31ad10d119824bbe8f457..64ab52259204b24f20aa356d60ab73b1df982346 100644 (file)
@@ -143,5 +143,5 @@ const struct file_operations hpfs_file_ops =
 const struct inode_operations hpfs_file_iops =
 {
        .truncate       = hpfs_truncate,
-       .setattr        = hpfs_notify_change,
+       .setattr        = hpfs_setattr,
 };
index 42ff60ccf2a9f63b50643da396b6918a67fa3e10..c2ea31bae313092dff76107889b79596cf7b417a 100644 (file)
@@ -275,7 +275,7 @@ void hpfs_init_inode(struct inode *);
 void hpfs_read_inode(struct inode *);
 void hpfs_write_inode(struct inode *);
 void hpfs_write_inode_nolock(struct inode *);
-int hpfs_notify_change(struct dentry *, struct iattr *);
+int hpfs_setattr(struct dentry *, struct iattr *);
 void hpfs_write_if_changed(struct inode *);
 void hpfs_delete_inode(struct inode *);
 
index 85d3e1d9ac000072df33c32b52da5e16394cc676..39a1bfbea3122ed430fdffcd38f5aab02d62b68f 100644 (file)
@@ -260,19 +260,28 @@ void hpfs_write_inode_nolock(struct inode *i)
        brelse(bh);
 }
 
-int hpfs_notify_change(struct dentry *dentry, struct iattr *attr)
+int hpfs_setattr(struct dentry *dentry, struct iattr *attr)
 {
        struct inode *inode = dentry->d_inode;
-       int error=0;
+       int error = -EINVAL;
+
        lock_kernel();
-       if ( ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size) ||
-            (hpfs_sb(inode->i_sb)->sb_root == inode->i_ino) ) {
-               error = -EINVAL;
-       } else if ((error = inode_change_ok(inode, attr))) {
-       } else if ((error = inode_setattr(inode, attr))) {
-       } else {
-               hpfs_write_inode(inode);
-       }
+       if (inode->i_ino == hpfs_sb(inode->i_sb)->sb_root)
+               goto out_unlock;
+       if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size)
+               goto out_unlock;
+
+       error = inode_change_ok(inode, attr);
+       if (error)
+               goto out_unlock;
+
+       error = inode_setattr(inode, attr);
+       if (error)
+               goto out_unlock;
+
+       hpfs_write_inode(inode);
+
+ out_unlock:
        unlock_kernel();
        return error;
 }
index d9c59a775449ee9abfc27e24ed898ce17d05251a..10783f3d265abd8876502fa63bebad1be2f3be35 100644 (file)
@@ -669,5 +669,5 @@ const struct inode_operations hpfs_dir_iops =
        .rmdir          = hpfs_rmdir,
        .mknod          = hpfs_mknod,
        .rename         = hpfs_rename,
-       .setattr        = hpfs_notify_change,
+       .setattr        = hpfs_setattr,
 };
index bb219138331a23672b53bbbf74ee20a0afe920b3..e81a30593ba9aa1b1e857032f3a6a6faac82aea8 100644 (file)
@@ -22,7 +22,7 @@ isofs_export_iget(struct super_block *sb,
                  __u32 generation)
 {
        struct inode *inode;
-       struct dentry *result;
+
        if (block == 0)
                return ERR_PTR(-ESTALE);
        inode = isofs_iget(sb, block, offset);
@@ -32,12 +32,7 @@ isofs_export_iget(struct super_block *sb,
                iput(inode);
                return ERR_PTR(-ESTALE);
        }
-       result = d_alloc_anon(inode);
-       if (!result) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
-       }
-       return result;
+       return d_obtain_alias(inode);
 }
 
 /* This function is surprisingly simple.  The trick is understanding
@@ -51,7 +46,6 @@ static struct dentry *isofs_export_get_parent(struct dentry *child)
        unsigned long parent_offset = 0;
        struct inode *child_inode = child->d_inode;
        struct iso_inode_info *e_child_inode = ISOFS_I(child_inode);
-       struct inode *parent_inode = NULL;
        struct iso_directory_record *de = NULL;
        struct buffer_head * bh = NULL;
        struct dentry *rv = NULL;
@@ -104,28 +98,11 @@ static struct dentry *isofs_export_get_parent(struct dentry *child)
        /* Normalize */
        isofs_normalize_block_and_offset(de, &parent_block, &parent_offset);
 
-       /* Get the inode. */
-       parent_inode = isofs_iget(child_inode->i_sb,
-                                 parent_block,
-                                 parent_offset);
-       if (IS_ERR(parent_inode)) {
-               rv = ERR_CAST(parent_inode);
-               if (rv != ERR_PTR(-ENOMEM))
-                       rv = ERR_PTR(-EACCES);
-               goto out;
-       }
-
-       /* Allocate the dentry. */
-       rv = d_alloc_anon(parent_inode);
-       if (rv == NULL) {
-               rv = ERR_PTR(-ENOMEM);
-               goto out;
-       }
-
+       rv = d_obtain_alias(isofs_iget(child_inode->i_sb, parent_block,
+                                    parent_offset));
  out:
-       if (bh) {
+       if (bh)
                brelse(bh);
-       }
        return rv;
 }
 
index a5432bbbfb88ab678a63b8cfb55b4d04cf8eae7d..1bd8d4acc6f2124a7574001d454a25b971fd9852 100644 (file)
@@ -93,7 +93,8 @@ static int __try_to_free_cp_buf(struct journal_head *jh)
        int ret = 0;
        struct buffer_head *bh = jh2bh(jh);
 
-       if (jh->b_jlist == BJ_None && !buffer_locked(bh) && !buffer_dirty(bh)) {
+       if (jh->b_jlist == BJ_None && !buffer_locked(bh) &&
+           !buffer_dirty(bh) && !buffer_write_io_error(bh)) {
                JBUFFER_TRACE(jh, "remove from checkpoint list");
                ret = __journal_remove_checkpoint(jh) + 1;
                jbd_unlock_bh_state(bh);
@@ -126,14 +127,29 @@ void __log_wait_for_space(journal_t *journal)
 
                /*
                 * Test again, another process may have checkpointed while we
-                * were waiting for the checkpoint lock
+                * were waiting for the checkpoint lock. If there are no
+                * outstanding transactions there is nothing to checkpoint and
+                * we can't make progress. Abort the journal in this case.
                 */
                spin_lock(&journal->j_state_lock);
+               spin_lock(&journal->j_list_lock);
                nblocks = jbd_space_needed(journal);
                if (__log_space_left(journal) < nblocks) {
+                       int chkpt = journal->j_checkpoint_transactions != NULL;
+
+                       spin_unlock(&journal->j_list_lock);
                        spin_unlock(&journal->j_state_lock);
-                       log_do_checkpoint(journal);
+                       if (chkpt) {
+                               log_do_checkpoint(journal);
+                       } else {
+                               printk(KERN_ERR "%s: no transactions\n",
+                                      __func__);
+                               journal_abort(journal, 0);
+                       }
+
                        spin_lock(&journal->j_state_lock);
+               } else {
+                       spin_unlock(&journal->j_list_lock);
                }
                mutex_unlock(&journal->j_checkpoint_mutex);
        }
@@ -160,21 +176,25 @@ static void jbd_sync_bh(journal_t *journal, struct buffer_head *bh)
  * buffers. Note that we take the buffers in the opposite ordering
  * from the one in which they were submitted for IO.
  *
+ * Return 0 on success, and return <0 if some buffers have failed
+ * to be written out.
+ *
  * Called with j_list_lock held.
  */
-static void __wait_cp_io(journal_t *journal, transaction_t *transaction)
+static int __wait_cp_io(journal_t *journal, transaction_t *transaction)
 {
        struct journal_head *jh;
        struct buffer_head *bh;
        tid_t this_tid;
        int released = 0;
+       int ret = 0;
 
        this_tid = transaction->t_tid;
 restart:
        /* Did somebody clean up the transaction in the meanwhile? */
        if (journal->j_checkpoint_transactions != transaction ||
                        transaction->t_tid != this_tid)
-               return;
+               return ret;
        while (!released && transaction->t_checkpoint_io_list) {
                jh = transaction->t_checkpoint_io_list;
                bh = jh2bh(jh);
@@ -194,6 +214,9 @@ restart:
                        spin_lock(&journal->j_list_lock);
                        goto restart;
                }
+               if (unlikely(buffer_write_io_error(bh)))
+                       ret = -EIO;
+
                /*
                 * Now in whatever state the buffer currently is, we know that
                 * it has been written out and so we can drop it from the list
@@ -203,6 +226,8 @@ restart:
                journal_remove_journal_head(bh);
                __brelse(bh);
        }
+
+       return ret;
 }
 
 #define NR_BATCH       64
@@ -226,7 +251,8 @@ __flush_batch(journal_t *journal, struct buffer_head **bhs, int *batch_count)
  * Try to flush one buffer from the checkpoint list to disk.
  *
  * Return 1 if something happened which requires us to abort the current
- * scan of the checkpoint list.
+ * scan of the checkpoint list.  Return <0 if the buffer has failed to
+ * be written out.
  *
  * Called with j_list_lock held and drops it if 1 is returned
  * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it
@@ -256,6 +282,9 @@ static int __process_buffer(journal_t *journal, struct journal_head *jh,
                log_wait_commit(journal, tid);
                ret = 1;
        } else if (!buffer_dirty(bh)) {
+               ret = 1;
+               if (unlikely(buffer_write_io_error(bh)))
+                       ret = -EIO;
                J_ASSERT_JH(jh, !buffer_jbddirty(bh));
                BUFFER_TRACE(bh, "remove from checkpoint");
                __journal_remove_checkpoint(jh);
@@ -263,7 +292,6 @@ static int __process_buffer(journal_t *journal, struct journal_head *jh,
                jbd_unlock_bh_state(bh);
                journal_remove_journal_head(bh);
                __brelse(bh);
-               ret = 1;
        } else {
                /*
                 * Important: we are about to write the buffer, and
@@ -295,6 +323,7 @@ static int __process_buffer(journal_t *journal, struct journal_head *jh,
  * to disk. We submit larger chunks of data at once.
  *
  * The journal should be locked before calling this function.
+ * Called with j_checkpoint_mutex held.
  */
 int log_do_checkpoint(journal_t *journal)
 {
@@ -318,6 +347,7 @@ int log_do_checkpoint(journal_t *journal)
         * OK, we need to start writing disk blocks.  Take one transaction
         * and write it.
         */
+       result = 0;
        spin_lock(&journal->j_list_lock);
        if (!journal->j_checkpoint_transactions)
                goto out;
@@ -334,7 +364,7 @@ restart:
                int batch_count = 0;
                struct buffer_head *bhs[NR_BATCH];
                struct journal_head *jh;
-               int retry = 0;
+               int retry = 0, err;
 
                while (!retry && transaction->t_checkpoint_list) {
                        struct buffer_head *bh;
@@ -347,6 +377,8 @@ restart:
                                break;
                        }
                        retry = __process_buffer(journal, jh, bhs,&batch_count);
+                       if (retry < 0 && !result)
+                               result = retry;
                        if (!retry && (need_resched() ||
                                spin_needbreak(&journal->j_list_lock))) {
                                spin_unlock(&journal->j_list_lock);
@@ -371,14 +403,18 @@ restart:
                 * Now we have cleaned up the first transaction's checkpoint
                 * list. Let's clean up the second one
                 */
-               __wait_cp_io(journal, transaction);
+               err = __wait_cp_io(journal, transaction);
+               if (!result)
+                       result = err;
        }
 out:
        spin_unlock(&journal->j_list_lock);
-       result = cleanup_journal_tail(journal);
        if (result < 0)
-               return result;
-       return 0;
+               journal_abort(journal, result);
+       else
+               result = cleanup_journal_tail(journal);
+
+       return (result < 0) ? result : 0;
 }
 
 /*
@@ -394,8 +430,9 @@ out:
  * This is the only part of the journaling code which really needs to be
  * aware of transaction aborts.  Checkpointing involves writing to the
  * main filesystem area rather than to the journal, so it can proceed
- * even in abort state, but we must not update the journal superblock if
- * we have an abort error outstanding.
+ * even in abort state, but we must not update the super block if
+ * checkpointing may have failed.  Otherwise, we would lose some metadata
+ * buffers which should be written-back to the filesystem.
  */
 
 int cleanup_journal_tail(journal_t *journal)
@@ -404,6 +441,9 @@ int cleanup_journal_tail(journal_t *journal)
        tid_t           first_tid;
        unsigned long   blocknr, freed;
 
+       if (is_journal_aborted(journal))
+               return 1;
+
        /* OK, work out the oldest transaction remaining in the log, and
         * the log block it starts at.
         *
index aa7143a8349bdd0fcb841e70a252d8d9047777bf..9e4fa52d7dc8df62527eb1fb9b141f7db3b37d10 100644 (file)
@@ -1121,9 +1121,12 @@ recovery_error:
  *
  * Release a journal_t structure once it is no longer in use by the
  * journaled object.
+ * Return <0 if we couldn't clean up the journal.
  */
-void journal_destroy(journal_t *journal)
+int journal_destroy(journal_t *journal)
 {
+       int err = 0;
+
        /* Wait for the commit thread to wake up and die. */
        journal_kill_thread(journal);
 
@@ -1146,11 +1149,16 @@ void journal_destroy(journal_t *journal)
        J_ASSERT(journal->j_checkpoint_transactions == NULL);
        spin_unlock(&journal->j_list_lock);
 
-       /* We can now mark the journal as empty. */
-       journal->j_tail = 0;
-       journal->j_tail_sequence = ++journal->j_transaction_sequence;
        if (journal->j_sb_buffer) {
-               journal_update_superblock(journal, 1);
+               if (!is_journal_aborted(journal)) {
+                       /* We can now mark the journal as empty. */
+                       journal->j_tail = 0;
+                       journal->j_tail_sequence =
+                               ++journal->j_transaction_sequence;
+                       journal_update_superblock(journal, 1);
+               } else {
+                       err = -EIO;
+               }
                brelse(journal->j_sb_buffer);
        }
 
@@ -1160,6 +1168,8 @@ void journal_destroy(journal_t *journal)
                journal_destroy_revoke(journal);
        kfree(journal->j_wbuf);
        kfree(journal);
+
+       return err;
 }
 
 
@@ -1359,10 +1369,16 @@ int journal_flush(journal_t *journal)
        spin_lock(&journal->j_list_lock);
        while (!err && journal->j_checkpoint_transactions != NULL) {
                spin_unlock(&journal->j_list_lock);
+               mutex_lock(&journal->j_checkpoint_mutex);
                err = log_do_checkpoint(journal);
+               mutex_unlock(&journal->j_checkpoint_mutex);
                spin_lock(&journal->j_list_lock);
        }
        spin_unlock(&journal->j_list_lock);
+
+       if (is_journal_aborted(journal))
+               return -EIO;
+
        cleanup_journal_tail(journal);
 
        /* Finally, mark the journal as really needing no recovery.
@@ -1384,7 +1400,7 @@ int journal_flush(journal_t *journal)
        J_ASSERT(journal->j_head == journal->j_tail);
        J_ASSERT(journal->j_tail_sequence == journal->j_transaction_sequence);
        spin_unlock(&journal->j_state_lock);
-       return err;
+       return 0;
 }
 
 /**
index 43bc5e5ed0648860aa4971f038bdc17c11142e6a..db5e982c5ddf44f5b442348a6c16f6001b7a8b4d 100644 (file)
@@ -223,7 +223,7 @@ do {                                                                        \
  */
 int journal_recover(journal_t *journal)
 {
-       int                     err;
+       int                     err, err2;
        journal_superblock_t *  sb;
 
        struct recovery_info    info;
@@ -261,7 +261,10 @@ int journal_recover(journal_t *journal)
        journal->j_transaction_sequence = ++info.end_transaction;
 
        journal_clear_revoke(journal);
-       sync_blockdev(journal->j_fs_dev);
+       err2 = sync_blockdev(journal->j_fs_dev);
+       if (!err)
+               err = err2;
+
        return err;
 }
 
index b1aaae823a5227de63ebb0175e904f435ab27772..6f60cc910f4c568f527354357f60d63349a1d8c5 100644 (file)
@@ -39,7 +39,8 @@ const struct file_operations jffs2_dir_operations =
        .read =         generic_read_dir,
        .readdir =      jffs2_readdir,
        .unlocked_ioctl=jffs2_ioctl,
-       .fsync =        jffs2_fsync
+       .fsync =        jffs2_fsync,
+       .llseek =       generic_file_llseek,
 };
 
 
@@ -108,9 +109,7 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target,
                }
        }
 
-       d_add(target, inode);
-
-       return NULL;
+       return d_splice_alias(inode, target);
 }
 
 /***********************************************************************/
index efd401257ed9401bc5e438d5548d6e2e9638ba55..4c4e18c54a5119e209ea23a7bb6ad9eb78182b95 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/mtd/super.h>
 #include <linux/ctype.h>
 #include <linux/namei.h>
+#include <linux/exportfs.h>
 #include "compr.h"
 #include "nodelist.h"
 
@@ -62,6 +63,52 @@ static int jffs2_sync_fs(struct super_block *sb, int wait)
        return 0;
 }
 
+static struct inode *jffs2_nfs_get_inode(struct super_block *sb, uint64_t ino,
+                                        uint32_t generation)
+{
+       /* We don't care about i_generation. We'll destroy the flash
+          before we start re-using inode numbers anyway. And even
+          if that wasn't true, we'd have other problems...*/
+       return jffs2_iget(sb, ino);
+}
+
+static struct dentry *jffs2_fh_to_dentry(struct super_block *sb, struct fid *fid,
+                                        int fh_len, int fh_type)
+{
+        return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
+                                    jffs2_nfs_get_inode);
+}
+
+static struct dentry *jffs2_fh_to_parent(struct super_block *sb, struct fid *fid,
+                                        int fh_len, int fh_type)
+{
+        return generic_fh_to_parent(sb, fid, fh_len, fh_type,
+                                    jffs2_nfs_get_inode);
+}
+
+static struct dentry *jffs2_get_parent(struct dentry *child)
+{
+       struct jffs2_inode_info *f;
+       uint32_t pino;
+
+       BUG_ON(!S_ISDIR(child->d_inode->i_mode));
+
+       f = JFFS2_INODE_INFO(child->d_inode);
+
+       pino = f->inocache->pino_nlink;
+
+       JFFS2_DEBUG("Parent of directory ino #%u is #%u\n",
+                   f->inocache->ino, pino);
+
+       return d_obtain_alias(jffs2_iget(child->d_inode->i_sb, pino));
+}
+
+static struct export_operations jffs2_export_ops = {
+       .get_parent = jffs2_get_parent,
+       .fh_to_dentry = jffs2_fh_to_dentry,
+       .fh_to_parent = jffs2_fh_to_parent,
+};
+
 static const struct super_operations jffs2_super_operations =
 {
        .alloc_inode =  jffs2_alloc_inode,
@@ -104,6 +151,7 @@ static int jffs2_fill_super(struct super_block *sb, void *data, int silent)
        spin_lock_init(&c->inocache_lock);
 
        sb->s_op = &jffs2_super_operations;
+       sb->s_export_op = &jffs2_export_ops;
        sb->s_flags = sb->s_flags | MS_NOATIME;
        sb->s_xattr = jffs2_xattr_handlers;
 #ifdef CONFIG_JFFS2_FS_POSIX_ACL
index cd2ec2988b59ab05304a5e2c864ee9aa2e3baa69..335c4de6552d1a8fb7b1450fd5c20bd9ac5dc29e 100644 (file)
@@ -1168,7 +1168,7 @@ journal_found:
        bd_release(bdev);
 
       close:           /* close external log device */
-       blkdev_put(bdev);
+       blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
 
       free:            /* free log descriptor */
        mutex_unlock(&jfs_log_mutex);
@@ -1514,7 +1514,7 @@ int lmLogClose(struct super_block *sb)
        rc = lmLogShutdown(log);
 
        bd_release(bdev);
-       blkdev_put(bdev);
+       blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
 
        kfree(log);
 
index 2aba82386810591560890e91b02c8f62a4959bd3..cc3cedffbfa11d69b4c6b5bb4b4a5ab96e99dc4c 100644 (file)
@@ -1511,25 +1511,12 @@ struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
 
 struct dentry *jfs_get_parent(struct dentry *dentry)
 {
-       struct super_block *sb = dentry->d_inode->i_sb;
-       struct dentry *parent = ERR_PTR(-ENOENT);
-       struct inode *inode;
        unsigned long parent_ino;
 
        parent_ino =
                le32_to_cpu(JFS_IP(dentry->d_inode)->i_dtroot.header.idotdot);
-       inode = jfs_iget(sb, parent_ino);
-       if (IS_ERR(inode)) {
-               parent = ERR_CAST(inode);
-       } else {
-               parent = d_alloc_anon(inode);
-               if (!parent) {
-                       parent = ERR_PTR(-ENOMEM);
-                       iput(inode);
-               }
-       }
 
-       return parent;
+       return d_obtain_alias(jfs_iget(dentry->d_inode->i_sb, parent_ino));
 }
 
 const struct inode_operations jfs_dir_inode_operations = {
@@ -1560,6 +1547,7 @@ const struct file_operations jfs_dir_operations = {
 #ifdef CONFIG_COMPAT
        .compat_ioctl   = jfs_compat_ioctl,
 #endif
+       .llseek         = generic_file_llseek,
 };
 
 static int jfs_ci_hash(struct dentry *dir, struct qstr *this)
index 1add676a19dfa88f05b97ad6d1d501f38086ec17..74688598bcf72ebadb7f978099f9691747369d6a 100644 (file)
@@ -732,28 +732,6 @@ out:
        return ret;
 }
 
-/*
- * This is what d_alloc_anon should have been.  Once the exportfs
- * argument transition has been finished I will update d_alloc_anon
- * to this prototype and this wrapper will go away.   --hch
- */
-static struct dentry *exportfs_d_alloc(struct inode *inode)
-{
-       struct dentry *dentry;
-
-       if (!inode)
-               return NULL;
-       if (IS_ERR(inode))
-               return ERR_PTR(PTR_ERR(inode));
-
-       dentry = d_alloc_anon(inode);
-       if (!dentry) {
-               iput(inode);
-               dentry = ERR_PTR(-ENOMEM);
-       }
-       return dentry;
-}
-
 /**
  * generic_fh_to_dentry - generic helper for the fh_to_dentry export operation
  * @sb:                filesystem to do the file handle conversion on
@@ -782,7 +760,7 @@ struct dentry *generic_fh_to_dentry(struct super_block *sb, struct fid *fid,
                break;
        }
 
-       return exportfs_d_alloc(inode);
+       return d_obtain_alias(inode);
 }
 EXPORT_SYMBOL_GPL(generic_fh_to_dentry);
 
@@ -815,7 +793,7 @@ struct dentry *generic_fh_to_parent(struct super_block *sb, struct fid *fid,
                break;
        }
 
-       return exportfs_d_alloc(inode);
+       return d_obtain_alias(inode);
 }
 EXPORT_SYMBOL_GPL(generic_fh_to_parent);
 
index 5eb259e3cd38431e7e52baa5ed6975307ff782b5..09062e3ff104d7222d4725d757c5493da3ad68fa 100644 (file)
@@ -1580,7 +1580,8 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd)
        cmd &= ~LOCK_NB;
        unlock = (cmd == LOCK_UN);
 
-       if (!unlock && !(cmd & LOCK_MAND) && !(filp->f_mode & 3))
+       if (!unlock && !(cmd & LOCK_MAND) &&
+           !(filp->f_mode & (FMODE_READ|FMODE_WRITE)))
                goto out_putf;
 
        error = flock_make_lock(filp, &lock, cmd);
@@ -2078,6 +2079,7 @@ int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
 EXPORT_SYMBOL_GPL(vfs_cancel_lock);
 
 #ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 
 static void lock_get_status(struct seq_file *f, struct file_lock *fl,
@@ -2183,12 +2185,31 @@ static void locks_stop(struct seq_file *f, void *v)
        unlock_kernel();
 }
 
-struct seq_operations locks_seq_operations = {
+static const struct seq_operations locks_seq_operations = {
        .start  = locks_start,
        .next   = locks_next,
        .stop   = locks_stop,
        .show   = locks_show,
 };
+
+static int locks_open(struct inode *inode, struct file *filp)
+{
+       return seq_open(filp, &locks_seq_operations);
+}
+
+static const struct file_operations proc_locks_operations = {
+       .open           = locks_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+static int __init proc_locks_init(void)
+{
+       proc_create("locks", 0, NULL, &proc_locks_operations);
+       return 0;
+}
+module_init(proc_locks_init);
 #endif
 
 /**
index 4ea63ed5e79100d991e5f25656a263b04a29e611..09ce58e49e72bb000004851a1ea23e958b0b917d 100644 (file)
@@ -212,8 +212,7 @@ int generic_permission(struct inode *inode, int mask,
         * Read/write DACs are always overridable.
         * Executable DACs are overridable if at least one exec bit is set.
         */
-       if (!(mask & MAY_EXEC) ||
-           (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode))
+       if (!(mask & MAY_EXEC) || execute_ok(inode))
                if (capable(CAP_DAC_OVERRIDE))
                        return 0;
 
@@ -249,23 +248,11 @@ int inode_permission(struct inode *inode, int mask)
        }
 
        /* Ordinary permission routines do not understand MAY_APPEND. */
-       if (inode->i_op && inode->i_op->permission) {
+       if (inode->i_op && inode->i_op->permission)
                retval = inode->i_op->permission(inode, mask);
-               if (!retval) {
-                       /*
-                        * Exec permission on a regular file is denied if none
-                        * of the execute bits are set.
-                        *
-                        * This check should be done by the ->permission()
-                        * method.
-                        */
-                       if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode) &&
-                           !(inode->i_mode & S_IXUGO))
-                               return -EACCES;
-               }
-       } else {
+       else
                retval = generic_permission(inode, mask, NULL);
-       }
+
        if (retval)
                return retval;
 
@@ -1106,6 +1093,15 @@ int path_lookup(const char *name, unsigned int flags,
        return do_path_lookup(AT_FDCWD, name, flags, nd);
 }
 
+int kern_path(const char *name, unsigned int flags, struct path *path)
+{
+       struct nameidata nd;
+       int res = do_path_lookup(AT_FDCWD, name, flags, &nd);
+       if (!res)
+               *path = nd.path;
+       return res;
+}
+
 /**
  * vfs_path_lookup - lookup a file path relative to a dentry-vfsmount pair
  * @dentry:  pointer to dentry of the base directory
@@ -1138,9 +1134,16 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
 
 }
 
-static int __path_lookup_intent_open(int dfd, const char *name,
-               unsigned int lookup_flags, struct nameidata *nd,
-               int open_flags, int create_mode)
+/**
+ * path_lookup_open - lookup a file path with open intent
+ * @dfd: the directory to use as base, or AT_FDCWD
+ * @name: pointer to file name
+ * @lookup_flags: lookup intent flags
+ * @nd: pointer to nameidata
+ * @open_flags: open intent flags
+ */
+int path_lookup_open(int dfd, const char *name, unsigned int lookup_flags,
+               struct nameidata *nd, int open_flags)
 {
        struct file *filp = get_empty_filp();
        int err;
@@ -1149,7 +1152,7 @@ static int __path_lookup_intent_open(int dfd, const char *name,
                return -ENFILE;
        nd->intent.open.file = filp;
        nd->intent.open.flags = open_flags;
-       nd->intent.open.create_mode = create_mode;
+       nd->intent.open.create_mode = 0;
        err = do_path_lookup(dfd, name, lookup_flags|LOOKUP_OPEN, nd);
        if (IS_ERR(nd->intent.open.file)) {
                if (err == 0) {
@@ -1161,38 +1164,6 @@ static int __path_lookup_intent_open(int dfd, const char *name,
        return err;
 }
 
-/**
- * path_lookup_open - lookup a file path with open intent
- * @dfd: the directory to use as base, or AT_FDCWD
- * @name: pointer to file name
- * @lookup_flags: lookup intent flags
- * @nd: pointer to nameidata
- * @open_flags: open intent flags
- */
-int path_lookup_open(int dfd, const char *name, unsigned int lookup_flags,
-               struct nameidata *nd, int open_flags)
-{
-       return __path_lookup_intent_open(dfd, name, lookup_flags, nd,
-                       open_flags, 0);
-}
-
-/**
- * path_lookup_create - lookup a file path with open + create intent
- * @dfd: the directory to use as base, or AT_FDCWD
- * @name: pointer to file name
- * @lookup_flags: lookup intent flags
- * @nd: pointer to nameidata
- * @open_flags: open intent flags
- * @create_mode: create intent flags
- */
-static int path_lookup_create(int dfd, const char *name,
-                             unsigned int lookup_flags, struct nameidata *nd,
-                             int open_flags, int create_mode)
-{
-       return __path_lookup_intent_open(dfd, name, lookup_flags|LOOKUP_CREATE,
-                       nd, open_flags, create_mode);
-}
-
 static struct dentry *__lookup_hash(struct qstr *name,
                struct dentry *base, struct nameidata *nd)
 {
@@ -1470,20 +1441,18 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
 
        mutex_lock(&p1->d_inode->i_sb->s_vfs_rename_mutex);
 
-       for (p = p1; p->d_parent != p; p = p->d_parent) {
-               if (p->d_parent == p2) {
-                       mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_PARENT);
-                       mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_CHILD);
-                       return p;
-               }
+       p = d_ancestor(p2, p1);
+       if (p) {
+               mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_PARENT);
+               mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_CHILD);
+               return p;
        }
 
-       for (p = p2; p->d_parent != p; p = p->d_parent) {
-               if (p->d_parent == p1) {
-                       mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT);
-                       mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_CHILD);
-                       return p;
-               }
+       p = d_ancestor(p1, p2);
+       if (p) {
+               mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT);
+               mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_CHILD);
+               return p;
        }
 
        mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT);
@@ -1702,8 +1671,7 @@ struct file *do_filp_open(int dfd, const char *pathname,
        /*
         * Create - we need to know the parent.
         */
-       error = path_lookup_create(dfd, pathname, LOOKUP_PARENT,
-                                  &nd, flag, mode);
+       error = do_path_lookup(dfd, pathname, LOOKUP_PARENT, &nd);
        if (error)
                return ERR_PTR(error);
 
@@ -1714,10 +1682,20 @@ struct file *do_filp_open(int dfd, const char *pathname,
         */
        error = -EISDIR;
        if (nd.last_type != LAST_NORM || nd.last.name[nd.last.len])
-               goto exit;
+               goto exit_parent;
 
+       error = -ENFILE;
+       filp = get_empty_filp();
+       if (filp == NULL)
+               goto exit_parent;
+       nd.intent.open.file = filp;
+       nd.intent.open.flags = flag;
+       nd.intent.open.create_mode = mode;
        dir = nd.path.dentry;
        nd.flags &= ~LOOKUP_PARENT;
+       nd.flags |= LOOKUP_CREATE | LOOKUP_OPEN;
+       if (flag & O_EXCL)
+               nd.flags |= LOOKUP_EXCL;
        mutex_lock(&dir->d_inode->i_mutex);
        path.dentry = lookup_hash(&nd);
        path.mnt = nd.path.mnt;
@@ -1822,6 +1800,7 @@ exit_dput:
 exit:
        if (!IS_ERR(nd.intent.open.file))
                release_open_intent(&nd);
+exit_parent:
        path_put(&nd.path);
        return ERR_PTR(error);
 
@@ -1914,7 +1893,7 @@ struct dentry *lookup_create(struct nameidata *nd, int is_dir)
        if (nd->last_type != LAST_NORM)
                goto fail;
        nd->flags &= ~LOOKUP_PARENT;
-       nd->flags |= LOOKUP_CREATE;
+       nd->flags |= LOOKUP_CREATE | LOOKUP_EXCL;
        nd->intent.open.flags = O_EXCL;
 
        /*
@@ -2178,16 +2157,19 @@ static long do_rmdir(int dfd, const char __user *pathname)
                return error;
 
        switch(nd.last_type) {
-               case LAST_DOTDOT:
-                       error = -ENOTEMPTY;
-                       goto exit1;
-               case LAST_DOT:
-                       error = -EINVAL;
-                       goto exit1;
-               case LAST_ROOT:
-                       error = -EBUSY;
-                       goto exit1;
+       case LAST_DOTDOT:
+               error = -ENOTEMPTY;
+               goto exit1;
+       case LAST_DOT:
+               error = -EINVAL;
+               goto exit1;
+       case LAST_ROOT:
+               error = -EBUSY;
+               goto exit1;
        }
+
+       nd.flags &= ~LOOKUP_PARENT;
+
        mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
        dentry = lookup_hash(&nd);
        error = PTR_ERR(dentry);
@@ -2265,6 +2247,9 @@ static long do_unlinkat(int dfd, const char __user *pathname)
        error = -EISDIR;
        if (nd.last_type != LAST_NORM)
                goto exit1;
+
+       nd.flags &= ~LOOKUP_PARENT;
+
        mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
        dentry = lookup_hash(&nd);
        error = PTR_ERR(dentry);
@@ -2654,6 +2639,10 @@ asmlinkage long sys_renameat(int olddfd, const char __user *oldname,
        if (newnd.last_type != LAST_NORM)
                goto exit2;
 
+       oldnd.flags &= ~LOOKUP_PARENT;
+       newnd.flags &= ~LOOKUP_PARENT;
+       newnd.flags |= LOOKUP_RENAME_TARGET;
+
        trap = lock_rename(new_dir, old_dir);
 
        old_dentry = lookup_hash(&oldnd);
@@ -2855,6 +2844,7 @@ EXPORT_SYMBOL(__page_symlink);
 EXPORT_SYMBOL(page_symlink);
 EXPORT_SYMBOL(page_symlink_inode_operations);
 EXPORT_SYMBOL(path_lookup);
+EXPORT_SYMBOL(kern_path);
 EXPORT_SYMBOL(vfs_path_lookup);
 EXPORT_SYMBOL(inode_permission);
 EXPORT_SYMBOL(vfs_permission);
index 6e283c93b50dad95a723633b8f257c6d7dccefb7..cce46702d33c98f6d9e1669ac10f4d6c23be82c2 100644 (file)
@@ -1167,19 +1167,19 @@ asmlinkage long sys_oldumount(char __user * name)
 
 #endif
 
-static int mount_is_safe(struct nameidata *nd)
+static int mount_is_safe(struct path *path)
 {
        if (capable(CAP_SYS_ADMIN))
                return 0;
        return -EPERM;
 #ifdef notyet
-       if (S_ISLNK(nd->path.dentry->d_inode->i_mode))
+       if (S_ISLNK(path->dentry->d_inode->i_mode))
                return -EPERM;
-       if (nd->path.dentry->d_inode->i_mode & S_ISVTX) {
-               if (current->uid != nd->path.dentry->d_inode->i_uid)
+       if (path->dentry->d_inode->i_mode & S_ISVTX) {
+               if (current->uid != path->dentry->d_inode->i_uid)
                        return -EPERM;
        }
-       if (vfs_permission(nd, MAY_WRITE))
+       if (inode_permission(path->dentry->d_inode, MAY_WRITE))
                return -EPERM;
        return 0;
 #endif
@@ -1425,11 +1425,10 @@ out_unlock:
 
 /*
  * recursively change the type of the mountpoint.
- * noinline this do_mount helper to save do_mount stack space.
  */
-static noinline int do_change_type(struct nameidata *nd, int flag)
+static int do_change_type(struct path *path, int flag)
 {
-       struct vfsmount *m, *mnt = nd->path.mnt;
+       struct vfsmount *m, *mnt = path->mnt;
        int recurse = flag & MS_REC;
        int type = flag & ~MS_REC;
        int err = 0;
@@ -1437,7 +1436,7 @@ static noinline int do_change_type(struct nameidata *nd, int flag)
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
-       if (nd->path.dentry != nd->path.mnt->mnt_root)
+       if (path->dentry != path->mnt->mnt_root)
                return -EINVAL;
 
        down_write(&namespace_sem);
@@ -1459,40 +1458,39 @@ static noinline int do_change_type(struct nameidata *nd, int flag)
 
 /*
  * do loopback mount.
- * noinline this do_mount helper to save do_mount stack space.
  */
-static noinline int do_loopback(struct nameidata *nd, char *old_name,
+static int do_loopback(struct path *path, char *old_name,
                                int recurse)
 {
-       struct nameidata old_nd;
+       struct path old_path;
        struct vfsmount *mnt = NULL;
-       int err = mount_is_safe(nd);
+       int err = mount_is_safe(path);
        if (err)
                return err;
        if (!old_name || !*old_name)
                return -EINVAL;
-       err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd);
+       err = kern_path(old_name, LOOKUP_FOLLOW, &old_path);
        if (err)
                return err;
 
        down_write(&namespace_sem);
        err = -EINVAL;
-       if (IS_MNT_UNBINDABLE(old_nd.path.mnt))
+       if (IS_MNT_UNBINDABLE(old_path.mnt))
                goto out;
 
-       if (!check_mnt(nd->path.mnt) || !check_mnt(old_nd.path.mnt))
+       if (!check_mnt(path->mnt) || !check_mnt(old_path.mnt))
                goto out;
 
        err = -ENOMEM;
        if (recurse)
-               mnt = copy_tree(old_nd.path.mnt, old_nd.path.dentry, 0);
+               mnt = copy_tree(old_path.mnt, old_path.dentry, 0);
        else
-               mnt = clone_mnt(old_nd.path.mnt, old_nd.path.dentry, 0);
+               mnt = clone_mnt(old_path.mnt, old_path.dentry, 0);
 
        if (!mnt)
                goto out;
 
-       err = graft_tree(mnt, &nd->path);
+       err = graft_tree(mnt, path);
        if (err) {
                LIST_HEAD(umount_list);
                spin_lock(&vfsmount_lock);
@@ -1503,7 +1501,7 @@ static noinline int do_loopback(struct nameidata *nd, char *old_name,
 
 out:
        up_write(&namespace_sem);
-       path_put(&old_nd.path);
+       path_put(&old_path);
        return err;
 }
 
@@ -1528,33 +1526,37 @@ static int change_mount_flags(struct vfsmount *mnt, int ms_flags)
  * change filesystem flags. dir should be a physical root of filesystem.
  * If you've mounted a non-root directory somewhere and want to do remount
  * on it - tough luck.
- * noinline this do_mount helper to save do_mount stack space.
  */
-static noinline int do_remount(struct nameidata *nd, int flags, int mnt_flags,
+static int do_remount(struct path *path, int flags, int mnt_flags,
                      void *data)
 {
        int err;
-       struct super_block *sb = nd->path.mnt->mnt_sb;
+       struct super_block *sb = path->mnt->mnt_sb;
 
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
-       if (!check_mnt(nd->path.mnt))
+       if (!check_mnt(path->mnt))
                return -EINVAL;
 
-       if (nd->path.dentry != nd->path.mnt->mnt_root)
+       if (path->dentry != path->mnt->mnt_root)
                return -EINVAL;
 
        down_write(&sb->s_umount);
        if (flags & MS_BIND)
-               err = change_mount_flags(nd->path.mnt, flags);
+               err = change_mount_flags(path->mnt, flags);
        else
                err = do_remount_sb(sb, flags, data, 0);
        if (!err)
-               nd->path.mnt->mnt_flags = mnt_flags;
+               path->mnt->mnt_flags = mnt_flags;
        up_write(&sb->s_umount);
-       if (!err)
-               security_sb_post_remount(nd->path.mnt, flags, data);
+       if (!err) {
+               security_sb_post_remount(path->mnt, flags, data);
+
+               spin_lock(&vfsmount_lock);
+               touch_mnt_namespace(path->mnt->mnt_ns);
+               spin_unlock(&vfsmount_lock);
+       }
        return err;
 }
 
@@ -1568,90 +1570,85 @@ static inline int tree_contains_unbindable(struct vfsmount *mnt)
        return 0;
 }
 
-/*
- * noinline this do_mount helper to save do_mount stack space.
- */
-static noinline int do_move_mount(struct nameidata *nd, char *old_name)
+static int do_move_mount(struct path *path, char *old_name)
 {
-       struct nameidata old_nd;
-       struct path parent_path;
+       struct path old_path, parent_path;
        struct vfsmount *p;
        int err = 0;
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
        if (!old_name || !*old_name)
                return -EINVAL;
-       err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd);
+       err = kern_path(old_name, LOOKUP_FOLLOW, &old_path);
        if (err)
                return err;
 
        down_write(&namespace_sem);
-       while (d_mountpoint(nd->path.dentry) &&
-              follow_down(&nd->path.mnt, &nd->path.dentry))
+       while (d_mountpoint(path->dentry) &&
+              follow_down(&path->mnt, &path->dentry))
                ;
        err = -EINVAL;
-       if (!check_mnt(nd->path.mnt) || !check_mnt(old_nd.path.mnt))
+       if (!check_mnt(path->mnt) || !check_mnt(old_path.mnt))
                goto out;
 
        err = -ENOENT;
-       mutex_lock(&nd->path.dentry->d_inode->i_mutex);
-       if (IS_DEADDIR(nd->path.dentry->d_inode))
+       mutex_lock(&path->dentry->d_inode->i_mutex);
+       if (IS_DEADDIR(path->dentry->d_inode))
                goto out1;
 
-       if (!IS_ROOT(nd->path.dentry) && d_unhashed(nd->path.dentry))
+       if (!IS_ROOT(path->dentry) && d_unhashed(path->dentry))
                goto out1;
 
        err = -EINVAL;
-       if (old_nd.path.dentry != old_nd.path.mnt->mnt_root)
+       if (old_path.dentry != old_path.mnt->mnt_root)
                goto out1;
 
-       if (old_nd.path.mnt == old_nd.path.mnt->mnt_parent)
+       if (old_path.mnt == old_path.mnt->mnt_parent)
                goto out1;
 
-       if (S_ISDIR(nd->path.dentry->d_inode->i_mode) !=
-             S_ISDIR(old_nd.path.dentry->d_inode->i_mode))
+       if (S_ISDIR(path->dentry->d_inode->i_mode) !=
+             S_ISDIR(old_path.dentry->d_inode->i_mode))
                goto out1;
        /*
         * Don't move a mount residing in a shared parent.
         */
-       if (old_nd.path.mnt->mnt_parent &&
-           IS_MNT_SHARED(old_nd.path.mnt->mnt_parent))
+       if (old_path.mnt->mnt_parent &&
+           IS_MNT_SHARED(old_path.mnt->mnt_parent))
                goto out1;
        /*
         * Don't move a mount tree containing unbindable mounts to a destination
         * mount which is shared.
         */
-       if (IS_MNT_SHARED(nd->path.mnt) &&
-           tree_contains_unbindable(old_nd.path.mnt))
+       if (IS_MNT_SHARED(path->mnt) &&
+           tree_contains_unbindable(old_path.mnt))
                goto out1;
        err = -ELOOP;
-       for (p = nd->path.mnt; p->mnt_parent != p; p = p->mnt_parent)
-               if (p == old_nd.path.mnt)
+       for (p = path->mnt; p->mnt_parent != p; p = p->mnt_parent)
+               if (p == old_path.mnt)
                        goto out1;
 
-       err = attach_recursive_mnt(old_nd.path.mnt, &nd->path, &parent_path);
+       err = attach_recursive_mnt(old_path.mnt, path, &parent_path);
        if (err)
                goto out1;
 
        /* if the mount is moved, it should no longer be expire
         * automatically */
-       list_del_init(&old_nd.path.mnt->mnt_expire);
+       list_del_init(&old_path.mnt->mnt_expire);
 out1:
-       mutex_unlock(&nd->path.dentry->d_inode->i_mutex);
+       mutex_unlock(&path->dentry->d_inode->i_mutex);
 out:
        up_write(&namespace_sem);
        if (!err)
                path_put(&parent_path);
-       path_put(&old_nd.path);
+       path_put(&old_path);
        return err;
 }
 
 /*
  * create a new mount for userspace and request it to be added into the
  * namespace's tree
- * noinline this do_mount helper to save do_mount stack space.
  */
-static noinline int do_new_mount(struct nameidata *nd, char *type, int flags,
+static int do_new_mount(struct path *path, char *type, int flags,
                        int mnt_flags, char *name, void *data)
 {
        struct vfsmount *mnt;
@@ -1667,7 +1664,7 @@ static noinline int do_new_mount(struct nameidata *nd, char *type, int flags,
        if (IS_ERR(mnt))
                return PTR_ERR(mnt);
 
-       return do_add_mount(mnt, &nd->path, mnt_flags, NULL);
+       return do_add_mount(mnt, path, mnt_flags, NULL);
 }
 
 /*
@@ -1902,7 +1899,7 @@ int copy_mount_options(const void __user * data, unsigned long *where)
 long do_mount(char *dev_name, char *dir_name, char *type_page,
                  unsigned long flags, void *data_page)
 {
-       struct nameidata nd;
+       struct path path;
        int retval = 0;
        int mnt_flags = 0;
 
@@ -1940,29 +1937,29 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
                   MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT);
 
        /* ... and get the mountpoint */
-       retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd);
+       retval = kern_path(dir_name, LOOKUP_FOLLOW, &path);
        if (retval)
                return retval;
 
-       retval = security_sb_mount(dev_name, &nd.path,
+       retval = security_sb_mount(dev_name, &path,
                                   type_page, flags, data_page);
        if (retval)
                goto dput_out;
 
        if (flags & MS_REMOUNT)
-               retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
+               retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
                                    data_page);
        else if (flags & MS_BIND)
-               retval = do_loopback(&nd, dev_name, flags & MS_REC);
+               retval = do_loopback(&path, dev_name, flags & MS_REC);
        else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
-               retval = do_change_type(&nd, flags);
+               retval = do_change_type(&path, flags);
        else if (flags & MS_MOVE)
-               retval = do_move_mount(&nd, dev_name);
+               retval = do_move_mount(&path, dev_name);
        else
-               retval = do_new_mount(&nd, type_page, flags, mnt_flags,
+               retval = do_new_mount(&path, type_page, flags, mnt_flags,
                                      dev_name, data_page);
 dput_out:
-       path_put(&nd.path);
+       path_put(&path);
        return retval;
 }
 
index efdba2e802d78bcdf520794e964e873fce793280..3e64b98f3a9337ab241624fc5a544425e7f05e45 100644 (file)
@@ -707,9 +707,7 @@ static int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd)
 {
        if (NFS_PROTO(dir)->version == 2)
                return 0;
-       if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0)
-               return 0;
-       return (nd->intent.open.flags & O_EXCL) != 0;
+       return nd && nfs_lookup_check_intent(nd, LOOKUP_EXCL);
 }
 
 /*
@@ -1009,7 +1007,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
 
        /* Let vfs_create() deal with O_EXCL. Instantiate, but don't hash
         * the dentry. */
-       if (nd->intent.open.flags & O_EXCL) {
+       if (nd->flags & LOOKUP_EXCL) {
                d_instantiate(dentry, NULL);
                goto out;
        }
@@ -1959,6 +1957,9 @@ force_lookup:
        } else
                res = PTR_ERR(cred);
 out:
+       if (!res && (mask & MAY_EXEC) && !execute_ok(inode))
+               res = -EACCES;
+
        dfprintk(VFS, "NFS: permission(%s/%ld), mask=0x%x, res=%d\n",
                inode->i_sb->s_id, inode->i_ino, mask, res);
        return res;
index fae97196daadb74c1dd1c28a5767460557402478..b7c9b2df1f299dd15d30b81d533b602d8ae09572 100644 (file)
@@ -107,11 +107,10 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh)
         * if the dentry tree reaches them; however if the dentry already
         * exists, we'll pick it up at this point and use it as the root
         */
-       mntroot = d_alloc_anon(inode);
-       if (!mntroot) {
-               iput(inode);
+       mntroot = d_obtain_alias(inode);
+       if (IS_ERR(mntroot)) {
                dprintk("nfs_get_root: get root dentry failed\n");
-               return ERR_PTR(-ENOMEM);
+               return mntroot;
        }
 
        security_d_instantiate(mntroot, inode);
@@ -277,11 +276,10 @@ struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh)
         * if the dentry tree reaches them; however if the dentry already
         * exists, we'll pick it up at this point and use it as the root
         */
-       mntroot = d_alloc_anon(inode);
-       if (!mntroot) {
-               iput(inode);
+       mntroot = d_obtain_alias(inode);
+       if (IS_ERR(mntroot)) {
                dprintk("nfs_get_root: get root dentry failed\n");
-               return ERR_PTR(-ENOMEM);
+               return mntroot;
        }
 
        security_d_instantiate(mntroot, inode);
index 9dc036f1835614e3c2505abad50496071cf8b0b2..5839b229cd0ea9bbd631441b89a07e639be0a98f 100644 (file)
@@ -99,7 +99,7 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
        int fsidtype;
        char *ep;
        struct svc_expkey key;
-       struct svc_expkey *ek;
+       struct svc_expkey *ek = NULL;
 
        if (mesg[mlen-1] != '\n')
                return -EINVAL;
@@ -107,7 +107,8 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
 
        buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
        err = -ENOMEM;
-       if (!buf) goto out;
+       if (!buf)
+               goto out;
 
        err = -EINVAL;
        if ((len=qword_get(&mesg, buf, PAGE_SIZE)) <= 0)
@@ -151,34 +152,32 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
 
        /* now we want a pathname, or empty meaning NEGATIVE  */
        err = -EINVAL;
-       if ((len=qword_get(&mesg, buf, PAGE_SIZE)) < 0)
+       len = qword_get(&mesg, buf, PAGE_SIZE);
+       if (len < 0)
                goto out;
        dprintk("Path seems to be <%s>\n", buf);
        err = 0;
        if (len == 0) {
                set_bit(CACHE_NEGATIVE, &key.h.flags);
                ek = svc_expkey_update(&key, ek);
-               if (ek)
-                       cache_put(&ek->h, &svc_expkey_cache);
-               else err = -ENOMEM;
+               if (!ek)
+                       err = -ENOMEM;
        } else {
-               struct nameidata nd;
-               err = path_lookup(buf, 0, &nd);
+               err = kern_path(buf, 0, &key.ek_path);
                if (err)
                        goto out;
 
                dprintk("Found the path %s\n", buf);
-               key.ek_path = nd.path;
 
                ek = svc_expkey_update(&key, ek);
-               if (ek)
-                       cache_put(&ek->h, &svc_expkey_cache);
-               else
+               if (!ek)
                        err = -ENOMEM;
-               path_put(&nd.path);
+               path_put(&key.ek_path);
        }
        cache_flush();
  out:
+       if (ek)
+               cache_put(&ek->h, &svc_expkey_cache);
        if (dom)
                auth_domain_put(dom);
        kfree(buf);
@@ -500,35 +499,22 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
        int len;
        int err;
        struct auth_domain *dom = NULL;
-       struct nameidata nd;
-       struct svc_export exp, *expp;
+       struct svc_export exp = {}, *expp;
        int an_int;
 
-       nd.path.dentry = NULL;
-       exp.ex_pathname = NULL;
-
-       /* fs locations */
-       exp.ex_fslocs.locations = NULL;
-       exp.ex_fslocs.locations_count = 0;
-       exp.ex_fslocs.migrated = 0;
-
-       exp.ex_uuid = NULL;
-
-       /* secinfo */
-       exp.ex_nflavors = 0;
-
        if (mesg[mlen-1] != '\n')
                return -EINVAL;
        mesg[mlen-1] = 0;
 
        buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-       err = -ENOMEM;
-       if (!buf) goto out;
+       if (!buf)
+               return -ENOMEM;
 
        /* client */
-       len = qword_get(&mesg, buf, PAGE_SIZE);
        err = -EINVAL;
-       if (len <= 0) goto out;
+       len = qword_get(&mesg, buf, PAGE_SIZE);
+       if (len <= 0)
+               goto out;
 
        err = -ENOENT;
        dom = auth_domain_find(buf);
@@ -537,25 +523,25 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
 
        /* path */
        err = -EINVAL;
-       if ((len=qword_get(&mesg, buf, PAGE_SIZE)) <= 0)
-               goto out;
-       err = path_lookup(buf, 0, &nd);
-       if (err) goto out_no_path;
+       if ((len = qword_get(&mesg, buf, PAGE_SIZE)) <= 0)
+               goto out1;
+
+       err = kern_path(buf, 0, &exp.ex_path);
+       if (err)
+               goto out1;
 
-       exp.h.flags = 0;
        exp.ex_client = dom;
-       exp.ex_path.mnt = nd.path.mnt;
-       exp.ex_path.dentry = nd.path.dentry;
-       exp.ex_pathname = kstrdup(buf, GFP_KERNEL);
+
        err = -ENOMEM;
+       exp.ex_pathname = kstrdup(buf, GFP_KERNEL);
        if (!exp.ex_pathname)
-               goto out;
+               goto out2;
 
        /* expiry */
        err = -EINVAL;
        exp.h.expiry_time = get_expiry(&mesg);
        if (exp.h.expiry_time == 0)
-               goto out;
+               goto out3;
 
        /* flags */
        err = get_int(&mesg, &an_int);
@@ -563,22 +549,26 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
                err = 0;
                set_bit(CACHE_NEGATIVE, &exp.h.flags);
        } else {
-               if (err || an_int < 0) goto out;        
+               if (err || an_int < 0)
+                       goto out3;
                exp.ex_flags= an_int;
        
                /* anon uid */
                err = get_int(&mesg, &an_int);
-               if (err) goto out;
+               if (err)
+                       goto out3;
                exp.ex_anon_uid= an_int;
 
                /* anon gid */
                err = get_int(&mesg, &an_int);
-               if (err) goto out;
+               if (err)
+                       goto out3;
                exp.ex_anon_gid= an_int;
 
                /* fsid */
                err = get_int(&mesg, &an_int);
-               if (err) goto out;
+               if (err)
+                       goto out3;
                exp.ex_fsid = an_int;
 
                while ((len = qword_get(&mesg, buf, PAGE_SIZE)) > 0) {
@@ -604,12 +594,13 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
                                 */
                                break;
                        if (err)
-                               goto out;
+                               goto out4;
                }
 
-               err = check_export(nd.path.dentry->d_inode, exp.ex_flags,
+               err = check_export(exp.ex_path.dentry->d_inode, exp.ex_flags,
                                   exp.ex_uuid);
-               if (err) goto out;
+               if (err)
+                       goto out4;
        }
 
        expp = svc_export_lookup(&exp);
@@ -622,15 +613,16 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
                err = -ENOMEM;
        else
                exp_put(expp);
- out:
+out4:
        nfsd4_fslocs_free(&exp.ex_fslocs);
        kfree(exp.ex_uuid);
+out3:
        kfree(exp.ex_pathname);
-       if (nd.path.dentry)
-               path_put(&nd.path);
- out_no_path:
-       if (dom)
-               auth_domain_put(dom);
+out2:
+       path_put(&exp.ex_path);
+out1:
+       auth_domain_put(dom);
+out:
        kfree(buf);
        return err;
 }
@@ -998,7 +990,7 @@ exp_export(struct nfsctl_export *nxp)
        struct svc_export       *exp = NULL;
        struct svc_export       new;
        struct svc_expkey       *fsid_key = NULL;
-       struct nameidata nd;
+       struct path path;
        int             err;
 
        /* Consistency check */
@@ -1021,12 +1013,12 @@ exp_export(struct nfsctl_export *nxp)
 
 
        /* Look up the dentry */
-       err = path_lookup(nxp->ex_path, 0, &nd);
+       err = kern_path(nxp->ex_path, 0, &path);
        if (err)
                goto out_put_clp;
        err = -EINVAL;
 
-       exp = exp_get_by_name(clp, nd.path.mnt, nd.path.dentry, NULL);
+       exp = exp_get_by_name(clp, path.mnt, path.dentry, NULL);
 
        memset(&new, 0, sizeof(new));
 
@@ -1034,8 +1026,8 @@ exp_export(struct nfsctl_export *nxp)
        if ((nxp->ex_flags & NFSEXP_FSID) &&
            (!IS_ERR(fsid_key = exp_get_fsid_key(clp, nxp->ex_dev))) &&
            fsid_key->ek_path.mnt &&
-           (fsid_key->ek_path.mnt != nd.path.mnt ||
-            fsid_key->ek_path.dentry != nd.path.dentry))
+           (fsid_key->ek_path.mnt != path.mnt ||
+            fsid_key->ek_path.dentry != path.dentry))
                goto finish;
 
        if (!IS_ERR(exp)) {
@@ -1051,7 +1043,7 @@ exp_export(struct nfsctl_export *nxp)
                goto finish;
        }
 
-       err = check_export(nd.path.dentry->d_inode, nxp->ex_flags, NULL);
+       err = check_export(path.dentry->d_inode, nxp->ex_flags, NULL);
        if (err) goto finish;
 
        err = -ENOMEM;
@@ -1064,7 +1056,7 @@ exp_export(struct nfsctl_export *nxp)
        if (!new.ex_pathname)
                goto finish;
        new.ex_client = clp;
-       new.ex_path = nd.path;
+       new.ex_path = path;
        new.ex_flags = nxp->ex_flags;
        new.ex_anon_uid = nxp->ex_anon_uid;
        new.ex_anon_gid = nxp->ex_anon_gid;
@@ -1090,7 +1082,7 @@ finish:
                exp_put(exp);
        if (fsid_key && !IS_ERR(fsid_key))
                cache_put(&fsid_key->h, &svc_expkey_cache);
-       path_put(&nd.path);
+       path_put(&path);
 out_put_clp:
        auth_domain_put(clp);
 out_unlock:
@@ -1121,7 +1113,7 @@ exp_unexport(struct nfsctl_export *nxp)
 {
        struct auth_domain *dom;
        svc_export *exp;
-       struct nameidata nd;
+       struct path path;
        int             err;
 
        /* Consistency check */
@@ -1138,13 +1130,13 @@ exp_unexport(struct nfsctl_export *nxp)
                goto out_unlock;
        }
 
-       err = path_lookup(nxp->ex_path, 0, &nd);
+       err = kern_path(nxp->ex_path, 0, &path);
        if (err)
                goto out_domain;
 
        err = -EINVAL;
-       exp = exp_get_by_name(dom, nd.path.mnt, nd.path.dentry, NULL);
-       path_put(&nd.path);
+       exp = exp_get_by_name(dom, path.mnt, path.dentry, NULL);
+       path_put(&path);
        if (IS_ERR(exp))
                goto out_domain;
 
@@ -1166,26 +1158,26 @@ out_unlock:
  * since its harder to fool a kernel module than a user space program.
  */
 int
-exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
+exp_rootfh(svc_client *clp, char *name, struct knfsd_fh *f, int maxsize)
 {
        struct svc_export       *exp;
-       struct nameidata        nd;
+       struct path             path;
        struct inode            *inode;
        struct svc_fh           fh;
        int                     err;
 
        err = -EPERM;
        /* NB: we probably ought to check that it's NUL-terminated */
-       if (path_lookup(path, 0, &nd)) {
-               printk("nfsd: exp_rootfh path not found %s", path);
+       if (kern_path(name, 0, &path)) {
+               printk("nfsd: exp_rootfh path not found %s", name);
                return err;
        }
-       inode = nd.path.dentry->d_inode;
+       inode = path.dentry->d_inode;
 
        dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n",
-                path, nd.path.dentry, clp->name,
+                name, path.dentry, clp->name,
                 inode->i_sb->s_id, inode->i_ino);
-       exp = exp_parent(clp, nd.path.mnt, nd.path.dentry, NULL);
+       exp = exp_parent(clp, path.mnt, path.dentry, NULL);
        if (IS_ERR(exp)) {
                err = PTR_ERR(exp);
                goto out;
@@ -1195,7 +1187,7 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
         * fh must be initialized before calling fh_compose
         */
        fh_init(&fh, maxsize);
-       if (fh_compose(&fh, exp, nd.path.dentry, NULL))
+       if (fh_compose(&fh, exp, path.dentry, NULL))
                err = -EINVAL;
        else
                err = 0;
@@ -1203,7 +1195,7 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
        fh_put(&fh);
        exp_put(exp);
 out:
-       path_put(&nd.path);
+       path_put(&path);
        return err;
 }
 
index 145b3c877a27c222984f3671f29b004c84db9cfd..bb93946ace2249841dd94a25d4ce0a0582e9dfde 100644 (file)
@@ -51,7 +51,7 @@
 #define NFSDDBG_FACILITY                NFSDDBG_PROC
 
 /* Globals */
-static struct nameidata rec_dir;
+static struct path rec_dir;
 static int rec_dir_init = 0;
 
 static void
@@ -121,9 +121,9 @@ out_no_tfm:
 static void
 nfsd4_sync_rec_dir(void)
 {
-       mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex);
-       nfsd_sync_dir(rec_dir.path.dentry);
-       mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex);
+       mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
+       nfsd_sync_dir(rec_dir.dentry);
+       mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
 }
 
 int
@@ -143,9 +143,9 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
        nfs4_save_user(&uid, &gid);
 
        /* lock the parent */
-       mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex);
+       mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
 
-       dentry = lookup_one_len(dname, rec_dir.path.dentry, HEXDIR_LEN-1);
+       dentry = lookup_one_len(dname, rec_dir.dentry, HEXDIR_LEN-1);
        if (IS_ERR(dentry)) {
                status = PTR_ERR(dentry);
                goto out_unlock;
@@ -155,15 +155,15 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
                dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
                goto out_put;
        }
-       status = mnt_want_write(rec_dir.path.mnt);
+       status = mnt_want_write(rec_dir.mnt);
        if (status)
                goto out_put;
-       status = vfs_mkdir(rec_dir.path.dentry->d_inode, dentry, S_IRWXU);
-       mnt_drop_write(rec_dir.path.mnt);
+       status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU);
+       mnt_drop_write(rec_dir.mnt);
 out_put:
        dput(dentry);
 out_unlock:
-       mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex);
+       mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
        if (status == 0) {
                clp->cl_firststate = 1;
                nfsd4_sync_rec_dir();
@@ -226,7 +226,7 @@ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
 
        nfs4_save_user(&uid, &gid);
 
-       filp = dentry_open(dget(dir), mntget(rec_dir.path.mnt), O_RDONLY);
+       filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY);
        status = PTR_ERR(filp);
        if (IS_ERR(filp))
                goto out;
@@ -291,9 +291,9 @@ nfsd4_unlink_clid_dir(char *name, int namlen)
 
        dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);
 
-       mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex);
-       dentry = lookup_one_len(name, rec_dir.path.dentry, namlen);
-       mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex);
+       mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
+       dentry = lookup_one_len(name, rec_dir.dentry, namlen);
+       mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
        if (IS_ERR(dentry)) {
                status = PTR_ERR(dentry);
                return status;
@@ -302,7 +302,7 @@ nfsd4_unlink_clid_dir(char *name, int namlen)
        if (!dentry->d_inode)
                goto out;
 
-       status = nfsd4_clear_clid_dir(rec_dir.path.dentry, dentry);
+       status = nfsd4_clear_clid_dir(rec_dir.dentry, dentry);
 out:
        dput(dentry);
        return status;
@@ -318,7 +318,7 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
        if (!rec_dir_init || !clp->cl_firststate)
                return;
 
-       status = mnt_want_write(rec_dir.path.mnt);
+       status = mnt_want_write(rec_dir.mnt);
        if (status)
                goto out;
        clp->cl_firststate = 0;
@@ -327,7 +327,7 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
        nfs4_reset_user(uid, gid);
        if (status == 0)
                nfsd4_sync_rec_dir();
-       mnt_drop_write(rec_dir.path.mnt);
+       mnt_drop_write(rec_dir.mnt);
 out:
        if (status)
                printk("NFSD: Failed to remove expired client state directory"
@@ -357,17 +357,17 @@ nfsd4_recdir_purge_old(void) {
 
        if (!rec_dir_init)
                return;
-       status = mnt_want_write(rec_dir.path.mnt);
+       status = mnt_want_write(rec_dir.mnt);
        if (status)
                goto out;
-       status = nfsd4_list_rec_dir(rec_dir.path.dentry, purge_old);
+       status = nfsd4_list_rec_dir(rec_dir.dentry, purge_old);
        if (status == 0)
                nfsd4_sync_rec_dir();
-       mnt_drop_write(rec_dir.path.mnt);
+       mnt_drop_write(rec_dir.mnt);
 out:
        if (status)
                printk("nfsd4: failed to purge old clients from recovery"
-                       " directory %s\n", rec_dir.path.dentry->d_name.name);
+                       " directory %s\n", rec_dir.dentry->d_name.name);
 }
 
 static int
@@ -387,10 +387,10 @@ int
 nfsd4_recdir_load(void) {
        int status;
 
-       status = nfsd4_list_rec_dir(rec_dir.path.dentry, load_recdir);
+       status = nfsd4_list_rec_dir(rec_dir.dentry, load_recdir);
        if (status)
                printk("nfsd4: failed loading clients from recovery"
-                       " directory %s\n", rec_dir.path.dentry->d_name.name);
+                       " directory %s\n", rec_dir.dentry->d_name.name);
        return status;
 }
 
@@ -412,7 +412,7 @@ nfsd4_init_recdir(char *rec_dirname)
 
        nfs4_save_user(&uid, &gid);
 
-       status = path_lookup(rec_dirname, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
+       status = kern_path(rec_dirname, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
                        &rec_dir);
        if (status)
                printk("NFSD: unable to find recovery directory %s\n",
@@ -429,5 +429,5 @@ nfsd4_shutdown_recdir(void)
        if (!rec_dir_init)
                return;
        rec_dir_init = 0;
-       path_put(&rec_dir.path);
+       path_put(&rec_dir);
 }
index 0cc7ff5d5ab53e4bf0c0c5e4646cac4012f18165..b0bebc552a11f3cec582b83c80c45c97a7734cdd 100644 (file)
@@ -3284,17 +3284,17 @@ int
 nfs4_reset_recoverydir(char *recdir)
 {
        int status;
-       struct nameidata nd;
+       struct path path;
 
-       status = path_lookup(recdir, LOOKUP_FOLLOW, &nd);
+       status = kern_path(recdir, LOOKUP_FOLLOW, &path);
        if (status)
                return status;
        status = -ENOTDIR;
-       if (S_ISDIR(nd.path.dentry->d_inode->i_mode)) {
+       if (S_ISDIR(path.dentry->d_inode->i_mode)) {
                nfs4_set_recdir(recdir);
                status = 0;
        }
-       path_put(&nd.path);
+       path_put(&path);
        return status;
 }
 
index 97543df58242f1bc54244aeac633a4fc2e139c8f..e3f9783fdcf7eba3872331b0c48f5aee7207fd62 100644 (file)
@@ -341,7 +341,7 @@ static ssize_t failover_unlock_ip(struct file *file, char *buf, size_t size)
 
 static ssize_t failover_unlock_fs(struct file *file, char *buf, size_t size)
 {
-       struct nameidata nd;
+       struct path path;
        char *fo_path;
        int error;
 
@@ -356,13 +356,13 @@ static ssize_t failover_unlock_fs(struct file *file, char *buf, size_t size)
        if (qword_get(&buf, fo_path, size) < 0)
                return -EINVAL;
 
-       error = path_lookup(fo_path, 0, &nd);
+       error = kern_path(fo_path, 0, &path);
        if (error)
                return error;
 
-       error = nlmsvc_unlock_all_by_sb(nd.path.mnt->mnt_sb);
+       error = nlmsvc_unlock_all_by_sb(path.mnt->mnt_sb);
 
-       path_put(&nd.path);
+       path_put(&path);
        return error;
 }
 
index 59eeb46f82c5e842c528ff63a905347c2015e15e..07e4f5d7baa8c63f3639cfee85cb043d0ae8cd84 100644 (file)
@@ -249,6 +249,10 @@ static int nfsd_init_socks(int port)
        if (error < 0)
                return error;
 
+       error = lockd_up();
+       if (error < 0)
+               return error;
+
        error = svc_create_xprt(nfsd_serv, "tcp", port,
                                        SVC_SOCK_DEFAULTS);
        if (error < 0)
index aa1d0d6489a119a3e8e00aa301cc9a9719006087..0bc56f6d9276b96878edd55837354d6c5ea87d02 100644 (file)
@@ -410,6 +410,7 @@ out_nfserr:
 static ssize_t nfsd_getxattr(struct dentry *dentry, char *key, void **buf)
 {
        ssize_t buflen;
+       ssize_t ret;
 
        buflen = vfs_getxattr(dentry, key, NULL, 0);
        if (buflen <= 0)
@@ -419,7 +420,10 @@ static ssize_t nfsd_getxattr(struct dentry *dentry, char *key, void **buf)
        if (!*buf)
                return -ENOMEM;
 
-       return vfs_getxattr(dentry, key, *buf, buflen);
+       ret = vfs_getxattr(dentry, key, *buf, buflen);
+       if (ret < 0)
+               kfree(*buf);
+       return ret;
 }
 #endif
 
@@ -1813,6 +1817,115 @@ out:
        return err;
 }
 
+/*
+ * We do this buffering because we must not call back into the file
+ * system's ->lookup() method from the filldir callback. That may well
+ * deadlock a number of file systems.
+ *
+ * This is based heavily on the implementation of same in XFS.
+ */
+struct buffered_dirent {
+       u64             ino;
+       loff_t          offset;
+       int             namlen;
+       unsigned int    d_type;
+       char            name[];
+};
+
+struct readdir_data {
+       char            *dirent;
+       size_t          used;
+       int             full;
+};
+
+static int nfsd_buffered_filldir(void *__buf, const char *name, int namlen,
+                                loff_t offset, u64 ino, unsigned int d_type)
+{
+       struct readdir_data *buf = __buf;
+       struct buffered_dirent *de = (void *)(buf->dirent + buf->used);
+       unsigned int reclen;
+
+       reclen = ALIGN(sizeof(struct buffered_dirent) + namlen, sizeof(u64));
+       if (buf->used + reclen > PAGE_SIZE) {
+               buf->full = 1;
+               return -EINVAL;
+       }
+
+       de->namlen = namlen;
+       de->offset = offset;
+       de->ino = ino;
+       de->d_type = d_type;
+       memcpy(de->name, name, namlen);
+       buf->used += reclen;
+
+       return 0;
+}
+
+static int nfsd_buffered_readdir(struct file *file, filldir_t func,
+                                struct readdir_cd *cdp, loff_t *offsetp)
+{
+       struct readdir_data buf;
+       struct buffered_dirent *de;
+       int host_err;
+       int size;
+       loff_t offset;
+
+       buf.dirent = (void *)__get_free_page(GFP_KERNEL);
+       if (!buf.dirent)
+               return -ENOMEM;
+
+       offset = *offsetp;
+       cdp->err = nfserr_eof; /* will be cleared on successful read */
+
+       while (1) {
+               unsigned int reclen;
+
+               buf.used = 0;
+               buf.full = 0;
+
+               host_err = vfs_readdir(file, nfsd_buffered_filldir, &buf);
+               if (buf.full)
+                       host_err = 0;
+
+               if (host_err < 0)
+                       break;
+
+               size = buf.used;
+
+               if (!size)
+                       break;
+
+               de = (struct buffered_dirent *)buf.dirent;
+               while (size > 0) {
+                       offset = de->offset;
+
+                       if (func(cdp, de->name, de->namlen, de->offset,
+                                de->ino, de->d_type))
+                               goto done;
+
+                       if (cdp->err != nfs_ok)
+                               goto done;
+
+                       reclen = ALIGN(sizeof(*de) + de->namlen,
+                                      sizeof(u64));
+                       size -= reclen;
+                       de = (struct buffered_dirent *)((char *)de + reclen);
+               }
+               offset = vfs_llseek(file, 0, SEEK_CUR);
+               if (!buf.full)
+                       break;
+       }
+
+ done:
+       free_page((unsigned long)(buf.dirent));
+
+       if (host_err)
+               return nfserrno(host_err);
+
+       *offsetp = offset;
+       return cdp->err;
+}
+
 /*
  * Read entries from a directory.
  * The  NFSv3/4 verifier we ignore for now.
@@ -1822,7 +1935,6 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp,
             struct readdir_cd *cdp, filldir_t func)
 {
        __be32          err;
-       int             host_err;
        struct file     *file;
        loff_t          offset = *offsetp;
 
@@ -1836,21 +1948,7 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp,
                goto out_close;
        }
 
-       /*
-        * Read the directory entries. This silly loop is necessary because
-        * readdir() is not guaranteed to fill up the entire buffer, but
-        * may choose to do less.
-        */
-
-       do {
-               cdp->err = nfserr_eof; /* will be cleared on successful read */
-               host_err = vfs_readdir(file, func, cdp);
-       } while (host_err >=0 && cdp->err == nfs_ok);
-       if (host_err)
-               err = nfserrno(host_err);
-       else
-               err = cdp->err;
-       *offsetp = vfs_llseek(file, 0, 1);
+       err = nfsd_buffered_readdir(file, func, cdp, offsetp);
 
        if (err == nfserr_eof || err == nfserr_toosmall)
                err = nfs_ok; /* can still be found in ->err */
index 9e8a95be7a1e27c2938753e245513c0650e8b7b1..2ca00153b6ece6ea51de28d8eb3925eb86be36bc 100644 (file)
@@ -304,8 +304,6 @@ static struct dentry *ntfs_get_parent(struct dentry *child_dent)
        ntfs_attr_search_ctx *ctx;
        ATTR_RECORD *attr;
        FILE_NAME_ATTR *fn;
-       struct inode *parent_vi;
-       struct dentry *parent_dent;
        unsigned long parent_ino;
        int err;
 
@@ -345,24 +343,8 @@ try_next:
        /* Release the search context and the mft record of the child. */
        ntfs_attr_put_search_ctx(ctx);
        unmap_mft_record(ni);
-       /* Get the inode of the parent directory. */
-       parent_vi = ntfs_iget(vi->i_sb, parent_ino);
-       if (IS_ERR(parent_vi) || unlikely(is_bad_inode(parent_vi))) {
-               if (!IS_ERR(parent_vi))
-                       iput(parent_vi);
-               ntfs_error(vi->i_sb, "Failed to get parent directory inode "
-                               "0x%lx of child inode 0x%lx.", parent_ino,
-                               vi->i_ino);
-               return ERR_PTR(-EACCES);
-       }
-       /* Finally get a dentry for the parent directory and return it. */
-       parent_dent = d_alloc_anon(parent_vi);
-       if (unlikely(!parent_dent)) {
-               iput(parent_vi);
-               return ERR_PTR(-ENOMEM);
-       }
-       ntfs_debug("Done for inode 0x%lx.", vi->i_ino);
-       return parent_dent;
+
+       return d_obtain_alias(ntfs_iget(vi->i_sb, parent_ino));
 }
 
 static struct inode *ntfs_nfs_get_inode(struct super_block *sb,
index 7dce1612553e424e5d006ed20aa9d3429284f34c..6ebaa58e2c03a1b4b237ceb1179b3c26607e7c4d 100644 (file)
@@ -976,7 +976,7 @@ static void o2hb_region_release(struct config_item *item)
        }
 
        if (reg->hr_bdev)
-               blkdev_put(reg->hr_bdev);
+               blkdev_put(reg->hr_bdev, FMODE_READ|FMODE_WRITE);
 
        if (reg->hr_slots)
                kfree(reg->hr_slots);
@@ -1268,7 +1268,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
                goto out;
 
        reg->hr_bdev = I_BDEV(filp->f_mapping->host);
-       ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ, 0);
+       ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ);
        if (ret) {
                reg->hr_bdev = NULL;
                goto out;
@@ -1358,7 +1358,7 @@ out:
                iput(inode);
        if (ret < 0) {
                if (reg->hr_bdev) {
-                       blkdev_put(reg->hr_bdev);
+                       blkdev_put(reg->hr_bdev, FMODE_READ|FMODE_WRITE);
                        reg->hr_bdev = NULL;
                }
        }
index 67527cebf21400fb7d86039dccbe566f2265b9b5..2f27b332d8b316949b131eb8172c1e1bdf4d1362 100644 (file)
@@ -68,14 +68,9 @@ static struct dentry *ocfs2_get_dentry(struct super_block *sb,
                return ERR_PTR(-ESTALE);
        }
 
-       result = d_alloc_anon(inode);
-
-       if (!result) {
-               iput(inode);
-               mlog_errno(-ENOMEM);
-               return ERR_PTR(-ENOMEM);
-       }
-       result->d_op = &ocfs2_dentry_ops;
+       result = d_obtain_alias(inode);
+       if (!IS_ERR(result))
+               result->d_op = &ocfs2_dentry_ops;
 
        mlog_exit_ptr(result);
        return result;
@@ -86,7 +81,6 @@ static struct dentry *ocfs2_get_parent(struct dentry *child)
        int status;
        u64 blkno;
        struct dentry *parent;
-       struct inode *inode;
        struct inode *dir = child->d_inode;
 
        mlog_entry("(0x%p, '%.*s')\n", child,
@@ -109,21 +103,9 @@ static struct dentry *ocfs2_get_parent(struct dentry *child)
                goto bail_unlock;
        }
 
-       inode = ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0, 0);
-       if (IS_ERR(inode)) {
-               mlog(ML_ERROR, "Unable to create inode %llu\n",
-                    (unsigned long long)blkno);
-               parent = ERR_PTR(-EACCES);
-               goto bail_unlock;
-       }
-
-       parent = d_alloc_anon(inode);
-       if (!parent) {
-               iput(inode);
-               parent = ERR_PTR(-ENOMEM);
-       }
-
-       parent->d_op = &ocfs2_dentry_ops;
+       parent = d_obtain_alias(ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0, 0));
+       if (!IS_ERR(parent))
+               parent->d_op = &ocfs2_dentry_ops;
 
 bail_unlock:
        ocfs2_inode_unlock(dir, 0);
index c0757e9988762eecae25683905188138e05832bb..c7275cfbdcfb92d4ca1a17a0444546c52d7b38c1 100644 (file)
@@ -501,4 +501,5 @@ struct inode_operations omfs_dir_inops = {
 struct file_operations omfs_dir_operations = {
        .read = generic_read_dir,
        .readdir = omfs_readdir,
+       .llseek = generic_file_llseek,
 };
index 5596049863bf742eadb115bafe0deef35b209421..83cdb9dee0c10ba29d3e2c793b2f4fffbc6522d9 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -798,7 +798,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
        int error;
 
        f->f_flags = flags;
-       f->f_mode = ((flags+1) & O_ACCMODE) | FMODE_LSEEK |
+       f->f_mode = (__force fmode_t)((flags+1) & O_ACCMODE) | FMODE_LSEEK |
                                FMODE_PREAD | FMODE_PWRITE;
        inode = dentry->d_inode;
        if (f->f_mode & FMODE_WRITE) {
index 9f5b054f06b932f873327a9c82e5674da54707cf..d41bdc784de4e920c2966fe0d18d27228df95aed 100644 (file)
@@ -167,6 +167,7 @@ static int openpromfs_readdir(struct file *, void *, filldir_t);
 static const struct file_operations openprom_operations = {
        .read           = generic_read_dir,
        .readdir        = openpromfs_readdir,
+       .llseek         = generic_file_llseek,
 };
 
 static struct dentry *openpromfs_lookup(struct inode *, struct dentry *, struct nameidata *);
index cfb0c80690aaa4d9ba0da46a02a30d036c233fdf..633f7a0ebb2cdfb28207cbb9ec14128ede23f59b 100644 (file)
@@ -485,10 +485,10 @@ void register_disk(struct gendisk *disk)
                goto exit;
 
        bdev->bd_invalidated = 1;
-       err = blkdev_get(bdev, FMODE_READ, 0);
+       err = blkdev_get(bdev, FMODE_READ);
        if (err < 0)
                goto exit;
-       blkdev_put(bdev);
+       blkdev_put(bdev, FMODE_READ);
 
 exit:
        /* announce disk after possible partitions are created */
index ebaba0213546a9cabc11539bb5cf047124e3a32e..63d965193b228726cc15957c54edc333d4ff0676 100644 (file)
@@ -8,11 +8,20 @@ proc-y                        := nommu.o task_nommu.o
 proc-$(CONFIG_MMU)     := mmu.o task_mmu.o
 
 proc-y       += inode.o root.o base.o generic.o array.o \
-               proc_tty.o proc_misc.o
-
+               proc_tty.o
+proc-y += cmdline.o
+proc-y += cpuinfo.o
+proc-y += devices.o
+proc-y += interrupts.o
+proc-y += loadavg.o
+proc-y += meminfo.o
+proc-y += stat.o
+proc-y += uptime.o
+proc-y += version.o
 proc-$(CONFIG_PROC_SYSCTL)     += proc_sysctl.o
 proc-$(CONFIG_NET)             += proc_net.o
 proc-$(CONFIG_PROC_KCORE)      += kcore.o
 proc-$(CONFIG_PROC_VMCORE)     += vmcore.o
 proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o
 proc-$(CONFIG_PRINTK)  += kmsg.o
+proc-$(CONFIG_PROC_PAGE_MONITOR)       += page.o
index f4bc0e789539f413e080324ab8209575ba349c42..bb9f4b05703de9b587a1b2cbd36ab651d2613da8 100644 (file)
@@ -388,20 +388,20 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
 
                /* add up live thread stats at the group level */
                if (whole) {
+                       struct task_cputime cputime;
                        struct task_struct *t = task;
                        do {
                                min_flt += t->min_flt;
                                maj_flt += t->maj_flt;
-                               utime = cputime_add(utime, task_utime(t));
-                               stime = cputime_add(stime, task_stime(t));
                                gtime = cputime_add(gtime, task_gtime(t));
                                t = next_thread(t);
                        } while (t != task);
 
                        min_flt += sig->min_flt;
                        maj_flt += sig->maj_flt;
-                       utime = cputime_add(utime, sig->utime);
-                       stime = cputime_add(stime, sig->stime);
+                       thread_group_cputime(task, &cputime);
+                       utime = cputime.utime;
+                       stime = cputime.stime;
                        gtime = cputime_add(gtime, sig->gtime);
                }
 
index b5918ae8ca79a7823bd6a4d3eb0ecfc0b08d30f6..486cf3fe7139949a0911e0e33f9cb99a06bfb8fb 100644 (file)
@@ -1712,9 +1712,9 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,
        file = fcheck_files(files, fd);
        if (!file)
                goto out_unlock;
-       if (file->f_mode & 1)
+       if (file->f_mode & FMODE_READ)
                inode->i_mode |= S_IRUSR | S_IXUSR;
-       if (file->f_mode & 2)
+       if (file->f_mode & FMODE_WRITE)
                inode->i_mode |= S_IWUSR | S_IXUSR;
        spin_unlock(&files->file_lock);
        put_files_struct(files);
diff --git a/fs/proc/cmdline.c b/fs/proc/cmdline.c
new file mode 100644 (file)
index 0000000..82676e3
--- /dev/null
@@ -0,0 +1,29 @@
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+static int cmdline_proc_show(struct seq_file *m, void *v)
+{
+       seq_printf(m, "%s\n", saved_command_line);
+       return 0;
+}
+
+static int cmdline_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, cmdline_proc_show, NULL);
+}
+
+static const struct file_operations cmdline_proc_fops = {
+       .open           = cmdline_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int __init proc_cmdline_init(void)
+{
+       proc_create("cmdline", 0, NULL, &cmdline_proc_fops);
+       return 0;
+}
+module_init(proc_cmdline_init);
diff --git a/fs/proc/cpuinfo.c b/fs/proc/cpuinfo.c
new file mode 100644 (file)
index 0000000..5a1e539
--- /dev/null
@@ -0,0 +1,24 @@
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+extern const struct seq_operations cpuinfo_op;
+static int cpuinfo_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &cpuinfo_op);
+}
+
+static const struct file_operations proc_cpuinfo_operations = {
+       .open           = cpuinfo_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+static int __init proc_cpuinfo_init(void)
+{
+       proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations);
+       return 0;
+}
+module_init(proc_cpuinfo_init);
diff --git a/fs/proc/devices.c b/fs/proc/devices.c
new file mode 100644 (file)
index 0000000..59ee7da
--- /dev/null
@@ -0,0 +1,70 @@
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+static int devinfo_show(struct seq_file *f, void *v)
+{
+       int i = *(loff_t *) v;
+
+       if (i < CHRDEV_MAJOR_HASH_SIZE) {
+               if (i == 0)
+                       seq_printf(f, "Character devices:\n");
+               chrdev_show(f, i);
+       }
+#ifdef CONFIG_BLOCK
+       else {
+               i -= CHRDEV_MAJOR_HASH_SIZE;
+               if (i == 0)
+                       seq_printf(f, "\nBlock devices:\n");
+               blkdev_show(f, i);
+       }
+#endif
+       return 0;
+}
+
+static void *devinfo_start(struct seq_file *f, loff_t *pos)
+{
+       if (*pos < (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
+               return pos;
+       return NULL;
+}
+
+static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
+{
+       (*pos)++;
+       if (*pos >= (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
+               return NULL;
+       return pos;
+}
+
+static void devinfo_stop(struct seq_file *f, void *v)
+{
+       /* Nothing to do */
+}
+
+static const struct seq_operations devinfo_ops = {
+       .start = devinfo_start,
+       .next  = devinfo_next,
+       .stop  = devinfo_stop,
+       .show  = devinfo_show
+};
+
+static int devinfo_open(struct inode *inode, struct file *filp)
+{
+       return seq_open(filp, &devinfo_ops);
+}
+
+static const struct file_operations proc_devinfo_operations = {
+       .open           = devinfo_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+static int __init proc_devices_init(void)
+{
+       proc_create("devices", 0, NULL, &proc_devinfo_operations);
+       return 0;
+}
+module_init(proc_devices_init);
index 7821589a17d58748f9143108be13bbcd1de9dc97..60a359b355821a032c36d22beb4740fdc763075e 100644 (file)
@@ -547,9 +547,8 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp
 
        for (tmp = dir->subdir; tmp; tmp = tmp->next)
                if (strcmp(tmp->name, dp->name) == 0) {
-                       printk(KERN_WARNING "proc_dir_entry '%s/%s' already registered\n",
+                       WARN(1, KERN_WARNING "proc_dir_entry '%s/%s' already registered\n",
                                dir->name, dp->name);
-                       dump_stack();
                        break;
                }
 
index c6b4fa7e3b49e9a2625bf3a76465c85d7df7eba2..2543fd00c6589cc8218169f16b0214de9c063f81 100644 (file)
@@ -106,14 +106,13 @@ static void init_once(void *foo)
        inode_init_once(&ei->vfs_inode);
 }
 
-int __init proc_init_inodecache(void)
+void __init proc_init_inodecache(void)
 {
        proc_inode_cachep = kmem_cache_create("proc_inode_cache",
                                             sizeof(struct proc_inode),
                                             0, (SLAB_RECLAIM_ACCOUNT|
                                                SLAB_MEM_SPREAD|SLAB_PANIC),
                                             init_once);
-       return 0;
 }
 
 static const struct super_operations proc_sops = {
index 3bfb7b8747b3f027657a217a18ff0a7bc37b6f5d..3e8aeb8b61ce251601f8795d3f6bd4fd423beed0 100644 (file)
@@ -61,12 +61,11 @@ extern const struct file_operations proc_smaps_operations;
 extern const struct file_operations proc_clear_refs_operations;
 extern const struct file_operations proc_pagemap_operations;
 extern const struct file_operations proc_net_operations;
-extern const struct file_operations proc_kmsg_operations;
 extern const struct inode_operations proc_net_inode_operations;
 
 void free_proc_entry(struct proc_dir_entry *de);
 
-int proc_init_inodecache(void);
+void proc_init_inodecache(void);
 
 static inline struct pid *proc_pid(struct inode *inode)
 {
diff --git a/fs/proc/interrupts.c b/fs/proc/interrupts.c
new file mode 100644 (file)
index 0000000..05029c0
--- /dev/null
@@ -0,0 +1,53 @@
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irqnr.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+/*
+ * /proc/interrupts
+ */
+static void *int_seq_start(struct seq_file *f, loff_t *pos)
+{
+       return (*pos <= nr_irqs) ? pos : NULL;
+}
+
+static void *int_seq_next(struct seq_file *f, void *v, loff_t *pos)
+{
+       (*pos)++;
+       if (*pos > nr_irqs)
+               return NULL;
+       return pos;
+}
+
+static void int_seq_stop(struct seq_file *f, void *v)
+{
+       /* Nothing to do */
+}
+
+static const struct seq_operations int_seq_ops = {
+       .start = int_seq_start,
+       .next  = int_seq_next,
+       .stop  = int_seq_stop,
+       .show  = show_interrupts
+};
+
+static int interrupts_open(struct inode *inode, struct file *filp)
+{
+       return seq_open(filp, &int_seq_ops);
+}
+
+static const struct file_operations proc_interrupts_operations = {
+       .open           = interrupts_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+static int __init proc_interrupts_init(void)
+{
+       proc_create("interrupts", 0, NULL, &proc_interrupts_operations);
+       return 0;
+}
+module_init(proc_interrupts_init);
index c2370c76fb711d6c7c32fba6ec34ffac437d7b65..59b43a068872de286df70b7632ae982f4ce149ab 100644 (file)
@@ -27,6 +27,8 @@
 #define ELF_CORE_EFLAGS        0
 #endif
 
+static struct proc_dir_entry *proc_root_kcore;
+
 static int open_kcore(struct inode * inode, struct file * filp)
 {
        return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
@@ -34,7 +36,7 @@ static int open_kcore(struct inode * inode, struct file * filp)
 
 static ssize_t read_kcore(struct file *, char __user *, size_t, loff_t *);
 
-const struct file_operations proc_kcore_operations = {
+static const struct file_operations proc_kcore_operations = {
        .read           = read_kcore,
        .open           = open_kcore,
 };
@@ -399,3 +401,13 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
 
        return acc;
 }
+
+static int __init proc_kcore_init(void)
+{
+       proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &proc_kcore_operations);
+       if (proc_root_kcore)
+               proc_root_kcore->size =
+                               (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
+       return 0;
+}
+module_init(proc_kcore_init);
index 9fd5df3f40ce7d0dcc4f78559fdd5eb2c521da4f..7ca78346d3f0f9ceed2014a42c2c03b774f1393f 100644 (file)
 #include <linux/time.h>
 #include <linux/kernel.h>
 #include <linux/poll.h>
+#include <linux/proc_fs.h>
 #include <linux/fs.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
-#include "internal.h"
-
 extern wait_queue_head_t log_wait;
 
 extern int do_syslog(int type, char __user *bug, int count);
@@ -49,9 +48,16 @@ static unsigned int kmsg_poll(struct file *file, poll_table *wait)
 }
 
 
-const struct file_operations proc_kmsg_operations = {
+static const struct file_operations proc_kmsg_operations = {
        .read           = kmsg_read,
        .poll           = kmsg_poll,
        .open           = kmsg_open,
        .release        = kmsg_release,
 };
+
+static int __init proc_kmsg_init(void)
+{
+       proc_create("kmsg", S_IRUSR, NULL, &proc_kmsg_operations);
+       return 0;
+}
+module_init(proc_kmsg_init);
diff --git a/fs/proc/loadavg.c b/fs/proc/loadavg.c
new file mode 100644 (file)
index 0000000..9bca39c
--- /dev/null
@@ -0,0 +1,51 @@
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/pid_namespace.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/seqlock.h>
+#include <linux/time.h>
+
+#define LOAD_INT(x) ((x) >> FSHIFT)
+#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
+
+static int loadavg_proc_show(struct seq_file *m, void *v)
+{
+       int a, b, c;
+       unsigned long seq;
+
+       do {
+               seq = read_seqbegin(&xtime_lock);
+               a = avenrun[0] + (FIXED_1/200);
+               b = avenrun[1] + (FIXED_1/200);
+               c = avenrun[2] + (FIXED_1/200);
+       } while (read_seqretry(&xtime_lock, seq));
+
+       seq_printf(m, "%d.%02d %d.%02d %d.%02d %ld/%d %d\n",
+               LOAD_INT(a), LOAD_FRAC(a),
+               LOAD_INT(b), LOAD_FRAC(b),
+               LOAD_INT(c), LOAD_FRAC(c),
+               nr_running(), nr_threads,
+               task_active_pid_ns(current)->last_pid);
+       return 0;
+}
+
+static int loadavg_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, loadavg_proc_show, NULL);
+}
+
+static const struct file_operations loadavg_proc_fops = {
+       .open           = loadavg_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int __init proc_loadavg_init(void)
+{
+       proc_create("loadavg", 0, NULL, &loadavg_proc_fops);
+       return 0;
+}
+module_init(proc_loadavg_init);
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c
new file mode 100644 (file)
index 0000000..b1675c4
--- /dev/null
@@ -0,0 +1,168 @@
+#include <linux/fs.h>
+#include <linux/hugetlb.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/mmzone.h>
+#include <linux/proc_fs.h>
+#include <linux/quicklist.h>
+#include <linux/seq_file.h>
+#include <linux/swap.h>
+#include <linux/vmstat.h>
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include "internal.h"
+
+void __attribute__((weak)) arch_report_meminfo(struct seq_file *m)
+{
+}
+
+static int meminfo_proc_show(struct seq_file *m, void *v)
+{
+       struct sysinfo i;
+       unsigned long committed;
+       unsigned long allowed;
+       struct vmalloc_info vmi;
+       long cached;
+       unsigned long pages[NR_LRU_LISTS];
+       int lru;
+
+/*
+ * display in kilobytes.
+ */
+#define K(x) ((x) << (PAGE_SHIFT - 10))
+       si_meminfo(&i);
+       si_swapinfo(&i);
+       committed = atomic_long_read(&vm_committed_space);
+       allowed = ((totalram_pages - hugetlb_total_pages())
+               * sysctl_overcommit_ratio / 100) + total_swap_pages;
+
+       cached = global_page_state(NR_FILE_PAGES) -
+                       total_swapcache_pages - i.bufferram;
+       if (cached < 0)
+               cached = 0;
+
+       get_vmalloc_info(&vmi);
+
+       for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++)
+               pages[lru] = global_page_state(NR_LRU_BASE + lru);
+
+       /*
+        * Tagged format, for easy grepping and expansion.
+        */
+       seq_printf(m,
+               "MemTotal:       %8lu kB\n"
+               "MemFree:        %8lu kB\n"
+               "Buffers:        %8lu kB\n"
+               "Cached:         %8lu kB\n"
+               "SwapCached:     %8lu kB\n"
+               "Active:         %8lu kB\n"
+               "Inactive:       %8lu kB\n"
+               "Active(anon):   %8lu kB\n"
+               "Inactive(anon): %8lu kB\n"
+               "Active(file):   %8lu kB\n"
+               "Inactive(file): %8lu kB\n"
+#ifdef CONFIG_UNEVICTABLE_LRU
+               "Unevictable:    %8lu kB\n"
+               "Mlocked:        %8lu kB\n"
+#endif
+#ifdef CONFIG_HIGHMEM
+               "HighTotal:      %8lu kB\n"
+               "HighFree:       %8lu kB\n"
+               "LowTotal:       %8lu kB\n"
+               "LowFree:        %8lu kB\n"
+#endif
+               "SwapTotal:      %8lu kB\n"
+               "SwapFree:       %8lu kB\n"
+               "Dirty:          %8lu kB\n"
+               "Writeback:      %8lu kB\n"
+               "AnonPages:      %8lu kB\n"
+               "Mapped:         %8lu kB\n"
+               "Slab:           %8lu kB\n"
+               "SReclaimable:   %8lu kB\n"
+               "SUnreclaim:     %8lu kB\n"
+               "PageTables:     %8lu kB\n"
+#ifdef CONFIG_QUICKLIST
+               "Quicklists:     %8lu kB\n"
+#endif
+               "NFS_Unstable:   %8lu kB\n"
+               "Bounce:         %8lu kB\n"
+               "WritebackTmp:   %8lu kB\n"
+               "CommitLimit:    %8lu kB\n"
+               "Committed_AS:   %8lu kB\n"
+               "VmallocTotal:   %8lu kB\n"
+               "VmallocUsed:    %8lu kB\n"
+               "VmallocChunk:   %8lu kB\n",
+               K(i.totalram),
+               K(i.freeram),
+               K(i.bufferram),
+               K(cached),
+               K(total_swapcache_pages),
+               K(pages[LRU_ACTIVE_ANON]   + pages[LRU_ACTIVE_FILE]),
+               K(pages[LRU_INACTIVE_ANON] + pages[LRU_INACTIVE_FILE]),
+               K(pages[LRU_ACTIVE_ANON]),
+               K(pages[LRU_INACTIVE_ANON]),
+               K(pages[LRU_ACTIVE_FILE]),
+               K(pages[LRU_INACTIVE_FILE]),
+#ifdef CONFIG_UNEVICTABLE_LRU
+               K(pages[LRU_UNEVICTABLE]),
+               K(global_page_state(NR_MLOCK)),
+#endif
+#ifdef CONFIG_HIGHMEM
+               K(i.totalhigh),
+               K(i.freehigh),
+               K(i.totalram-i.totalhigh),
+               K(i.freeram-i.freehigh),
+#endif
+               K(i.totalswap),
+               K(i.freeswap),
+               K(global_page_state(NR_FILE_DIRTY)),
+               K(global_page_state(NR_WRITEBACK)),
+               K(global_page_state(NR_ANON_PAGES)),
+               K(global_page_state(NR_FILE_MAPPED)),
+               K(global_page_state(NR_SLAB_RECLAIMABLE) +
+                               global_page_state(NR_SLAB_UNRECLAIMABLE)),
+               K(global_page_state(NR_SLAB_RECLAIMABLE)),
+               K(global_page_state(NR_SLAB_UNRECLAIMABLE)),
+               K(global_page_state(NR_PAGETABLE)),
+#ifdef CONFIG_QUICKLIST
+               K(quicklist_total_size()),
+#endif
+               K(global_page_state(NR_UNSTABLE_NFS)),
+               K(global_page_state(NR_BOUNCE)),
+               K(global_page_state(NR_WRITEBACK_TEMP)),
+               K(allowed),
+               K(committed),
+               (unsigned long)VMALLOC_TOTAL >> 10,
+               vmi.used >> 10,
+               vmi.largest_chunk >> 10
+               );
+
+       hugetlb_report_meminfo(m);
+
+       arch_report_meminfo(m);
+
+       return 0;
+#undef K
+}
+
+static int meminfo_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, meminfo_proc_show, NULL);
+}
+
+static const struct file_operations meminfo_proc_fops = {
+       .open           = meminfo_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int __init proc_meminfo_init(void)
+{
+       proc_create("meminfo", 0, NULL, &meminfo_proc_fops);
+       return 0;
+}
+module_init(proc_meminfo_init);
diff --git a/fs/proc/page.c b/fs/proc/page.c
new file mode 100644 (file)
index 0000000..767d95a
--- /dev/null
@@ -0,0 +1,147 @@
+#include <linux/bootmem.h>
+#include <linux/compiler.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/mmzone.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <asm/uaccess.h>
+#include "internal.h"
+
+#define KPMSIZE sizeof(u64)
+#define KPMMASK (KPMSIZE - 1)
+/* /proc/kpagecount - an array exposing page counts
+ *
+ * Each entry is a u64 representing the corresponding
+ * physical page count.
+ */
+static ssize_t kpagecount_read(struct file *file, char __user *buf,
+                            size_t count, loff_t *ppos)
+{
+       u64 __user *out = (u64 __user *)buf;
+       struct page *ppage;
+       unsigned long src = *ppos;
+       unsigned long pfn;
+       ssize_t ret = 0;
+       u64 pcount;
+
+       pfn = src / KPMSIZE;
+       count = min_t(size_t, count, (max_pfn * KPMSIZE) - src);
+       if (src & KPMMASK || count & KPMMASK)
+               return -EINVAL;
+
+       while (count > 0) {
+               ppage = NULL;
+               if (pfn_valid(pfn))
+                       ppage = pfn_to_page(pfn);
+               pfn++;
+               if (!ppage)
+                       pcount = 0;
+               else
+                       pcount = page_mapcount(ppage);
+
+               if (put_user(pcount, out++)) {
+                       ret = -EFAULT;
+                       break;
+               }
+
+               count -= KPMSIZE;
+       }
+
+       *ppos += (char __user *)out - buf;
+       if (!ret)
+               ret = (char __user *)out - buf;
+       return ret;
+}
+
+static const struct file_operations proc_kpagecount_operations = {
+       .llseek = mem_lseek,
+       .read = kpagecount_read,
+};
+
+/* /proc/kpageflags - an array exposing page flags
+ *
+ * Each entry is a u64 representing the corresponding
+ * physical page flags.
+ */
+
+/* These macros are used to decouple internal flags from exported ones */
+
+#define KPF_LOCKED     0
+#define KPF_ERROR      1
+#define KPF_REFERENCED 2
+#define KPF_UPTODATE   3
+#define KPF_DIRTY      4
+#define KPF_LRU        5
+#define KPF_ACTIVE     6
+#define KPF_SLAB       7
+#define KPF_WRITEBACK  8
+#define KPF_RECLAIM    9
+#define KPF_BUDDY     10
+
+#define kpf_copy_bit(flags, srcpos, dstpos) (((flags >> srcpos) & 1) << dstpos)
+
+static ssize_t kpageflags_read(struct file *file, char __user *buf,
+                            size_t count, loff_t *ppos)
+{
+       u64 __user *out = (u64 __user *)buf;
+       struct page *ppage;
+       unsigned long src = *ppos;
+       unsigned long pfn;
+       ssize_t ret = 0;
+       u64 kflags, uflags;
+
+       pfn = src / KPMSIZE;
+       count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src);
+       if (src & KPMMASK || count & KPMMASK)
+               return -EINVAL;
+
+       while (count > 0) {
+               ppage = NULL;
+               if (pfn_valid(pfn))
+                       ppage = pfn_to_page(pfn);
+               pfn++;
+               if (!ppage)
+                       kflags = 0;
+               else
+                       kflags = ppage->flags;
+
+               uflags = kpf_copy_bit(KPF_LOCKED, PG_locked, kflags) |
+                       kpf_copy_bit(kflags, KPF_ERROR, PG_error) |
+                       kpf_copy_bit(kflags, KPF_REFERENCED, PG_referenced) |
+                       kpf_copy_bit(kflags, KPF_UPTODATE, PG_uptodate) |
+                       kpf_copy_bit(kflags, KPF_DIRTY, PG_dirty) |
+                       kpf_copy_bit(kflags, KPF_LRU, PG_lru) |
+                       kpf_copy_bit(kflags, KPF_ACTIVE, PG_active) |
+                       kpf_copy_bit(kflags, KPF_SLAB, PG_slab) |
+                       kpf_copy_bit(kflags, KPF_WRITEBACK, PG_writeback) |
+                       kpf_copy_bit(kflags, KPF_RECLAIM, PG_reclaim) |
+                       kpf_copy_bit(kflags, KPF_BUDDY, PG_buddy);
+
+               if (put_user(uflags, out++)) {
+                       ret = -EFAULT;
+                       break;
+               }
+
+               count -= KPMSIZE;
+       }
+
+       *ppos += (char __user *)out - buf;
+       if (!ret)
+               ret = (char __user *)out - buf;
+       return ret;
+}
+
+static const struct file_operations proc_kpageflags_operations = {
+       .llseek = mem_lseek,
+       .read = kpageflags_read,
+};
+
+static int __init proc_page_init(void)
+{
+       proc_create("kpagecount", S_IRUSR, NULL, &proc_kpagecount_operations);
+       proc_create("kpageflags", S_IRUSR, NULL, &proc_kpageflags_operations);
+       return 0;
+}
+module_init(proc_page_init);
index eca471bc85125626d32c011a820fd828f3124837..d777789b7a89e8f177a3ca5163590626bbe29983 100644 (file)
@@ -4,6 +4,7 @@
  * Copyright 1997 Paul Mackerras
  */
 #include <linux/errno.h>
+#include <linux/init.h>
 #include <linux/time.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
@@ -214,7 +215,7 @@ void proc_device_tree_add_node(struct device_node *np,
 /*
  * Called on initialization to set up the /proc/device-tree subtree
  */
-void proc_device_tree_init(void)
+void __init proc_device_tree_init(void)
 {
        struct device_node *root;
        if ( !have_of )
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
deleted file mode 100644 (file)
index 61b25f4..0000000
+++ /dev/null
@@ -1,935 +0,0 @@
-/*
- *  linux/fs/proc/proc_misc.c
- *
- *  linux/fs/proc/array.c
- *  Copyright (C) 1992  by Linus Torvalds
- *  based on ideas by Darren Senn
- *
- *  This used to be the part of array.c. See the rest of history and credits
- *  there. I took this into a separate file and switched the thing to generic
- *  proc_file_inode_operations, leaving in array.c only per-process stuff.
- *  Inumbers allocation made dynamic (via create_proc_entry()).  AV, May 1999.
- *
- * Changes:
- * Fulton Green      :  Encapsulated position metric calculations.
- *                     <kernel@FultonGreen.com>
- */
-
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/time.h>
-#include <linux/kernel.h>
-#include <linux/kernel_stat.h>
-#include <linux/fs.h>
-#include <linux/tty.h>
-#include <linux/string.h>
-#include <linux/mman.h>
-#include <linux/quicklist.h>
-#include <linux/proc_fs.h>
-#include <linux/ioport.h>
-#include <linux/mm.h>
-#include <linux/mmzone.h>
-#include <linux/pagemap.h>
-#include <linux/interrupt.h>
-#include <linux/swap.h>
-#include <linux/slab.h>
-#include <linux/genhd.h>
-#include <linux/smp.h>
-#include <linux/signal.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/seq_file.h>
-#include <linux/times.h>
-#include <linux/profile.h>
-#include <linux/utsname.h>
-#include <linux/blkdev.h>
-#include <linux/hugetlb.h>
-#include <linux/jiffies.h>
-#include <linux/vmalloc.h>
-#include <linux/crash_dump.h>
-#include <linux/pid_namespace.h>
-#include <linux/bootmem.h>
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/io.h>
-#include <asm/tlb.h>
-#include <asm/div64.h>
-#include "internal.h"
-
-#define LOAD_INT(x) ((x) >> FSHIFT)
-#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
-/*
- * Warning: stuff below (imported functions) assumes that its output will fit
- * into one page. For some of those functions it may be wrong. Moreover, we
- * have a way to deal with that gracefully. Right now I used straightforward
- * wrappers, but this needs further analysis wrt potential overflows.
- */
-extern int get_hardware_list(char *);
-extern int get_stram_list(char *);
-extern int get_exec_domain_list(char *);
-
-static int proc_calc_metrics(char *page, char **start, off_t off,
-                                int count, int *eof, int len)
-{
-       if (len <= off+count) *eof = 1;
-       *start = page + off;
-       len -= off;
-       if (len>count) len = count;
-       if (len<0) len = 0;
-       return len;
-}
-
-static int loadavg_read_proc(char *page, char **start, off_t off,
-                                int count, int *eof, void *data)
-{
-       int a, b, c;
-       int len;
-       unsigned long seq;
-
-       do {
-               seq = read_seqbegin(&xtime_lock);
-               a = avenrun[0] + (FIXED_1/200);
-               b = avenrun[1] + (FIXED_1/200);
-               c = avenrun[2] + (FIXED_1/200);
-       } while (read_seqretry(&xtime_lock, seq));
-
-       len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n",
-               LOAD_INT(a), LOAD_FRAC(a),
-               LOAD_INT(b), LOAD_FRAC(b),
-               LOAD_INT(c), LOAD_FRAC(c),
-               nr_running(), nr_threads,
-               task_active_pid_ns(current)->last_pid);
-       return proc_calc_metrics(page, start, off, count, eof, len);
-}
-
-static int uptime_read_proc(char *page, char **start, off_t off,
-                                int count, int *eof, void *data)
-{
-       struct timespec uptime;
-       struct timespec idle;
-       int len;
-       cputime_t idletime = cputime_add(init_task.utime, init_task.stime);
-
-       do_posix_clock_monotonic_gettime(&uptime);
-       monotonic_to_bootbased(&uptime);
-       cputime_to_timespec(idletime, &idle);
-       len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
-                       (unsigned long) uptime.tv_sec,
-                       (uptime.tv_nsec / (NSEC_PER_SEC / 100)),
-                       (unsigned long) idle.tv_sec,
-                       (idle.tv_nsec / (NSEC_PER_SEC / 100)));
-
-       return proc_calc_metrics(page, start, off, count, eof, len);
-}
-
-int __attribute__((weak)) arch_report_meminfo(char *page)
-{
-       return 0;
-}
-
-static int meminfo_read_proc(char *page, char **start, off_t off,
-                                int count, int *eof, void *data)
-{
-       struct sysinfo i;
-       int len;
-       unsigned long committed;
-       unsigned long allowed;
-       struct vmalloc_info vmi;
-       long cached;
-       unsigned long pages[NR_LRU_LISTS];
-       int lru;
-
-/*
- * display in kilobytes.
- */
-#define K(x) ((x) << (PAGE_SHIFT - 10))
-       si_meminfo(&i);
-       si_swapinfo(&i);
-       committed = atomic_long_read(&vm_committed_space);
-       allowed = ((totalram_pages - hugetlb_total_pages())
-               * sysctl_overcommit_ratio / 100) + total_swap_pages;
-
-       cached = global_page_state(NR_FILE_PAGES) -
-                       total_swapcache_pages - i.bufferram;
-       if (cached < 0)
-               cached = 0;
-
-       get_vmalloc_info(&vmi);
-
-       for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++)
-               pages[lru] = global_page_state(NR_LRU_BASE + lru);
-
-       /*
-        * Tagged format, for easy grepping and expansion.
-        */
-       len = sprintf(page,
-               "MemTotal:       %8lu kB\n"
-               "MemFree:        %8lu kB\n"
-               "Buffers:        %8lu kB\n"
-               "Cached:         %8lu kB\n"
-               "SwapCached:     %8lu kB\n"
-               "Active:         %8lu kB\n"
-               "Inactive:       %8lu kB\n"
-               "Active(anon):   %8lu kB\n"
-               "Inactive(anon): %8lu kB\n"
-               "Active(file):   %8lu kB\n"
-               "Inactive(file): %8lu kB\n"
-#ifdef CONFIG_UNEVICTABLE_LRU
-               "Unevictable:    %8lu kB\n"
-               "Mlocked:        %8lu kB\n"
-#endif
-#ifdef CONFIG_HIGHMEM
-               "HighTotal:      %8lu kB\n"
-               "HighFree:       %8lu kB\n"
-               "LowTotal:       %8lu kB\n"
-               "LowFree:        %8lu kB\n"
-#endif
-               "SwapTotal:      %8lu kB\n"
-               "SwapFree:       %8lu kB\n"
-               "Dirty:          %8lu kB\n"
-               "Writeback:      %8lu kB\n"
-               "AnonPages:      %8lu kB\n"
-               "Mapped:         %8lu kB\n"
-               "Slab:           %8lu kB\n"
-               "SReclaimable:   %8lu kB\n"
-               "SUnreclaim:     %8lu kB\n"
-               "PageTables:     %8lu kB\n"
-#ifdef CONFIG_QUICKLIST
-               "Quicklists:     %8lu kB\n"
-#endif
-               "NFS_Unstable:   %8lu kB\n"
-               "Bounce:         %8lu kB\n"
-               "WritebackTmp:   %8lu kB\n"
-               "CommitLimit:    %8lu kB\n"
-               "Committed_AS:   %8lu kB\n"
-               "VmallocTotal:   %8lu kB\n"
-               "VmallocUsed:    %8lu kB\n"
-               "VmallocChunk:   %8lu kB\n",
-               K(i.totalram),
-               K(i.freeram),
-               K(i.bufferram),
-               K(cached),
-               K(total_swapcache_pages),
-               K(pages[LRU_ACTIVE_ANON]   + pages[LRU_ACTIVE_FILE]),
-               K(pages[LRU_INACTIVE_ANON] + pages[LRU_INACTIVE_FILE]),
-               K(pages[LRU_ACTIVE_ANON]),
-               K(pages[LRU_INACTIVE_ANON]),
-               K(pages[LRU_ACTIVE_FILE]),
-               K(pages[LRU_INACTIVE_FILE]),
-#ifdef CONFIG_UNEVICTABLE_LRU
-               K(pages[LRU_UNEVICTABLE]),
-               K(global_page_state(NR_MLOCK)),
-#endif
-#ifdef CONFIG_HIGHMEM
-               K(i.totalhigh),
-               K(i.freehigh),
-               K(i.totalram-i.totalhigh),
-               K(i.freeram-i.freehigh),
-#endif
-               K(i.totalswap),
-               K(i.freeswap),
-               K(global_page_state(NR_FILE_DIRTY)),
-               K(global_page_state(NR_WRITEBACK)),
-               K(global_page_state(NR_ANON_PAGES)),
-               K(global_page_state(NR_FILE_MAPPED)),
-               K(global_page_state(NR_SLAB_RECLAIMABLE) +
-                               global_page_state(NR_SLAB_UNRECLAIMABLE)),
-               K(global_page_state(NR_SLAB_RECLAIMABLE)),
-               K(global_page_state(NR_SLAB_UNRECLAIMABLE)),
-               K(global_page_state(NR_PAGETABLE)),
-#ifdef CONFIG_QUICKLIST
-               K(quicklist_total_size()),
-#endif
-               K(global_page_state(NR_UNSTABLE_NFS)),
-               K(global_page_state(NR_BOUNCE)),
-               K(global_page_state(NR_WRITEBACK_TEMP)),
-               K(allowed),
-               K(committed),
-               (unsigned long)VMALLOC_TOTAL >> 10,
-               vmi.used >> 10,
-               vmi.largest_chunk >> 10
-               );
-
-               len += hugetlb_report_meminfo(page + len);
-
-       len += arch_report_meminfo(page + len);
-
-       return proc_calc_metrics(page, start, off, count, eof, len);
-#undef K
-}
-
-static int fragmentation_open(struct inode *inode, struct file *file)
-{
-       (void)inode;
-       return seq_open(file, &fragmentation_op);
-}
-
-static const struct file_operations fragmentation_file_operations = {
-       .open           = fragmentation_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
-};
-
-static int pagetypeinfo_open(struct inode *inode, struct file *file)
-{
-       return seq_open(file, &pagetypeinfo_op);
-}
-
-static const struct file_operations pagetypeinfo_file_ops = {
-       .open           = pagetypeinfo_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
-};
-
-static int zoneinfo_open(struct inode *inode, struct file *file)
-{
-       return seq_open(file, &zoneinfo_op);
-}
-
-static const struct file_operations proc_zoneinfo_file_operations = {
-       .open           = zoneinfo_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
-};
-
-static int version_read_proc(char *page, char **start, off_t off,
-                                int count, int *eof, void *data)
-{
-       int len;
-
-       len = snprintf(page, PAGE_SIZE, linux_proc_banner,
-               utsname()->sysname,
-               utsname()->release,
-               utsname()->version);
-       return proc_calc_metrics(page, start, off, count, eof, len);
-}
-
-extern const struct seq_operations cpuinfo_op;
-static int cpuinfo_open(struct inode *inode, struct file *file)
-{
-       return seq_open(file, &cpuinfo_op);
-}
-
-static const struct file_operations proc_cpuinfo_operations = {
-       .open           = cpuinfo_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
-};
-
-static int devinfo_show(struct seq_file *f, void *v)
-{
-       int i = *(loff_t *) v;
-
-       if (i < CHRDEV_MAJOR_HASH_SIZE) {
-               if (i == 0)
-                       seq_printf(f, "Character devices:\n");
-               chrdev_show(f, i);
-       }
-#ifdef CONFIG_BLOCK
-       else {
-               i -= CHRDEV_MAJOR_HASH_SIZE;
-               if (i == 0)
-                       seq_printf(f, "\nBlock devices:\n");
-               blkdev_show(f, i);
-       }
-#endif
-       return 0;
-}
-
-static void *devinfo_start(struct seq_file *f, loff_t *pos)
-{
-       if (*pos < (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
-               return pos;
-       return NULL;
-}
-
-static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
-{
-       (*pos)++;
-       if (*pos >= (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
-               return NULL;
-       return pos;
-}
-
-static void devinfo_stop(struct seq_file *f, void *v)
-{
-       /* Nothing to do */
-}
-
-static const struct seq_operations devinfo_ops = {
-       .start = devinfo_start,
-       .next  = devinfo_next,
-       .stop  = devinfo_stop,
-       .show  = devinfo_show
-};
-
-static int devinfo_open(struct inode *inode, struct file *filp)
-{
-       return seq_open(filp, &devinfo_ops);
-}
-
-static const struct file_operations proc_devinfo_operations = {
-       .open           = devinfo_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
-};
-
-static int vmstat_open(struct inode *inode, struct file *file)
-{
-       return seq_open(file, &vmstat_op);
-}
-static const struct file_operations proc_vmstat_file_operations = {
-       .open           = vmstat_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
-};
-
-#ifdef CONFIG_PROC_HARDWARE
-static int hardware_read_proc(char *page, char **start, off_t off,
-                                int count, int *eof, void *data)
-{
-       int len = get_hardware_list(page);
-       return proc_calc_metrics(page, start, off, count, eof, len);
-}
-#endif
-
-#ifdef CONFIG_STRAM_PROC
-static int stram_read_proc(char *page, char **start, off_t off,
-                                int count, int *eof, void *data)
-{
-       int len = get_stram_list(page);
-       return proc_calc_metrics(page, start, off, count, eof, len);
-}
-#endif
-
-#ifdef CONFIG_BLOCK
-static int partitions_open(struct inode *inode, struct file *file)
-{
-       return seq_open(file, &partitions_op);
-}
-static const struct file_operations proc_partitions_operations = {
-       .open           = partitions_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
-};
-
-static int diskstats_open(struct inode *inode, struct file *file)
-{
-       return seq_open(file, &diskstats_op);
-}
-static const struct file_operations proc_diskstats_operations = {
-       .open           = diskstats_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
-};
-#endif
-
-#ifdef CONFIG_MODULES
-extern const struct seq_operations modules_op;
-static int modules_open(struct inode *inode, struct file *file)
-{
-       return seq_open(file, &modules_op);
-}
-static const struct file_operations proc_modules_operations = {
-       .open           = modules_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
-};
-#endif
-
-#ifdef CONFIG_SLABINFO
-static int slabinfo_open(struct inode *inode, struct file *file)
-{
-       return seq_open(file, &slabinfo_op);
-}
-static const struct file_operations proc_slabinfo_operations = {
-       .open           = slabinfo_open,
-       .read           = seq_read,
-       .write          = slabinfo_write,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
-};
-
-#ifdef CONFIG_DEBUG_SLAB_LEAK
-extern const struct seq_operations slabstats_op;
-static int slabstats_open(struct inode *inode, struct file *file)
-{
-       unsigned long *n = kzalloc(PAGE_SIZE, GFP_KERNEL);
-       int ret = -ENOMEM;
-       if (n) {
-               ret = seq_open(file, &slabstats_op);
-               if (!ret) {
-                       struct seq_file *m = file->private_data;
-                       *n = PAGE_SIZE / (2 * sizeof(unsigned long));
-                       m->private = n;
-                       n = NULL;
-               }
-               kfree(n);
-       }
-       return ret;
-}
-
-static const struct file_operations proc_slabstats_operations = {
-       .open           = slabstats_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release_private,
-};
-#endif
-#endif
-
-#ifdef CONFIG_MMU
-static int vmalloc_open(struct inode *inode, struct file *file)
-{
-       unsigned int *ptr = NULL;
-       int ret;
-
-       if (NUMA_BUILD)
-               ptr = kmalloc(nr_node_ids * sizeof(unsigned int), GFP_KERNEL);
-       ret = seq_open(file, &vmalloc_op);
-       if (!ret) {
-               struct seq_file *m = file->private_data;
-               m->private = ptr;
-       } else
-               kfree(ptr);
-       return ret;
-}
-
-static const struct file_operations proc_vmalloc_operations = {
-       .open           = vmalloc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release_private,
-};
-#endif
-
-#ifndef arch_irq_stat_cpu
-#define arch_irq_stat_cpu(cpu) 0
-#endif
-#ifndef arch_irq_stat
-#define arch_irq_stat() 0
-#endif
-
-static int show_stat(struct seq_file *p, void *v)
-{
-       int i;
-       unsigned long jif;
-       cputime64_t user, nice, system, idle, iowait, irq, softirq, steal;
-       cputime64_t guest;
-       u64 sum = 0;
-       struct timespec boottime;
-       unsigned int *per_irq_sum;
-
-       per_irq_sum = kzalloc(sizeof(unsigned int)*NR_IRQS, GFP_KERNEL);
-       if (!per_irq_sum)
-               return -ENOMEM;
-
-       user = nice = system = idle = iowait =
-               irq = softirq = steal = cputime64_zero;
-       guest = cputime64_zero;
-       getboottime(&boottime);
-       jif = boottime.tv_sec;
-
-       for_each_possible_cpu(i) {
-               int j;
-
-               user = cputime64_add(user, kstat_cpu(i).cpustat.user);
-               nice = cputime64_add(nice, kstat_cpu(i).cpustat.nice);
-               system = cputime64_add(system, kstat_cpu(i).cpustat.system);
-               idle = cputime64_add(idle, kstat_cpu(i).cpustat.idle);
-               iowait = cputime64_add(iowait, kstat_cpu(i).cpustat.iowait);
-               irq = cputime64_add(irq, kstat_cpu(i).cpustat.irq);
-               softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq);
-               steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal);
-               guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest);
-               for (j = 0; j < NR_IRQS; j++) {
-                       unsigned int temp = kstat_cpu(i).irqs[j];
-                       sum += temp;
-                       per_irq_sum[j] += temp;
-               }
-               sum += arch_irq_stat_cpu(i);
-       }
-       sum += arch_irq_stat();
-
-       seq_printf(p, "cpu  %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
-               (unsigned long long)cputime64_to_clock_t(user),
-               (unsigned long long)cputime64_to_clock_t(nice),
-               (unsigned long long)cputime64_to_clock_t(system),
-               (unsigned long long)cputime64_to_clock_t(idle),
-               (unsigned long long)cputime64_to_clock_t(iowait),
-               (unsigned long long)cputime64_to_clock_t(irq),
-               (unsigned long long)cputime64_to_clock_t(softirq),
-               (unsigned long long)cputime64_to_clock_t(steal),
-               (unsigned long long)cputime64_to_clock_t(guest));
-       for_each_online_cpu(i) {
-
-               /* Copy values here to work around gcc-2.95.3, gcc-2.96 */
-               user = kstat_cpu(i).cpustat.user;
-               nice = kstat_cpu(i).cpustat.nice;
-               system = kstat_cpu(i).cpustat.system;
-               idle = kstat_cpu(i).cpustat.idle;
-               iowait = kstat_cpu(i).cpustat.iowait;
-               irq = kstat_cpu(i).cpustat.irq;
-               softirq = kstat_cpu(i).cpustat.softirq;
-               steal = kstat_cpu(i).cpustat.steal;
-               guest = kstat_cpu(i).cpustat.guest;
-               seq_printf(p,
-                       "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
-                       i,
-                       (unsigned long long)cputime64_to_clock_t(user),
-                       (unsigned long long)cputime64_to_clock_t(nice),
-                       (unsigned long long)cputime64_to_clock_t(system),
-                       (unsigned long long)cputime64_to_clock_t(idle),
-                       (unsigned long long)cputime64_to_clock_t(iowait),
-                       (unsigned long long)cputime64_to_clock_t(irq),
-                       (unsigned long long)cputime64_to_clock_t(softirq),
-                       (unsigned long long)cputime64_to_clock_t(steal),
-                       (unsigned long long)cputime64_to_clock_t(guest));
-       }
-       seq_printf(p, "intr %llu", (unsigned long long)sum);
-
-       for (i = 0; i < NR_IRQS; i++)
-               seq_printf(p, " %u", per_irq_sum[i]);
-
-       seq_printf(p,
-               "\nctxt %llu\n"
-               "btime %lu\n"
-               "processes %lu\n"
-               "procs_running %lu\n"
-               "procs_blocked %lu\n",
-               nr_context_switches(),
-               (unsigned long)jif,
-               total_forks,
-               nr_running(),
-               nr_iowait());
-
-       kfree(per_irq_sum);
-       return 0;
-}
-
-static int stat_open(struct inode *inode, struct file *file)
-{
-       unsigned size = 4096 * (1 + num_possible_cpus() / 32);
-       char *buf;
-       struct seq_file *m;
-       int res;
-
-       /* don't ask for more than the kmalloc() max size, currently 128 KB */
-       if (size > 128 * 1024)
-               size = 128 * 1024;
-       buf = kmalloc(size, GFP_KERNEL);
-       if (!buf)
-               return -ENOMEM;
-
-       res = single_open(file, show_stat, NULL);
-       if (!res) {
-               m = file->private_data;
-               m->buf = buf;
-               m->size = size;
-       } else
-               kfree(buf);
-       return res;
-}
-static const struct file_operations proc_stat_operations = {
-       .open           = stat_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-
-/*
- * /proc/interrupts
- */
-static void *int_seq_start(struct seq_file *f, loff_t *pos)
-{
-       return (*pos <= NR_IRQS) ? pos : NULL;
-}
-
-static void *int_seq_next(struct seq_file *f, void *v, loff_t *pos)
-{
-       (*pos)++;
-       if (*pos > NR_IRQS)
-               return NULL;
-       return pos;
-}
-
-static void int_seq_stop(struct seq_file *f, void *v)
-{
-       /* Nothing to do */
-}
-
-
-static const struct seq_operations int_seq_ops = {
-       .start = int_seq_start,
-       .next  = int_seq_next,
-       .stop  = int_seq_stop,
-       .show  = show_interrupts
-};
-
-static int interrupts_open(struct inode *inode, struct file *filp)
-{
-       return seq_open(filp, &int_seq_ops);
-}
-
-static const struct file_operations proc_interrupts_operations = {
-       .open           = interrupts_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
-};
-
-static int filesystems_read_proc(char *page, char **start, off_t off,
-                                int count, int *eof, void *data)
-{
-       int len = get_filesystem_list(page);
-       return proc_calc_metrics(page, start, off, count, eof, len);
-}
-
-static int cmdline_read_proc(char *page, char **start, off_t off,
-                                int count, int *eof, void *data)
-{
-       int len;
-
-       len = sprintf(page, "%s\n", saved_command_line);
-       return proc_calc_metrics(page, start, off, count, eof, len);
-}
-
-#ifdef CONFIG_FILE_LOCKING
-static int locks_open(struct inode *inode, struct file *filp)
-{
-       return seq_open(filp, &locks_seq_operations);
-}
-
-static const struct file_operations proc_locks_operations = {
-       .open           = locks_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
-};
-#endif /* CONFIG_FILE_LOCKING */
-
-static int execdomains_read_proc(char *page, char **start, off_t off,
-                                int count, int *eof, void *data)
-{
-       int len = get_exec_domain_list(page);
-       return proc_calc_metrics(page, start, off, count, eof, len);
-}
-
-#ifdef CONFIG_PROC_PAGE_MONITOR
-#define KPMSIZE sizeof(u64)
-#define KPMMASK (KPMSIZE - 1)
-/* /proc/kpagecount - an array exposing page counts
- *
- * Each entry is a u64 representing the corresponding
- * physical page count.
- */
-static ssize_t kpagecount_read(struct file *file, char __user *buf,
-                            size_t count, loff_t *ppos)
-{
-       u64 __user *out = (u64 __user *)buf;
-       struct page *ppage;
-       unsigned long src = *ppos;
-       unsigned long pfn;
-       ssize_t ret = 0;
-       u64 pcount;
-
-       pfn = src / KPMSIZE;
-       count = min_t(size_t, count, (max_pfn * KPMSIZE) - src);
-       if (src & KPMMASK || count & KPMMASK)
-               return -EINVAL;
-
-       while (count > 0) {
-               ppage = NULL;
-               if (pfn_valid(pfn))
-                       ppage = pfn_to_page(pfn);
-               pfn++;
-               if (!ppage)
-                       pcount = 0;
-               else
-                       pcount = page_mapcount(ppage);
-
-               if (put_user(pcount, out++)) {
-                       ret = -EFAULT;
-                       break;
-               }
-
-               count -= KPMSIZE;
-       }
-
-       *ppos += (char __user *)out - buf;
-       if (!ret)
-               ret = (char __user *)out - buf;
-       return ret;
-}
-
-static struct file_operations proc_kpagecount_operations = {
-       .llseek = mem_lseek,
-       .read = kpagecount_read,
-};
-
-/* /proc/kpageflags - an array exposing page flags
- *
- * Each entry is a u64 representing the corresponding
- * physical page flags.
- */
-
-/* These macros are used to decouple internal flags from exported ones */
-
-#define KPF_LOCKED     0
-#define KPF_ERROR      1
-#define KPF_REFERENCED 2
-#define KPF_UPTODATE   3
-#define KPF_DIRTY      4
-#define KPF_LRU        5
-#define KPF_ACTIVE     6
-#define KPF_SLAB       7
-#define KPF_WRITEBACK  8
-#define KPF_RECLAIM    9
-#define KPF_BUDDY     10
-
-#define kpf_copy_bit(flags, srcpos, dstpos) (((flags >> srcpos) & 1) << dstpos)
-
-static ssize_t kpageflags_read(struct file *file, char __user *buf,
-                            size_t count, loff_t *ppos)
-{
-       u64 __user *out = (u64 __user *)buf;
-       struct page *ppage;
-       unsigned long src = *ppos;
-       unsigned long pfn;
-       ssize_t ret = 0;
-       u64 kflags, uflags;
-
-       pfn = src / KPMSIZE;
-       count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src);
-       if (src & KPMMASK || count & KPMMASK)
-               return -EINVAL;
-
-       while (count > 0) {
-               ppage = NULL;
-               if (pfn_valid(pfn))
-                       ppage = pfn_to_page(pfn);
-               pfn++;
-               if (!ppage)
-                       kflags = 0;
-               else
-                       kflags = ppage->flags;
-
-               uflags = kpf_copy_bit(KPF_LOCKED, PG_locked, kflags) |
-                       kpf_copy_bit(kflags, KPF_ERROR, PG_error) |
-                       kpf_copy_bit(kflags, KPF_REFERENCED, PG_referenced) |
-                       kpf_copy_bit(kflags, KPF_UPTODATE, PG_uptodate) |
-                       kpf_copy_bit(kflags, KPF_DIRTY, PG_dirty) |
-                       kpf_copy_bit(kflags, KPF_LRU, PG_lru) |
-                       kpf_copy_bit(kflags, KPF_ACTIVE, PG_active) |
-                       kpf_copy_bit(kflags, KPF_SLAB, PG_slab) |
-                       kpf_copy_bit(kflags, KPF_WRITEBACK, PG_writeback) |
-                       kpf_copy_bit(kflags, KPF_RECLAIM, PG_reclaim) |
-                       kpf_copy_bit(kflags, KPF_BUDDY, PG_buddy);
-
-               if (put_user(uflags, out++)) {
-                       ret = -EFAULT;
-                       break;
-               }
-
-               count -= KPMSIZE;
-       }
-
-       *ppos += (char __user *)out - buf;
-       if (!ret)
-               ret = (char __user *)out - buf;
-       return ret;
-}
-
-static struct file_operations proc_kpageflags_operations = {
-       .llseek = mem_lseek,
-       .read = kpageflags_read,
-};
-#endif /* CONFIG_PROC_PAGE_MONITOR */
-
-struct proc_dir_entry *proc_root_kcore;
-
-void __init proc_misc_init(void)
-{
-       static struct {
-               char *name;
-               int (*read_proc)(char*,char**,off_t,int,int*,void*);
-       } *p, simple_ones[] = {
-               {"loadavg",     loadavg_read_proc},
-               {"uptime",      uptime_read_proc},
-               {"meminfo",     meminfo_read_proc},
-               {"version",     version_read_proc},
-#ifdef CONFIG_PROC_HARDWARE
-               {"hardware",    hardware_read_proc},
-#endif
-#ifdef CONFIG_STRAM_PROC
-               {"stram",       stram_read_proc},
-#endif
-               {"filesystems", filesystems_read_proc},
-               {"cmdline",     cmdline_read_proc},
-               {"execdomains", execdomains_read_proc},
-               {NULL,}
-       };
-       for (p = simple_ones; p->name; p++)
-               create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
-
-       proc_symlink("mounts", NULL, "self/mounts");
-
-       /* And now for trickier ones */
-#ifdef CONFIG_PRINTK
-       proc_create("kmsg", S_IRUSR, NULL, &proc_kmsg_operations);
-#endif
-#ifdef CONFIG_FILE_LOCKING
-       proc_create("locks", 0, NULL, &proc_locks_operations);
-#endif
-       proc_create("devices", 0, NULL, &proc_devinfo_operations);
-       proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations);
-#ifdef CONFIG_BLOCK
-       proc_create("partitions", 0, NULL, &proc_partitions_operations);
-#endif
-       proc_create("stat", 0, NULL, &proc_stat_operations);
-       proc_create("interrupts", 0, NULL, &proc_interrupts_operations);
-#ifdef CONFIG_SLABINFO
-       proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
-#ifdef CONFIG_DEBUG_SLAB_LEAK
-       proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
-#endif
-#endif
-#ifdef CONFIG_MMU
-       proc_create("vmallocinfo", S_IRUSR, NULL, &proc_vmalloc_operations);
-#endif
-       proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations);
-       proc_create("pagetypeinfo", S_IRUGO, NULL, &pagetypeinfo_file_ops);
-       proc_create("vmstat", S_IRUGO, NULL, &proc_vmstat_file_operations);
-       proc_create("zoneinfo", S_IRUGO, NULL, &proc_zoneinfo_file_operations);
-#ifdef CONFIG_BLOCK
-       proc_create("diskstats", 0, NULL, &proc_diskstats_operations);
-#endif
-#ifdef CONFIG_MODULES
-       proc_create("modules", 0, NULL, &proc_modules_operations);
-#endif
-#ifdef CONFIG_SCHEDSTATS
-       proc_create("schedstat", 0, NULL, &proc_schedstat_operations);
-#endif
-#ifdef CONFIG_PROC_KCORE
-       proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &proc_kcore_operations);
-       if (proc_root_kcore)
-               proc_root_kcore->size =
-                               (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
-#endif
-#ifdef CONFIG_PROC_PAGE_MONITOR
-       proc_create("kpagecount", S_IRUSR, NULL, &proc_kpagecount_operations);
-       proc_create("kpageflags", S_IRUSR, NULL, &proc_kpageflags_operations);
-#endif
-#ifdef CONFIG_PROC_VMCORE
-       proc_vmcore = proc_create("vmcore", S_IRUSR, NULL, &proc_vmcore_operations);
-#endif
-}
index 945a81043ba223cd92206077be7847563243f89e..94fcfff6863a5976965b8d4253ff3ad1ac45386b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * /proc/sys support
  */
-
+#include <linux/init.h>
 #include <linux/sysctl.h>
 #include <linux/proc_fs.h>
 #include <linux/security.h>
@@ -298,13 +298,19 @@ static int proc_sys_permission(struct inode *inode, int mask)
         * sysctl entries that are not writeable,
         * are _NOT_ writeable, capabilities or not.
         */
-       struct ctl_table_header *head = grab_header(inode);
-       struct ctl_table *table = PROC_I(inode)->sysctl_entry;
+       struct ctl_table_header *head;
+       struct ctl_table *table;
        int error;
 
+       /* Executable files are not allowed under /proc/sys/ */
+       if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))
+               return -EACCES;
+
+       head = grab_header(inode);
        if (IS_ERR(head))
                return PTR_ERR(head);
 
+       table = PROC_I(inode)->sysctl_entry;
        if (!table) /* global root - r-xr-xr-x */
                error = mask & MAY_WRITE ? -EACCES : 0;
        else /* Use the permissions on the sysctl table entry */
@@ -353,6 +359,7 @@ static const struct file_operations proc_sys_file_operations = {
 
 static const struct file_operations proc_sys_dir_file_operations = {
        .readdir        = proc_sys_readdir,
+       .llseek         = generic_file_llseek,
 };
 
 static const struct inode_operations proc_sys_inode_operations = {
@@ -395,7 +402,7 @@ static struct dentry_operations proc_sys_dentry_operations = {
        .d_compare      = proc_sys_compare,
 };
 
-int proc_sys_init(void)
+int __init proc_sys_init(void)
 {
        struct proc_dir_entry *proc_sys_root;
 
index 95117538a4f6fd3b4fdc90558127caa282d7e800..7761602af9de4f7290f33c50a8d97e2f1f31c2ec 100644 (file)
@@ -104,9 +104,9 @@ static struct file_system_type proc_fs_type = {
 
 void __init proc_root_init(void)
 {
-       int err = proc_init_inodecache();
-       if (err)
-               return;
+       int err;
+
+       proc_init_inodecache();
        err = register_filesystem(&proc_fs_type);
        if (err)
                return;
@@ -117,7 +117,7 @@ void __init proc_root_init(void)
                return;
        }
 
-       proc_misc_init();
+       proc_symlink("mounts", NULL, "self/mounts");
 
        proc_net_init();
 
diff --git a/fs/proc/stat.c b/fs/proc/stat.c
new file mode 100644 (file)
index 0000000..81904f0
--- /dev/null
@@ -0,0 +1,153 @@
+#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>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <asm/cputime.h>
+
+#ifndef arch_irq_stat_cpu
+#define arch_irq_stat_cpu(cpu) 0
+#endif
+#ifndef arch_irq_stat
+#define arch_irq_stat() 0
+#endif
+
+static int show_stat(struct seq_file *p, void *v)
+{
+       int i, j;
+       unsigned long jif;
+       cputime64_t user, nice, system, idle, iowait, irq, softirq, steal;
+       cputime64_t guest;
+       u64 sum = 0;
+       struct timespec boottime;
+       unsigned int per_irq_sum;
+
+       user = nice = system = idle = iowait =
+               irq = softirq = steal = cputime64_zero;
+       guest = cputime64_zero;
+       getboottime(&boottime);
+       jif = boottime.tv_sec;
+
+       for_each_possible_cpu(i) {
+               user = cputime64_add(user, kstat_cpu(i).cpustat.user);
+               nice = cputime64_add(nice, kstat_cpu(i).cpustat.nice);
+               system = cputime64_add(system, kstat_cpu(i).cpustat.system);
+               idle = cputime64_add(idle, kstat_cpu(i).cpustat.idle);
+               iowait = cputime64_add(iowait, kstat_cpu(i).cpustat.iowait);
+               irq = cputime64_add(irq, kstat_cpu(i).cpustat.irq);
+               softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq);
+               steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal);
+               guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest);
+
+               for_each_irq_nr(j)
+                       sum += kstat_irqs_cpu(j, i);
+
+               sum += arch_irq_stat_cpu(i);
+       }
+       sum += arch_irq_stat();
+
+       seq_printf(p, "cpu  %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
+               (unsigned long long)cputime64_to_clock_t(user),
+               (unsigned long long)cputime64_to_clock_t(nice),
+               (unsigned long long)cputime64_to_clock_t(system),
+               (unsigned long long)cputime64_to_clock_t(idle),
+               (unsigned long long)cputime64_to_clock_t(iowait),
+               (unsigned long long)cputime64_to_clock_t(irq),
+               (unsigned long long)cputime64_to_clock_t(softirq),
+               (unsigned long long)cputime64_to_clock_t(steal),
+               (unsigned long long)cputime64_to_clock_t(guest));
+       for_each_online_cpu(i) {
+
+               /* Copy values here to work around gcc-2.95.3, gcc-2.96 */
+               user = kstat_cpu(i).cpustat.user;
+               nice = kstat_cpu(i).cpustat.nice;
+               system = kstat_cpu(i).cpustat.system;
+               idle = kstat_cpu(i).cpustat.idle;
+               iowait = kstat_cpu(i).cpustat.iowait;
+               irq = kstat_cpu(i).cpustat.irq;
+               softirq = kstat_cpu(i).cpustat.softirq;
+               steal = kstat_cpu(i).cpustat.steal;
+               guest = kstat_cpu(i).cpustat.guest;
+               seq_printf(p,
+                       "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
+                       i,
+                       (unsigned long long)cputime64_to_clock_t(user),
+                       (unsigned long long)cputime64_to_clock_t(nice),
+                       (unsigned long long)cputime64_to_clock_t(system),
+                       (unsigned long long)cputime64_to_clock_t(idle),
+                       (unsigned long long)cputime64_to_clock_t(iowait),
+                       (unsigned long long)cputime64_to_clock_t(irq),
+                       (unsigned long long)cputime64_to_clock_t(softirq),
+                       (unsigned long long)cputime64_to_clock_t(steal),
+                       (unsigned long long)cputime64_to_clock_t(guest));
+       }
+       seq_printf(p, "intr %llu", (unsigned long long)sum);
+
+       /* sum again ? it could be updated? */
+       for_each_irq_nr(j) {
+               per_irq_sum = 0;
+
+               for_each_possible_cpu(i)
+                       per_irq_sum += kstat_irqs_cpu(j, i);
+
+               seq_printf(p, " %u", per_irq_sum);
+       }
+
+       seq_printf(p,
+               "\nctxt %llu\n"
+               "btime %lu\n"
+               "processes %lu\n"
+               "procs_running %lu\n"
+               "procs_blocked %lu\n",
+               nr_context_switches(),
+               (unsigned long)jif,
+               total_forks,
+               nr_running(),
+               nr_iowait());
+
+       return 0;
+}
+
+static int stat_open(struct inode *inode, struct file *file)
+{
+       unsigned size = 4096 * (1 + num_possible_cpus() / 32);
+       char *buf;
+       struct seq_file *m;
+       int res;
+
+       /* don't ask for more than the kmalloc() max size, currently 128 KB */
+       if (size > 128 * 1024)
+               size = 128 * 1024;
+       buf = kmalloc(size, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       res = single_open(file, show_stat, NULL);
+       if (!res) {
+               m = file->private_data;
+               m->buf = buf;
+               m->size = size;
+       } else
+               kfree(buf);
+       return res;
+}
+
+static const struct file_operations proc_stat_operations = {
+       .open           = stat_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int __init proc_stat_init(void)
+{
+       proc_create("stat", 0, NULL, &proc_stat_operations);
+       return 0;
+}
+module_init(proc_stat_init);
index 4806830ea2a1b0515c2faf00f52a6134f0f418c1..b770c095e45c62f86e78da2f9d1524085f9d45fd 100644 (file)
@@ -198,11 +198,8 @@ static int do_maps_open(struct inode *inode, struct file *file,
        return ret;
 }
 
-static int show_map(struct seq_file *m, void *v)
+static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
 {
-       struct proc_maps_private *priv = m->private;
-       struct task_struct *task = priv->task;
-       struct vm_area_struct *vma = v;
        struct mm_struct *mm = vma->vm_mm;
        struct file *file = vma->vm_file;
        int flags = vma->vm_flags;
@@ -254,6 +251,15 @@ static int show_map(struct seq_file *m, void *v)
                }
        }
        seq_putc(m, '\n');
+}
+
+static int show_map(struct seq_file *m, void *v)
+{
+       struct vm_area_struct *vma = v;
+       struct proc_maps_private *priv = m->private;
+       struct task_struct *task = priv->task;
+
+       show_map_vma(m, vma);
 
        if (m->count < m->size)  /* vma is copied successfully */
                m->version = (vma != get_gate_vma(task))? vma->vm_start: 0;
@@ -364,9 +370,10 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
 
 static int show_smap(struct seq_file *m, void *v)
 {
+       struct proc_maps_private *priv = m->private;
+       struct task_struct *task = priv->task;
        struct vm_area_struct *vma = v;
        struct mem_size_stats mss;
-       int ret;
        struct mm_walk smaps_walk = {
                .pmd_entry = smaps_pte_range,
                .mm = vma->vm_mm,
@@ -378,9 +385,7 @@ static int show_smap(struct seq_file *m, void *v)
        if (vma->vm_mm && !is_vm_hugetlb_page(vma))
                walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
 
-       ret = show_map(m, v);
-       if (ret)
-               return ret;
+       show_map_vma(m, vma);
 
        seq_printf(m,
                   "Size:           %8lu kB\n"
@@ -402,7 +407,9 @@ static int show_smap(struct seq_file *m, void *v)
                   mss.referenced >> 10,
                   mss.swap >> 10);
 
-       return ret;
+       if (m->count < m->size)  /* vma is copied successfully */
+               m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0;
+       return 0;
 }
 
 static const struct seq_operations proc_pid_smaps_op = {
diff --git a/fs/proc/uptime.c b/fs/proc/uptime.c
new file mode 100644 (file)
index 0000000..0c10a0b
--- /dev/null
@@ -0,0 +1,43 @@
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/time.h>
+#include <asm/cputime.h>
+
+static int uptime_proc_show(struct seq_file *m, void *v)
+{
+       struct timespec uptime;
+       struct timespec idle;
+       cputime_t idletime = cputime_add(init_task.utime, init_task.stime);
+
+       do_posix_clock_monotonic_gettime(&uptime);
+       monotonic_to_bootbased(&uptime);
+       cputime_to_timespec(idletime, &idle);
+       seq_printf(m, "%lu.%02lu %lu.%02lu\n",
+                       (unsigned long) uptime.tv_sec,
+                       (uptime.tv_nsec / (NSEC_PER_SEC / 100)),
+                       (unsigned long) idle.tv_sec,
+                       (idle.tv_nsec / (NSEC_PER_SEC / 100)));
+       return 0;
+}
+
+static int uptime_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, uptime_proc_show, NULL);
+}
+
+static const struct file_operations uptime_proc_fops = {
+       .open           = uptime_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int __init proc_uptime_init(void)
+{
+       proc_create("uptime", 0, NULL, &uptime_proc_fops);
+       return 0;
+}
+module_init(proc_uptime_init);
diff --git a/fs/proc/version.c b/fs/proc/version.c
new file mode 100644 (file)
index 0000000..76817a6
--- /dev/null
@@ -0,0 +1,34 @@
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/utsname.h>
+
+static int version_proc_show(struct seq_file *m, void *v)
+{
+       seq_printf(m, linux_proc_banner,
+               utsname()->sysname,
+               utsname()->release,
+               utsname()->version);
+       return 0;
+}
+
+static int version_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, version_proc_show, NULL);
+}
+
+static const struct file_operations version_proc_fops = {
+       .open           = version_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int __init proc_version_init(void)
+{
+       proc_create("version", 0, NULL, &version_proc_fops);
+       return 0;
+}
+module_init(proc_version_init);
index cd9ca67f841bd38d6256f14eccfd3fd6d8174522..03ec595049065f41b2513d9b94e76058a02ebfec 100644 (file)
@@ -32,7 +32,7 @@ static size_t elfcorebuf_sz;
 /* Total size of vmcore file. */
 static u64 vmcore_size;
 
-struct proc_dir_entry *proc_vmcore = NULL;
+static struct proc_dir_entry *proc_vmcore = NULL;
 
 /* Reads a page from the oldmem device from given offset. */
 static ssize_t read_from_oldmem(char *buf, size_t count,
@@ -162,7 +162,7 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer,
        return acc;
 }
 
-const struct file_operations proc_vmcore_operations = {
+static const struct file_operations proc_vmcore_operations = {
        .read           = read_vmcore,
 };
 
@@ -652,7 +652,7 @@ static int __init vmcore_init(void)
                return rc;
        }
 
-       /* Initialize /proc/vmcore size if proc is already up. */
+       proc_vmcore = proc_create("vmcore", S_IRUSR, NULL, &proc_vmcore_operations);
        if (proc_vmcore)
                proc_vmcore->size = vmcore_size;
        return 0;
index 9ba495d5a29b26d9493eea556ccd0992deb68829..969a6d9c020ba01644578b04c86043b15e98b53a 100644 (file)
@@ -31,39 +31,61 @@ const struct file_operations generic_ro_fops = {
 
 EXPORT_SYMBOL(generic_ro_fops);
 
+/**
+ * generic_file_llseek_unlocked - lockless generic llseek implementation
+ * @file:      file structure to seek on
+ * @offset:    file offset to seek to
+ * @origin:    type of seek
+ *
+ * Updates the file offset to the value specified by @offset and @origin.
+ * Locking must be provided by the caller.
+ */
 loff_t
 generic_file_llseek_unlocked(struct file *file, loff_t offset, int origin)
 {
-       loff_t retval;
        struct inode *inode = file->f_mapping->host;
 
        switch (origin) {
-               case SEEK_END:
-                       offset += inode->i_size;
-                       break;
-               case SEEK_CUR:
-                       offset += file->f_pos;
+       case SEEK_END:
+               offset += inode->i_size;
+               break;
+       case SEEK_CUR:
+               offset += file->f_pos;
+               break;
        }
-       retval = -EINVAL;
-       if (offset>=0 && offset<=inode->i_sb->s_maxbytes) {
-               /* Special lock needed here? */
-               if (offset != file->f_pos) {
-                       file->f_pos = offset;
-                       file->f_version = 0;
-               }
-               retval = offset;
+
+       if (offset < 0 || offset > inode->i_sb->s_maxbytes)
+               return -EINVAL;
+
+       /* Special lock needed here? */
+       if (offset != file->f_pos) {
+               file->f_pos = offset;
+               file->f_version = 0;
        }
-       return retval;
+
+       return offset;
 }
 EXPORT_SYMBOL(generic_file_llseek_unlocked);
 
+/**
+ * generic_file_llseek - generic llseek implementation for regular files
+ * @file:      file structure to seek on
+ * @offset:    file offset to seek to
+ * @origin:    type of seek
+ *
+ * This is a generic implemenation of ->llseek useable for all normal local
+ * filesystems.  It just updates the file offset to the value specified by
+ * @offset and @origin under i_mutex.
+ */
 loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
 {
-       loff_t n;
+       loff_t rval;
+
        mutex_lock(&file->f_dentry->d_inode->i_mutex);
-       n = generic_file_llseek_unlocked(file, offset, origin);
+       rval = generic_file_llseek_unlocked(file, offset, origin);
        mutex_unlock(&file->f_dentry->d_inode->i_mutex);
-       return n;
+
+       return rval;
 }
 EXPORT_SYMBOL(generic_file_llseek);
 
index 93a7559bbfd8c6a265d2824058c00612d1aabe1c..b318d9b5af2e9c5d24a325ece38acac3027a2ef8 100644 (file)
@@ -117,7 +117,7 @@ asmlinkage long old_readdir(unsigned int fd, struct old_linux_dirent __user * di
        buf.dirent = dirent;
 
        error = vfs_readdir(file, fillonedir, &buf);
-       if (error >= 0)
+       if (buf.result)
                error = buf.result;
 
        fput(file);
@@ -209,9 +209,8 @@ asmlinkage long sys_getdents(unsigned int fd, struct linux_dirent __user * diren
        buf.error = 0;
 
        error = vfs_readdir(file, filldir, &buf);
-       if (error < 0)
-               goto out_putf;
-       error = buf.error;
+       if (error >= 0)
+               error = buf.error;
        lastdirent = buf.previous;
        if (lastdirent) {
                if (put_user(file->f_pos, &lastdirent->d_off))
@@ -219,8 +218,6 @@ asmlinkage long sys_getdents(unsigned int fd, struct linux_dirent __user * diren
                else
                        error = count - buf.count;
        }
-
-out_putf:
        fput(file);
 out:
        return error;
@@ -293,19 +290,16 @@ asmlinkage long sys_getdents64(unsigned int fd, struct linux_dirent64 __user * d
        buf.error = 0;
 
        error = vfs_readdir(file, filldir64, &buf);
-       if (error < 0)
-               goto out_putf;
-       error = buf.error;
+       if (error >= 0)
+               error = buf.error;
        lastdirent = buf.previous;
        if (lastdirent) {
                typeof(lastdirent->d_off) d_off = file->f_pos;
-               error = -EFAULT;
                if (__put_user(d_off, &lastdirent->d_off))
-                       goto out_putf;
-               error = count - buf.count;
+                       error = -EFAULT;
+               else
+                       error = count - buf.count;
        }
-
-out_putf:
        fput(file);
 out:
        return error;
index a804903d31d1e336e73072a7e15453a3eac59ce1..33408417038c2c93c576534c8d946deaa66ef4e9 100644 (file)
@@ -296,6 +296,7 @@ const struct file_operations reiserfs_file_operations = {
        .aio_write = generic_file_aio_write,
        .splice_read = generic_file_splice_read,
        .splice_write = generic_file_splice_write,
+       .llseek = generic_file_llseek,
 };
 
 const struct inode_operations reiserfs_file_inode_operations = {
index 5699171212ae2d3d3428c3b23c42c604d56a26ab..6c4c2c69449f6bc74dddf5c42a0daea09ccf6adf 100644 (file)
@@ -1522,7 +1522,6 @@ static struct dentry *reiserfs_get_dentry(struct super_block *sb,
 
 {
        struct cpu_key key;
-       struct dentry *result;
        struct inode *inode;
 
        key.on_disk_key.k_objectid = objectid;
@@ -1535,16 +1534,8 @@ static struct dentry *reiserfs_get_dentry(struct super_block *sb,
                inode = NULL;
        }
        reiserfs_write_unlock(sb);
-       if (!inode)
-               inode = ERR_PTR(-ESTALE);
-       if (IS_ERR(inode))
-               return ERR_CAST(inode);
-       result = d_alloc_anon(inode);
-       if (!result) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
-       }
-       return result;
+
+       return d_obtain_alias(inode);
 }
 
 struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
index c21df71943a635c7eedabbf36e0ae3ac6107c770..9643c3bbeb3b611d3817bc17698d76c5d54e89b5 100644 (file)
@@ -2575,7 +2575,7 @@ static int release_journal_dev(struct super_block *super,
        if (journal->j_dev_bd != NULL) {
                if (journal->j_dev_bd->bd_dev != super->s_dev)
                        bd_release(journal->j_dev_bd);
-               result = blkdev_put(journal->j_dev_bd);
+               result = blkdev_put(journal->j_dev_bd, journal->j_dev_mode);
                journal->j_dev_bd = NULL;
        }
 
@@ -2593,7 +2593,7 @@ static int journal_init_dev(struct super_block *super,
 {
        int result;
        dev_t jdev;
-       int blkdev_mode = FMODE_READ | FMODE_WRITE;
+       fmode_t blkdev_mode = FMODE_READ | FMODE_WRITE;
        char b[BDEVNAME_SIZE];
 
        result = 0;
@@ -2608,6 +2608,7 @@ static int journal_init_dev(struct super_block *super,
        /* there is no "jdev" option and journal is on separate device */
        if ((!jdev_name || !jdev_name[0])) {
                journal->j_dev_bd = open_by_devnum(jdev, blkdev_mode);
+               journal->j_dev_mode = blkdev_mode;
                if (IS_ERR(journal->j_dev_bd)) {
                        result = PTR_ERR(journal->j_dev_bd);
                        journal->j_dev_bd = NULL;
@@ -2618,7 +2619,7 @@ static int journal_init_dev(struct super_block *super,
                } else if (jdev != super->s_dev) {
                        result = bd_claim(journal->j_dev_bd, journal);
                        if (result) {
-                               blkdev_put(journal->j_dev_bd);
+                               blkdev_put(journal->j_dev_bd, blkdev_mode);
                                return result;
                        }
 
@@ -2628,7 +2629,9 @@ static int journal_init_dev(struct super_block *super,
                return 0;
        }
 
-       journal->j_dev_bd = open_bdev_excl(jdev_name, 0, journal);
+       journal->j_dev_mode = blkdev_mode;
+       journal->j_dev_bd = open_bdev_exclusive(jdev_name,
+                                               blkdev_mode, journal);
        if (IS_ERR(journal->j_dev_bd)) {
                result = PTR_ERR(journal->j_dev_bd);
                journal->j_dev_bd = NULL;
index c1add28dd45ec144ec946b3ddba2c06a340af405..f89ebb943f3f1f6a2f219db1a9ec9fd2275e5f0e 100644 (file)
@@ -383,7 +383,6 @@ struct dentry *reiserfs_get_parent(struct dentry *child)
        struct inode *inode = NULL;
        struct reiserfs_dir_entry de;
        INITIALIZE_PATH(path_to_entry);
-       struct dentry *parent;
        struct inode *dir = child->d_inode;
 
        if (dir->i_nlink == 0) {
@@ -401,15 +400,7 @@ struct dentry *reiserfs_get_parent(struct dentry *child)
        inode = reiserfs_iget(dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
        reiserfs_write_unlock(dir->i_sb);
 
-       if (!inode || IS_ERR(inode)) {
-               return ERR_PTR(-EACCES);
-       }
-       parent = d_alloc_anon(inode);
-       if (!parent) {
-               iput(inode);
-               parent = ERR_PTR(-ENOMEM);
-       }
-       return parent;
+       return d_obtain_alias(inode);
 }
 
 /* add entry to the directory (entry can be hidden). 
index d318c7e663faff15eb08ced95d11a123f6297866..663a91f5dce8a33d4f12c85658122a62da216bc8 100644 (file)
@@ -2058,10 +2058,10 @@ static int reiserfs_quota_on_mount(struct super_block *sb, int type)
  * Standard function to be called on quota_on
  */
 static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
-                            char *path, int remount)
+                            char *name, int remount)
 {
        int err;
-       struct nameidata nd;
+       struct path path;
        struct inode *inode;
        struct reiserfs_transaction_handle th;
 
@@ -2069,16 +2069,16 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
                return -EINVAL;
        /* No more checks needed? Path and format_id are bogus anyway... */
        if (remount)
-               return vfs_quota_on(sb, type, format_id, path, 1);
-       err = path_lookup(path, LOOKUP_FOLLOW, &nd);
+               return vfs_quota_on(sb, type, format_id, name, 1);
+       err = kern_path(name, LOOKUP_FOLLOW, &path);
        if (err)
                return err;
        /* Quotafile not on the same filesystem? */
-       if (nd.path.mnt->mnt_sb != sb) {
+       if (path.mnt->mnt_sb != sb) {
                err = -EXDEV;
                goto out;
        }
-       inode = nd.path.dentry->d_inode;
+       inode = path.dentry->d_inode;
        /* We must not pack tails for quota files on reiserfs for quota IO to work */
        if (!(REISERFS_I(inode)->i_flags & i_nopack_mask)) {
                err = reiserfs_unpack(inode, NULL);
@@ -2094,7 +2094,7 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
        /* Journaling quota? */
        if (REISERFS_SB(sb)->s_qf_names[type]) {
                /* Quotafile not of fs root? */
-               if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode)
+               if (path.dentry->d_parent != sb->s_root)
                        reiserfs_warning(sb,
                                 "reiserfs: Quota file not on filesystem root. "
                                 "Journalled quota will not work.");
@@ -2113,9 +2113,9 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
                if (err)
                        goto out;
        }
-       err = vfs_quota_on_path(sb, type, format_id, &nd.path);
+       err = vfs_quota_on_path(sb, type, format_id, &path);
 out:
-       path_put(&nd.path);
+       path_put(&path);
        return err;
 }
 
index da0e88201c3a03bfa7e44eea8805a62dcd540539..448e44001286754f891249f216f7af3a01d1bfee 100644 (file)
 #include <linux/fdtable.h>
 #include <linux/fs.h>
 #include <linux/rcupdate.h>
+#include <linux/hrtimer.h>
 
 #include <asm/uaccess.h>
 
+
+/*
+ * Estimate expected accuracy in ns from a timeval.
+ *
+ * After quite a bit of churning around, we've settled on
+ * a simple thing of taking 0.1% of the timeout as the
+ * slack, with a cap of 100 msec.
+ * "nice" tasks get a 0.5% slack instead.
+ *
+ * Consider this comment an open invitation to come up with even
+ * better solutions..
+ */
+
+static long __estimate_accuracy(struct timespec *tv)
+{
+       long slack;
+       int divfactor = 1000;
+
+       if (task_nice(current) > 0)
+               divfactor = divfactor / 5;
+
+       slack = tv->tv_nsec / divfactor;
+       slack += tv->tv_sec * (NSEC_PER_SEC/divfactor);
+
+       if (slack > 100 * NSEC_PER_MSEC)
+               slack =  100 * NSEC_PER_MSEC;
+
+       if (slack < 0)
+               slack = 0;
+       return slack;
+}
+
+static long estimate_accuracy(struct timespec *tv)
+{
+       unsigned long ret;
+       struct timespec now;
+
+       /*
+        * Realtime tasks get a slack of 0 for obvious reasons.
+        */
+
+       if (rt_task(current))
+               return 0;
+
+       ktime_get_ts(&now);
+       now = timespec_sub(*tv, now);
+       ret = __estimate_accuracy(&now);
+       if (ret < current->timer_slack_ns)
+               return current->timer_slack_ns;
+       return ret;
+}
+
+
+
 struct poll_table_page {
        struct poll_table_page * next;
        struct poll_table_entry * entry;
@@ -130,6 +185,79 @@ static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,
        add_wait_queue(wait_address, &entry->wait);
 }
 
+/**
+ * poll_select_set_timeout - helper function to setup the timeout value
+ * @to:                pointer to timespec variable for the final timeout
+ * @sec:       seconds (from user space)
+ * @nsec:      nanoseconds (from user space)
+ *
+ * Note, we do not use a timespec for the user space value here, That
+ * way we can use the function for timeval and compat interfaces as well.
+ *
+ * Returns -EINVAL if sec/nsec are not normalized. Otherwise 0.
+ */
+int poll_select_set_timeout(struct timespec *to, long sec, long nsec)
+{
+       struct timespec ts = {.tv_sec = sec, .tv_nsec = nsec};
+
+       if (!timespec_valid(&ts))
+               return -EINVAL;
+
+       /* Optimize for the zero timeout value here */
+       if (!sec && !nsec) {
+               to->tv_sec = to->tv_nsec = 0;
+       } else {
+               ktime_get_ts(to);
+               *to = timespec_add_safe(*to, ts);
+       }
+       return 0;
+}
+
+static int poll_select_copy_remaining(struct timespec *end_time, void __user *p,
+                                     int timeval, int ret)
+{
+       struct timespec rts;
+       struct timeval rtv;
+
+       if (!p)
+               return ret;
+
+       if (current->personality & STICKY_TIMEOUTS)
+               goto sticky;
+
+       /* No update for zero timeout */
+       if (!end_time->tv_sec && !end_time->tv_nsec)
+               return ret;
+
+       ktime_get_ts(&rts);
+       rts = timespec_sub(*end_time, rts);
+       if (rts.tv_sec < 0)
+               rts.tv_sec = rts.tv_nsec = 0;
+
+       if (timeval) {
+               rtv.tv_sec = rts.tv_sec;
+               rtv.tv_usec = rts.tv_nsec / NSEC_PER_USEC;
+
+               if (!copy_to_user(p, &rtv, sizeof(rtv)))
+                       return ret;
+
+       } else if (!copy_to_user(p, &rts, sizeof(rts)))
+               return ret;
+
+       /*
+        * If an application puts its timeval in read-only memory, we
+        * don't want the Linux-specific update to the timeval to
+        * cause a fault after the select has completed
+        * successfully. However, because we're not updating the
+        * timeval, we can't restart the system call.
+        */
+
+sticky:
+       if (ret == -ERESTARTNOHAND)
+               ret = -EINTR;
+       return ret;
+}
+
 #define FDS_IN(fds, n)         (fds->in + n)
 #define FDS_OUT(fds, n)                (fds->out + n)
 #define FDS_EX(fds, n)         (fds->ex + n)
@@ -182,11 +310,13 @@ get_max:
 #define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR)
 #define POLLEX_SET (POLLPRI)
 
-int do_select(int n, fd_set_bits *fds, s64 *timeout)
+int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
 {
+       ktime_t expire, *to = NULL;
        struct poll_wqueues table;
        poll_table *wait;
-       int retval, i;
+       int retval, i, timed_out = 0;
+       unsigned long slack = 0;
 
        rcu_read_lock();
        retval = max_select_fd(n, fds);
@@ -198,12 +328,17 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout)
 
        poll_initwait(&table);
        wait = &table.pt;
-       if (!*timeout)
+       if (end_time && !end_time->tv_sec && !end_time->tv_nsec) {
                wait = NULL;
+               timed_out = 1;
+       }
+
+       if (end_time && !timed_out)
+               slack = estimate_accuracy(end_time);
+
        retval = 0;
        for (;;) {
                unsigned long *rinp, *routp, *rexp, *inp, *outp, *exp;
-               long __timeout;
 
                set_current_state(TASK_INTERRUPTIBLE);
 
@@ -259,27 +394,25 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout)
                        cond_resched();
                }
                wait = NULL;
-               if (retval || !*timeout || signal_pending(current))
+               if (retval || timed_out || signal_pending(current))
                        break;
                if (table.error) {
                        retval = table.error;
                        break;
                }
 
-               if (*timeout < 0) {
-                       /* Wait indefinitely */
-                       __timeout = MAX_SCHEDULE_TIMEOUT;
-               } else if (unlikely(*timeout >= (s64)MAX_SCHEDULE_TIMEOUT - 1)) {
-                       /* Wait for longer than MAX_SCHEDULE_TIMEOUT. Do it in a loop */
-                       __timeout = MAX_SCHEDULE_TIMEOUT - 1;
-                       *timeout -= __timeout;
-               } else {
-                       __timeout = *timeout;
-                       *timeout = 0;
+               /*
+                * If this is the first loop and we have a timeout
+                * given, then we convert to ktime_t and set the to
+                * pointer to the expiry value.
+                */
+               if (end_time && !to) {
+                       expire = timespec_to_ktime(*end_time);
+                       to = &expire;
                }
-               __timeout = schedule_timeout(__timeout);
-               if (*timeout >= 0)
-                       *timeout += __timeout;
+
+               if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS))
+                       timed_out = 1;
        }
        __set_current_state(TASK_RUNNING);
 
@@ -300,7 +433,7 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout)
        ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
 
 int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
-                          fd_set __user *exp, s64 *timeout)
+                          fd_set __user *exp, struct timespec *end_time)
 {
        fd_set_bits fds;
        void *bits;
@@ -351,7 +484,7 @@ int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
        zero_fd_set(n, fds.res_out);
        zero_fd_set(n, fds.res_ex);
 
-       ret = do_select(n, &fds, timeout);
+       ret = do_select(n, &fds, end_time);
 
        if (ret < 0)
                goto out;
@@ -377,7 +510,7 @@ out_nofds:
 asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp,
                        fd_set __user *exp, struct timeval __user *tvp)
 {
-       s64 timeout = -1;
+       struct timespec end_time, *to = NULL;
        struct timeval tv;
        int ret;
 
@@ -385,43 +518,14 @@ asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp,
                if (copy_from_user(&tv, tvp, sizeof(tv)))
                        return -EFAULT;
 
-               if (tv.tv_sec < 0 || tv.tv_usec < 0)
+               to = &end_time;
+               if (poll_select_set_timeout(to, tv.tv_sec,
+                                           tv.tv_usec * NSEC_PER_USEC))
                        return -EINVAL;
-
-               /* Cast to u64 to make GCC stop complaining */
-               if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS)
-                       timeout = -1;   /* infinite */
-               else {
-                       timeout = DIV_ROUND_UP(tv.tv_usec, USEC_PER_SEC/HZ);
-                       timeout += tv.tv_sec * HZ;
-               }
        }
 
-       ret = core_sys_select(n, inp, outp, exp, &timeout);
-
-       if (tvp) {
-               struct timeval rtv;
-
-               if (current->personality & STICKY_TIMEOUTS)
-                       goto sticky;
-               rtv.tv_usec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ));
-               rtv.tv_sec = timeout;
-               if (timeval_compare(&rtv, &tv) >= 0)
-                       rtv = tv;
-               if (copy_to_user(tvp, &rtv, sizeof(rtv))) {
-sticky:
-                       /*
-                        * If an application puts its timeval in read-only
-                        * memory, we don't want the Linux-specific update to
-                        * the timeval to cause a fault after the select has
-                        * completed successfully. However, because we're not
-                        * updating the timeval, we can't restart the system
-                        * call.
-                        */
-                       if (ret == -ERESTARTNOHAND)
-                               ret = -EINTR;
-               }
-       }
+       ret = core_sys_select(n, inp, outp, exp, to);
+       ret = poll_select_copy_remaining(&end_time, tvp, 1, ret);
 
        return ret;
 }
@@ -431,25 +535,17 @@ asmlinkage long sys_pselect7(int n, fd_set __user *inp, fd_set __user *outp,
                fd_set __user *exp, struct timespec __user *tsp,
                const sigset_t __user *sigmask, size_t sigsetsize)
 {
-       s64 timeout = MAX_SCHEDULE_TIMEOUT;
        sigset_t ksigmask, sigsaved;
-       struct timespec ts;
+       struct timespec ts, end_time, *to = NULL;
        int ret;
 
        if (tsp) {
                if (copy_from_user(&ts, tsp, sizeof(ts)))
                        return -EFAULT;
 
-               if (ts.tv_sec < 0 || ts.tv_nsec < 0)
+               to = &end_time;
+               if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
                        return -EINVAL;
-
-               /* Cast to u64 to make GCC stop complaining */
-               if ((u64)ts.tv_sec >= (u64)MAX_INT64_SECONDS)
-                       timeout = -1;   /* infinite */
-               else {
-                       timeout = DIV_ROUND_UP(ts.tv_nsec, NSEC_PER_SEC/HZ);
-                       timeout += ts.tv_sec * HZ;
-               }
        }
 
        if (sigmask) {
@@ -463,32 +559,8 @@ asmlinkage long sys_pselect7(int n, fd_set __user *inp, fd_set __user *outp,
                sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
        }
 
-       ret = core_sys_select(n, inp, outp, exp, &timeout);
-
-       if (tsp) {
-               struct timespec rts;
-
-               if (current->personality & STICKY_TIMEOUTS)
-                       goto sticky;
-               rts.tv_nsec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)) *
-                                               1000;
-               rts.tv_sec = timeout;
-               if (timespec_compare(&rts, &ts) >= 0)
-                       rts = ts;
-               if (copy_to_user(tsp, &rts, sizeof(rts))) {
-sticky:
-                       /*
-                        * If an application puts its timeval in read-only
-                        * memory, we don't want the Linux-specific update to
-                        * the timeval to cause a fault after the select has
-                        * completed successfully. However, because we're not
-                        * updating the timeval, we can't restart the system
-                        * call.
-                        */
-                       if (ret == -ERESTARTNOHAND)
-                               ret = -EINTR;
-               }
-       }
+       ret = core_sys_select(n, inp, outp, exp, &end_time);
+       ret = poll_select_copy_remaining(&end_time, tsp, 0, ret);
 
        if (ret == -ERESTARTNOHAND) {
                /*
@@ -574,18 +646,24 @@ static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait)
 }
 
 static int do_poll(unsigned int nfds,  struct poll_list *list,
-                  struct poll_wqueues *wait, s64 *timeout)
+                  struct poll_wqueues *wait, struct timespec *end_time)
 {
-       int count = 0;
        poll_table* pt = &wait->pt;
+       ktime_t expire, *to = NULL;
+       int timed_out = 0, count = 0;
+       unsigned long slack = 0;
 
        /* Optimise the no-wait case */
-       if (!(*timeout))
+       if (end_time && !end_time->tv_sec && !end_time->tv_nsec) {
                pt = NULL;
+               timed_out = 1;
+       }
+
+       if (end_time && !timed_out)
+               slack = estimate_accuracy(end_time);
 
        for (;;) {
                struct poll_list *walk;
-               long __timeout;
 
                set_current_state(TASK_INTERRUPTIBLE);
                for (walk = list; walk != NULL; walk = walk->next) {
@@ -617,27 +695,21 @@ static int do_poll(unsigned int nfds,  struct poll_list *list,
                        if (signal_pending(current))
                                count = -EINTR;
                }
-               if (count || !*timeout)
+               if (count || timed_out)
                        break;
 
-               if (*timeout < 0) {
-                       /* Wait indefinitely */
-                       __timeout = MAX_SCHEDULE_TIMEOUT;
-               } else if (unlikely(*timeout >= (s64)MAX_SCHEDULE_TIMEOUT-1)) {
-                       /*
-                        * Wait for longer than MAX_SCHEDULE_TIMEOUT. Do it in
-                        * a loop
-                        */
-                       __timeout = MAX_SCHEDULE_TIMEOUT - 1;
-                       *timeout -= __timeout;
-               } else {
-                       __timeout = *timeout;
-                       *timeout = 0;
+               /*
+                * If this is the first loop and we have a timeout
+                * given, then we convert to ktime_t and set the to
+                * pointer to the expiry value.
+                */
+               if (end_time && !to) {
+                       expire = timespec_to_ktime(*end_time);
+                       to = &expire;
                }
 
-               __timeout = schedule_timeout(__timeout);
-               if (*timeout >= 0)
-                       *timeout += __timeout;
+               if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS))
+                       timed_out = 1;
        }
        __set_current_state(TASK_RUNNING);
        return count;
@@ -646,7 +718,8 @@ static int do_poll(unsigned int nfds,  struct poll_list *list,
 #define N_STACK_PPS ((sizeof(stack_pps) - sizeof(struct poll_list))  / \
                        sizeof(struct pollfd))
 
-int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout)
+int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
+               struct timespec *end_time)
 {
        struct poll_wqueues table;
        int err = -EFAULT, fdcount, len, size;
@@ -686,7 +759,7 @@ int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout)
        }
 
        poll_initwait(&table);
-       fdcount = do_poll(nfds, head, &table, timeout);
+       fdcount = do_poll(nfds, head, &table, end_time);
        poll_freewait(&table);
 
        for (walk = head; walk; walk = walk->next) {
@@ -712,16 +785,21 @@ out_fds:
 
 static long do_restart_poll(struct restart_block *restart_block)
 {
-       struct pollfd __user *ufds = (struct pollfd __user*)restart_block->arg0;
-       int nfds = restart_block->arg1;
-       s64 timeout = ((s64)restart_block->arg3<<32) | (s64)restart_block->arg2;
+       struct pollfd __user *ufds = restart_block->poll.ufds;
+       int nfds = restart_block->poll.nfds;
+       struct timespec *to = NULL, end_time;
        int ret;
 
-       ret = do_sys_poll(ufds, nfds, &timeout);
+       if (restart_block->poll.has_timeout) {
+               end_time.tv_sec = restart_block->poll.tv_sec;
+               end_time.tv_nsec = restart_block->poll.tv_nsec;
+               to = &end_time;
+       }
+
+       ret = do_sys_poll(ufds, nfds, to);
+
        if (ret == -EINTR) {
                restart_block->fn = do_restart_poll;
-               restart_block->arg2 = timeout & 0xFFFFFFFF;
-               restart_block->arg3 = (u64)timeout >> 32;
                ret = -ERESTART_RESTARTBLOCK;
        }
        return ret;
@@ -730,31 +808,32 @@ static long do_restart_poll(struct restart_block *restart_block)
 asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds,
                        long timeout_msecs)
 {
-       s64 timeout_jiffies;
+       struct timespec end_time, *to = NULL;
        int ret;
 
-       if (timeout_msecs > 0) {
-#if HZ > 1000
-               /* We can only overflow if HZ > 1000 */
-               if (timeout_msecs / 1000 > (s64)0x7fffffffffffffffULL / (s64)HZ)
-                       timeout_jiffies = -1;
-               else
-#endif
-                       timeout_jiffies = msecs_to_jiffies(timeout_msecs) + 1;
-       } else {
-               /* Infinite (< 0) or no (0) timeout */
-               timeout_jiffies = timeout_msecs;
+       if (timeout_msecs >= 0) {
+               to = &end_time;
+               poll_select_set_timeout(to, timeout_msecs / MSEC_PER_SEC,
+                       NSEC_PER_MSEC * (timeout_msecs % MSEC_PER_SEC));
        }
 
-       ret = do_sys_poll(ufds, nfds, &timeout_jiffies);
+       ret = do_sys_poll(ufds, nfds, to);
+
        if (ret == -EINTR) {
                struct restart_block *restart_block;
+
                restart_block = &current_thread_info()->restart_block;
                restart_block->fn = do_restart_poll;
-               restart_block->arg0 = (unsigned long)ufds;
-               restart_block->arg1 = nfds;
-               restart_block->arg2 = timeout_jiffies & 0xFFFFFFFF;
-               restart_block->arg3 = (u64)timeout_jiffies >> 32;
+               restart_block->poll.ufds = ufds;
+               restart_block->poll.nfds = nfds;
+
+               if (timeout_msecs >= 0) {
+                       restart_block->poll.tv_sec = end_time.tv_sec;
+                       restart_block->poll.tv_nsec = end_time.tv_nsec;
+                       restart_block->poll.has_timeout = 1;
+               } else
+                       restart_block->poll.has_timeout = 0;
+
                ret = -ERESTART_RESTARTBLOCK;
        }
        return ret;
@@ -766,21 +845,16 @@ asmlinkage long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds,
        size_t sigsetsize)
 {
        sigset_t ksigmask, sigsaved;
-       struct timespec ts;
-       s64 timeout = -1;
+       struct timespec ts, end_time, *to = NULL;
        int ret;
 
        if (tsp) {
                if (copy_from_user(&ts, tsp, sizeof(ts)))
                        return -EFAULT;
 
-               /* Cast to u64 to make GCC stop complaining */
-               if ((u64)ts.tv_sec >= (u64)MAX_INT64_SECONDS)
-                       timeout = -1;   /* infinite */
-               else {
-                       timeout = DIV_ROUND_UP(ts.tv_nsec, NSEC_PER_SEC/HZ);
-                       timeout += ts.tv_sec * HZ;
-               }
+               to = &end_time;
+               if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
+                       return -EINVAL;
        }
 
        if (sigmask) {
@@ -794,7 +868,7 @@ asmlinkage long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds,
                sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
        }
 
-       ret = do_sys_poll(ufds, nfds, &timeout);
+       ret = do_sys_poll(ufds, nfds, to);
 
        /* We can restart this syscall, usually */
        if (ret == -EINTR) {
@@ -812,31 +886,7 @@ asmlinkage long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds,
        } else if (sigmask)
                sigprocmask(SIG_SETMASK, &sigsaved, NULL);
 
-       if (tsp && timeout >= 0) {
-               struct timespec rts;
-
-               if (current->personality & STICKY_TIMEOUTS)
-                       goto sticky;
-               /* Yes, we know it's actually an s64, but it's also positive. */
-               rts.tv_nsec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)) *
-                                               1000;
-               rts.tv_sec = timeout;
-               if (timespec_compare(&rts, &ts) >= 0)
-                       rts = ts;
-               if (copy_to_user(tsp, &rts, sizeof(rts))) {
-               sticky:
-                       /*
-                        * If an application puts its timeval in read-only
-                        * memory, we don't want the Linux-specific update to
-                        * the timeval to cause a fault after the select has
-                        * completed successfully. However, because we're not
-                        * updating the timeval, we can't restart the system
-                        * call.
-                        */
-                       if (ret == -ERESTARTNOHAND && timeout >= 0)
-                               ret = -EINTR;
-               }
-       }
+       ret = poll_select_copy_remaining(&end_time, tsp, 0, ret);
 
        return ret;
 }
index e931ae9511fef01f5ae98ea477b89f491a73bb00..400a7608f15e7ea7b84837b106db1765c3efff4c 100644 (file)
@@ -682,7 +682,7 @@ void emergency_remount(void)
  * filesystems which don't use real block-devices.  -- jrs
  */
 
-static struct idr unnamed_dev_idr;
+static DEFINE_IDA(unnamed_dev_ida);
 static DEFINE_SPINLOCK(unnamed_dev_lock);/* protects the above */
 
 int set_anon_super(struct super_block *s, void *data)
@@ -691,10 +691,10 @@ int set_anon_super(struct super_block *s, void *data)
        int error;
 
  retry:
-       if (idr_pre_get(&unnamed_dev_idr, GFP_ATOMIC) == 0)
+       if (ida_pre_get(&unnamed_dev_ida, GFP_ATOMIC) == 0)
                return -ENOMEM;
        spin_lock(&unnamed_dev_lock);
-       error = idr_get_new(&unnamed_dev_idr, NULL, &dev);
+       error = ida_get_new(&unnamed_dev_ida, &dev);
        spin_unlock(&unnamed_dev_lock);
        if (error == -EAGAIN)
                /* We raced and lost with another CPU. */
@@ -704,7 +704,7 @@ int set_anon_super(struct super_block *s, void *data)
 
        if ((dev & MAX_ID_MASK) == (1 << MINORBITS)) {
                spin_lock(&unnamed_dev_lock);
-               idr_remove(&unnamed_dev_idr, dev);
+               ida_remove(&unnamed_dev_ida, dev);
                spin_unlock(&unnamed_dev_lock);
                return -EMFILE;
        }
@@ -720,17 +720,12 @@ void kill_anon_super(struct super_block *sb)
 
        generic_shutdown_super(sb);
        spin_lock(&unnamed_dev_lock);
-       idr_remove(&unnamed_dev_idr, slot);
+       ida_remove(&unnamed_dev_ida, slot);
        spin_unlock(&unnamed_dev_lock);
 }
 
 EXPORT_SYMBOL(kill_anon_super);
 
-void __init unnamed_dev_init(void)
-{
-       idr_init(&unnamed_dev_idr);
-}
-
 void kill_litter_super(struct super_block *sb)
 {
        if (sb->s_root)
@@ -760,9 +755,13 @@ int get_sb_bdev(struct file_system_type *fs_type,
 {
        struct block_device *bdev;
        struct super_block *s;
+       fmode_t mode = FMODE_READ;
        int error = 0;
 
-       bdev = open_bdev_excl(dev_name, flags, fs_type);
+       if (!(flags & MS_RDONLY))
+               mode |= FMODE_WRITE;
+
+       bdev = open_bdev_exclusive(dev_name, mode, fs_type);
        if (IS_ERR(bdev))
                return PTR_ERR(bdev);
 
@@ -785,11 +784,12 @@ int get_sb_bdev(struct file_system_type *fs_type,
                        goto error_bdev;
                }
 
-               close_bdev_excl(bdev);
+               close_bdev_exclusive(bdev, mode);
        } else {
                char b[BDEVNAME_SIZE];
 
                s->s_flags = flags;
+               s->s_mode = mode;
                strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
                sb_set_blocksize(s, block_size(bdev));
                error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
@@ -807,7 +807,7 @@ int get_sb_bdev(struct file_system_type *fs_type,
 error_s:
        error = PTR_ERR(s);
 error_bdev:
-       close_bdev_excl(bdev);
+       close_bdev_exclusive(bdev, mode);
 error:
        return error;
 }
@@ -817,10 +817,11 @@ EXPORT_SYMBOL(get_sb_bdev);
 void kill_block_super(struct super_block *sb)
 {
        struct block_device *bdev = sb->s_bdev;
+       fmode_t mode = sb->s_mode;
 
        generic_shutdown_super(sb);
        sync_blockdev(bdev);
-       close_bdev_excl(bdev);
+       close_bdev_exclusive(bdev, mode);
 }
 
 EXPORT_SYMBOL(kill_block_super);
index 3a05a596e3b4de91dcb522401441b8dc8d959aa9..82d3b79d0e080765fb3ceb43fae1549ffe7df96d 100644 (file)
@@ -983,4 +983,5 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
 const struct file_operations sysfs_dir_operations = {
        .read           = generic_read_dir,
        .readdir        = sysfs_readdir,
+       .llseek         = generic_file_llseek,
 };
index c502c60e4f54ddfe6ac9402c2c550a274485b003..0862f0e49d0cf8b5af985a2ea46991d25b6b9eaf 100644 (file)
@@ -52,11 +52,9 @@ static enum hrtimer_restart timerfd_tmrproc(struct hrtimer *htmr)
 
 static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx)
 {
-       ktime_t now, remaining;
-
-       now = ctx->tmr.base->get_time();
-       remaining = ktime_sub(ctx->tmr.expires, now);
+       ktime_t remaining;
 
+       remaining = hrtimer_expires_remaining(&ctx->tmr);
        return remaining.tv64 < 0 ? ktime_set(0, 0): remaining;
 }
 
@@ -74,7 +72,7 @@ static void timerfd_setup(struct timerfd_ctx *ctx, int flags,
        ctx->ticks = 0;
        ctx->tintv = timespec_to_ktime(ktmr->it_interval);
        hrtimer_init(&ctx->tmr, ctx->clockid, htmode);
-       ctx->tmr.expires = texp;
+       hrtimer_set_expires(&ctx->tmr, texp);
        ctx->tmr.function = timerfd_tmrproc;
        if (texp.tv64 != 0)
                hrtimer_start(&ctx->tmr, texp, htmode);
index d3231947db19edc3e4e592d3feadd7ab95e2c08a..082409cd4b8aec78918c697cc4666fe937cb26be 100644 (file)
@@ -142,7 +142,7 @@ int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi,
 }
 
 static struct fileIdentDesc *udf_find_entry(struct inode *dir,
-                                           struct dentry *dentry,
+                                           struct qstr *child,
                                            struct udf_fileident_bh *fibh,
                                            struct fileIdentDesc *cfi)
 {
@@ -159,8 +159,8 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
        sector_t offset;
        struct extent_position epos = {};
        struct udf_inode_info *dinfo = UDF_I(dir);
-       int isdotdot = dentry->d_name.len == 2 &&
-               dentry->d_name.name[0] == '.' && dentry->d_name.name[1] == '.';
+       int isdotdot = child->len == 2 &&
+               child->name[0] == '.' && child->name[1] == '.';
 
        size = udf_ext0_offset(dir) + dir->i_size;
        f_pos = udf_ext0_offset(dir);
@@ -238,8 +238,7 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
                        continue;
 
                flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi);
-               if (flen && udf_match(flen, fname, dentry->d_name.len,
-                                     dentry->d_name.name))
+               if (flen && udf_match(flen, fname, child->len, child->name))
                        goto out_ok;
        }
 
@@ -283,7 +282,7 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry,
        } else
 #endif /* UDF_RECOVERY */
 
-       if (udf_find_entry(dir, dentry, &fibh, &cfi)) {
+       if (udf_find_entry(dir, &dentry->d_name, &fibh, &cfi)) {
                if (fibh.sbh != fibh.ebh)
                        brelse(fibh.ebh);
                brelse(fibh.sbh);
@@ -783,7 +782,7 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry)
 
        retval = -ENOENT;
        lock_kernel();
-       fi = udf_find_entry(dir, dentry, &fibh, &cfi);
+       fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi);
        if (!fi)
                goto out;
 
@@ -829,7 +828,7 @@ static int udf_unlink(struct inode *dir, struct dentry *dentry)
 
        retval = -ENOENT;
        lock_kernel();
-       fi = udf_find_entry(dir, dentry, &fibh, &cfi);
+       fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi);
        if (!fi)
                goto out;
 
@@ -1113,7 +1112,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
        struct udf_inode_info *old_iinfo = UDF_I(old_inode);
 
        lock_kernel();
-       ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi);
+       ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi);
        if (ofi) {
                if (ofibh.sbh != ofibh.ebh)
                        brelse(ofibh.ebh);
@@ -1124,7 +1123,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
            != old_inode->i_ino)
                goto end_rename;
 
-       nfi = udf_find_entry(new_dir, new_dentry, &nfibh, &ncfi);
+       nfi = udf_find_entry(new_dir, &new_dentry->d_name, &nfibh, &ncfi);
        if (nfi) {
                if (!new_inode) {
                        if (nfibh.sbh != nfibh.ebh)
@@ -1192,7 +1191,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
        udf_write_fi(new_dir, &ncfi, nfi, &nfibh, NULL, NULL);
 
        /* The old fid may have moved - find it again */
-       ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi);
+       ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi);
        udf_delete_entry(old_dir, ofi, &ofibh, &ocfi);
 
        if (new_inode) {
@@ -1243,15 +1242,11 @@ end_rename:
 
 static struct dentry *udf_get_parent(struct dentry *child)
 {
-       struct dentry *parent;
        struct inode *inode = NULL;
-       struct dentry dotdot;
+       struct qstr dotdot = {.name = "..", .len = 2};
        struct fileIdentDesc cfi;
        struct udf_fileident_bh fibh;
 
-       dotdot.d_name.name = "..";
-       dotdot.d_name.len = 2;
-
        lock_kernel();
        if (!udf_find_entry(child->d_inode, &dotdot, &fibh, &cfi))
                goto out_unlock;
@@ -1266,13 +1261,7 @@ static struct dentry *udf_get_parent(struct dentry *child)
                goto out_unlock;
        unlock_kernel();
 
-       parent = d_alloc_anon(inode);
-       if (!parent) {
-               iput(inode);
-               parent = ERR_PTR(-ENOMEM);
-       }
-
-       return parent;
+       return d_obtain_alias(inode);
 out_unlock:
        unlock_kernel();
        return ERR_PTR(-EACCES);
@@ -1283,7 +1272,6 @@ static struct dentry *udf_nfs_get_inode(struct super_block *sb, u32 block,
                                        u16 partref, __u32 generation)
 {
        struct inode *inode;
-       struct dentry *result;
        kernel_lb_addr loc;
 
        if (block == 0)
@@ -1300,12 +1288,7 @@ static struct dentry *udf_nfs_get_inode(struct super_block *sb, u32 block,
                iput(inode);
                return ERR_PTR(-ESTALE);
        }
-       result = d_alloc_anon(inode);
-       if (!result) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
-       }
-       return result;
+       return d_obtain_alias(inode);
 }
 
 static struct dentry *udf_fh_to_dentry(struct super_block *sb,
index df0bef18742dc63b6dee218e029b2e90d35b1c37..dbbbc46687698e72b3662046f9cd67302c5e5b7a 100644 (file)
@@ -667,4 +667,5 @@ const struct file_operations ufs_dir_operations = {
        .read           = generic_read_dir,
        .readdir        = ufs_readdir,
        .fsync          = file_fsync,
+       .llseek         = generic_file_llseek,
 };
index 24fd598af84633876a169e7887818ac7742238fd..7f7abec25e141302458af4e72a0bf3ecce87fbab 100644 (file)
@@ -148,7 +148,6 @@ xfs_fs_fh_to_dentry(struct super_block *sb, struct fid *fid,
 {
        struct xfs_fid64        *fid64 = (struct xfs_fid64 *)fid;
        struct inode            *inode = NULL;
-       struct dentry           *result;
 
        if (fh_len < xfs_fileid_length(fileid_type))
                return NULL;
@@ -164,16 +163,7 @@ xfs_fs_fh_to_dentry(struct super_block *sb, struct fid *fid,
                break;
        }
 
-       if (!inode)
-               return NULL;
-       if (IS_ERR(inode))
-               return ERR_CAST(inode);
-       result = d_alloc_anon(inode);
-       if (!result) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
-       }
-       return result;
+       return d_obtain_alias(inode);
 }
 
 STATIC struct dentry *
@@ -182,7 +172,6 @@ xfs_fs_fh_to_parent(struct super_block *sb, struct fid *fid,
 {
        struct xfs_fid64        *fid64 = (struct xfs_fid64 *)fid;
        struct inode            *inode = NULL;
-       struct dentry           *result;
 
        switch (fileid_type) {
        case FILEID_INO32_GEN_PARENT:
@@ -195,16 +184,7 @@ xfs_fs_fh_to_parent(struct super_block *sb, struct fid *fid,
                break;
        }
 
-       if (!inode)
-               return NULL;
-       if (IS_ERR(inode))
-               return ERR_CAST(inode);
-       result = d_alloc_anon(inode);
-       if (!result) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
-       }
-       return result;
+       return d_obtain_alias(inode);
 }
 
 STATIC struct dentry *
@@ -213,18 +193,12 @@ xfs_fs_get_parent(
 {
        int                     error;
        struct xfs_inode        *cip;
-       struct dentry           *parent;
 
        error = xfs_lookup(XFS_I(child->d_inode), &xfs_name_dotdot, &cip, NULL);
        if (unlikely(error))
                return ERR_PTR(-error);
 
-       parent = d_alloc_anon(VFS_I(cip));
-       if (unlikely(!parent)) {
-               iput(VFS_I(cip));
-               return ERR_PTR(-ENOMEM);
-       }
-       return parent;
+       return d_obtain_alias(VFS_I(cip));
 }
 
 const struct export_operations xfs_export_operations = {
index 5311c1acdd402ab783723b48e14267657752b1d3..3fee790f138b0acc2358244e0385bd81919ae554 100644 (file)
@@ -204,15 +204,6 @@ xfs_file_fsync(
        return -xfs_fsync(XFS_I(dentry->d_inode));
 }
 
-/*
- * Unfortunately we can't just use the clean and simple readdir implementation
- * below, because nfs might call back into ->lookup from the filldir callback
- * and that will deadlock the low-level btree code.
- *
- * Hopefully we'll find a better workaround that allows to use the optimal
- * version at least for local readdirs for 2.6.25.
- */
-#if 0
 STATIC int
 xfs_file_readdir(
        struct file     *filp,
@@ -244,125 +235,6 @@ xfs_file_readdir(
                return -error;
        return 0;
 }
-#else
-
-struct hack_dirent {
-       u64             ino;
-       loff_t          offset;
-       int             namlen;
-       unsigned int    d_type;
-       char            name[];
-};
-
-struct hack_callback {
-       char            *dirent;
-       size_t          len;
-       size_t          used;
-};
-
-STATIC int
-xfs_hack_filldir(
-       void            *__buf,
-       const char      *name,
-       int             namlen,
-       loff_t          offset,
-       u64             ino,
-       unsigned int    d_type)
-{
-       struct hack_callback *buf = __buf;
-       struct hack_dirent *de = (struct hack_dirent *)(buf->dirent + buf->used);
-       unsigned int reclen;
-
-       reclen = ALIGN(sizeof(struct hack_dirent) + namlen, sizeof(u64));
-       if (buf->used + reclen > buf->len)
-               return -EINVAL;
-
-       de->namlen = namlen;
-       de->offset = offset;
-       de->ino = ino;
-       de->d_type = d_type;
-       memcpy(de->name, name, namlen);
-       buf->used += reclen;
-       return 0;
-}
-
-STATIC int
-xfs_file_readdir(
-       struct file     *filp,
-       void            *dirent,
-       filldir_t       filldir)
-{
-       struct inode    *inode = filp->f_path.dentry->d_inode;
-       xfs_inode_t     *ip = XFS_I(inode);
-       struct hack_callback buf;
-       struct hack_dirent *de;
-       int             error;
-       loff_t          size;
-       int             eof = 0;
-       xfs_off_t       start_offset, curr_offset, offset;
-
-       /*
-        * Try fairly hard to get memory
-        */
-       buf.len = PAGE_CACHE_SIZE;
-       do {
-               buf.dirent = kmalloc(buf.len, GFP_KERNEL);
-               if (buf.dirent)
-                       break;
-               buf.len >>= 1;
-       } while (buf.len >= 1024);
-
-       if (!buf.dirent)
-               return -ENOMEM;
-
-       curr_offset = filp->f_pos;
-       if (curr_offset == 0x7fffffff)
-               offset = 0xffffffff;
-       else
-               offset = filp->f_pos;
-
-       while (!eof) {
-               unsigned int reclen;
-
-               start_offset = offset;
-
-               buf.used = 0;
-               error = -xfs_readdir(ip, &buf, buf.len, &offset,
-                                    xfs_hack_filldir);
-               if (error || offset == start_offset) {
-                       size = 0;
-                       break;
-               }
-
-               size = buf.used;
-               de = (struct hack_dirent *)buf.dirent;
-               while (size > 0) {
-                       curr_offset = de->offset /* & 0x7fffffff */;
-                       if (filldir(dirent, de->name, de->namlen,
-                                       curr_offset & 0x7fffffff,
-                                       de->ino, de->d_type)) {
-                               goto done;
-                       }
-
-                       reclen = ALIGN(sizeof(struct hack_dirent) + de->namlen,
-                                      sizeof(u64));
-                       size -= reclen;
-                       de = (struct hack_dirent *)((char *)de + reclen);
-               }
-       }
-
- done:
-       if (!error) {
-               if (size == 0)
-                       filp->f_pos = offset & 0x7fffffff;
-               else if (de)
-                       filp->f_pos = curr_offset;
-       }
-
-       kfree(buf.dirent);
-       return error;
-}
-#endif
 
 STATIC int
 xfs_file_mmap(
index 48799ba7e3e6f2ded6a46e972a254044c76bb83d..d3438c72dcaf555b8d18174a00d1b6eab264615f 100644 (file)
@@ -311,11 +311,10 @@ xfs_open_by_handle(
                return new_fd;
        }
 
-       dentry = d_alloc_anon(inode);
-       if (dentry == NULL) {
-               iput(inode);
+       dentry = d_obtain_alias(inode);
+       if (IS_ERR(dentry)) {
                put_unused_fd(new_fd);
-               return -XFS_ERROR(ENOMEM);
+               return PTR_ERR(dentry);
        }
 
        /* Ensure umount returns EBUSY on umounts while this file is open. */
index e39013619b2619317a77cb8e1ceb3aee05de033f..37ebe36056ebd758af0e62012b60c5dfb13b7039 100644 (file)
@@ -589,7 +589,7 @@ xfs_blkdev_get(
 {
        int                     error = 0;
 
-       *bdevp = open_bdev_excl(name, 0, mp);
+       *bdevp = open_bdev_exclusive(name, FMODE_READ|FMODE_WRITE, mp);
        if (IS_ERR(*bdevp)) {
                error = PTR_ERR(*bdevp);
                printk("XFS: Invalid device [%s], error=%d\n", name, error);
@@ -603,7 +603,7 @@ xfs_blkdev_put(
        struct block_device     *bdev)
 {
        if (bdev)
-               close_bdev_excl(bdev);
+               close_bdev_exclusive(bdev, FMODE_READ|FMODE_WRITE);
 }
 
 /*
index 4eb75a88795ad21da088d394f5e08faa898e04ad..29feee27f0ea8aeef29352635eb4f6720f55e1f2 100644 (file)
@@ -63,7 +63,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                0x20080609
+#define ACPI_CA_VERSION                 0x20080926
 
 /*
  * OS name, used for the _OS object.  The _OS object is essentially obsolete,
index c5a1b50d8d94c27ccb9f6d6dff2682ba3c30d115..62c59df3b86c049799e78f280d8a743bbed38aac 100644 (file)
@@ -123,6 +123,10 @@ void acpi_db_check_integrity(void);
 
 void acpi_db_generate_gpe(char *gpe_arg, char *block_arg);
 
+void acpi_db_check_predefined_names(void);
+
+void acpi_db_batch_execute(void);
+
 /*
  * dbdisply - debug display commands
  */
@@ -150,6 +154,10 @@ void
 acpi_db_display_argument_object(union acpi_operand_object *obj_desc,
                                struct acpi_walk_state *walk_state);
 
+void acpi_db_check_predefined_names(void);
+
+void acpi_db_batch_execute(void);
+
 /*
  * dbexec - debugger control method execution
  */
index f53faca8ec8055cc367968aa9982ddd8ca0fcad0..0c1ed387073cf206cb7a3a4b3d02af15a086175f 100644 (file)
@@ -186,6 +186,8 @@ extern struct acpi_dmtable_info acpi_dm_table_info_madt5[];
 extern struct acpi_dmtable_info acpi_dm_table_info_madt6[];
 extern struct acpi_dmtable_info acpi_dm_table_info_madt7[];
 extern struct acpi_dmtable_info acpi_dm_table_info_madt8[];
+extern struct acpi_dmtable_info acpi_dm_table_info_madt9[];
+extern struct acpi_dmtable_info acpi_dm_table_info_madt10[];
 extern struct acpi_dmtable_info acpi_dm_table_info_madt_hdr[];
 extern struct acpi_dmtable_info acpi_dm_table_info_mcfg[];
 extern struct acpi_dmtable_info acpi_dm_table_info_mcfg0[];
@@ -197,8 +199,10 @@ extern struct acpi_dmtable_info acpi_dm_table_info_slit[];
 extern struct acpi_dmtable_info acpi_dm_table_info_spcr[];
 extern struct acpi_dmtable_info acpi_dm_table_info_spmi[];
 extern struct acpi_dmtable_info acpi_dm_table_info_srat[];
+extern struct acpi_dmtable_info acpi_dm_table_info_srat_hdr[];
 extern struct acpi_dmtable_info acpi_dm_table_info_srat0[];
 extern struct acpi_dmtable_info acpi_dm_table_info_srat1[];
+extern struct acpi_dmtable_info acpi_dm_table_info_srat2[];
 extern struct acpi_dmtable_info acpi_dm_table_info_tcpa[];
 extern struct acpi_dmtable_info acpi_dm_table_info_wdrt[];
 
index 21a73a105d0ab2920962c4febb1e6a2d795dd263..6291904be01e564d7b4433a1d35fbd30144f2774 100644 (file)
@@ -157,7 +157,7 @@ acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number);
  * dsmthdat - method data (locals/args)
  */
 acpi_status
-acpi_ds_store_object_to_local(u16 opcode,
+acpi_ds_store_object_to_local(u8 type,
                              u32 index,
                              union acpi_operand_object *src_desc,
                              struct acpi_walk_state *walk_state);
@@ -173,7 +173,7 @@ void acpi_ds_method_data_delete_all(struct acpi_walk_state *walk_state);
 u8 acpi_ds_is_method_value(union acpi_operand_object *obj_desc);
 
 acpi_status
-acpi_ds_method_data_get_value(u16 opcode,
+acpi_ds_method_data_get_value(u8 type,
                              u32 index,
                              struct acpi_walk_state *walk_state,
                              union acpi_operand_object **dest_desc);
@@ -184,7 +184,7 @@ acpi_ds_method_data_init_args(union acpi_operand_object **params,
                              struct acpi_walk_state *walk_state);
 
 acpi_status
-acpi_ds_method_data_get_node(u16 opcode,
+acpi_ds_method_data_get_node(u8 type,
                             u32 index,
                             struct acpi_walk_state *walk_state,
                             struct acpi_namespace_node **node);
index e5a890ffeb02c26ec55f73ff4a0ff58912306087..84f5cb242863c28829c3919b62c57c1e699c68e3 100644 (file)
 #define AE_STACK_OVERFLOW               (acpi_status) (0x000C | AE_CODE_ENVIRONMENTAL)
 #define AE_STACK_UNDERFLOW              (acpi_status) (0x000D | AE_CODE_ENVIRONMENTAL)
 #define AE_NOT_IMPLEMENTED              (acpi_status) (0x000E | AE_CODE_ENVIRONMENTAL)
-#define AE_VERSION_MISMATCH             (acpi_status) (0x000F | AE_CODE_ENVIRONMENTAL)
-#define AE_SUPPORT                      (acpi_status) (0x0010 | AE_CODE_ENVIRONMENTAL)
-#define AE_SHARE                        (acpi_status) (0x0011 | AE_CODE_ENVIRONMENTAL)
-#define AE_LIMIT                        (acpi_status) (0x0012 | AE_CODE_ENVIRONMENTAL)
-#define AE_TIME                         (acpi_status) (0x0013 | AE_CODE_ENVIRONMENTAL)
-#define AE_UNKNOWN_STATUS               (acpi_status) (0x0014 | AE_CODE_ENVIRONMENTAL)
-#define AE_ACQUIRE_DEADLOCK             (acpi_status) (0x0015 | AE_CODE_ENVIRONMENTAL)
-#define AE_RELEASE_DEADLOCK             (acpi_status) (0x0016 | AE_CODE_ENVIRONMENTAL)
-#define AE_NOT_ACQUIRED                 (acpi_status) (0x0017 | AE_CODE_ENVIRONMENTAL)
-#define AE_ALREADY_ACQUIRED             (acpi_status) (0x0018 | AE_CODE_ENVIRONMENTAL)
-#define AE_NO_HARDWARE_RESPONSE         (acpi_status) (0x0019 | AE_CODE_ENVIRONMENTAL)
-#define AE_NO_GLOBAL_LOCK               (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL)
-#define AE_LOGICAL_ADDRESS              (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL)
-#define AE_ABORT_METHOD                 (acpi_status) (0x001C | AE_CODE_ENVIRONMENTAL)
-#define AE_SAME_HANDLER                 (acpi_status) (0x001D | AE_CODE_ENVIRONMENTAL)
-#define AE_WAKE_ONLY_GPE                (acpi_status) (0x001E | AE_CODE_ENVIRONMENTAL)
-#define AE_OWNER_ID_LIMIT               (acpi_status) (0x001F | AE_CODE_ENVIRONMENTAL)
+#define AE_SUPPORT                      (acpi_status) (0x000F | AE_CODE_ENVIRONMENTAL)
+#define AE_LIMIT                        (acpi_status) (0x0010 | AE_CODE_ENVIRONMENTAL)
+#define AE_TIME                         (acpi_status) (0x0011 | AE_CODE_ENVIRONMENTAL)
+#define AE_ACQUIRE_DEADLOCK             (acpi_status) (0x0012 | AE_CODE_ENVIRONMENTAL)
+#define AE_RELEASE_DEADLOCK             (acpi_status) (0x0013 | AE_CODE_ENVIRONMENTAL)
+#define AE_NOT_ACQUIRED                 (acpi_status) (0x0014 | AE_CODE_ENVIRONMENTAL)
+#define AE_ALREADY_ACQUIRED             (acpi_status) (0x0015 | AE_CODE_ENVIRONMENTAL)
+#define AE_NO_HARDWARE_RESPONSE         (acpi_status) (0x0016 | AE_CODE_ENVIRONMENTAL)
+#define AE_NO_GLOBAL_LOCK               (acpi_status) (0x0017 | AE_CODE_ENVIRONMENTAL)
+#define AE_ABORT_METHOD                 (acpi_status) (0x0018 | AE_CODE_ENVIRONMENTAL)
+#define AE_SAME_HANDLER                 (acpi_status) (0x0019 | AE_CODE_ENVIRONMENTAL)
+#define AE_WAKE_ONLY_GPE                (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL)
+#define AE_OWNER_ID_LIMIT               (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL)
 
-#define AE_CODE_ENV_MAX                 0x001F
+#define AE_CODE_ENV_MAX                 0x001B
 
 /*
  * Programmer exceptions
 #define AE_BAD_CHARACTER                (acpi_status) (0x0002 | AE_CODE_PROGRAMMER)
 #define AE_BAD_PATHNAME                 (acpi_status) (0x0003 | AE_CODE_PROGRAMMER)
 #define AE_BAD_DATA                     (acpi_status) (0x0004 | AE_CODE_PROGRAMMER)
-#define AE_BAD_ADDRESS                  (acpi_status) (0x0005 | AE_CODE_PROGRAMMER)
-#define AE_ALIGNMENT                    (acpi_status) (0x0006 | AE_CODE_PROGRAMMER)
-#define AE_BAD_HEX_CONSTANT             (acpi_status) (0x0007 | AE_CODE_PROGRAMMER)
-#define AE_BAD_OCTAL_CONSTANT           (acpi_status) (0x0008 | AE_CODE_PROGRAMMER)
-#define AE_BAD_DECIMAL_CONSTANT         (acpi_status) (0x0009 | AE_CODE_PROGRAMMER)
-#define AE_MISSING_ARGUMENTS           (acpi_status) (0x000A | AE_CODE_PROGRAMMER)
+#define AE_BAD_HEX_CONSTANT             (acpi_status) (0x0005 | AE_CODE_PROGRAMMER)
+#define AE_BAD_OCTAL_CONSTANT           (acpi_status) (0x0006 | AE_CODE_PROGRAMMER)
+#define AE_BAD_DECIMAL_CONSTANT         (acpi_status) (0x0007 | AE_CODE_PROGRAMMER)
+#define AE_MISSING_ARGUMENTS            (acpi_status) (0x0008 | AE_CODE_PROGRAMMER)
 
-#define AE_CODE_PGM_MAX                0x000A
+#define AE_CODE_PGM_MAX                 0x0008
 
 /*
  * Acpi table exceptions
 #define AE_BAD_HEADER                   (acpi_status) (0x0002 | AE_CODE_ACPI_TABLES)
 #define AE_BAD_CHECKSUM                 (acpi_status) (0x0003 | AE_CODE_ACPI_TABLES)
 #define AE_BAD_VALUE                    (acpi_status) (0x0004 | AE_CODE_ACPI_TABLES)
-#define AE_TABLE_NOT_SUPPORTED          (acpi_status) (0x0005 | AE_CODE_ACPI_TABLES)
-#define AE_INVALID_TABLE_LENGTH         (acpi_status) (0x0006 | AE_CODE_ACPI_TABLES)
+#define AE_INVALID_TABLE_LENGTH         (acpi_status) (0x0005 | AE_CODE_ACPI_TABLES)
 
-#define AE_CODE_TBL_MAX                 0x0006
+#define AE_CODE_TBL_MAX                 0x0005
 
 /*
  * AML exceptions.  These are caused by problems with
  * the actual AML byte stream
  */
-#define AE_AML_ERROR                    (acpi_status) (0x0001 | AE_CODE_AML)
-#define AE_AML_PARSE                    (acpi_status) (0x0002 | AE_CODE_AML)
-#define AE_AML_BAD_OPCODE               (acpi_status) (0x0003 | AE_CODE_AML)
-#define AE_AML_NO_OPERAND               (acpi_status) (0x0004 | AE_CODE_AML)
-#define AE_AML_OPERAND_TYPE             (acpi_status) (0x0005 | AE_CODE_AML)
-#define AE_AML_OPERAND_VALUE            (acpi_status) (0x0006 | AE_CODE_AML)
-#define AE_AML_UNINITIALIZED_LOCAL      (acpi_status) (0x0007 | AE_CODE_AML)
-#define AE_AML_UNINITIALIZED_ARG        (acpi_status) (0x0008 | AE_CODE_AML)
-#define AE_AML_UNINITIALIZED_ELEMENT    (acpi_status) (0x0009 | AE_CODE_AML)
-#define AE_AML_NUMERIC_OVERFLOW         (acpi_status) (0x000A | AE_CODE_AML)
-#define AE_AML_REGION_LIMIT             (acpi_status) (0x000B | AE_CODE_AML)
-#define AE_AML_BUFFER_LIMIT             (acpi_status) (0x000C | AE_CODE_AML)
-#define AE_AML_PACKAGE_LIMIT            (acpi_status) (0x000D | AE_CODE_AML)
-#define AE_AML_DIVIDE_BY_ZERO           (acpi_status) (0x000E | AE_CODE_AML)
-#define AE_AML_BAD_NAME                 (acpi_status) (0x000F | AE_CODE_AML)
-#define AE_AML_NAME_NOT_FOUND           (acpi_status) (0x0010 | AE_CODE_AML)
-#define AE_AML_INTERNAL                 (acpi_status) (0x0011 | AE_CODE_AML)
-#define AE_AML_INVALID_SPACE_ID         (acpi_status) (0x0012 | AE_CODE_AML)
-#define AE_AML_STRING_LIMIT             (acpi_status) (0x0013 | AE_CODE_AML)
-#define AE_AML_NO_RETURN_VALUE          (acpi_status) (0x0014 | AE_CODE_AML)
-#define AE_AML_METHOD_LIMIT             (acpi_status) (0x0015 | AE_CODE_AML)
-#define AE_AML_NOT_OWNER                (acpi_status) (0x0016 | AE_CODE_AML)
-#define AE_AML_MUTEX_ORDER              (acpi_status) (0x0017 | AE_CODE_AML)
-#define AE_AML_MUTEX_NOT_ACQUIRED       (acpi_status) (0x0018 | AE_CODE_AML)
-#define AE_AML_INVALID_RESOURCE_TYPE    (acpi_status) (0x0019 | AE_CODE_AML)
-#define AE_AML_INVALID_INDEX            (acpi_status) (0x001A | AE_CODE_AML)
-#define AE_AML_REGISTER_LIMIT           (acpi_status) (0x001B | AE_CODE_AML)
-#define AE_AML_NO_WHILE                 (acpi_status) (0x001C | AE_CODE_AML)
-#define AE_AML_ALIGNMENT                (acpi_status) (0x001D | AE_CODE_AML)
-#define AE_AML_NO_RESOURCE_END_TAG      (acpi_status) (0x001E | AE_CODE_AML)
-#define AE_AML_BAD_RESOURCE_VALUE       (acpi_status) (0x001F | AE_CODE_AML)
-#define AE_AML_CIRCULAR_REFERENCE       (acpi_status) (0x0020 | AE_CODE_AML)
-#define AE_AML_BAD_RESOURCE_LENGTH      (acpi_status) (0x0021 | AE_CODE_AML)
-#define AE_AML_ILLEGAL_ADDRESS          (acpi_status) (0x0022 | AE_CODE_AML)
+#define AE_AML_BAD_OPCODE               (acpi_status) (0x0001 | AE_CODE_AML)
+#define AE_AML_NO_OPERAND               (acpi_status) (0x0002 | AE_CODE_AML)
+#define AE_AML_OPERAND_TYPE             (acpi_status) (0x0003 | AE_CODE_AML)
+#define AE_AML_OPERAND_VALUE            (acpi_status) (0x0004 | AE_CODE_AML)
+#define AE_AML_UNINITIALIZED_LOCAL      (acpi_status) (0x0005 | AE_CODE_AML)
+#define AE_AML_UNINITIALIZED_ARG        (acpi_status) (0x0006 | AE_CODE_AML)
+#define AE_AML_UNINITIALIZED_ELEMENT    (acpi_status) (0x0007 | AE_CODE_AML)
+#define AE_AML_NUMERIC_OVERFLOW         (acpi_status) (0x0008 | AE_CODE_AML)
+#define AE_AML_REGION_LIMIT             (acpi_status) (0x0009 | AE_CODE_AML)
+#define AE_AML_BUFFER_LIMIT             (acpi_status) (0x000A | AE_CODE_AML)
+#define AE_AML_PACKAGE_LIMIT            (acpi_status) (0x000B | AE_CODE_AML)
+#define AE_AML_DIVIDE_BY_ZERO           (acpi_status) (0x000C | AE_CODE_AML)
+#define AE_AML_BAD_NAME                 (acpi_status) (0x000D | AE_CODE_AML)
+#define AE_AML_NAME_NOT_FOUND           (acpi_status) (0x000E | AE_CODE_AML)
+#define AE_AML_INTERNAL                 (acpi_status) (0x000F | AE_CODE_AML)
+#define AE_AML_INVALID_SPACE_ID         (acpi_status) (0x0010 | AE_CODE_AML)
+#define AE_AML_STRING_LIMIT             (acpi_status) (0x0011 | AE_CODE_AML)
+#define AE_AML_NO_RETURN_VALUE          (acpi_status) (0x0012 | AE_CODE_AML)
+#define AE_AML_METHOD_LIMIT             (acpi_status) (0x0013 | AE_CODE_AML)
+#define AE_AML_NOT_OWNER                (acpi_status) (0x0014 | AE_CODE_AML)
+#define AE_AML_MUTEX_ORDER              (acpi_status) (0x0015 | AE_CODE_AML)
+#define AE_AML_MUTEX_NOT_ACQUIRED       (acpi_status) (0x0016 | AE_CODE_AML)
+#define AE_AML_INVALID_RESOURCE_TYPE    (acpi_status) (0x0017 | AE_CODE_AML)
+#define AE_AML_INVALID_INDEX            (acpi_status) (0x0018 | AE_CODE_AML)
+#define AE_AML_REGISTER_LIMIT           (acpi_status) (0x0019 | AE_CODE_AML)
+#define AE_AML_NO_WHILE                 (acpi_status) (0x001A | AE_CODE_AML)
+#define AE_AML_ALIGNMENT                (acpi_status) (0x001B | AE_CODE_AML)
+#define AE_AML_NO_RESOURCE_END_TAG      (acpi_status) (0x001C | AE_CODE_AML)
+#define AE_AML_BAD_RESOURCE_VALUE       (acpi_status) (0x001D | AE_CODE_AML)
+#define AE_AML_CIRCULAR_REFERENCE       (acpi_status) (0x001E | AE_CODE_AML)
+#define AE_AML_BAD_RESOURCE_LENGTH      (acpi_status) (0x001F | AE_CODE_AML)
+#define AE_AML_ILLEGAL_ADDRESS          (acpi_status) (0x0020 | AE_CODE_AML)
 
-#define AE_CODE_AML_MAX                 0x0022
+#define AE_CODE_AML_MAX                 0x0020
 
 /*
  * Internal exceptions used for control
@@ -206,19 +197,15 @@ char const *acpi_gbl_exception_names_env[] = {
        "AE_STACK_OVERFLOW",
        "AE_STACK_UNDERFLOW",
        "AE_NOT_IMPLEMENTED",
-       "AE_VERSION_MISMATCH",
        "AE_SUPPORT",
-       "AE_SHARE",
        "AE_LIMIT",
        "AE_TIME",
-       "AE_UNKNOWN_STATUS",
        "AE_ACQUIRE_DEADLOCK",
        "AE_RELEASE_DEADLOCK",
        "AE_NOT_ACQUIRED",
        "AE_ALREADY_ACQUIRED",
        "AE_NO_HARDWARE_RESPONSE",
        "AE_NO_GLOBAL_LOCK",
-       "AE_LOGICAL_ADDRESS",
        "AE_ABORT_METHOD",
        "AE_SAME_HANDLER",
        "AE_WAKE_ONLY_GPE",
@@ -231,8 +218,6 @@ char const *acpi_gbl_exception_names_pgm[] = {
        "AE_BAD_CHARACTER",
        "AE_BAD_PATHNAME",
        "AE_BAD_DATA",
-       "AE_BAD_ADDRESS",
-       "AE_ALIGNMENT",
        "AE_BAD_HEX_CONSTANT",
        "AE_BAD_OCTAL_CONSTANT",
        "AE_BAD_DECIMAL_CONSTANT",
@@ -245,14 +230,11 @@ char const *acpi_gbl_exception_names_tbl[] = {
        "AE_BAD_HEADER",
        "AE_BAD_CHECKSUM",
        "AE_BAD_VALUE",
-       "AE_TABLE_NOT_SUPPORTED",
        "AE_INVALID_TABLE_LENGTH"
 };
 
 char const *acpi_gbl_exception_names_aml[] = {
        NULL,
-       "AE_AML_ERROR",
-       "AE_AML_PARSE",
        "AE_AML_BAD_OPCODE",
        "AE_AML_NO_OPERAND",
        "AE_AML_OPERAND_TYPE",
@@ -284,7 +266,7 @@ char const *acpi_gbl_exception_names_aml[] = {
        "AE_AML_BAD_RESOURCE_VALUE",
        "AE_AML_CIRCULAR_REFERENCE",
        "AE_AML_BAD_RESOURCE_LENGTH",
-       "AE_AML_ILLEGAL_ADDRESS"
+       "AE_AML_ILLEGAL_ADDRESS",
 };
 
 char const *acpi_gbl_exception_names_ctrl[] = {
index b221c8583dddf22966e65b3e974d508e17f43079..ecab527cf78ef72afe33309782bf184a12c13641 100644 (file)
@@ -208,6 +208,7 @@ struct acpi_namespace_node {
 #define ANOBJ_METHOD_ARG                0x04   /* Node is a method argument */
 #define ANOBJ_METHOD_LOCAL              0x08   /* Node is a method local */
 #define ANOBJ_SUBTREE_HAS_INI           0x10   /* Used to optimize device initialization */
+#define ANOBJ_EVALUATED                 0x20   /* Set on first evaluation of node */
 
 #define ANOBJ_IS_EXTERNAL               0x08   /* i_aSL only: This object created via External() */
 #define ANOBJ_METHOD_NO_RETVAL          0x10   /* i_aSL only: Method has no return value */
@@ -340,6 +341,82 @@ acpi_status(*ACPI_INTERNAL_METHOD) (struct acpi_walk_state * walk_state);
 #define ACPI_BTYPE_OBJECTS_AND_REFS     0x0001FFFF     /* ARG or LOCAL */
 #define ACPI_BTYPE_ALL_OBJECTS          0x0000FFFF
 
+/*
+ * Information structure for ACPI predefined names.
+ * Each entry in the table contains the following items:
+ *
+ * Name                 - The ACPI reserved name
+ * param_count          - Number of arguments to the method
+ * expected_return_btypes - Allowed type(s) for the return value
+ */
+struct acpi_name_info {
+       char name[ACPI_NAME_SIZE];
+       u8 param_count;
+       u8 expected_btypes;
+};
+
+/*
+ * Secondary information structures for ACPI predefined objects that return
+ * package objects. This structure appears as the next entry in the table
+ * after the NAME_INFO structure above.
+ *
+ * The reason for this is to minimize the size of the predefined name table.
+ */
+
+/*
+ * Used for ACPI_PTYPE1_FIXED, ACPI_PTYPE1_VAR, ACPI_PTYPE2,
+ * ACPI_PTYPE2_MIN, ACPI_PTYPE2_PKG_COUNT, ACPI_PTYPE2_COUNT
+ */
+struct acpi_package_info {
+       u8 type;
+       u8 object_type1;
+       u8 count1;
+       u8 object_type2;
+       u8 count2;
+       u8 reserved;
+};
+
+/* Used for ACPI_PTYPE2_FIXED */
+
+struct acpi_package_info2 {
+       u8 type;
+       u8 count;
+       u8 object_type[4];
+};
+
+/* Used for ACPI_PTYPE1_OPTION */
+
+struct acpi_package_info3 {
+       u8 type;
+       u8 count;
+       u8 object_type[2];
+       u8 tail_object_type;
+       u8 reserved;
+};
+
+union acpi_predefined_info {
+       struct acpi_name_info info;
+       struct acpi_package_info ret_info;
+       struct acpi_package_info2 ret_info2;
+       struct acpi_package_info3 ret_info3;
+};
+
+/*
+ * Bitmapped return value types
+ * Note: the actual data types must be contiguous, a loop in nspredef.c
+ * depends on this.
+ */
+#define ACPI_RTYPE_ANY                  0x00
+#define ACPI_RTYPE_NONE                 0x01
+#define ACPI_RTYPE_INTEGER              0x02
+#define ACPI_RTYPE_STRING               0x04
+#define ACPI_RTYPE_BUFFER               0x08
+#define ACPI_RTYPE_PACKAGE              0x10
+#define ACPI_RTYPE_REFERENCE            0x20
+#define ACPI_RTYPE_ALL                  0x3F
+
+#define ACPI_NUM_RTYPES                 5      /* Number of actual object types */
+
 /*****************************************************************************
  *
  * Event typedefs and structs
index 74a9617776a80f728b874ab47f58a5f124d00996..a597207e28352ab4de53a69d9d6eb8d29f6c0a28 100644 (file)
@@ -62,7 +62,7 @@
 #define ACPI_ARRAY_LENGTH(x)            (sizeof(x) / sizeof((x)[0]))
 
 /*
- * Extract data using a pointer.  Any more than a byte and we
+ * Extract data using a pointer. Any more than a byte and we
  * get into potential aligment issues -- see the STORE macros below.
  * Use with care.
  */
  */
 #define ACPI_CAST_PTR(t, p)             ((t *) (acpi_uintptr_t) (p))
 #define ACPI_CAST_INDIRECT_PTR(t, p)    ((t **) (acpi_uintptr_t) (p))
-#define ACPI_ADD_PTR(t, a, b)          ACPI_CAST_PTR (t, (ACPI_CAST_PTR (u8,(a)) + (acpi_size)(b)))
-#define ACPI_PTR_DIFF(a, b)            (acpi_size) (ACPI_CAST_PTR (u8,(a)) - ACPI_CAST_PTR (u8,(b)))
+#define ACPI_ADD_PTR(t, a, b)          ACPI_CAST_PTR (t, (ACPI_CAST_PTR (u8, (a)) + (acpi_size)(b)))
+#define ACPI_PTR_DIFF(a, b)            (acpi_size) (ACPI_CAST_PTR (u8, (a)) - ACPI_CAST_PTR (u8, (b)))
 
 /* Pointer/Integer type conversions */
 
 #define ACPI_TO_POINTER(i)             ACPI_ADD_PTR (void, (void *) NULL, (acpi_size) i)
-#define ACPI_TO_INTEGER(p)              ACPI_PTR_DIFF (p,(void *) NULL)
-#define ACPI_OFFSET(d,f)                (acpi_size) ACPI_PTR_DIFF (&(((d *)0)->f),(void *) NULL)
+#define ACPI_TO_INTEGER(p)              ACPI_PTR_DIFF (p, (void *) NULL)
+#define ACPI_OFFSET(d, f)               (acpi_size) ACPI_PTR_DIFF (&(((d *)0)->f), (void *) NULL)
 #define ACPI_PHYSADDR_TO_PTR(i)         ACPI_TO_POINTER(i)
 #define ACPI_PTR_TO_PHYSADDR(i)         ACPI_TO_INTEGER(i)
 
 #ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
-#define ACPI_COMPARE_NAME(a,b)          (*ACPI_CAST_PTR (u32,(a)) == *ACPI_CAST_PTR (u32,(b)))
+#define ACPI_COMPARE_NAME(a, b)         (*ACPI_CAST_PTR (u32, (a)) == *ACPI_CAST_PTR (u32, (b)))
 #else
-#define ACPI_COMPARE_NAME(a,b)          (!ACPI_STRNCMP (ACPI_CAST_PTR (char,(a)), ACPI_CAST_PTR (char,(b)), ACPI_NAME_SIZE))
+#define ACPI_COMPARE_NAME(a, b)         (!ACPI_STRNCMP (ACPI_CAST_PTR (char, (a)), ACPI_CAST_PTR (char, (b)), ACPI_NAME_SIZE))
 #endif
 
 /*
@@ -114,7 +114,7 @@ struct acpi_integer_overlay {
 
 /* Split 64-bit integer into two 32-bit values. Use with %8.8_x%8.8_x */
 
-#define ACPI_FORMAT_UINT64(i)           ACPI_HIDWORD(i),ACPI_LODWORD(i)
+#define ACPI_FORMAT_UINT64(i)           ACPI_HIDWORD(i), ACPI_LODWORD(i)
 
 #if ACPI_MACHINE_WIDTH == 64
 #define ACPI_FORMAT_NATIVE_UINT(i)      ACPI_FORMAT_UINT64(i)
@@ -132,37 +132,33 @@ struct acpi_integer_overlay {
  * Macros for big-endian machines
  */
 
-/* This macro sets a buffer index, starting from the end of the buffer */
-
-#define ACPI_BUFFER_INDEX(buf_len,buf_offset,byte_gran) ((buf_len) - (((buf_offset)+1) * (byte_gran)))
-
 /* These macros reverse the bytes during the move, converting little-endian to big endian */
 
                          /* Big Endian      <==        Little Endian */
                          /*  Hi...Lo                     Lo...Hi     */
 /* 16-bit source, 16/32/64 destination */
 
-#define ACPI_MOVE_16_TO_16(d,s)         {((  u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[1];\
+#define ACPI_MOVE_16_TO_16(d, s)        {((  u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[1];\
                                           ((  u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[0];}
 
-#define ACPI_MOVE_16_TO_32(d,s)         {(*(u32 *)(void *)(d))=0;\
+#define ACPI_MOVE_16_TO_32(d, s)        {(*(u32 *)(void *)(d))=0;\
                                                           ((u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[1];\
                                                           ((u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[0];}
 
-#define ACPI_MOVE_16_TO_64(d,s)         {(*(u64 *)(void *)(d))=0;\
+#define ACPI_MOVE_16_TO_64(d, s)        {(*(u64 *)(void *)(d))=0;\
                                                                         ((u8 *)(void *)(d))[6] = ((u8 *)(void *)(s))[1];\
                                                                         ((u8 *)(void *)(d))[7] = ((u8 *)(void *)(s))[0];}
 
 /* 32-bit source, 16/32/64 destination */
 
-#define ACPI_MOVE_32_TO_16(d,s)         ACPI_MOVE_16_TO_16(d,s)        /* Truncate to 16 */
+#define ACPI_MOVE_32_TO_16(d, s)        ACPI_MOVE_16_TO_16(d, s)       /* Truncate to 16 */
 
-#define ACPI_MOVE_32_TO_32(d,s)         {((  u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[3];\
+#define ACPI_MOVE_32_TO_32(d, s)        {((  u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[3];\
                                                                                 ((  u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[2];\
                                                                                 ((  u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[1];\
                                                                                 ((  u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[0];}
 
-#define ACPI_MOVE_32_TO_64(d,s)         {(*(u64 *)(void *)(d))=0;\
+#define ACPI_MOVE_32_TO_64(d, s)        {(*(u64 *)(void *)(d))=0;\
                                                                                   ((u8 *)(void *)(d))[4] = ((u8 *)(void *)(s))[3];\
                                                                                   ((u8 *)(void *)(d))[5] = ((u8 *)(void *)(s))[2];\
                                                                                   ((u8 *)(void *)(d))[6] = ((u8 *)(void *)(s))[1];\
@@ -170,11 +166,11 @@ struct acpi_integer_overlay {
 
 /* 64-bit source, 16/32/64 destination */
 
-#define ACPI_MOVE_64_TO_16(d,s)         ACPI_MOVE_16_TO_16(d,s)        /* Truncate to 16 */
+#define ACPI_MOVE_64_TO_16(d, s)        ACPI_MOVE_16_TO_16(d, s)       /* Truncate to 16 */
 
-#define ACPI_MOVE_64_TO_32(d,s)         ACPI_MOVE_32_TO_32(d,s)        /* Truncate to 32 */
+#define ACPI_MOVE_64_TO_32(d, s)        ACPI_MOVE_32_TO_32(d, s)       /* Truncate to 32 */
 
-#define ACPI_MOVE_64_TO_64(d,s)         {((  u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[7];\
+#define ACPI_MOVE_64_TO_64(d, s)        {((  u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[7];\
                                                                                 ((  u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[6];\
                                                                                 ((  u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[5];\
                                                                                 ((  u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[4];\
@@ -187,63 +183,59 @@ struct acpi_integer_overlay {
  * Macros for little-endian machines
  */
 
-/* This macro sets a buffer index, starting from the beginning of the buffer */
-
-#define ACPI_BUFFER_INDEX(buf_len,buf_offset,byte_gran) (buf_offset)
-
 #ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
 
 /* The hardware supports unaligned transfers, just do the little-endian move */
 
 /* 16-bit source, 16/32/64 destination */
 
-#define ACPI_MOVE_16_TO_16(d,s)         *(u16 *)(void *)(d) = *(u16 *)(void *)(s)
-#define ACPI_MOVE_16_TO_32(d,s)         *(u32 *)(void *)(d) = *(u16 *)(void *)(s)
-#define ACPI_MOVE_16_TO_64(d,s)         *(u64 *)(void *)(d) = *(u16 *)(void *)(s)
+#define ACPI_MOVE_16_TO_16(d, s)        *(u16 *)(void *)(d) = *(u16 *)(void *)(s)
+#define ACPI_MOVE_16_TO_32(d, s)        *(u32 *)(void *)(d) = *(u16 *)(void *)(s)
+#define ACPI_MOVE_16_TO_64(d, s)        *(u64 *)(void *)(d) = *(u16 *)(void *)(s)
 
 /* 32-bit source, 16/32/64 destination */
 
-#define ACPI_MOVE_32_TO_16(d,s)         ACPI_MOVE_16_TO_16(d,s)        /* Truncate to 16 */
-#define ACPI_MOVE_32_TO_32(d,s)         *(u32 *)(void *)(d) = *(u32 *)(void *)(s)
-#define ACPI_MOVE_32_TO_64(d,s)         *(u64 *)(void *)(d) = *(u32 *)(void *)(s)
+#define ACPI_MOVE_32_TO_16(d, s)        ACPI_MOVE_16_TO_16(d, s)       /* Truncate to 16 */
+#define ACPI_MOVE_32_TO_32(d, s)        *(u32 *)(void *)(d) = *(u32 *)(void *)(s)
+#define ACPI_MOVE_32_TO_64(d, s)        *(u64 *)(void *)(d) = *(u32 *)(void *)(s)
 
 /* 64-bit source, 16/32/64 destination */
 
-#define ACPI_MOVE_64_TO_16(d,s)         ACPI_MOVE_16_TO_16(d,s)        /* Truncate to 16 */
-#define ACPI_MOVE_64_TO_32(d,s)         ACPI_MOVE_32_TO_32(d,s)        /* Truncate to 32 */
-#define ACPI_MOVE_64_TO_64(d,s)         *(u64 *)(void *)(d) = *(u64 *)(void *)(s)
+#define ACPI_MOVE_64_TO_16(d, s)        ACPI_MOVE_16_TO_16(d, s)       /* Truncate to 16 */
+#define ACPI_MOVE_64_TO_32(d, s)        ACPI_MOVE_32_TO_32(d, s)       /* Truncate to 32 */
+#define ACPI_MOVE_64_TO_64(d, s)        *(u64 *)(void *)(d) = *(u64 *)(void *)(s)
 
 #else
 /*
- * The hardware does not support unaligned transfers.  We must move the
- * data one byte at a time.  These macros work whether the source or
+ * The hardware does not support unaligned transfers. We must move the
+ * data one byte at a time. These macros work whether the source or
  * the destination (or both) is/are unaligned.  (Little-endian move)
  */
 
 /* 16-bit source, 16/32/64 destination */
 
-#define ACPI_MOVE_16_TO_16(d,s)         {((  u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\
+#define ACPI_MOVE_16_TO_16(d, s)        {((  u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\
                                                                                 ((  u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1];}
 
-#define ACPI_MOVE_16_TO_32(d,s)         {(*(u32 *)(void *)(d)) = 0; ACPI_MOVE_16_TO_16(d,s);}
-#define ACPI_MOVE_16_TO_64(d,s)         {(*(u64 *)(void *)(d)) = 0; ACPI_MOVE_16_TO_16(d,s);}
+#define ACPI_MOVE_16_TO_32(d, s)        {(*(u32 *)(void *)(d)) = 0; ACPI_MOVE_16_TO_16(d, s);}
+#define ACPI_MOVE_16_TO_64(d, s)        {(*(u64 *)(void *)(d)) = 0; ACPI_MOVE_16_TO_16(d, s);}
 
 /* 32-bit source, 16/32/64 destination */
 
-#define ACPI_MOVE_32_TO_16(d,s)         ACPI_MOVE_16_TO_16(d,s)        /* Truncate to 16 */
+#define ACPI_MOVE_32_TO_16(d, s)        ACPI_MOVE_16_TO_16(d, s)       /* Truncate to 16 */
 
-#define ACPI_MOVE_32_TO_32(d,s)         {((  u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\
+#define ACPI_MOVE_32_TO_32(d, s)        {((  u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\
                                                                                 ((  u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1];\
                                                                                 ((  u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[2];\
                                                                                 ((  u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[3];}
 
-#define ACPI_MOVE_32_TO_64(d,s)         {(*(u64 *)(void *)(d)) = 0; ACPI_MOVE_32_TO_32(d,s);}
+#define ACPI_MOVE_32_TO_64(d, s)        {(*(u64 *)(void *)(d)) = 0; ACPI_MOVE_32_TO_32(d, s);}
 
 /* 64-bit source, 16/32/64 destination */
 
-#define ACPI_MOVE_64_TO_16(d,s)         ACPI_MOVE_16_TO_16(d,s)        /* Truncate to 16 */
-#define ACPI_MOVE_64_TO_32(d,s)         ACPI_MOVE_32_TO_32(d,s)        /* Truncate to 32 */
-#define ACPI_MOVE_64_TO_64(d,s)         {((  u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\
+#define ACPI_MOVE_64_TO_16(d, s)        ACPI_MOVE_16_TO_16(d, s)       /* Truncate to 16 */
+#define ACPI_MOVE_64_TO_32(d, s)        ACPI_MOVE_32_TO_32(d, s)       /* Truncate to 32 */
+#define ACPI_MOVE_64_TO_64(d, s)        {((  u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\
                                                                                 ((  u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1];\
                                                                                 ((  u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[2];\
                                                                                 ((  u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[3];\
@@ -257,10 +249,10 @@ struct acpi_integer_overlay {
 /* Macros based on machine integer width */
 
 #if ACPI_MACHINE_WIDTH == 32
-#define ACPI_MOVE_SIZE_TO_16(d,s)       ACPI_MOVE_32_TO_16(d,s)
+#define ACPI_MOVE_SIZE_TO_16(d, s)       ACPI_MOVE_32_TO_16(d, s)
 
 #elif ACPI_MACHINE_WIDTH == 64
-#define ACPI_MOVE_SIZE_TO_16(d,s)       ACPI_MOVE_64_TO_16(d,s)
+#define ACPI_MOVE_SIZE_TO_16(d, s)       ACPI_MOVE_64_TO_16(d, s)
 
 #else
 #error unknown ACPI_MACHINE_WIDTH
@@ -269,29 +261,29 @@ struct acpi_integer_overlay {
 /*
  * Fast power-of-two math macros for non-optimized compilers
  */
-#define _ACPI_DIV(value,power_of2)      ((u32) ((value) >> (power_of2)))
-#define _ACPI_MUL(value,power_of2)      ((u32) ((value) << (power_of2)))
-#define _ACPI_MOD(value,divisor)        ((u32) ((value) & ((divisor) -1)))
+#define _ACPI_DIV(value, power_of2)      ((u32) ((value) >> (power_of2)))
+#define _ACPI_MUL(value, power_of2)      ((u32) ((value) << (power_of2)))
+#define _ACPI_MOD(value, divisor)        ((u32) ((value) & ((divisor) -1)))
 
-#define ACPI_DIV_2(a)                   _ACPI_DIV(a,1)
-#define ACPI_MUL_2(a)                   _ACPI_MUL(a,1)
-#define ACPI_MOD_2(a)                   _ACPI_MOD(a,2)
+#define ACPI_DIV_2(a)                   _ACPI_DIV(a, 1)
+#define ACPI_MUL_2(a)                   _ACPI_MUL(a, 1)
+#define ACPI_MOD_2(a)                   _ACPI_MOD(a, 2)
 
-#define ACPI_DIV_4(a)                   _ACPI_DIV(a,2)
-#define ACPI_MUL_4(a)                   _ACPI_MUL(a,2)
-#define ACPI_MOD_4(a)                   _ACPI_MOD(a,4)
+#define ACPI_DIV_4(a)                   _ACPI_DIV(a, 2)
+#define ACPI_MUL_4(a)                   _ACPI_MUL(a, 2)
+#define ACPI_MOD_4(a)                   _ACPI_MOD(a, 4)
 
-#define ACPI_DIV_8(a)                   _ACPI_DIV(a,3)
-#define ACPI_MUL_8(a)                   _ACPI_MUL(a,3)
-#define ACPI_MOD_8(a)                   _ACPI_MOD(a,8)
+#define ACPI_DIV_8(a)                   _ACPI_DIV(a, 3)
+#define ACPI_MUL_8(a)                   _ACPI_MUL(a, 3)
+#define ACPI_MOD_8(a)                   _ACPI_MOD(a, 8)
 
-#define ACPI_DIV_16(a)                  _ACPI_DIV(a,4)
-#define ACPI_MUL_16(a)                  _ACPI_MUL(a,4)
-#define ACPI_MOD_16(a)                  _ACPI_MOD(a,16)
+#define ACPI_DIV_16(a)                  _ACPI_DIV(a, 4)
+#define ACPI_MUL_16(a)                  _ACPI_MUL(a, 4)
+#define ACPI_MOD_16(a)                  _ACPI_MOD(a, 16)
 
-#define ACPI_DIV_32(a)                  _ACPI_DIV(a,5)
-#define ACPI_MUL_32(a)                  _ACPI_MUL(a,5)
-#define ACPI_MOD_32(a)                  _ACPI_MOD(a,32)
+#define ACPI_DIV_32(a)                  _ACPI_DIV(a, 5)
+#define ACPI_MUL_32(a)                  _ACPI_MUL(a, 5)
+#define ACPI_MOD_32(a)                  _ACPI_MOD(a, 32)
 
 /*
  * Rounding macros (Power of two boundaries only)
@@ -305,13 +297,13 @@ struct acpi_integer_overlay {
 
 /* Note: sizeof(acpi_size) evaluates to either 4 or 8 (32- vs 64-bit mode) */
 
-#define ACPI_ROUND_DOWN_TO_32BIT(a)         ACPI_ROUND_DOWN(a,4)
-#define ACPI_ROUND_DOWN_TO_64BIT(a)         ACPI_ROUND_DOWN(a,8)
-#define ACPI_ROUND_DOWN_TO_NATIVE_WORD(a)   ACPI_ROUND_DOWN(a,sizeof(acpi_size))
+#define ACPI_ROUND_DOWN_TO_32BIT(a)         ACPI_ROUND_DOWN(a, 4)
+#define ACPI_ROUND_DOWN_TO_64BIT(a)         ACPI_ROUND_DOWN(a, 8)
+#define ACPI_ROUND_DOWN_TO_NATIVE_WORD(a)   ACPI_ROUND_DOWN(a, sizeof(acpi_size))
 
-#define ACPI_ROUND_UP_TO_32BIT(a)           ACPI_ROUND_UP(a,4)
-#define ACPI_ROUND_UP_TO_64BIT(a)           ACPI_ROUND_UP(a,8)
-#define ACPI_ROUND_UP_TO_NATIVE_WORD(a)     ACPI_ROUND_UP(a,sizeof(acpi_size))
+#define ACPI_ROUND_UP_TO_32BIT(a)           ACPI_ROUND_UP(a, 4)
+#define ACPI_ROUND_UP_TO_64BIT(a)           ACPI_ROUND_UP(a, 8)
+#define ACPI_ROUND_UP_TO_NATIVE_WORD(a)     ACPI_ROUND_UP(a, sizeof(acpi_size))
 
 #define ACPI_ROUND_BITS_UP_TO_BYTES(a)      ACPI_DIV_8((a) + 7)
 #define ACPI_ROUND_BITS_DOWN_TO_BYTES(a)    ACPI_DIV_8((a))
@@ -320,9 +312,9 @@ struct acpi_integer_overlay {
 
 /* Generic (non-power-of-two) rounding */
 
-#define ACPI_ROUND_UP_TO(value,boundary)    (((value) + ((boundary)-1)) / (boundary))
+#define ACPI_ROUND_UP_TO(value, boundary)   (((value) + ((boundary)-1)) / (boundary))
 
-#define ACPI_IS_MISALIGNED(value)          (((acpi_size)value) & (sizeof(acpi_size)-1))
+#define ACPI_IS_MISALIGNED(value)          (((acpi_size) value) & (sizeof(acpi_size)-1))
 
 /*
  * Bitmask creation
@@ -333,8 +325,6 @@ struct acpi_integer_overlay {
 #define ACPI_MASK_BITS_ABOVE(position)      (~((ACPI_INTEGER_MAX) << ((u32) (position))))
 #define ACPI_MASK_BITS_BELOW(position)      ((ACPI_INTEGER_MAX) << ((u32) (position)))
 
-#define ACPI_IS_OCTAL_DIGIT(d)              (((char)(d) >= '0') && ((char)(d) <= '7'))
-
 /* Bitfields within ACPI registers */
 
 #define ACPI_REGISTER_PREPARE_BITS(val, pos, mask)      ((val << pos) & mask)
@@ -342,39 +332,29 @@ struct acpi_integer_overlay {
 
 #define ACPI_INSERT_BITS(target, mask, source)          target = ((target & (~(mask))) | (source & mask))
 
-/* Generate a UUID */
-
-#define ACPI_INIT_UUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
-       (a) & 0xFF, ((a) >> 8) & 0xFF, ((a) >> 16) & 0xFF, ((a) >> 24) & 0xFF, \
-       (b) & 0xFF, ((b) >> 8) & 0xFF, \
-       (c) & 0xFF, ((c) >> 8) & 0xFF, \
-       (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7)
-
 /*
- * An struct acpi_namespace_node * can appear in some contexts,
- * where a pointer to an union acpi_operand_object    can also
- * appear.  This macro is used to distinguish them.
+ * An struct acpi_namespace_node can appear in some contexts
+ * where a pointer to an union acpi_operand_object can also
+ * appear. This macro is used to distinguish them.
  *
  * The "Descriptor" field is the first field in both structures.
  */
 #define ACPI_GET_DESCRIPTOR_TYPE(d)     (((union acpi_descriptor *)(void *)(d))->common.descriptor_type)
-#define ACPI_SET_DESCRIPTOR_TYPE(d,t)   (((union acpi_descriptor *)(void *)(d))->common.descriptor_type = t)
+#define ACPI_SET_DESCRIPTOR_TYPE(d, t)  (((union acpi_descriptor *)(void *)(d))->common.descriptor_type = t)
 
 /* Macro to test the object type */
 
 #define ACPI_GET_OBJECT_TYPE(d)         (((union acpi_operand_object *)(void *)(d))->common.type)
 
-/* Macro to check the table flags for SINGLE or MULTIPLE tables are allowed */
-
-#define ACPI_IS_SINGLE_TABLE(x)         (((x) & 0x01) == ACPI_TABLE_SINGLE ? 1 : 0)
-
 /*
  * Macros for the master AML opcode table
  */
-#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUG_OUTPUT)
-#define ACPI_OP(name,Pargs,Iargs,obj_type,class,type,flags)    {name,(u32)(Pargs),(u32)(Iargs),(u32)(flags),obj_type,class,type}
+#if defined (ACPI_DISASSEMBLER) || defined (ACPI_DEBUG_OUTPUT)
+#define ACPI_OP(name, Pargs, Iargs, obj_type, class, type, flags) \
+       {name, (u32)(Pargs), (u32)(Iargs), (u32)(flags), obj_type, class, type}
 #else
-#define ACPI_OP(name,Pargs,Iargs,obj_type,class,type,flags)    {(u32)(Pargs),(u32)(Iargs),(u32)(flags),obj_type,class,type}
+#define ACPI_OP(name, Pargs, Iargs, obj_type, class, type, flags) \
+       {(u32)(Pargs), (u32)(Iargs), (u32)(flags), obj_type, class, type}
 #endif
 
 #ifdef ACPI_DISASSEMBLER
@@ -392,18 +372,18 @@ struct acpi_integer_overlay {
 #define ARG_6(x)                        ((u32)(x) << (5 * ARG_TYPE_WIDTH))
 
 #define ARGI_LIST1(a)                   (ARG_1(a))
-#define ARGI_LIST2(a,b)                 (ARG_1(b)|ARG_2(a))
-#define ARGI_LIST3(a,b,c)               (ARG_1(c)|ARG_2(b)|ARG_3(a))
-#define ARGI_LIST4(a,b,c,d)             (ARG_1(d)|ARG_2(c)|ARG_3(b)|ARG_4(a))
-#define ARGI_LIST5(a,b,c,d,e)           (ARG_1(e)|ARG_2(d)|ARG_3(c)|ARG_4(b)|ARG_5(a))
-#define ARGI_LIST6(a,b,c,d,e,f)         (ARG_1(f)|ARG_2(e)|ARG_3(d)|ARG_4(c)|ARG_5(b)|ARG_6(a))
+#define ARGI_LIST2(a, b)                (ARG_1(b)|ARG_2(a))
+#define ARGI_LIST3(a, b, c)             (ARG_1(c)|ARG_2(b)|ARG_3(a))
+#define ARGI_LIST4(a, b, c, d)          (ARG_1(d)|ARG_2(c)|ARG_3(b)|ARG_4(a))
+#define ARGI_LIST5(a, b, c, d, e)       (ARG_1(e)|ARG_2(d)|ARG_3(c)|ARG_4(b)|ARG_5(a))
+#define ARGI_LIST6(a, b, c, d, e, f)    (ARG_1(f)|ARG_2(e)|ARG_3(d)|ARG_4(c)|ARG_5(b)|ARG_6(a))
 
 #define ARGP_LIST1(a)                   (ARG_1(a))
-#define ARGP_LIST2(a,b)                 (ARG_1(a)|ARG_2(b))
-#define ARGP_LIST3(a,b,c)               (ARG_1(a)|ARG_2(b)|ARG_3(c))
-#define ARGP_LIST4(a,b,c,d)             (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d))
-#define ARGP_LIST5(a,b,c,d,e)           (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e))
-#define ARGP_LIST6(a,b,c,d,e,f)         (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)|ARG_6(f))
+#define ARGP_LIST2(a, b)                (ARG_1(a)|ARG_2(b))
+#define ARGP_LIST3(a, b, c)             (ARG_1(a)|ARG_2(b)|ARG_3(c))
+#define ARGP_LIST4(a, b, c, d)          (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d))
+#define ARGP_LIST5(a, b, c, d, e)       (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e))
+#define ARGP_LIST6(a, b, c, d, e, f)    (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)|ARG_6(f))
 
 #define GET_CURRENT_ARG_TYPE(list)      (list & ((u32) 0x1F))
 #define INCREMENT_ARG_LIST(list)        (list >>= ((u32) ARG_TYPE_WIDTH))
@@ -434,8 +414,8 @@ struct acpi_integer_overlay {
 #define ACPI_WARNING(plist)             acpi_ut_warning plist
 #define ACPI_EXCEPTION(plist)           acpi_ut_exception plist
 #define ACPI_ERROR(plist)               acpi_ut_error plist
-#define ACPI_ERROR_NAMESPACE(s,e)       acpi_ns_report_error (AE_INFO, s, e);
-#define ACPI_ERROR_METHOD(s,n,p,e)      acpi_ns_report_method_error (AE_INFO, s, n, p, e);
+#define ACPI_ERROR_NAMESPACE(s, e)      acpi_ns_report_error (AE_INFO, s, e);
+#define ACPI_ERROR_METHOD(s, n, p, e)   acpi_ns_report_method_error (AE_INFO, s, n, p, e);
 
 #else
 
@@ -445,8 +425,8 @@ struct acpi_integer_overlay {
 #define ACPI_WARNING(plist)
 #define ACPI_EXCEPTION(plist)
 #define ACPI_ERROR(plist)
-#define ACPI_ERROR_NAMESPACE(s,e)
-#define ACPI_ERROR_METHOD(s,n,p,e)
+#define ACPI_ERROR_NAMESPACE(s, e)
+#define ACPI_ERROR_METHOD(s, n, p, e)
 #endif
 
 /*
@@ -489,18 +469,18 @@ struct acpi_integer_overlay {
 
 #define ACPI_FUNCTION_TRACE(a)          ACPI_FUNCTION_NAME(a) \
                          acpi_ut_trace(ACPI_DEBUG_PARAMETERS)
-#define ACPI_FUNCTION_TRACE_PTR(a,b)    ACPI_FUNCTION_NAME(a) \
-                                          acpi_ut_trace_ptr(ACPI_DEBUG_PARAMETERS,(void *)b)
-#define ACPI_FUNCTION_TRACE_U32(a,b)    ACPI_FUNCTION_NAME(a) \
-                                                        acpi_ut_trace_u32(ACPI_DEBUG_PARAMETERS,(u32)b)
-#define ACPI_FUNCTION_TRACE_STR(a,b)    ACPI_FUNCTION_NAME(a) \
-                                                                         acpi_ut_trace_str(ACPI_DEBUG_PARAMETERS,(char *)b)
+#define ACPI_FUNCTION_TRACE_PTR(a, b)   ACPI_FUNCTION_NAME(a) \
+                                          acpi_ut_trace_ptr(ACPI_DEBUG_PARAMETERS, (void *)b)
+#define ACPI_FUNCTION_TRACE_U32(a, b)   ACPI_FUNCTION_NAME(a) \
+                                                        acpi_ut_trace_u32(ACPI_DEBUG_PARAMETERS, (u32)b)
+#define ACPI_FUNCTION_TRACE_STR(a, b)   ACPI_FUNCTION_NAME(a) \
+                                                                         acpi_ut_trace_str(ACPI_DEBUG_PARAMETERS, (char *)b)
 
 #define ACPI_FUNCTION_ENTRY()           acpi_ut_track_stack_ptr()
 
 /*
  * Function exit tracing.
- * WARNING: These macros include a return statement.  This is usually considered
+ * WARNING: These macros include a return statement. This is usually considered
  * bad form, but having a separate exit macro is very ugly and difficult to maintain.
  * One of the FUNCTION_TRACE macros above must be used in conjunction with these macros
  * so that "_AcpiFunctionName" is defined.
@@ -596,13 +576,13 @@ struct acpi_integer_overlay {
 
 /* Stack and buffer dumping */
 
-#define ACPI_DUMP_STACK_ENTRY(a)        acpi_ex_dump_operand((a),0)
-#define ACPI_DUMP_OPERANDS(a,b,c)      acpi_ex_dump_operands(a,b,c)
+#define ACPI_DUMP_STACK_ENTRY(a)        acpi_ex_dump_operand((a), 0)
+#define ACPI_DUMP_OPERANDS(a, b, c)    acpi_ex_dump_operands(a, b, c)
 
-#define ACPI_DUMP_ENTRY(a,b)            acpi_ns_dump_entry (a,b)
-#define ACPI_DUMP_PATHNAME(a,b,c,d)     acpi_ns_dump_pathname(a,b,c,d)
+#define ACPI_DUMP_ENTRY(a, b)           acpi_ns_dump_entry (a, b)
+#define ACPI_DUMP_PATHNAME(a, b, c, d)  acpi_ns_dump_pathname(a, b, c, d)
 #define ACPI_DUMP_RESOURCE_LIST(a)      acpi_rs_dump_resource_list(a)
-#define ACPI_DUMP_BUFFER(a,b)           acpi_ut_dump_buffer((u8 *)a,b,DB_BYTE_DISPLAY,_COMPONENT)
+#define ACPI_DUMP_BUFFER(a, b)          acpi_ut_dump_buffer((u8 *) a, b, DB_BYTE_DISPLAY, _COMPONENT)
 
 /*
  * Master debug print macros
@@ -625,20 +605,20 @@ struct acpi_integer_overlay {
 #define ACPI_DEBUG_ONLY_MEMBERS(a)     do { } while(0)
 #define ACPI_FUNCTION_NAME(a)          do { } while(0)
 #define ACPI_FUNCTION_TRACE(a)         do { } while(0)
-#define ACPI_FUNCTION_TRACE_PTR(a,b)   do { } while(0)
-#define ACPI_FUNCTION_TRACE_U32(a,b)   do { } while(0)
-#define ACPI_FUNCTION_TRACE_STR(a,b)   do { } while(0)
+#define ACPI_FUNCTION_TRACE_PTR(a, b)  do { } while(0)
+#define ACPI_FUNCTION_TRACE_U32(a, b)  do { } while(0)
+#define ACPI_FUNCTION_TRACE_STR(a, b)  do { } while(0)
 #define ACPI_FUNCTION_EXIT             do { } while(0)
 #define ACPI_FUNCTION_STATUS_EXIT(s)   do { } while(0)
 #define ACPI_FUNCTION_VALUE_EXIT(s)    do { } while(0)
 #define ACPI_FUNCTION_ENTRY()          do { } while(0)
 #define ACPI_DUMP_STACK_ENTRY(a)       do { } while(0)
-#define ACPI_DUMP_OPERANDS(a,b,c)      do { } while(0)
-#define ACPI_DUMP_ENTRY(a,b)           do { } while(0)
-#define ACPI_DUMP_TABLES(a,b)          do { } while(0)
-#define ACPI_DUMP_PATHNAME(a,b,c,d)    do { } while(0)
+#define ACPI_DUMP_OPERANDS(a, b, c)     do { } while(0)
+#define ACPI_DUMP_ENTRY(a, b)          do { } while(0)
+#define ACPI_DUMP_TABLES(a, b)         do { } while(0)
+#define ACPI_DUMP_PATHNAME(a, b, c, d) do { } while(0)
 #define ACPI_DUMP_RESOURCE_LIST(a)     do { } while(0)
-#define ACPI_DUMP_BUFFER(a,b)          do { } while(0)
+#define ACPI_DUMP_BUFFER(a, b)         do { } while(0)
 #define ACPI_DEBUG_PRINT(pl)           do { } while(0)
 #define ACPI_DEBUG_PRINT_RAW(pl)       do { } while(0)
 
@@ -677,15 +657,17 @@ struct acpi_integer_overlay {
 /*
  * Memory allocation tracking (DEBUG ONLY)
  */
+#define ACPI_MEM_PARAMETERS         _COMPONENT, _acpi_module_name, __LINE__
+
 #ifndef ACPI_DBG_TRACK_ALLOCATIONS
 
 /* Memory allocation */
 
 #ifndef ACPI_ALLOCATE
-#define ACPI_ALLOCATE(a)            acpi_ut_allocate((acpi_size)(a),_COMPONENT,_acpi_module_name,__LINE__)
+#define ACPI_ALLOCATE(a)            acpi_ut_allocate((acpi_size)(a), ACPI_MEM_PARAMETERS)
 #endif
 #ifndef ACPI_ALLOCATE_ZEROED
-#define ACPI_ALLOCATE_ZEROED(a)     acpi_ut_allocate_zeroed((acpi_size)(a), _COMPONENT,_acpi_module_name,__LINE__)
+#define ACPI_ALLOCATE_ZEROED(a)     acpi_ut_allocate_zeroed((acpi_size)(a), ACPI_MEM_PARAMETERS)
 #endif
 #ifndef ACPI_FREE
 #define ACPI_FREE(a)                acpio_os_free(a)
@@ -696,11 +678,16 @@ struct acpi_integer_overlay {
 
 /* Memory allocation */
 
-#define ACPI_ALLOCATE(a)            acpi_ut_allocate_and_track((acpi_size)(a),_COMPONENT,_acpi_module_name,__LINE__)
-#define ACPI_ALLOCATE_ZEROED(a)     acpi_ut_allocate_zeroed_and_track((acpi_size)(a), _COMPONENT,_acpi_module_name,__LINE__)
-#define ACPI_FREE(a)                acpi_ut_free_and_track(a,_COMPONENT,_acpi_module_name,__LINE__)
+#define ACPI_ALLOCATE(a)            acpi_ut_allocate_and_track((acpi_size)(a), ACPI_MEM_PARAMETERS)
+#define ACPI_ALLOCATE_ZEROED(a)     acpi_ut_allocate_zeroed_and_track((acpi_size)(a), ACPI_MEM_PARAMETERS)
+#define ACPI_FREE(a)                acpi_ut_free_and_track(a, ACPI_MEM_PARAMETERS)
 #define ACPI_MEM_TRACKING(a)        a
 
 #endif                         /* ACPI_DBG_TRACK_ALLOCATIONS */
 
+/* Preemption point */
+#ifndef ACPI_PREEMPTION_POINT
+#define ACPI_PREEMPTION_POINT() /* no preemption */
+#endif
+
 #endif                         /* ACMACROS_H */
index c34008507b69f463e8dceeee8325cc7abbe6bf08..db4e6f677855293c1533c142ea575ce1a1306b00 100644 (file)
@@ -177,6 +177,22 @@ acpi_ns_dump_objects(acpi_object_type type,
  */
 acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info);
 
+/*
+ * nspredef - Support for predefined/reserved names
+ */
+acpi_status
+acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
+                              union acpi_operand_object *return_object);
+
+const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct
+                                                                   acpi_namespace_node
+                                                                   *node);
+
+void
+acpi_ns_check_parameter_count(char *pathname,
+                             struct acpi_namespace_node *node,
+                             const union acpi_predefined_info *info);
+
 /*
  * nsnames - Name and Scope manipulation
  */
index e9657dac69b788b6ed391efc4e838c5338f67889..eb6f038b03d9f23d8479fe1a2caa40bab2ee2cb3 100644 (file)
@@ -308,18 +308,34 @@ struct acpi_object_addr_handler {
  *****************************************************************************/
 
 /*
- * The Reference object type is used for these opcodes:
- * Arg[0-6], Local[0-7], index_op, name_op, zero_op, one_op, ones_op, debug_op
+ * The Reference object is used for these opcodes:
+ * Arg[0-6], Local[0-7], index_op, name_op, ref_of_op, load_op, load_table_op, debug_op
+ * The Reference.Class differentiates these types.
  */
 struct acpi_object_reference {
-       ACPI_OBJECT_COMMON_HEADER u8 target_type;       /* Used for index_op */
-       u16 opcode;
+       ACPI_OBJECT_COMMON_HEADER u8 class;     /* Reference Class */
+       u8 target_type;         /* Used for Index Op */
+       u8 reserved;
        void *object;           /* name_op=>HANDLE to obj, index_op=>union acpi_operand_object */
-       struct acpi_namespace_node *node;
-       union acpi_operand_object **where;
-       u32 offset;             /* Used for arg_op, local_op, and index_op */
+       struct acpi_namespace_node *node;       /* ref_of or Namepath */
+       union acpi_operand_object **where;      /* Target of Index */
+       u32 value;              /* Used for Local/Arg/Index/ddb_handle */
 };
 
+/* Values for Reference.Class above */
+
+typedef enum {
+       ACPI_REFCLASS_LOCAL = 0,        /* Method local */
+       ACPI_REFCLASS_ARG = 1,  /* Method argument */
+       ACPI_REFCLASS_REFOF = 2,        /* Result of ref_of() TBD: Split to Ref/Node and Ref/operand_obj? */
+       ACPI_REFCLASS_INDEX = 3,        /* Result of Index() */
+       ACPI_REFCLASS_TABLE = 4,        /* ddb_handle - Load(), load_table() */
+       ACPI_REFCLASS_NAME = 5, /* Reference to a named object */
+       ACPI_REFCLASS_DEBUG = 6,        /* Debug object */
+
+       ACPI_REFCLASS_MAX = 6
+} ACPI_REFERENCE_CLASSES;
+
 /*
  * Extra object is used as additional storage for types that
  * have AML code in their declarations (term_args) that must be
@@ -379,6 +395,13 @@ union acpi_operand_object {
        struct acpi_object_extra extra;
        struct acpi_object_data data;
        struct acpi_object_cache_list cache;
+
+       /*
+        * Add namespace node to union in order to simplify code that accepts both
+        * ACPI_OPERAND_OBJECTs and ACPI_NAMESPACE_NODEs. The structures share
+        * a common descriptor_type field in order to differentiate them.
+        */
+       struct acpi_namespace_node node;
 };
 
 /******************************************************************************
index e17873defcec4fbc9ccf2548b95b9631f7e2e508..09d33c7740f0bfbf48f195c57bb209a03297baf4 100644 (file)
 /*
  * Raw debug output levels, do not use these in the DEBUG_PRINT macros
  */
-#define ACPI_LV_ERROR               0x00000001
-#define ACPI_LV_WARN                0x00000002
-#define ACPI_LV_INIT                0x00000004
-#define ACPI_LV_DEBUG_OBJECT        0x00000008
-#define ACPI_LV_INFO                0x00000010
-#define ACPI_LV_ALL_EXCEPTIONS      0x0000001F
+#define ACPI_LV_INIT                0x00000001
+#define ACPI_LV_DEBUG_OBJECT        0x00000002
+#define ACPI_LV_INFO                0x00000004
+#define ACPI_LV_ALL_EXCEPTIONS      0x00000007
 
 /* Trace verbosity level 1 [Standard Trace Level] */
 
 #define ACPI_LV_VERBOSE_INFO        0x20000000
 #define ACPI_LV_FULL_TABLES         0x40000000
 #define ACPI_LV_EVENTS              0x80000000
-
 #define ACPI_LV_VERBOSE             0xF0000000
 
 /*
  */
 #define ACPI_DEBUG_LEVEL(dl)        (u32) dl,ACPI_DEBUG_PARAMETERS
 
-/* Exception level -- used in the global "DebugLevel" */
-
+/*
+ * Exception level -- used in the global "DebugLevel"
+ *
+ * Note: For errors, use the ACPI_ERROR or ACPI_EXCEPTION interfaces.
+ * For warnings, use ACPI_WARNING.
+ */
 #define ACPI_DB_INIT                ACPI_DEBUG_LEVEL (ACPI_LV_INIT)
 #define ACPI_DB_DEBUG_OBJECT        ACPI_DEBUG_LEVEL (ACPI_LV_DEBUG_OBJECT)
 #define ACPI_DB_INFO                ACPI_DEBUG_LEVEL (ACPI_LV_INFO)
 #define ACPI_DB_ALL_EXCEPTIONS      ACPI_DEBUG_LEVEL (ACPI_LV_ALL_EXCEPTIONS)
 
-/*
- * These two levels are essentially obsolete, all instances in the
- * ACPICA core code have been replaced by ACPI_ERROR and ACPI_WARNING
- * (Kept here because some drivers may still use them)
- */
-#define ACPI_DB_ERROR               ACPI_DEBUG_LEVEL (ACPI_LV_ERROR)
-#define ACPI_DB_WARN                ACPI_DEBUG_LEVEL (ACPI_LV_WARN)
-
 /* Trace level -- also used in the global "DebugLevel" */
 
 #define ACPI_DB_INIT_NAMES          ACPI_DEBUG_LEVEL (ACPI_LV_INIT_NAMES)
 #define ACPI_DB_USER_REQUESTS       ACPI_DEBUG_LEVEL (ACPI_LV_USER_REQUESTS)
 #define ACPI_DB_PACKAGE             ACPI_DEBUG_LEVEL (ACPI_LV_PACKAGE)
 #define ACPI_DB_MUTEX               ACPI_DEBUG_LEVEL (ACPI_LV_MUTEX)
+#define ACPI_DB_EVENTS              ACPI_DEBUG_LEVEL (ACPI_LV_EVENTS)
 
 #define ACPI_DB_ALL                 ACPI_DEBUG_LEVEL (ACPI_LV_ALL)
 
 /* Defaults for debug_level, debug and normal */
 
-#define ACPI_DEBUG_DEFAULT          (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR)
-#define ACPI_NORMAL_DEFAULT         (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR)
+#define ACPI_DEBUG_DEFAULT          (ACPI_LV_INIT | ACPI_LV_DEBUG_OBJECT)
+#define ACPI_NORMAL_DEFAULT         (ACPI_LV_INIT | ACPI_LV_DEBUG_OBJECT)
 #define ACPI_DEBUG_ALL              (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL)
 
 #endif                         /* __ACOUTPUT_H__ */
index a5ac0bc7f52eb1cc1849fb29afda135fb9dda6c1..54a279e44c9a4eb42dc0e83c836cfcc275d79c73 100644 (file)
@@ -46,7 +46,7 @@ acpi_extract_package(union acpi_object *package,
 acpi_status
 acpi_evaluate_integer(acpi_handle handle,
                      acpi_string pathname,
-                     struct acpi_object_list *arguments, unsigned long *data);
+                     struct acpi_object_list *arguments, unsigned long long *data);
 acpi_status
 acpi_evaluate_reference(acpi_handle handle,
                        acpi_string pathname,
@@ -300,7 +300,11 @@ struct acpi_device {
        enum acpi_bus_removal_type removal_type;        /* indicate for different removal type */
 };
 
-#define acpi_driver_data(d)    ((d)->driver_data)
+static inline void *acpi_driver_data(struct acpi_device *d)
+{
+       return d->driver_data;
+}
+
 #define to_acpi_device(d)      container_of(d, struct acpi_device, dev)
 #define to_acpi_driver(d)      container_of(d, struct acpi_driver, drv)
 
@@ -327,6 +331,9 @@ int acpi_bus_get_private_data(acpi_handle, void **);
 extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32);
 extern int register_acpi_notifier(struct notifier_block *);
 extern int unregister_acpi_notifier(struct notifier_block *);
+
+extern int register_acpi_bus_notifier(struct notifier_block *nb);
+extern void unregister_acpi_bus_notifier(struct notifier_block *nb);
 /*
  * External Functions
  */
index e5f38e5ce86fc5a4e28ec624e529ee1db59c16c0..cf04c6011c2acadf4624a7a39f06fd66668383f4 100644 (file)
@@ -93,6 +93,7 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state);
 int acpi_disable_wakeup_device_power(struct acpi_device *dev);
 int acpi_power_get_inferred_state(struct acpi_device *device);
 int acpi_power_transition(struct acpi_device *device, int state);
+extern int acpi_power_nocheck;
 #endif
 
 /* --------------------------------------------------------------------------
@@ -100,6 +101,7 @@ int acpi_power_transition(struct acpi_device *device, int state);
    -------------------------------------------------------------------------- */
 #ifdef CONFIG_ACPI_EC
 int acpi_ec_ecdt_probe(void);
+int acpi_boot_ec_enable(void);
 #endif
 
 /* --------------------------------------------------------------------------
@@ -115,12 +117,17 @@ int acpi_processor_set_thermal_limit(acpi_handle handle, int type);
 /*--------------------------------------------------------------------------
                                   Dock Station
   -------------------------------------------------------------------------- */
+struct acpi_dock_ops {
+       acpi_notify_handler handler;
+       acpi_notify_handler uevent;
+};
+
 #if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE)
 extern int is_dock_device(acpi_handle handle);
 extern int register_dock_notifier(struct notifier_block *nb);
 extern void unregister_dock_notifier(struct notifier_block *nb);
 extern int register_hotplug_dock_device(acpi_handle handle,
-                                       acpi_notify_handler handler,
+                                       struct acpi_dock_ops *ops,
                                        void *context);
 extern void unregister_hotplug_dock_device(acpi_handle handle);
 #else
@@ -136,7 +143,7 @@ static inline void unregister_dock_notifier(struct notifier_block *nb)
 {
 }
 static inline int register_hotplug_dock_device(acpi_handle handle,
-                                              acpi_notify_handler handler,
+                                              struct acpi_dock_ops *ops,
                                               void *context)
 {
        return -ENODEV;
index 3f93a6b4e17fe61ccd6735dd84a78b89edc8dc0d..b91440ac0d168e0865d0e5e4156d1e7fe8356958 100644 (file)
@@ -193,6 +193,9 @@ acpi_status
 acpi_os_execute(acpi_execute_type type,
                acpi_osd_exec_callback function, void *context);
 
+acpi_status
+acpi_os_hotplug_execute(acpi_osd_exec_callback function, void *context);
+
 void acpi_os_wait_events_complete(void *context);
 
 void acpi_os_sleep(acpi_integer milliseconds);
diff --git a/include/acpi/acpredef.h b/include/acpi/acpredef.h
new file mode 100644 (file)
index 0000000..619fb75
--- /dev/null
@@ -0,0 +1,371 @@
+/******************************************************************************
+ *
+ * Name: acpredef - Information table for ACPI predefined methods and objects
+ *              $Revision: 1.1 $
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2008, Intel Corp.
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * 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 MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ */
+
+#ifndef __ACPREDEF_H__
+#define __ACPREDEF_H__
+
+/******************************************************************************
+ *
+ * Return Package types
+ *
+ * 1) PTYPE1 packages do not contain sub-packages.
+ *
+ * ACPI_PTYPE1_FIXED: Fixed length, 1 or 2 object types:
+ *     object type
+ *     count
+ *     object type
+ *     count
+ *
+ * ACPI_PTYPE1_VAR: Variable length:
+ *    object type (Int/Buf/Ref)
+ *
+ * ACPI_PTYPE1_OPTION: Package has some required and some optional elements:
+ *      Used for _PRW
+ *
+ *
+ * 2) PTYPE2 packages contain a variable number of sub-packages. Each of the
+ *    different types describe the contents of each of the sub-packages.
+ *
+ * ACPI_PTYPE2: Each subpackage contains 1 or 2 object types:
+ *     object type
+ *     count
+ *     object type
+ *     count
+ *
+ * ACPI_PTYPE2_COUNT: Each subpackage has a count as first element:
+ *     object type
+ *
+ * ACPI_PTYPE2_PKG_COUNT: Count of subpackages at start, 1 or 2 object types:
+ *     object type
+ *     count
+ *     object type
+ *     count
+ *
+ * ACPI_PTYPE2_FIXED: Each subpackage is of fixed length:
+ *      Used for _PRT
+ *
+ * ACPI_PTYPE2_MIN: Each subpackage has a variable but minimum length
+ *      Used for _HPX
+ *
+ *****************************************************************************/
+
+enum acpi_return_package_types {
+       ACPI_PTYPE1_FIXED = 1,
+       ACPI_PTYPE1_VAR = 2,
+       ACPI_PTYPE1_OPTION = 3,
+       ACPI_PTYPE2 = 4,
+       ACPI_PTYPE2_COUNT = 5,
+       ACPI_PTYPE2_PKG_COUNT = 6,
+       ACPI_PTYPE2_FIXED = 7,
+       ACPI_PTYPE2_MIN = 8
+};
+
+/*
+ * Predefined method/object information table.
+ *
+ * These are the names that can actually be evaluated via acpi_evaluate_object.
+ * Not present in this table are the following:
+ *
+ *      1) Predefined/Reserved names that are never evaluated via acpi_evaluate_object:
+ *          _Lxx and _Exx GPE methods
+ *          _Qxx EC methods
+ *          _T_x compiler temporary variables
+ *
+ *      2) Predefined names that never actually exist within the AML code:
+ *          Predefined resource descriptor field names
+ *
+ *      3) Predefined names that are implemented within ACPICA:
+ *          _OSI
+ *
+ *      4) Some predefined names that are not documented within the ACPI spec.
+ *          _WDG, _WED
+ *
+ * The main entries in the table each contain the following items:
+ *
+ * Name                 - The ACPI reserved name
+ * param_count          - Number of arguments to the method
+ * expected_btypes      - Allowed type(s) for the return value.
+ *                        0 means that no return value is expected.
+ *
+ * For methods that return packages, the next entry in the table contains
+ * information about the expected structure of the package. This information
+ * is saved here (rather than in a separate table) in order to minimize the
+ * overall size of the stored data.
+ */
+static const union acpi_predefined_info predefined_names[] = {
+       {.info = {"_AC0", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_AC1", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_AC2", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_AC3", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_AC4", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_AC5", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_AC6", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_AC7", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_AC8", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_AC9", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_ADR", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_AL0", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}},   /* variable (Refs) */
+       {.info = {"_AL1", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}},   /* variable (Refs) */
+       {.info = {"_AL2", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}},   /* variable (Refs) */
+       {.info = {"_AL3", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}},   /* variable (Refs) */
+       {.info = {"_AL4", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}},   /* variable (Refs) */
+       {.info = {"_AL5", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}},   /* variable (Refs) */
+       {.info = {"_AL6", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}},   /* variable (Refs) */
+       {.info = {"_AL7", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}},   /* variable (Refs) */
+       {.info = {"_AL8", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}},   /* variable (Refs) */
+       {.info = {"_AL9", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}},   /* variable (Refs) */
+       {.info = {"_ALC", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_ALI", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_ALP", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_ALR", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 2, 0, 0, 0}}, /* variable (Pkgs) each 2 (Ints) */
+       {.info = {"_ALT", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_BBN", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_BCL", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0, 0, 0, 0}},     /* variable (Ints) */
+       {.info = {"_BCM", 1, 0}},
+       {.info = {"_BDN", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_BFS", 1, 0}},
+       {.info = {"_BIF", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER,
+                                         9,
+                                         ACPI_RTYPE_STRING, 4, 0}},    /* fixed (9 Int),(4 Str) */
+       {.info = {"_BLT", 3, 0}},
+       {.info = {"_BMC", 1, 0}},
+       {.info = {"_BMD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 5, 0, 0, 0}},   /* fixed (5 Int) */
+       {.info = {"_BQC", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_BST", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4, 0, 0, 0}},   /* fixed (4 Int) */
+       {.info = {"_BTM", 1, ACPI_RTYPE_INTEGER}},
+       {.info = {"_BTP", 1, 0}},
+       {.info = {"_CBA", 0, ACPI_RTYPE_INTEGER}},      /* see PCI firmware spec 3.0 */
+       {.info = {"_CID", 0,
+        ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_PACKAGE}},
+       {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING, 0, 0, 0, 0}},    /* variable (Ints/Strs) */
+       {.info = {"_CRS", 0, ACPI_RTYPE_BUFFER}},
+       {.info = {"_CRT", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_CSD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER, 0, 0, 0, 0}},   /* variable (1 Int(n), n-1 Int) */
+       {.info = {"_CST", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_PKG_COUNT,
+                                         ACPI_RTYPE_BUFFER, 1,
+                                         ACPI_RTYPE_INTEGER, 3, 0}},   /* variable (1 Int(n), n Pkg (1 Buf/3 Int) */
+       {.info = {"_DCK", 1, ACPI_RTYPE_INTEGER}},
+       {.info = {"_DCS", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_DDC", 1, ACPI_RTYPE_INTEGER | ACPI_RTYPE_BUFFER}},
+       {.info = {"_DDN", 0, ACPI_RTYPE_STRING}},
+       {.info = {"_DGS", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_DIS", 0, 0}},
+       {.info = {"_DMA", 0, ACPI_RTYPE_BUFFER}},
+       {.info = {"_DOD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0, 0, 0, 0}},     /* variable (Ints) */
+       {.info = {"_DOS", 1, 0}},
+       {.info = {"_DSM", 4, ACPI_RTYPE_ALL}},  /* Must return a type, but it can be of any type */
+       {.info = {"_DSS", 1, 0}},
+       {.info = {"_DSW", 3, 0}},
+       {.info = {"_EC_", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_EDL", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}},   /* variable (Refs) */
+       {.info = {"_EJ0", 1, 0}},
+       {.info = {"_EJ1", 1, 0}},
+       {.info = {"_EJ2", 1, 0}},
+       {.info = {"_EJ3", 1, 0}},
+       {.info = {"_EJ4", 1, 0}},
+       {.info = {"_EJD", 0, ACPI_RTYPE_STRING}},
+       {.info = {"_FDE", 0, ACPI_RTYPE_BUFFER}},
+       {.info = {"_FDI", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16, 0, 0, 0}},  /* fixed (16 Int) */
+       {.info = {"_FDM", 1, 0}},
+       {.info = {"_FIX", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0, 0, 0, 0}},     /* variable (Ints) */
+       {.info = {"_GLK", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_GPD", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_GPE", 0, ACPI_RTYPE_INTEGER}},      /* _GPE method, not _GPE scope */
+       {.info = {"_GSB", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_GTF", 0, ACPI_RTYPE_BUFFER}},
+       {.info = {"_GTM", 0, ACPI_RTYPE_BUFFER}},
+       {.info = {"_GTS", 1, 0}},
+       {.info = {"_HID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING}},
+       {.info = {"_HOT", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_HPP", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4, 0, 0, 0}},   /* fixed (4 Int) */
+
+       /*
+        * For _HPX, a single package is returned, containing a variable number of sub-packages.
+        * Each sub-package contains a PCI record setting. There are several different type of
+        * record settings, of different lengths, but all elements of all settings are Integers.
+        */
+       {.info = {"_HPX", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_MIN, ACPI_RTYPE_INTEGER, 5, 0, 0, 0}},     /* variable (Pkgs) each (var Ints) */
+       {.info = {"_IFT", 0, ACPI_RTYPE_INTEGER}},      /* see IPMI spec */
+       {.info = {"_INI", 0, 0}},
+       {.info = {"_IRC", 0, 0}},
+       {.info = {"_LCK", 1, 0}},
+       {.info = {"_LID", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_MAT", 0, ACPI_RTYPE_BUFFER}},
+       {.info = {"_MLS", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2, ACPI_RTYPE_STRING, 2, 0, 0, 0}},  /* variable (Pkgs) each (2 Str) */
+       {.info = {"_MSG", 1, 0}},
+       {.info = {"_OFF", 0, 0}},
+       {.info = {"_ON_", 0, 0}},
+       {.info = {"_OS_", 0, ACPI_RTYPE_STRING}},
+       {.info = {"_OSC", 4, ACPI_RTYPE_BUFFER}},
+       {.info = {"_OST", 3, 0}},
+       {.info = {"_PCL", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}},   /* variable (Refs) */
+       {.info = {"_PCT", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER, 2, 0, 0, 0}},    /* fixed (2 Buf) */
+       {.info = {"_PDC", 1, 0}},
+       {.info = {"_PIC", 1, 0}},
+       {.info = {"_PLD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_BUFFER, 0, 0, 0, 0}},      /* variable (Bufs) */
+       {.info = {"_PPC", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_PPE", 0, ACPI_RTYPE_INTEGER}},      /* see dig64 spec */
+       {.info = {"_PR0", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}},   /* variable (Refs) */
+       {.info = {"_PR1", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}},   /* variable (Refs) */
+       {.info = {"_PR2", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}},   /* variable (Refs) */
+       {.info = {"_PRS", 0, ACPI_RTYPE_BUFFER}},
+
+       /*
+        * For _PRT, many BIOSs reverse the 2nd and 3rd Package elements. This bug is so prevalent that there
+        * is code in the ACPICA Resource Manager to detect this and switch them back. For now, do not allow
+        * and issue a warning. To allow this and eliminate the warning, add the ACPI_RTYPE_REFERENCE
+        * type to the 2nd element (index 1) in the statement below.
+        */
+       {.info = {"_PRT", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_FIXED, 4,
+                                         ACPI_RTYPE_INTEGER,
+                                         ACPI_RTYPE_INTEGER,
+                                         ACPI_RTYPE_INTEGER | ACPI_RTYPE_REFERENCE, ACPI_RTYPE_INTEGER}},      /* variable (Pkgs) each (4): Int,Int,Int/Ref,Int */
+
+       {.info = {"_PRW", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_OPTION, 2,
+                                         ACPI_RTYPE_INTEGER |
+                                         ACPI_RTYPE_PACKAGE,
+                                         ACPI_RTYPE_INTEGER, ACPI_RTYPE_REFERENCE, 0}},        /* variable (Pkgs) each: Pkg/Int,Int,[variable Refs] (Pkg is Ref/Int) */
+
+       {.info = {"_PS0", 0, 0}},
+       {.info = {"_PS1", 0, 0}},
+       {.info = {"_PS2", 0, 0}},
+       {.info = {"_PS3", 0, 0}},
+       {.info = {"_PSC", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_PSD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER, 0, 0, 0, 0}},   /* variable (Pkgs) each (5 Int) with count */
+       {.info = {"_PSL", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}},   /* variable (Refs) */
+       {.info = {"_PSR", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_PSS", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 6, 0, 0, 0}}, /* variable (Pkgs) each (6 Int) */
+       {.info = {"_PSV", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_PSW", 1, 0}},
+       {.info = {"_PTC", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER, 2, 0, 0, 0}},    /* fixed (2 Buf) */
+       {.info = {"_PTS", 1, 0}},
+       {.info = {"_PXM", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_REG", 2, 0}},
+       {.info = {"_REV", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_RMV", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_ROM", 2, ACPI_RTYPE_BUFFER}},
+       {.info = {"_RTV", 0, ACPI_RTYPE_INTEGER}},
+
+       /*
+        * For _S0_ through _S5_, the ACPI spec defines a return Package containing 1 Integer,
+        * but most DSDTs have it wrong - 2,3, or 4 integers. Allow this by making the objects "variable length",
+        * but all elements must be Integers.
+        */
+       {.info = {"_S0_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}},     /* fixed (1 Int) */
+       {.info = {"_S1_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}},     /* fixed (1 Int) */
+       {.info = {"_S2_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}},     /* fixed (1 Int) */
+       {.info = {"_S3_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}},     /* fixed (1 Int) */
+       {.info = {"_S4_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}},     /* fixed (1 Int) */
+       {.info = {"_S5_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}},     /* fixed (1 Int) */
+
+       {.info = {"_S1D", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_S2D", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_S3D", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_S4D", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_S0W", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_S1W", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_S2W", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_S3W", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_S4W", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_SBS", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_SCP", 0x13, 0}},    /* Acpi 1.0 allowed 1 arg. Acpi 3.0 expanded to 3 args. Allow both. */
+       /* Note: the 3-arg definition may be removed for ACPI 4.0 */
+       {.info = {"_SDD", 1, 0}},
+       {.info = {"_SEG", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_SLI", 0, ACPI_RTYPE_BUFFER}},
+       {.info = {"_SPD", 1, ACPI_RTYPE_INTEGER}},
+       {.info = {"_SRS", 1, 0}},
+       {.info = {"_SRV", 0, ACPI_RTYPE_INTEGER}},      /* see IPMI spec */
+       {.info = {"_SST", 1, 0}},
+       {.info = {"_STA", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_STM", 3, 0}},
+       {.info = {"_STR", 0, ACPI_RTYPE_BUFFER}},
+       {.info = {"_SUN", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_SWS", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_TC1", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_TC2", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_TMP", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_TPC", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_TPT", 1, 0}},
+       {.info = {"_TRT", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2, ACPI_RTYPE_REFERENCE, 2,
+                                         ACPI_RTYPE_INTEGER, 6, 0}},   /* variable (Pkgs) each 2_ref/6_int */
+       {.info = {"_TSD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER, 5, 0, 0, 0}},   /* variable (Pkgs) each 5_int with count */
+       {.info = {"_TSP", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_TSS", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 5, 0, 0, 0}}, /* variable (Pkgs) each 5_int */
+       {.info = {"_TST", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_TTS", 1, 0}},
+       {.info = {"_TZD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}},   /* variable (Refs) */
+       {.info = {"_TZM", 0, ACPI_RTYPE_REFERENCE}},
+       {.info = {"_TZP", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_UID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING}},
+       {.info = {"_UPC", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4, 0, 0, 0}},   /* fixed (4 Int) */
+       {.info = {"_UPD", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_UPP", 0, ACPI_RTYPE_INTEGER}},
+       {.info = {"_VPO", 0, ACPI_RTYPE_INTEGER}},
+
+       /* Acpi 1.0 defined _WAK with no return value. Later, it was changed to return a package */
+
+       {.info = {"_WAK", 1, ACPI_RTYPE_NONE | ACPI_RTYPE_PACKAGE}},
+       {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2, 0, 0, 0}},      /* fixed (2 Int), but is optional */
+       {.ret_info = {0, 0, 0, 0, 0, 0}}        /* Table terminator */
+};
+
+#if 0
+       /* Not implemented */
+
+{
+"_WDG", 0, ACPI_RTYPE_BUFFER}, /* MS Extension */
+
+{
+"_WED", 1, ACPI_RTYPE_PACKAGE},        /* MS Extension */
+
+    /* This is an internally implemented control method, no need to check */
+{
+"_OSI", 1, ACPI_RTYPE_INTEGER},
+
+    /* TBD: */
+    _PRT - currently ignore reversed entries.attempt to fix here ?
+    think about code that attempts to fix package elements like _BIF, etc.
+#endif
+#endif
index d38f9be2f6eeda77b42f48e492060ed6a9f3000b..63f5b4cf4de1e06c9075164ad65cea947b77ed94 100644 (file)
@@ -908,7 +908,9 @@ enum acpi_madt_type {
        ACPI_MADT_TYPE_IO_SAPIC = 6,
        ACPI_MADT_TYPE_LOCAL_SAPIC = 7,
        ACPI_MADT_TYPE_INTERRUPT_SOURCE = 8,
-       ACPI_MADT_TYPE_RESERVED = 9     /* 9 and greater are reserved */
+       ACPI_MADT_TYPE_LOCAL_X2APIC = 9,
+       ACPI_MADT_TYPE_LOCAL_X2APIC_NMI = 10,
+       ACPI_MADT_TYPE_RESERVED = 11    /* 11 and greater are reserved */
 };
 
 /*
@@ -1009,6 +1011,26 @@ struct acpi_madt_interrupt_source {
 
 #define ACPI_MADT_CPEI_OVERRIDE     (1)
 
+/* 9: Processor Local X2_APIC (07/2008) */
+
+struct acpi_madt_local_x2apic {
+       struct acpi_subtable_header header;
+       u16 reserved;           /* Reserved - must be zero */
+       u32 local_apic_id;      /* Processor X2_APIC ID  */
+       u32 lapic_flags;
+       u32 uid;                /* Extended X2_APIC processor ID */
+};
+
+/* 10: Local X2APIC NMI (07/2008) */
+
+struct acpi_madt_local_x2apic_nmi {
+       struct acpi_subtable_header header;
+       u16 inti_flags;
+       u32 uid;                /* Processor X2_APIC ID */
+       u8 lint;                /* LINTn to which NMI is connected */
+       u8 reserved[3];
+};
+
 /*
  * Common flags fields for MADT subtables
  */
@@ -1150,10 +1172,15 @@ struct acpi_table_srat {
 enum acpi_srat_type {
        ACPI_SRAT_TYPE_CPU_AFFINITY = 0,
        ACPI_SRAT_TYPE_MEMORY_AFFINITY = 1,
-       ACPI_SRAT_TYPE_RESERVED = 2
+       ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY = 2,
+       ACPI_SRAT_TYPE_RESERVED = 3     /* 3 and greater are reserved */
 };
 
-/* SRAT sub-tables */
+/*
+ * SRAT Sub-tables, correspond to Type in struct acpi_subtable_header
+ */
+
+/* 0: Processor Local APIC/SAPIC Affinity */
 
 struct acpi_srat_cpu_affinity {
        struct acpi_subtable_header header;
@@ -1165,9 +1192,7 @@ struct acpi_srat_cpu_affinity {
        u32 reserved;           /* Reserved, must be zero */
 };
 
-/* Flags */
-
-#define ACPI_SRAT_CPU_ENABLED       (1)        /* 00: Use affinity structure */
+/* 1: Memory Affinity */
 
 struct acpi_srat_mem_affinity {
        struct acpi_subtable_header header;
@@ -1186,6 +1211,20 @@ struct acpi_srat_mem_affinity {
 #define ACPI_SRAT_MEM_HOT_PLUGGABLE (1<<1)     /* 01: Memory region is hot pluggable */
 #define ACPI_SRAT_MEM_NON_VOLATILE  (1<<2)     /* 02: Memory region is non-volatile */
 
+/* 2: Processor Local X2_APIC Affinity (07/2008) */
+
+struct acpi_srat_x2apic_cpu_affinity {
+       struct acpi_subtable_header header;
+       u16 reserved;           /* Reserved, must be zero */
+       u32 proximity_domain;
+       u32 apic_id;
+       u32 flags;
+};
+
+/* Flags for struct acpi_srat_cpu_affinity and struct acpi_srat_x2apic_cpu_affinity */
+
+#define ACPI_SRAT_CPU_ENABLED       (1)        /* 00: Use affinity structure */
+
 /*******************************************************************************
  *
  * TCPA - Trusted Computing Platform Alliance table
index 4ea4f40bf894c22e0a1f99b745bd503e6a996f24..e8936ab596277e26e1047dc8c3e2ceeb3b465427 100644 (file)
@@ -607,8 +607,15 @@ typedef u8 acpi_adr_space_type;
 
 /*
  * bit_register IDs
- * These are bitfields defined within the full ACPI registers
+ *
+ * These values are intended to be used by the hardware interfaces
+ * and are mapped to individual bitfields defined within the ACPI
+ * registers. See the acpi_gbl_bit_register_info global table in utglobal.c
+ * for this mapping.
  */
+
+/* PM1 Status register */
+
 #define ACPI_BITREG_TIMER_STATUS                0x00
 #define ACPI_BITREG_BUS_MASTER_STATUS           0x01
 #define ACPI_BITREG_GLOBAL_LOCK_STATUS          0x02
@@ -618,24 +625,29 @@ typedef u8 acpi_adr_space_type;
 #define ACPI_BITREG_WAKE_STATUS                 0x06
 #define ACPI_BITREG_PCIEXP_WAKE_STATUS          0x07
 
+/* PM1 Enable register */
+
 #define ACPI_BITREG_TIMER_ENABLE                0x08
 #define ACPI_BITREG_GLOBAL_LOCK_ENABLE          0x09
 #define ACPI_BITREG_POWER_BUTTON_ENABLE         0x0A
 #define ACPI_BITREG_SLEEP_BUTTON_ENABLE         0x0B
 #define ACPI_BITREG_RT_CLOCK_ENABLE             0x0C
-#define ACPI_BITREG_WAKE_ENABLE                 0x0D
-#define ACPI_BITREG_PCIEXP_WAKE_DISABLE         0x0E
+#define ACPI_BITREG_PCIEXP_WAKE_DISABLE         0x0D
+
+/* PM1 Control register */
+
+#define ACPI_BITREG_SCI_ENABLE                  0x0E
+#define ACPI_BITREG_BUS_MASTER_RLD              0x0F
+#define ACPI_BITREG_GLOBAL_LOCK_RELEASE         0x10
+#define ACPI_BITREG_SLEEP_TYPE_A                0x11
+#define ACPI_BITREG_SLEEP_TYPE_B                0x12
+#define ACPI_BITREG_SLEEP_ENABLE                0x13
 
-#define ACPI_BITREG_SCI_ENABLE                  0x0F
-#define ACPI_BITREG_BUS_MASTER_RLD              0x10
-#define ACPI_BITREG_GLOBAL_LOCK_RELEASE         0x11
-#define ACPI_BITREG_SLEEP_TYPE_A                0x12
-#define ACPI_BITREG_SLEEP_TYPE_B                0x13
-#define ACPI_BITREG_SLEEP_ENABLE                0x14
+/* PM2 Control register */
 
-#define ACPI_BITREG_ARB_DISABLE                 0x15
+#define ACPI_BITREG_ARB_DISABLE                 0x14
 
-#define ACPI_BITREG_MAX                         0x15
+#define ACPI_BITREG_MAX                         0x14
 #define ACPI_NUM_BITREG                         ACPI_BITREG_MAX + 1
 
 /*
@@ -859,6 +871,7 @@ struct acpi_obj_info_header {
 struct acpi_device_info {
        ACPI_COMMON_OBJ_INFO;
 
+       u32 param_count;        /* If a method, required parameter count */
        u32 valid;              /* Indicates which fields below are valid */
        u32 current_status;     /* _STA value */
        acpi_integer address;   /* _ADR value if any */
@@ -1225,8 +1238,8 @@ struct acpi_resource {
 
 #pragma pack()
 
-#define ACPI_RS_SIZE_MIN                    12
 #define ACPI_RS_SIZE_NO_DATA                8  /* Id + Length fields */
+#define ACPI_RS_SIZE_MIN                    (u32) ACPI_ROUND_UP_TO_NATIVE_WORD (12)
 #define ACPI_RS_SIZE(type)                  (u32) (ACPI_RS_SIZE_NO_DATA + sizeof (type))
 
 #define ACPI_NEXT_RESOURCE(res)             (struct acpi_resource *)((u8 *) res + res->length)
index 69f8888771fffa6cdf532117ac31bc14eb5997ff..d8307b2987e371b706ac7e0c96359606fb5cd900 100644 (file)
@@ -110,7 +110,7 @@ struct acpi_pkg_info {
 /*
  * utglobal - Global data structures and procedures
  */
-void acpi_ut_init_globals(void);
+acpi_status acpi_ut_init_globals(void);
 
 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
 
@@ -126,6 +126,8 @@ char *acpi_ut_get_node_name(void *object);
 
 char *acpi_ut_get_descriptor_name(void *object);
 
+const char *acpi_ut_get_reference_name(union acpi_operand_object *object);
+
 char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc);
 
 char *acpi_ut_get_region_name(u8 space_id);
index 9af4645986829bbf00ea5b77d3aeae2f818763ed..029c8c06c151ab4f7153d4aeb143bb51ed4d258c 100644 (file)
@@ -53,6 +53,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/ctype.h>
+#include <linux/sched.h>
 #include <asm/system.h>
 #include <asm/atomic.h>
 #include <asm/div64.h>
@@ -137,4 +138,9 @@ static inline void *acpi_os_acquire_object(acpi_cache_t * cache)
 #define ACPI_ALLOCATE_ZEROED(a)        acpi_os_allocate_zeroed(a)
 #define ACPI_FREE(a)           kfree(a)
 
+/*
+ * We need to show where it is safe to preempt execution of ACPICA
+ */
+#define ACPI_PREEMPTION_POINT()        cond_resched()
+
 #endif                         /* __ACLINUX_H__ */
index 7ebcc56a22291edb6388332d16f84686c1542e61..361076611855ad1fb1afac6c5cc2aeb2454720cb 100644 (file)
 #include <asm/io.h>
 #include <asm/irq.h>
 
-/****************************************************************************/
-/*
- * some bits needed for parts of the IDE subsystem to compile
- */
-#define __ide_mm_insw(port, addr, n)   insw((unsigned long) (port), addr, n)
-#define __ide_mm_insl(port, addr, n)   insl((unsigned long) (port), addr, n)
-#define __ide_mm_outsw(port, addr, n)  outsw((unsigned long) (port), addr, n)
-#define __ide_mm_outsl(port, addr, n)  outsl((unsigned long) (port), addr, n)
-
+#include <asm-generic/ide_iops.h>
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_IDE_H */
index 0f6dabd4b5175488081fc8395a30b9a5d5e5f217..12c07c1866b2072f9c2529829c27dac5077c96a3 100644 (file)
@@ -41,7 +41,7 @@ extern void warn_slowpath(const char *file, const int line,
 #define __WARN() warn_on_slowpath(__FILE__, __LINE__)
 #define __WARN_printf(arg...) warn_slowpath(__FILE__, __LINE__, arg)
 #else
-#define __WARN_printf(arg...) __WARN()
+#define __WARN_printf(arg...) do { printk(arg); __WARN(); } while (0)
 #endif
 
 #ifndef WARN_ON
index ed108be6743fcaaca05c2f312f66bdca825abd9e..f104af7cf4375f045af902af4315834ae41460c2 100644 (file)
@@ -22,8 +22,6 @@ __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
 {
        if (unlikely(atomic_dec_return(count) < 0))
                fail_fn(count);
-       else
-               smp_mb();
 }
 
 /**
@@ -41,10 +39,7 @@ __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
 {
        if (unlikely(atomic_dec_return(count) < 0))
                return fail_fn(count);
-       else {
-               smp_mb();
-               return 0;
-       }
+       return 0;
 }
 
 /**
@@ -63,7 +58,6 @@ __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
 static inline void
 __mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
 {
-       smp_mb();
        if (unlikely(atomic_inc_return(count) <= 0))
                fail_fn(count);
 }
@@ -88,25 +82,9 @@ __mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
 static inline int
 __mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
 {
-       /*
-        * We have two variants here. The cmpxchg based one is the best one
-        * because it never induce a false contention state.  It is included
-        * here because architectures using the inc/dec algorithms over the
-        * xchg ones are much more likely to support cmpxchg natively.
-        *
-        * If not we fall back to the spinlock based variant - that is
-        * just as efficient (and simpler) as a 'destructive' probing of
-        * the mutex state would be.
-        */
-#ifdef __HAVE_ARCH_CMPXCHG
-       if (likely(atomic_cmpxchg(count, 1, 0) == 1)) {
-               smp_mb();
+       if (likely(atomic_cmpxchg(count, 1, 0) == 1))
                return 1;
-       }
        return 0;
-#else
-       return fail_fn(count);
-#endif
 }
 
 #endif
index 7b9cd2cbfebe527cffbea01df889465b039c91be..580a6d35c70078bd91bff6619860b5159b7130b2 100644 (file)
@@ -27,8 +27,6 @@ __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
 {
        if (unlikely(atomic_xchg(count, 0) != 1))
                fail_fn(count);
-       else
-               smp_mb();
 }
 
 /**
@@ -46,10 +44,7 @@ __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
 {
        if (unlikely(atomic_xchg(count, 0) != 1))
                return fail_fn(count);
-       else {
-               smp_mb();
-               return 0;
-       }
+       return 0;
 }
 
 /**
@@ -67,7 +62,6 @@ __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
 static inline void
 __mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
 {
-       smp_mb();
        if (unlikely(atomic_xchg(count, 1) != 0))
                fail_fn(count);
 }
@@ -110,7 +104,6 @@ __mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
                if (prev < 0)
                        prev = 0;
        }
-       smp_mb();
 
        return prev;
 }
index 74c5faf26c053a137768d5f4224d466945bc3253..80744606bad172b57d2ab52dc01bb0bf33af293e 100644 (file)
 #define MEM_DISCARD(sec) *(.mem##sec)
 #endif
 
+#ifdef CONFIG_FTRACE_MCOUNT_RECORD
+#define MCOUNT_REC()   VMLINUX_SYMBOL(__start_mcount_loc) = .; \
+                       *(__mcount_loc)                         \
+                       VMLINUX_SYMBOL(__stop_mcount_loc) = .;
+#else
+#define MCOUNT_REC()
+#endif
 
 /* .data section */
 #define DATA_DATA                                                      \
        . = ALIGN(8);                                                   \
        VMLINUX_SYMBOL(__start___markers) = .;                          \
        *(__markers)                                                    \
-       VMLINUX_SYMBOL(__stop___markers) = .;
+       VMLINUX_SYMBOL(__stop___markers) = .;                           \
+       VMLINUX_SYMBOL(__start___tracepoints) = .;                      \
+       *(__tracepoints)                                                \
+       VMLINUX_SYMBOL(__stop___tracepoints) = .;
 
 #define RO_DATA(align)                                                 \
        . = ALIGN((align));                                             \
@@ -61,6 +71,7 @@
                *(.rodata) *(.rodata.*)                                 \
                *(__vermagic)           /* Kernel version magic */      \
                *(__markers_strings)    /* Markers: strings */          \
+               *(__tracepoints_strings)/* Tracepoints: strings */      \
        }                                                               \
                                                                        \
        .rodata1          : AT(ADDR(.rodata1) - LOAD_OFFSET) {          \
        /* __*init sections */                                          \
        __init_rodata : AT(ADDR(__init_rodata) - LOAD_OFFSET) {         \
                *(.ref.rodata)                                          \
+               MCOUNT_REC()                                            \
                DEV_KEEP(init.rodata)                                   \
                DEV_KEEP(exit.rodata)                                   \
                CPU_KEEP(init.rodata)                                   \
index 1daf6cbdd9f0de3d9b3ae515dd939e887b7dd1e7..b996a3c8cff54ae4a4857c1a5b955af6b6a391d4 100644 (file)
 #define outsw_swapw(port, addr, n)     raw_outsw_swapw((u16 *)port, addr, n)
 #endif
 
-
-/* Q40 and Atari have byteswapped IDE busses and since many interesting
- * values in the identification string are text, chars and words they
- * happened to be almost correct without swapping.. However *_capacity
- * is needed for drives over 8 GB. RZ */
-#if defined(CONFIG_Q40) || defined(CONFIG_ATARI)
-#define M68K_IDE_SWAPW  (MACH_IS_Q40 || MACH_IS_ATARI)
-#endif
-
 #ifdef CONFIG_BLK_DEV_FALCON_IDE
 #define IDE_ARCH_LOCK
 
index 26d2b91209c5e9f701341865300b0a9cccf2a952..5637dcef314ec2c85ba65f98d8013d117486ed1b 100644 (file)
@@ -14,7 +14,7 @@ extern void (*mach_sched_init) (irq_handler_t handler);
 /* machine dependent irq functions */
 extern void (*mach_init_IRQ) (void);
 extern void (*mach_get_model) (char *model);
-extern int (*mach_get_hardware_list) (char *buffer);
+extern void (*mach_get_hardware_list) (struct seq_file *m);
 /* machine dependent timer functions */
 extern unsigned long (*mach_gettimeoffset)(void);
 extern int (*mach_hwclk)(int, struct rtc_time*);
diff --git a/include/asm-um/a.out.h b/include/asm-um/a.out.h
deleted file mode 100644 (file)
index 754181e..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- * Licensed under the GPL
- */
-
-#ifndef __UM_A_OUT_H
-#define __UM_A_OUT_H
-
-#include "asm/arch/a.out.h"
-
-#endif
diff --git a/include/asm-um/alternative-asm.h b/include/asm-um/alternative-asm.h
deleted file mode 100644 (file)
index 9aa9fa2..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_ALTERNATIVE_ASM_I
-#define __UM_ALTERNATIVE_ASM_I
-
-#include "asm/arch/alternative-asm.h"
-
-#endif
diff --git a/include/asm-um/alternative.h b/include/asm-um/alternative.h
deleted file mode 100644 (file)
index b643439..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_ALTERNATIVE_H
-#define __UM_ALTERNATIVE_H
-
-#include "asm/arch/alternative.h"
-
-#endif
diff --git a/include/asm-um/asm.h b/include/asm-um/asm.h
deleted file mode 100644 (file)
index af1269a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_ASM_H
-#define __UM_ASM_H
-
-#include "asm/arch/asm.h"
-
-#endif
diff --git a/include/asm-um/atomic.h b/include/asm-um/atomic.h
deleted file mode 100644 (file)
index b683f10..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef __UM_ATOMIC_H
-#define __UM_ATOMIC_H
-
-/* The i386 atomic.h calls printk, but doesn't include kernel.h, so we
- * include it here.
- */
-#include "linux/kernel.h"
-
-#include "asm/arch/atomic.h"
-
-#endif
diff --git a/include/asm-um/bitops.h b/include/asm-um/bitops.h
deleted file mode 100644 (file)
index e4d38d4..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __UM_BITOPS_H
-#define __UM_BITOPS_H
-
-#ifndef _LINUX_BITOPS_H
-#error only <linux/bitops.h> can be included directly
-#endif
-
-#include "asm/arch/bitops.h"
-
-#endif
diff --git a/include/asm-um/boot.h b/include/asm-um/boot.h
deleted file mode 100644 (file)
index 09548c3..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_BOOT_H
-#define __UM_BOOT_H
-
-#include "asm/arch/boot.h"
-
-#endif
diff --git a/include/asm-um/bug.h b/include/asm-um/bug.h
deleted file mode 100644 (file)
index 9e33b86..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_BUG_H
-#define __UM_BUG_H
-
-#include <asm-generic/bug.h>
-
-#endif
diff --git a/include/asm-um/byteorder.h b/include/asm-um/byteorder.h
deleted file mode 100644 (file)
index eee0a83..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_BYTEORDER_H
-#define __UM_BYTEORDER_H
-
-#include "asm/arch/byteorder.h"
-
-#endif
diff --git a/include/asm-um/cacheflush.h b/include/asm-um/cacheflush.h
deleted file mode 100644 (file)
index 12e9d4b..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_CACHEFLUSH_H
-#define __UM_CACHEFLUSH_H
-
-#include "asm/arch/cacheflush.h"
-
-#endif
diff --git a/include/asm-um/calling.h b/include/asm-um/calling.h
deleted file mode 100644 (file)
index 0b2384c..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright 2003 - 2004 Pathscale, Inc
-# Released under the GPL
-
-#ifndef __UM_CALLING_H /* XXX x86_64 */
-#define __UM_CALLING_H
-
-#include "asm/arch/calling.h"
-
-#endif
diff --git a/include/asm-um/cmpxchg.h b/include/asm-um/cmpxchg.h
deleted file mode 100644 (file)
index 529376a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_CMPXCHG_H
-#define __UM_CMPXCHG_H
-
-#include "asm/arch/cmpxchg.h"
-
-#endif
diff --git a/include/asm-um/cobalt.h b/include/asm-um/cobalt.h
deleted file mode 100644 (file)
index f813a68..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_COBALT_H
-#define __UM_COBALT_H
-
-#include "asm/arch/cobalt.h"
-
-#endif
diff --git a/include/asm-um/cpufeature.h b/include/asm-um/cpufeature.h
deleted file mode 100644 (file)
index fb7bd42..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_CPUFEATURE_H
-#define __UM_CPUFEATURE_H
-
-#include "asm/arch/cpufeature.h"
-
-#endif
diff --git a/include/asm-um/div64.h b/include/asm-um/div64.h
deleted file mode 100644 (file)
index 1e17f74..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _UM_DIV64_H
-#define _UM_DIV64_H
-
-#include "asm/arch/div64.h"
-
-#endif
diff --git a/include/asm-um/dwarf2.h b/include/asm-um/dwarf2.h
deleted file mode 100644 (file)
index d1a02e7..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/* Copyright 2003 - 2004 Pathscale, Inc
- * Released under the GPL
- */
-
-/* Needed on x86_64 by thunk.S */
-#ifndef __UM_DWARF2_H
-#define __UM_DWARF2_H
-
-#include "asm/arch/dwarf2.h"
-
-#endif
diff --git a/include/asm-um/errno.h b/include/asm-um/errno.h
deleted file mode 100644 (file)
index b7a9e37..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_ERRNO_H
-#define __UM_ERRNO_H
-
-#include "asm/arch/errno.h"
-
-#endif
diff --git a/include/asm-um/fcntl.h b/include/asm-um/fcntl.h
deleted file mode 100644 (file)
index 812a654..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_FCNTL_H
-#define __UM_FCNTL_H
-
-#include "asm/arch/fcntl.h"
-
-#endif
diff --git a/include/asm-um/floppy.h b/include/asm-um/floppy.h
deleted file mode 100644 (file)
index 453e741..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_FLOPPY_H
-#define __UM_FLOPPY_H
-
-#include "asm/arch/floppy.h"
-
-#endif
diff --git a/include/asm-um/frame.h b/include/asm-um/frame.h
deleted file mode 100644 (file)
index 8a8c1cb..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_FRAME_I
-#define __UM_FRAME_I
-
-#include "asm/arch/frame.h"
-
-#endif
diff --git a/include/asm-um/highmem.h b/include/asm-um/highmem.h
deleted file mode 100644 (file)
index 36974cb..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef __UM_HIGHMEM_H
-#define __UM_HIGHMEM_H
-
-#include "asm/page.h"
-#include "asm/fixmap.h"
-#include "asm/arch/highmem.h"
-
-#undef PKMAP_BASE
-
-#define PKMAP_BASE ((FIXADDR_START - LAST_PKMAP * PAGE_SIZE) & PMD_MASK)
-
-#endif
diff --git a/include/asm-um/ide.h b/include/asm-um/ide.h
deleted file mode 100644 (file)
index 3d1cceb..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_IDE_H
-#define __UM_IDE_H
-
-#include "asm/arch/ide.h"
-
-#endif
diff --git a/include/asm-um/ioctl.h b/include/asm-um/ioctl.h
deleted file mode 100644 (file)
index cc22157..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_IOCTL_H
-#define __UM_IOCTL_H
-
-#include "asm/arch/ioctl.h"
-
-#endif
diff --git a/include/asm-um/ioctls.h b/include/asm-um/ioctls.h
deleted file mode 100644 (file)
index 9a1a017..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_IOCTLS_H
-#define __UM_IOCTLS_H
-
-#include "asm/arch/ioctls.h"
-
-#endif
diff --git a/include/asm-um/ipcbuf.h b/include/asm-um/ipcbuf.h
deleted file mode 100644 (file)
index bb2ad31..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_IPCBUF_H
-#define __UM_IPCBUF_H
-
-#include "asm/arch/ipcbuf.h"
-
-#endif
diff --git a/include/asm-um/linkage.h b/include/asm-um/linkage.h
deleted file mode 100644 (file)
index 7dfce37..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __ASM_UM_LINKAGE_H
-#define __ASM_UM_LINKAGE_H
-
-#include "asm/arch/linkage.h"
-
-#endif
diff --git a/include/asm-um/local.h b/include/asm-um/local.h
deleted file mode 100644 (file)
index 9a280c5..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_LOCAL_H
-#define __UM_LOCAL_H
-
-#include "asm/arch/local.h"
-
-#endif
diff --git a/include/asm-um/locks.h b/include/asm-um/locks.h
deleted file mode 100644 (file)
index f80030a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_LOCKS_H
-#define __UM_LOCKS_H
-
-#include "asm/arch/locks.h"
-
-#endif
diff --git a/include/asm-um/mca_dma.h b/include/asm-um/mca_dma.h
deleted file mode 100644 (file)
index e492e4e..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef mca___UM_DMA_H
-#define mca___UM_DMA_H
-
-#include "asm/arch/mca_dma.h"
-
-#endif
diff --git a/include/asm-um/mman.h b/include/asm-um/mman.h
deleted file mode 100644 (file)
index b09ed52..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_MMAN_H
-#define __UM_MMAN_H
-
-#include "asm/arch/mman.h"
-
-#endif
diff --git a/include/asm-um/module-generic.h b/include/asm-um/module-generic.h
deleted file mode 100644 (file)
index 5a265f5..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_MODULE_GENERIC_H
-#define __UM_MODULE_GENERIC_H
-
-#include "asm/arch/module.h"
-
-#endif
diff --git a/include/asm-um/msgbuf.h b/include/asm-um/msgbuf.h
deleted file mode 100644 (file)
index 8ce8c30..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_MSGBUF_H
-#define __UM_MSGBUF_H
-
-#include "asm/arch/msgbuf.h"
-
-#endif
diff --git a/include/asm-um/mtrr.h b/include/asm-um/mtrr.h
deleted file mode 100644 (file)
index 5e9cd12..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_MTRR_H
-#define __UM_MTRR_H
-
-#include "asm/arch/mtrr.h"
-
-#endif
diff --git a/include/asm-um/nops.h b/include/asm-um/nops.h
deleted file mode 100644 (file)
index 814e9bf..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_NOPS_H
-#define __UM_NOPS_H
-
-#include "asm/arch/nops.h"
-
-#endif
diff --git a/include/asm-um/paravirt.h b/include/asm-um/paravirt.h
deleted file mode 100644 (file)
index 9d6aaad..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_PARAVIRT_H
-#define __UM_PARAVIRT_H
-
-#include "asm/arch/paravirt.h"
-
-#endif
diff --git a/include/asm-um/percpu.h b/include/asm-um/percpu.h
deleted file mode 100644 (file)
index 5723e2a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_PERCPU_H
-#define __UM_PERCPU_H
-
-#include "asm/arch/percpu.h"
-
-#endif
diff --git a/include/asm-um/poll.h b/include/asm-um/poll.h
deleted file mode 100644 (file)
index 1eb4e1b..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_POLL_H
-#define __UM_POLL_H
-
-#include "asm/arch/poll.h"
-
-#endif
diff --git a/include/asm-um/posix_types.h b/include/asm-um/posix_types.h
deleted file mode 100644 (file)
index 32fb419..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_POSIX_TYPES_H
-#define __UM_POSIX_TYPES_H
-
-#include "asm/arch/posix_types.h"
-
-#endif
diff --git a/include/asm-um/prctl.h b/include/asm-um/prctl.h
deleted file mode 100644 (file)
index 64b6d09..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_PRCTL_H
-#define __UM_PRCTL_H
-
-#include "asm/arch/prctl.h"
-
-#endif
diff --git a/include/asm-um/resource.h b/include/asm-um/resource.h
deleted file mode 100644 (file)
index c9b0740..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_RESOURCE_H
-#define __UM_RESOURCE_H
-
-#include "asm/arch/resource.h"
-
-#endif
diff --git a/include/asm-um/rwlock.h b/include/asm-um/rwlock.h
deleted file mode 100644 (file)
index ff383aa..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_RWLOCK_H
-#define __UM_RWLOCK_H
-
-#include "asm/arch/rwlock.h"
-
-#endif
diff --git a/include/asm-um/rwsem.h b/include/asm-um/rwsem.h
deleted file mode 100644 (file)
index b5fc449..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_RWSEM_H__
-#define __UM_RWSEM_H__
-
-#include "asm/arch/rwsem.h"
-
-#endif
diff --git a/include/asm-um/scatterlist.h b/include/asm-um/scatterlist.h
deleted file mode 100644 (file)
index e92016a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_SCATTERLIST_H
-#define __UM_SCATTERLIST_H
-
-#include "asm/arch/scatterlist.h"
-
-#endif
diff --git a/include/asm-um/sembuf.h b/include/asm-um/sembuf.h
deleted file mode 100644 (file)
index 1ae82c1..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_SEMBUF_H
-#define __UM_SEMBUF_H
-
-#include "asm/arch/sembuf.h"
-
-#endif
diff --git a/include/asm-um/serial.h b/include/asm-um/serial.h
deleted file mode 100644 (file)
index 61ad07c..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_SERIAL_H
-#define __UM_SERIAL_H
-
-#include "asm/arch/serial.h"
-
-#endif
diff --git a/include/asm-um/shmbuf.h b/include/asm-um/shmbuf.h
deleted file mode 100644 (file)
index 9684d4a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_SHMBUF_H
-#define __UM_SHMBUF_H
-
-#include "asm/arch/shmbuf.h"
-
-#endif
diff --git a/include/asm-um/shmparam.h b/include/asm-um/shmparam.h
deleted file mode 100644 (file)
index 124c001..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_SHMPARAM_H
-#define __UM_SHMPARAM_H
-
-#include "asm/arch/shmparam.h"
-
-#endif
diff --git a/include/asm-um/sigcontext-generic.h b/include/asm-um/sigcontext-generic.h
deleted file mode 100644 (file)
index 1645870..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_SIGCONTEXT_GENERIC_H
-#define __UM_SIGCONTEXT_GENERIC_H
-
-#include "asm/arch/sigcontext.h"
-
-#endif
diff --git a/include/asm-um/sigcontext-i386.h b/include/asm-um/sigcontext-i386.h
deleted file mode 100644 (file)
index b88333f..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_SIGCONTEXT_I386_H
-#define __UM_SIGCONTEXT_I386_H
-
-#include "asm/sigcontext-generic.h"
-
-#endif
diff --git a/include/asm-um/sigcontext-ppc.h b/include/asm-um/sigcontext-ppc.h
deleted file mode 100644 (file)
index 2467f20..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __UM_SIGCONTEXT_PPC_H
-#define __UM_SIGCONTEXT_PPC_H
-
-#define pt_regs sys_pt_regs
-
-#include "asm/sigcontext-generic.h"
-
-#undef pt_regs
-
-#endif
diff --git a/include/asm-um/sigcontext-x86_64.h b/include/asm-um/sigcontext-x86_64.h
deleted file mode 100644 (file)
index b600e0b..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright 2003 PathScale, Inc.
- *
- * Licensed under the GPL
- */
-
-#ifndef __UM_SIGCONTEXT_X86_64_H
-#define __UM_SIGCONTEXT_X86_64_H
-
-#include "asm/sigcontext-generic.h"
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/include/asm-um/siginfo.h b/include/asm-um/siginfo.h
deleted file mode 100644 (file)
index bec6124..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_SIGINFO_H
-#define __UM_SIGINFO_H
-
-#include "asm/arch/siginfo.h"
-
-#endif
diff --git a/include/asm-um/signal.h b/include/asm-um/signal.h
deleted file mode 100644 (file)
index 52ed92c..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __UM_SIGNAL_H
-#define __UM_SIGNAL_H
-
-/* Need to kill the do_signal() declaration in the i386 signal.h */
-
-#define do_signal do_signal_renamed
-#include "asm/arch/signal.h"
-#undef do_signal
-#undef ptrace_signal_deliver
-
-#define ptrace_signal_deliver(regs, cookie) do {} while(0)
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/include/asm-um/socket.h b/include/asm-um/socket.h
deleted file mode 100644 (file)
index 67886e4..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_SOCKET_H
-#define __UM_SOCKET_H
-
-#include "asm/arch/socket.h"
-
-#endif
diff --git a/include/asm-um/sockios.h b/include/asm-um/sockios.h
deleted file mode 100644 (file)
index 93ee1c5..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_SOCKIOS_H
-#define __UM_SOCKIOS_H
-
-#include "asm/arch/sockios.h"
-
-#endif
diff --git a/include/asm-um/spinlock.h b/include/asm-um/spinlock.h
deleted file mode 100644 (file)
index f18c828..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_SPINLOCK_H
-#define __UM_SPINLOCK_H
-
-#include "asm/arch/spinlock.h"
-
-#endif
diff --git a/include/asm-um/spinlock_types.h b/include/asm-um/spinlock_types.h
deleted file mode 100644 (file)
index e5a9429..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_SPINLOCK_TYPES_H
-#define __UM_SPINLOCK_TYPES_H
-
-#include "asm/arch/spinlock_types.h"
-
-#endif
diff --git a/include/asm-um/stat.h b/include/asm-um/stat.h
deleted file mode 100644 (file)
index 83ed85a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_STAT_H
-#define __UM_STAT_H
-
-#include "asm/arch/stat.h"
-
-#endif
diff --git a/include/asm-um/statfs.h b/include/asm-um/statfs.h
deleted file mode 100644 (file)
index ba6fb53..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _UM_STATFS_H
-#define _UM_STATFS_H
-
-#include "asm/arch/statfs.h"
-
-#endif
diff --git a/include/asm-um/string.h b/include/asm-um/string.h
deleted file mode 100644 (file)
index 9a0571f..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __UM_STRING_H
-#define __UM_STRING_H
-
-#include "asm/arch/string.h"
-#include "asm/archparam.h"
-
-#endif
diff --git a/include/asm-um/system-i386.h b/include/asm-um/system-i386.h
deleted file mode 100644 (file)
index c436263..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_SYSTEM_I386_H
-#define __UM_SYSTEM_I386_H
-
-#include "asm/system-generic.h"
-    
-#endif
diff --git a/include/asm-um/system-ppc.h b/include/asm-um/system-ppc.h
deleted file mode 100644 (file)
index 17cde66..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef __UM_SYSTEM_PPC_H
-#define __UM_SYSTEM_PPC_H
-
-#define _switch_to _ppc_switch_to
-
-#include "asm/arch/system.h"
-
-#undef _switch_to
-#include "asm/system-generic.h"
-
-#endif
diff --git a/include/asm-um/system-x86_64.h b/include/asm-um/system-x86_64.h
deleted file mode 100644 (file)
index e1b61b5..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2003 PathScale, Inc.
- *
- * Licensed under the GPL
- */
-
-#ifndef __UM_SYSTEM_X86_64_H
-#define __UM_SYSTEM_X86_64_H
-
-#include "asm/system-generic.h"
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/include/asm-um/termbits.h b/include/asm-um/termbits.h
deleted file mode 100644 (file)
index 5739c60..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_TERMBITS_H
-#define __UM_TERMBITS_H
-
-#include "asm/arch/termbits.h"
-
-#endif
diff --git a/include/asm-um/termios.h b/include/asm-um/termios.h
deleted file mode 100644 (file)
index d9f97b3..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_TERMIOS_H
-#define __UM_TERMIOS_H
-
-#include "asm/arch/termios.h"
-
-#endif
diff --git a/include/asm-um/types.h b/include/asm-um/types.h
deleted file mode 100644 (file)
index 816e959..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_TYPES_H
-#define __UM_TYPES_H
-
-#include "asm/arch/types.h"
-
-#endif
diff --git a/include/asm-um/ucontext.h b/include/asm-um/ucontext.h
deleted file mode 100644 (file)
index 5c96c0e..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_UM_UCONTEXT_H
-#define _ASM_UM_UCONTEXT_H
-
-#include "asm/arch/ucontext.h"
-
-#endif
diff --git a/include/asm-um/unaligned.h b/include/asm-um/unaligned.h
deleted file mode 100644 (file)
index a471969..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_UM_UNALIGNED_H
-#define _ASM_UM_UNALIGNED_H
-
-#include "asm/arch/unaligned.h"
-
-#endif /* _ASM_UM_UNALIGNED_H */
diff --git a/include/asm-um/unistd.h b/include/asm-um/unistd.h
deleted file mode 100644 (file)
index 38bd9d9..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* 
- * Copyright (C) 2000 - 2004  Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef _UM_UNISTD_H_
-#define _UM_UNISTD_H_
-
-#include <linux/syscalls.h>
-#include "linux/resource.h"
-#include "asm/uaccess.h"
-
-extern int um_execve(const char *file, char *const argv[], char *const env[]);
-
-#ifdef __KERNEL__
-/* We get __ARCH_WANT_OLD_STAT and __ARCH_WANT_STAT64 from the base arch */
-#define __ARCH_WANT_OLD_READDIR
-#define __ARCH_WANT_SYS_ALARM
-#define __ARCH_WANT_SYS_GETHOSTNAME
-#define __ARCH_WANT_SYS_PAUSE
-#define __ARCH_WANT_SYS_SGETMASK
-#define __ARCH_WANT_SYS_SIGNAL
-#define __ARCH_WANT_SYS_TIME
-#define __ARCH_WANT_SYS_UTIME
-#define __ARCH_WANT_SYS_WAITPID
-#define __ARCH_WANT_SYS_SOCKETCALL
-#define __ARCH_WANT_SYS_FADVISE64
-#define __ARCH_WANT_SYS_GETPGRP
-#define __ARCH_WANT_SYS_LLSEEK
-#define __ARCH_WANT_SYS_NICE
-#define __ARCH_WANT_SYS_OLD_GETRLIMIT
-#define __ARCH_WANT_SYS_OLDUMOUNT
-#define __ARCH_WANT_SYS_SIGPENDING
-#define __ARCH_WANT_SYS_SIGPROCMASK
-#define __ARCH_WANT_SYS_RT_SIGACTION
-#define __ARCH_WANT_SYS_RT_SIGSUSPEND
-#endif
-
-#include "asm/arch/unistd.h"
-
-#endif /* _UM_UNISTD_H_*/
diff --git a/include/asm-um/user.h b/include/asm-um/user.h
deleted file mode 100644 (file)
index aae414e..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_USER_H
-#define __UM_USER_H
-
-#include "asm/arch/user.h"
-
-#endif
diff --git a/include/asm-um/vga.h b/include/asm-um/vga.h
deleted file mode 100644 (file)
index 903a592..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_VGA_H
-#define __UM_VGA_H
-
-#include "asm/arch/vga.h"
-
-#endif
diff --git a/include/asm-um/vm86.h b/include/asm-um/vm86.h
deleted file mode 100644 (file)
index 7801f82..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_VM86_H
-#define __UM_VM86_H
-
-#include "asm/arch/vm86.h"
-
-#endif
diff --git a/include/asm-x86/ftrace.h b/include/asm-x86/ftrace.h
deleted file mode 100644 (file)
index be0e004..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef ASM_X86__FTRACE_H
-#define ASM_X86__FTRACE_H
-
-#ifdef CONFIG_FTRACE
-#define MCOUNT_ADDR            ((long)(mcount))
-#define MCOUNT_INSN_SIZE       5 /* sizeof mcount call */
-
-#ifndef __ASSEMBLY__
-extern void mcount(void);
-#endif
-
-#endif /* CONFIG_FTRACE */
-
-#endif /* ASM_X86__FTRACE_H */
diff --git a/include/asm-x86/irq_remapping.h b/include/asm-x86/irq_remapping.h
deleted file mode 100644 (file)
index 78242c6..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _ASM_IRQ_REMAPPING_H
-#define _ASM_IRQ_REMAPPING_H
-
-extern int x2apic;
-
-#define IRTE_DEST(dest) ((x2apic) ? dest : dest << 8)
-
-#endif
diff --git a/include/asm-x86/mach-default/mach_mpspec.h b/include/asm-x86/mach-default/mach_mpspec.h
deleted file mode 100644 (file)
index d77646f..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef ASM_X86__MACH_DEFAULT__MACH_MPSPEC_H
-#define ASM_X86__MACH_DEFAULT__MACH_MPSPEC_H
-
-#define MAX_IRQ_SOURCES 256
-
-#if CONFIG_BASE_SMALL == 0
-#define MAX_MP_BUSSES 256
-#else
-#define MAX_MP_BUSSES 32
-#endif
-
-#endif /* ASM_X86__MACH_DEFAULT__MACH_MPSPEC_H */
diff --git a/include/asm-x86/mach-generic/irq_vectors_limits.h b/include/asm-x86/mach-generic/irq_vectors_limits.h
deleted file mode 100644 (file)
index f7870e1..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef ASM_X86__MACH_GENERIC__IRQ_VECTORS_LIMITS_H
-#define ASM_X86__MACH_GENERIC__IRQ_VECTORS_LIMITS_H
-
-/*
- * For Summit or generic (i.e. installer) kernels, we have lots of I/O APICs,
- * even with uni-proc kernels, so use a big array.
- *
- * This value should be the same in both the generic and summit subarches.
- * Change one, change 'em both.
- */
-#define NR_IRQS        224
-#define NR_IRQ_VECTORS 1024
-
-#endif /* ASM_X86__MACH_GENERIC__IRQ_VECTORS_LIMITS_H */
diff --git a/include/asm-x86/reboot_fixups.h b/include/asm-x86/reboot_fixups.h
deleted file mode 100644 (file)
index 2c2987d..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef ASM_X86__REBOOT_FIXUPS_H
-#define ASM_X86__REBOOT_FIXUPS_H
-
-extern void mach_reboot_fixups(void);
-
-#endif /* ASM_X86__REBOOT_FIXUPS_H */
diff --git a/include/asm-x86/shmparam.h b/include/asm-x86/shmparam.h
deleted file mode 100644 (file)
index a83a1fd..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef ASM_X86__SHMPARAM_H
-#define ASM_X86__SHMPARAM_H
-
-#define SHMLBA PAGE_SIZE        /* attach addr a multiple of this */
-
-#endif /* ASM_X86__SHMPARAM_H */
diff --git a/include/asm-x86/summit/irq_vectors_limits.h b/include/asm-x86/summit/irq_vectors_limits.h
deleted file mode 100644 (file)
index 890ce3f..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _ASM_IRQ_VECTORS_LIMITS_H
-#define _ASM_IRQ_VECTORS_LIMITS_H
-
-/*
- * For Summit or generic (i.e. installer) kernels, we have lots of I/O APICs,
- * even with uni-proc kernels, so use a big array.
- *
- * This value should be the same in both the generic and summit subarches.
- * Change one, change 'em both.
- */
-#define NR_IRQS        224
-#define NR_IRQ_VECTORS 1024
-
-#endif /* _ASM_IRQ_VECTORS_LIMITS_H */
diff --git a/include/asm-x86/therm_throt.h b/include/asm-x86/therm_throt.h
deleted file mode 100644 (file)
index 1c7f57b..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef ASM_X86__THERM_THROT_H
-#define ASM_X86__THERM_THROT_H
-
-#include <asm/atomic.h>
-
-extern atomic_t therm_throt_en;
-int therm_throt_process(int curr);
-
-#endif /* ASM_X86__THERM_THROT_H */
diff --git a/include/asm-x86/uv/bios.h b/include/asm-x86/uv/bios.h
deleted file mode 100644 (file)
index 7cd6d7e..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef ASM_X86__UV__BIOS_H
-#define ASM_X86__UV__BIOS_H
-
-/*
- * BIOS layer definitions.
- *
- *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; 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/rtc.h>
-
-#define BIOS_FREQ_BASE                 0x01000001
-
-enum {
-       BIOS_FREQ_BASE_PLATFORM = 0,
-       BIOS_FREQ_BASE_INTERVAL_TIMER = 1,
-       BIOS_FREQ_BASE_REALTIME_CLOCK = 2
-};
-
-# define BIOS_CALL(result, a0, a1, a2, a3, a4, a5, a6, a7)             \
-       do {                                                            \
-               /* XXX - the real call goes here */                     \
-               result.status = BIOS_STATUS_UNIMPLEMENTED;              \
-               isrv.v0 = 0;                                            \
-               isrv.v1 = 0;                                            \
-       } while (0)
-
-enum {
-       BIOS_STATUS_SUCCESS             =  0,
-       BIOS_STATUS_UNIMPLEMENTED       = -1,
-       BIOS_STATUS_EINVAL              = -2,
-       BIOS_STATUS_ERROR               = -3
-};
-
-struct uv_bios_retval {
-       /*
-        * A zero status value indicates call completed without error.
-        * A negative status value indicates reason of call failure.
-        * A positive status value indicates success but an
-        * informational value should be printed (e.g., "reboot for
-        * change to take effect").
-        */
-       s64 status;
-       u64 v0;
-       u64 v1;
-       u64 v2;
-};
-
-extern long
-x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
-                  unsigned long *drift_info);
-extern const char *x86_bios_strerror(long status);
-
-#endif /* ASM_X86__UV__BIOS_H */
diff --git a/include/asm-x86/xen/grant_table.h b/include/asm-x86/xen/grant_table.h
deleted file mode 100644 (file)
index c4baab4..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef ASM_X86__XEN__GRANT_TABLE_H
-#define ASM_X86__XEN__GRANT_TABLE_H
-
-#define xen_alloc_vm_area(size)        alloc_vm_area(size)
-#define xen_free_vm_area(area) free_vm_area(area)
-
-#endif /* ASM_X86__XEN__GRANT_TABLE_H */
index 47c3616ea9acc4ec937d3fd9db25d9563f62a6f1..07b7299dab20e3ccb8c6c5740d408cf577d8174f 100644 (file)
 
 #include <linux/types.h>
 
-#define XCHAL_KIO_CACHED_VADDR 0xf0000000
-#define XCHAL_KIO_BYPASS_VADDR 0xf8000000
+#define XCHAL_KIO_CACHED_VADDR 0xe0000000
+#define XCHAL_KIO_BYPASS_VADDR 0xf0000000
 #define XCHAL_KIO_PADDR                0xf0000000
-#define XCHAL_KIO_SIZE         0x08000000
+#define XCHAL_KIO_SIZE         0x10000000
+
+#define IOADDR(x)              (XCHAL_KIO_BYPASS_VADDR + (x))
 
 /*
  * swap functions to change byte order from little-endian to big-endian and
index 0aad3a5875516a3c640b5e7cddf41cf7c044225f..e39edf5c86f2da432c181f1e503c787137e4c623 100644 (file)
 #ifndef _XTENSA_RWSEM_H
 #define _XTENSA_RWSEM_H
 
+#ifndef _LINUX_RWSEM_H
+#error "Please don't include <asm/rwsem.h> directly, use <linux/rwsem.h> instead."
+#endif
+
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <asm/atomic.h>
diff --git a/include/asm-xtensa/variant-dc232b/core.h b/include/asm-xtensa/variant-dc232b/core.h
new file mode 100644 (file)
index 0000000..525bd3d
--- /dev/null
@@ -0,0 +1,424 @@
+/*
+ * Xtensa processor core configuration information.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2007 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CORE_CONFIGURATION_H
+#define _XTENSA_CORE_CONFIGURATION_H
+
+
+/****************************************************************************
+           Parameters Useful for Any Code, USER or PRIVILEGED
+ ****************************************************************************/
+
+/*
+ *  Note:  Macros of the form XCHAL_HAVE_*** have a value of 1 if the option is
+ *  configured, and a value of 0 otherwise.  These macros are always defined.
+ */
+
+
+/*----------------------------------------------------------------------
+                               ISA
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_BE                  0       /* big-endian byte ordering */
+#define XCHAL_HAVE_WINDOWED            1       /* windowed registers option */
+#define XCHAL_NUM_AREGS                        32      /* num of physical addr regs */
+#define XCHAL_NUM_AREGS_LOG2           5       /* log2(XCHAL_NUM_AREGS) */
+#define XCHAL_MAX_INSTRUCTION_SIZE     3       /* max instr bytes (3..8) */
+#define XCHAL_HAVE_DEBUG               1       /* debug option */
+#define XCHAL_HAVE_DENSITY             1       /* 16-bit instructions */
+#define XCHAL_HAVE_LOOPS               1       /* zero-overhead loops */
+#define XCHAL_HAVE_NSA                 1       /* NSA/NSAU instructions */
+#define XCHAL_HAVE_MINMAX              1       /* MIN/MAX instructions */
+#define XCHAL_HAVE_SEXT                        1       /* SEXT instruction */
+#define XCHAL_HAVE_CLAMPS              1       /* CLAMPS instruction */
+#define XCHAL_HAVE_MUL16               1       /* MUL16S/MUL16U instructions */
+#define XCHAL_HAVE_MUL32               1       /* MULL instruction */
+#define XCHAL_HAVE_MUL32_HIGH          0       /* MULUH/MULSH instructions */
+#define XCHAL_HAVE_DIV32               1       /* QUOS/QUOU/REMS/REMU instructions */
+#define XCHAL_HAVE_L32R                        1       /* L32R instruction */
+#define XCHAL_HAVE_ABSOLUTE_LITERALS   1       /* non-PC-rel (extended) L32R */
+#define XCHAL_HAVE_CONST16             0       /* CONST16 instruction */
+#define XCHAL_HAVE_ADDX                        1       /* ADDX#/SUBX# instructions */
+#define XCHAL_HAVE_WIDE_BRANCHES       0       /* B*.W18 or B*.W15 instr's */
+#define XCHAL_HAVE_PREDICTED_BRANCHES  0       /* B[EQ/EQZ/NE/NEZ]T instr's */
+#define XCHAL_HAVE_CALL4AND12          1       /* (obsolete option) */
+#define XCHAL_HAVE_ABS                 1       /* ABS instruction */
+/*#define XCHAL_HAVE_POPC              0*/     /* POPC instruction */
+/*#define XCHAL_HAVE_CRC               0*/     /* CRC instruction */
+#define XCHAL_HAVE_RELEASE_SYNC                1       /* L32AI/S32RI instructions */
+#define XCHAL_HAVE_S32C1I              1       /* S32C1I instruction */
+#define XCHAL_HAVE_SPECULATION         0       /* speculation */
+#define XCHAL_HAVE_FULL_RESET          1       /* all regs/state reset */
+#define XCHAL_NUM_CONTEXTS             1       /* */
+#define XCHAL_NUM_MISC_REGS            2       /* num of scratch regs (0..4) */
+#define XCHAL_HAVE_TAP_MASTER          0       /* JTAG TAP control instr's */
+#define XCHAL_HAVE_PRID                        1       /* processor ID register */
+#define XCHAL_HAVE_THREADPTR           1       /* THREADPTR register */
+#define XCHAL_HAVE_BOOLEANS            0       /* boolean registers */
+#define XCHAL_HAVE_CP                  1       /* CPENABLE reg (coprocessor) */
+#define XCHAL_CP_MAXCFG                        8       /* max allowed cp id plus one */
+#define XCHAL_HAVE_MAC16               1       /* MAC16 package */
+#define XCHAL_HAVE_VECTORFPU2005       0       /* vector floating-point pkg */
+#define XCHAL_HAVE_FP                  0       /* floating point pkg */
+#define XCHAL_HAVE_VECTRA1             0       /* Vectra I  pkg */
+#define XCHAL_HAVE_VECTRALX            0       /* Vectra LX pkg */
+#define XCHAL_HAVE_HIFI2               0       /* HiFi2 Audio Engine pkg */
+
+
+/*----------------------------------------------------------------------
+                               MISC
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_NUM_WRITEBUFFER_ENTRIES  8       /* size of write buffer */
+#define XCHAL_INST_FETCH_WIDTH         4       /* instr-fetch width in bytes */
+#define XCHAL_DATA_WIDTH               4       /* data width in bytes */
+/*  In T1050, applies to selected core load and store instructions (see ISA): */
+#define XCHAL_UNALIGNED_LOAD_EXCEPTION 1       /* unaligned loads cause exc. */
+#define XCHAL_UNALIGNED_STORE_EXCEPTION        1       /* unaligned stores cause exc.*/
+
+#define XCHAL_SW_VERSION               701001  /* sw version of this header */
+
+#define XCHAL_CORE_ID                  "dc232b"        /* alphanum core name
+                                                  (CoreID) set in the Xtensa
+                                                  Processor Generator */
+
+#define XCHAL_CORE_DESCRIPTION         "Diamond 232L Standard Core Rev.B (LE)"
+#define XCHAL_BUILD_UNIQUE_ID          0x0000BEEF      /* 22-bit sw build ID */
+
+/*
+ *  These definitions describe the hardware targeted by this software.
+ */
+#define XCHAL_HW_CONFIGID0             0xC56307FE      /* ConfigID hi 32 bits*/
+#define XCHAL_HW_CONFIGID1             0x0D40BEEF      /* ConfigID lo 32 bits*/
+#define XCHAL_HW_VERSION_NAME          "LX2.1.1"       /* full version name */
+#define XCHAL_HW_VERSION_MAJOR         2210    /* major ver# of targeted hw */
+#define XCHAL_HW_VERSION_MINOR         1       /* minor ver# of targeted hw */
+#define XCHAL_HW_VERSION               221001  /* major*100+minor */
+#define XCHAL_HW_REL_LX2               1
+#define XCHAL_HW_REL_LX2_1             1
+#define XCHAL_HW_REL_LX2_1_1           1
+#define XCHAL_HW_CONFIGID_RELIABLE     1
+/*  If software targets a *range* of hardware versions, these are the bounds: */
+#define XCHAL_HW_MIN_VERSION_MAJOR     2210    /* major v of earliest tgt hw */
+#define XCHAL_HW_MIN_VERSION_MINOR     1       /* minor v of earliest tgt hw */
+#define XCHAL_HW_MIN_VERSION           221001  /* earliest targeted hw */
+#define XCHAL_HW_MAX_VERSION_MAJOR     2210    /* major v of latest tgt hw */
+#define XCHAL_HW_MAX_VERSION_MINOR     1       /* minor v of latest tgt hw */
+#define XCHAL_HW_MAX_VERSION           221001  /* latest targeted hw */
+
+
+/*----------------------------------------------------------------------
+                               CACHE
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_ICACHE_LINESIZE          32      /* I-cache line size in bytes */
+#define XCHAL_DCACHE_LINESIZE          32      /* D-cache line size in bytes */
+#define XCHAL_ICACHE_LINEWIDTH         5       /* log2(I line size in bytes) */
+#define XCHAL_DCACHE_LINEWIDTH         5       /* log2(D line size in bytes) */
+
+#define XCHAL_ICACHE_SIZE              16384   /* I-cache size in bytes or 0 */
+#define XCHAL_DCACHE_SIZE              16384   /* D-cache size in bytes or 0 */
+
+#define XCHAL_DCACHE_IS_WRITEBACK      1       /* writeback feature */
+
+
+
+
+/****************************************************************************
+    Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code
+ ****************************************************************************/
+
+
+#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY
+
+/*----------------------------------------------------------------------
+                               CACHE
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_PIF                 1       /* any outbound PIF present */
+
+/*  If present, cache size in bytes == (ways * 2^(linewidth + setwidth)).  */
+
+/*  Number of cache sets in log2(lines per way):  */
+#define XCHAL_ICACHE_SETWIDTH          7
+#define XCHAL_DCACHE_SETWIDTH          7
+
+/*  Cache set associativity (number of ways):  */
+#define XCHAL_ICACHE_WAYS              4
+#define XCHAL_DCACHE_WAYS              4
+
+/*  Cache features:  */
+#define XCHAL_ICACHE_LINE_LOCKABLE     1
+#define XCHAL_DCACHE_LINE_LOCKABLE     1
+#define XCHAL_ICACHE_ECC_PARITY                0
+#define XCHAL_DCACHE_ECC_PARITY                0
+
+/*  Number of encoded cache attr bits (see <xtensa/hal.h> for decoded bits):  */
+#define XCHAL_CA_BITS                  4
+
+
+/*----------------------------------------------------------------------
+                       INTERNAL I/D RAM/ROMs and XLMI
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_NUM_INSTROM              0       /* number of core instr. ROMs */
+#define XCHAL_NUM_INSTRAM              0       /* number of core instr. RAMs */
+#define XCHAL_NUM_DATAROM              0       /* number of core data ROMs */
+#define XCHAL_NUM_DATARAM              0       /* number of core data RAMs */
+#define XCHAL_NUM_URAM                 0       /* number of core unified RAMs*/
+#define XCHAL_NUM_XLMI                 0       /* number of core XLMI ports */
+
+
+/*----------------------------------------------------------------------
+                       INTERRUPTS and TIMERS
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_INTERRUPTS          1       /* interrupt option */
+#define XCHAL_HAVE_HIGHPRI_INTERRUPTS  1       /* med/high-pri. interrupts */
+#define XCHAL_HAVE_NMI                 1       /* non-maskable interrupt */
+#define XCHAL_HAVE_CCOUNT              1       /* CCOUNT reg. (timer option) */
+#define XCHAL_NUM_TIMERS               3       /* number of CCOMPAREn regs */
+#define XCHAL_NUM_INTERRUPTS           22      /* number of interrupts */
+#define XCHAL_NUM_INTERRUPTS_LOG2      5       /* ceil(log2(NUM_INTERRUPTS)) */
+#define XCHAL_NUM_EXTINTERRUPTS                17      /* num of external interrupts */
+#define XCHAL_NUM_INTLEVELS            6       /* number of interrupt levels
+                                                  (not including level zero) */
+#define XCHAL_EXCM_LEVEL               3       /* level masked by PS.EXCM */
+       /* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */
+
+/*  Masks of interrupts at each interrupt level:  */
+#define XCHAL_INTLEVEL1_MASK           0x001F80FF
+#define XCHAL_INTLEVEL2_MASK           0x00000100
+#define XCHAL_INTLEVEL3_MASK           0x00200E00
+#define XCHAL_INTLEVEL4_MASK           0x00001000
+#define XCHAL_INTLEVEL5_MASK           0x00002000
+#define XCHAL_INTLEVEL6_MASK           0x00000000
+#define XCHAL_INTLEVEL7_MASK           0x00004000
+
+/*  Masks of interrupts at each range 1..n of interrupt levels:  */
+#define XCHAL_INTLEVEL1_ANDBELOW_MASK  0x001F80FF
+#define XCHAL_INTLEVEL2_ANDBELOW_MASK  0x001F81FF
+#define XCHAL_INTLEVEL3_ANDBELOW_MASK  0x003F8FFF
+#define XCHAL_INTLEVEL4_ANDBELOW_MASK  0x003F9FFF
+#define XCHAL_INTLEVEL5_ANDBELOW_MASK  0x003FBFFF
+#define XCHAL_INTLEVEL6_ANDBELOW_MASK  0x003FBFFF
+#define XCHAL_INTLEVEL7_ANDBELOW_MASK  0x003FFFFF
+
+/*  Level of each interrupt:  */
+#define XCHAL_INT0_LEVEL               1
+#define XCHAL_INT1_LEVEL               1
+#define XCHAL_INT2_LEVEL               1
+#define XCHAL_INT3_LEVEL               1
+#define XCHAL_INT4_LEVEL               1
+#define XCHAL_INT5_LEVEL               1
+#define XCHAL_INT6_LEVEL               1
+#define XCHAL_INT7_LEVEL               1
+#define XCHAL_INT8_LEVEL               2
+#define XCHAL_INT9_LEVEL               3
+#define XCHAL_INT10_LEVEL              3
+#define XCHAL_INT11_LEVEL              3
+#define XCHAL_INT12_LEVEL              4
+#define XCHAL_INT13_LEVEL              5
+#define XCHAL_INT14_LEVEL              7
+#define XCHAL_INT15_LEVEL              1
+#define XCHAL_INT16_LEVEL              1
+#define XCHAL_INT17_LEVEL              1
+#define XCHAL_INT18_LEVEL              1
+#define XCHAL_INT19_LEVEL              1
+#define XCHAL_INT20_LEVEL              1
+#define XCHAL_INT21_LEVEL              3
+#define XCHAL_DEBUGLEVEL               6       /* debug interrupt level */
+#define XCHAL_HAVE_DEBUG_EXTERN_INT    1       /* OCD external db interrupt */
+#define XCHAL_NMILEVEL                 7       /* NMI "level" (for use with
+                                                  EXCSAVE/EPS/EPC_n, RFI n) */
+
+/*  Type of each interrupt:  */
+#define XCHAL_INT0_TYPE        XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT1_TYPE        XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT2_TYPE        XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT3_TYPE        XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT4_TYPE        XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT5_TYPE        XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT6_TYPE        XTHAL_INTTYPE_TIMER
+#define XCHAL_INT7_TYPE        XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT8_TYPE        XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT9_TYPE        XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT10_TYPE       XTHAL_INTTYPE_TIMER
+#define XCHAL_INT11_TYPE       XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT12_TYPE       XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT13_TYPE       XTHAL_INTTYPE_TIMER
+#define XCHAL_INT14_TYPE       XTHAL_INTTYPE_NMI
+#define XCHAL_INT15_TYPE       XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT16_TYPE       XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT17_TYPE       XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT18_TYPE       XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT19_TYPE       XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT20_TYPE       XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT21_TYPE       XTHAL_INTTYPE_EXTERN_EDGE
+
+/*  Masks of interrupts for each type of interrupt:  */
+#define XCHAL_INTTYPE_MASK_UNCONFIGURED        0xFFC00000
+#define XCHAL_INTTYPE_MASK_SOFTWARE    0x00000880
+#define XCHAL_INTTYPE_MASK_EXTERN_EDGE 0x003F8000
+#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL        0x0000133F
+#define XCHAL_INTTYPE_MASK_TIMER       0x00002440
+#define XCHAL_INTTYPE_MASK_NMI         0x00004000
+#define XCHAL_INTTYPE_MASK_WRITE_ERROR 0x00000000
+
+/*  Interrupt numbers assigned to specific interrupt sources:  */
+#define XCHAL_TIMER0_INTERRUPT         6       /* CCOMPARE0 */
+#define XCHAL_TIMER1_INTERRUPT         10      /* CCOMPARE1 */
+#define XCHAL_TIMER2_INTERRUPT         13      /* CCOMPARE2 */
+#define XCHAL_TIMER3_INTERRUPT         XTHAL_TIMER_UNCONFIGURED
+#define XCHAL_NMI_INTERRUPT            14      /* non-maskable interrupt */
+
+/*  Interrupt numbers for levels at which only one interrupt is configured:  */
+#define XCHAL_INTLEVEL2_NUM            8
+#define XCHAL_INTLEVEL4_NUM            12
+#define XCHAL_INTLEVEL5_NUM            13
+#define XCHAL_INTLEVEL7_NUM            14
+/*  (There are many interrupts each at level(s) 1, 3.)  */
+
+
+/*
+ *  External interrupt vectors/levels.
+ *  These macros describe how Xtensa processor interrupt numbers
+ *  (as numbered internally, eg. in INTERRUPT and INTENABLE registers)
+ *  map to external BInterrupt<n> pins, for those interrupts
+ *  configured as external (level-triggered, edge-triggered, or NMI).
+ *  See the Xtensa processor databook for more details.
+ */
+
+/*  Core interrupt numbers mapped to each EXTERNAL interrupt number:  */
+#define XCHAL_EXTINT0_NUM              0       /* (intlevel 1) */
+#define XCHAL_EXTINT1_NUM              1       /* (intlevel 1) */
+#define XCHAL_EXTINT2_NUM              2       /* (intlevel 1) */
+#define XCHAL_EXTINT3_NUM              3       /* (intlevel 1) */
+#define XCHAL_EXTINT4_NUM              4       /* (intlevel 1) */
+#define XCHAL_EXTINT5_NUM              5       /* (intlevel 1) */
+#define XCHAL_EXTINT6_NUM              8       /* (intlevel 2) */
+#define XCHAL_EXTINT7_NUM              9       /* (intlevel 3) */
+#define XCHAL_EXTINT8_NUM              12      /* (intlevel 4) */
+#define XCHAL_EXTINT9_NUM              14      /* (intlevel 7) */
+#define XCHAL_EXTINT10_NUM             15      /* (intlevel 1) */
+#define XCHAL_EXTINT11_NUM             16      /* (intlevel 1) */
+#define XCHAL_EXTINT12_NUM             17      /* (intlevel 1) */
+#define XCHAL_EXTINT13_NUM             18      /* (intlevel 1) */
+#define XCHAL_EXTINT14_NUM             19      /* (intlevel 1) */
+#define XCHAL_EXTINT15_NUM             20      /* (intlevel 1) */
+#define XCHAL_EXTINT16_NUM             21      /* (intlevel 3) */
+
+
+/*----------------------------------------------------------------------
+                       EXCEPTIONS and VECTORS
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_XEA_VERSION              2       /* Xtensa Exception Architecture
+                                                  number: 1 == XEA1 (old)
+                                                          2 == XEA2 (new)
+                                                          0 == XEAX (extern) */
+#define XCHAL_HAVE_XEA1                        0       /* Exception Architecture 1 */
+#define XCHAL_HAVE_XEA2                        1       /* Exception Architecture 2 */
+#define XCHAL_HAVE_XEAX                        0       /* External Exception Arch. */
+#define XCHAL_HAVE_EXCEPTIONS          1       /* exception option */
+#define XCHAL_HAVE_MEM_ECC_PARITY      0       /* local memory ECC/parity */
+#define XCHAL_HAVE_VECTOR_SELECT       1       /* relocatable vectors */
+#define XCHAL_HAVE_VECBASE             1       /* relocatable vectors */
+#define XCHAL_VECBASE_RESET_VADDR      0xD0000000  /* VECBASE reset value */
+#define XCHAL_VECBASE_RESET_PADDR      0x00000000
+#define XCHAL_RESET_VECBASE_OVERLAP    0
+
+#define XCHAL_RESET_VECTOR0_VADDR      0xFE000000
+#define XCHAL_RESET_VECTOR0_PADDR      0xFE000000
+#define XCHAL_RESET_VECTOR1_VADDR      0xD8000500
+#define XCHAL_RESET_VECTOR1_PADDR      0x00000500
+#define XCHAL_RESET_VECTOR_VADDR       0xFE000000
+#define XCHAL_RESET_VECTOR_PADDR       0xFE000000
+#define XCHAL_USER_VECOFS              0x00000340
+#define XCHAL_USER_VECTOR_VADDR                0xD0000340
+#define XCHAL_USER_VECTOR_PADDR                0x00000340
+#define XCHAL_KERNEL_VECOFS            0x00000300
+#define XCHAL_KERNEL_VECTOR_VADDR      0xD0000300
+#define XCHAL_KERNEL_VECTOR_PADDR      0x00000300
+#define XCHAL_DOUBLEEXC_VECOFS         0x000003C0
+#define XCHAL_DOUBLEEXC_VECTOR_VADDR   0xD00003C0
+#define XCHAL_DOUBLEEXC_VECTOR_PADDR   0x000003C0
+#define XCHAL_WINDOW_OF4_VECOFS                0x00000000
+#define XCHAL_WINDOW_UF4_VECOFS                0x00000040
+#define XCHAL_WINDOW_OF8_VECOFS                0x00000080
+#define XCHAL_WINDOW_UF8_VECOFS                0x000000C0
+#define XCHAL_WINDOW_OF12_VECOFS       0x00000100
+#define XCHAL_WINDOW_UF12_VECOFS       0x00000140
+#define XCHAL_WINDOW_VECTORS_VADDR     0xD0000000
+#define XCHAL_WINDOW_VECTORS_PADDR     0x00000000
+#define XCHAL_INTLEVEL2_VECOFS         0x00000180
+#define XCHAL_INTLEVEL2_VECTOR_VADDR   0xD0000180
+#define XCHAL_INTLEVEL2_VECTOR_PADDR   0x00000180
+#define XCHAL_INTLEVEL3_VECOFS         0x000001C0
+#define XCHAL_INTLEVEL3_VECTOR_VADDR   0xD00001C0
+#define XCHAL_INTLEVEL3_VECTOR_PADDR   0x000001C0
+#define XCHAL_INTLEVEL4_VECOFS         0x00000200
+#define XCHAL_INTLEVEL4_VECTOR_VADDR   0xD0000200
+#define XCHAL_INTLEVEL4_VECTOR_PADDR   0x00000200
+#define XCHAL_INTLEVEL5_VECOFS         0x00000240
+#define XCHAL_INTLEVEL5_VECTOR_VADDR   0xD0000240
+#define XCHAL_INTLEVEL5_VECTOR_PADDR   0x00000240
+#define XCHAL_INTLEVEL6_VECOFS         0x00000280
+#define XCHAL_INTLEVEL6_VECTOR_VADDR   0xD0000280
+#define XCHAL_INTLEVEL6_VECTOR_PADDR   0x00000280
+#define XCHAL_DEBUG_VECOFS             XCHAL_INTLEVEL6_VECOFS
+#define XCHAL_DEBUG_VECTOR_VADDR       XCHAL_INTLEVEL6_VECTOR_VADDR
+#define XCHAL_DEBUG_VECTOR_PADDR       XCHAL_INTLEVEL6_VECTOR_PADDR
+#define XCHAL_NMI_VECOFS               0x000002C0
+#define XCHAL_NMI_VECTOR_VADDR         0xD00002C0
+#define XCHAL_NMI_VECTOR_PADDR         0x000002C0
+#define XCHAL_INTLEVEL7_VECOFS         XCHAL_NMI_VECOFS
+#define XCHAL_INTLEVEL7_VECTOR_VADDR   XCHAL_NMI_VECTOR_VADDR
+#define XCHAL_INTLEVEL7_VECTOR_PADDR   XCHAL_NMI_VECTOR_PADDR
+
+
+/*----------------------------------------------------------------------
+                               DEBUG
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_OCD                 1       /* OnChipDebug option */
+#define XCHAL_NUM_IBREAK               2       /* number of IBREAKn regs */
+#define XCHAL_NUM_DBREAK               2       /* number of DBREAKn regs */
+#define XCHAL_HAVE_OCD_DIR_ARRAY       1       /* faster OCD option */
+
+
+/*----------------------------------------------------------------------
+                               MMU
+  ----------------------------------------------------------------------*/
+
+/*  See core-matmap.h header file for more details.  */
+
+#define XCHAL_HAVE_TLBS                        1       /* inverse of HAVE_CACHEATTR */
+#define XCHAL_HAVE_SPANNING_WAY                0       /* one way maps I+D 4GB vaddr */
+#define XCHAL_HAVE_IDENTITY_MAP                0       /* vaddr == paddr always */
+#define XCHAL_HAVE_CACHEATTR           0       /* CACHEATTR register present */
+#define XCHAL_HAVE_MIMIC_CACHEATTR     0       /* region protection */
+#define XCHAL_HAVE_XLT_CACHEATTR       0       /* region prot. w/translation */
+#define XCHAL_HAVE_PTP_MMU             1       /* full MMU (with page table
+                                                  [autorefill] and protection)
+                                                  usable for an MMU-based OS */
+/*  If none of the above last 4 are set, it's a custom TLB configuration.  */
+#define XCHAL_ITLB_ARF_ENTRIES_LOG2    2       /* log2(autorefill way size) */
+#define XCHAL_DTLB_ARF_ENTRIES_LOG2    2       /* log2(autorefill way size) */
+
+#define XCHAL_MMU_ASID_BITS            8       /* number of bits in ASIDs */
+#define XCHAL_MMU_RINGS                        4       /* number of rings (1..4) */
+#define XCHAL_MMU_RING_BITS            2       /* num of bits in RING field */
+
+#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */
+
+
+#endif /* _XTENSA_CORE_CONFIGURATION_H */
+
diff --git a/include/asm-xtensa/variant-dc232b/tie-asm.h b/include/asm-xtensa/variant-dc232b/tie-asm.h
new file mode 100644 (file)
index 0000000..ed4f53f
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * This header file contains assembly-language definitions (assembly
+ * macros, etc.) for this specific Xtensa processor's TIE extensions
+ * and options.  It is customized to this Xtensa processor configuration.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999-2007 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CORE_TIE_ASM_H
+#define _XTENSA_CORE_TIE_ASM_H
+
+/*  Selection parameter values for save-area save/restore macros:  */
+/*  Option vs. TIE:  */
+#define XTHAL_SAS_TIE  0x0001  /* custom extension or coprocessor */
+#define XTHAL_SAS_OPT  0x0002  /* optional (and not a coprocessor) */
+/*  Whether used automatically by compiler:  */
+#define XTHAL_SAS_NOCC 0x0004  /* not used by compiler w/o special opts/code */
+#define XTHAL_SAS_CC   0x0008  /* used by compiler without special opts/code */
+/*  ABI handling across function calls:  */
+#define XTHAL_SAS_CALR 0x0010  /* caller-saved */
+#define XTHAL_SAS_CALE 0x0020  /* callee-saved */
+#define XTHAL_SAS_GLOB 0x0040  /* global across function calls (in thread) */
+/*  Misc  */
+#define XTHAL_SAS_ALL  0xFFFF  /* include all default NCP contents */
+
+
+
+/* Macro to save all non-coprocessor (extra) custom TIE and optional state
+ * (not including zero-overhead loop registers).
+ * Save area ptr (clobbered):  ptr  (1 byte aligned)
+ * Scratch regs  (clobbered):  at1..at4  (only first XCHAL_NCP_NUM_ATMPS needed)
+ */
+       .macro xchal_ncp_store  ptr at1 at2 at3 at4  continue=0 ofs=-1 select=XTHAL_SAS_ALL
+       xchal_sa_start  \continue, \ofs
+       .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_CALR) & ~\select
+       xchal_sa_align  \ptr, 0, 1024-8, 4, 4
+       rsr     \at1, ACCLO             // MAC16 accumulator
+       rsr     \at2, ACCHI
+       s32i    \at1, \ptr, .Lxchal_ofs_ + 0
+       s32i    \at2, \ptr, .Lxchal_ofs_ + 4
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 8
+       .endif
+       .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+       xchal_sa_align  \ptr, 0, 1024-16, 4, 4
+       rsr     \at1, M0                // MAC16 registers
+       rsr     \at2, M1
+       s32i    \at1, \ptr, .Lxchal_ofs_ + 0
+       s32i    \at2, \ptr, .Lxchal_ofs_ + 4
+       rsr     \at1, M2
+       rsr     \at2, M3
+       s32i    \at1, \ptr, .Lxchal_ofs_ + 8
+       s32i    \at2, \ptr, .Lxchal_ofs_ + 12
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 16
+       .endif
+       .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+       xchal_sa_align  \ptr, 0, 1024-4, 4, 4
+       rsr     \at1, SCOMPARE1         // conditional store option
+       s32i    \at1, \ptr, .Lxchal_ofs_ + 0
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 4
+       .endif
+       .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~\select
+       xchal_sa_align  \ptr, 0, 1024-4, 4, 4
+       rur     \at1, THREADPTR         // threadptr option
+       s32i    \at1, \ptr, .Lxchal_ofs_ + 0
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 4
+       .endif
+       .endm   // xchal_ncp_store
+
+/* Macro to save all non-coprocessor (extra) custom TIE and optional state
+ * (not including zero-overhead loop registers).
+ * Save area ptr (clobbered):  ptr  (1 byte aligned)
+ * Scratch regs  (clobbered):  at1..at4  (only first XCHAL_NCP_NUM_ATMPS needed)
+ */
+       .macro xchal_ncp_load  ptr at1 at2 at3 at4  continue=0 ofs=-1 select=XTHAL_SAS_ALL
+       xchal_sa_start  \continue, \ofs
+       .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_CALR) & ~\select
+       xchal_sa_align  \ptr, 0, 1024-8, 4, 4
+       l32i    \at1, \ptr, .Lxchal_ofs_ + 0
+       l32i    \at2, \ptr, .Lxchal_ofs_ + 4
+       wsr     \at1, ACCLO             // MAC16 accumulator
+       wsr     \at2, ACCHI
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 8
+       .endif
+       .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+       xchal_sa_align  \ptr, 0, 1024-16, 4, 4
+       l32i    \at1, \ptr, .Lxchal_ofs_ + 0
+       l32i    \at2, \ptr, .Lxchal_ofs_ + 4
+       wsr     \at1, M0                // MAC16 registers
+       wsr     \at2, M1
+       l32i    \at1, \ptr, .Lxchal_ofs_ + 8
+       l32i    \at2, \ptr, .Lxchal_ofs_ + 12
+       wsr     \at1, M2
+       wsr     \at2, M3
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 16
+       .endif
+       .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+       xchal_sa_align  \ptr, 0, 1024-4, 4, 4
+       l32i    \at1, \ptr, .Lxchal_ofs_ + 0
+       wsr     \at1, SCOMPARE1         // conditional store option
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 4
+       .endif
+       .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~\select
+       xchal_sa_align  \ptr, 0, 1024-4, 4, 4
+       l32i    \at1, \ptr, .Lxchal_ofs_ + 0
+       wur     \at1, THREADPTR         // threadptr option
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 4
+       .endif
+       .endm   // xchal_ncp_load
+
+
+
+#define XCHAL_NCP_NUM_ATMPS    2
+
+
+#define XCHAL_SA_NUM_ATMPS     2
+
+#endif /*_XTENSA_CORE_TIE_ASM_H*/
+
diff --git a/include/asm-xtensa/variant-dc232b/tie.h b/include/asm-xtensa/variant-dc232b/tie.h
new file mode 100644 (file)
index 0000000..018e81a
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * This header file describes this specific Xtensa processor's TIE extensions
+ * that extend basic Xtensa core functionality.  It is customized to this
+ * Xtensa processor configuration.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999-2007 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CORE_TIE_H
+#define _XTENSA_CORE_TIE_H
+
+#define XCHAL_CP_NUM                   1       /* number of coprocessors */
+#define XCHAL_CP_MAX                   8       /* max CP ID + 1 (0 if none) */
+#define XCHAL_CP_MASK                  0x80    /* bitmask of all CPs by ID */
+#define XCHAL_CP_PORT_MASK             0x80    /* bitmask of only port CPs */
+
+/*  Basic parameters of each coprocessor:  */
+#define XCHAL_CP7_NAME                 "XTIOP"
+#define XCHAL_CP7_IDENT                        XTIOP
+#define XCHAL_CP7_SA_SIZE              0       /* size of state save area */
+#define XCHAL_CP7_SA_ALIGN             1       /* min alignment of save area */
+#define XCHAL_CP_ID_XTIOP              7       /* coprocessor ID (0..7) */
+
+/*  Filler info for unassigned coprocessors, to simplify arrays etc:  */
+#define XCHAL_CP0_SA_SIZE              0
+#define XCHAL_CP0_SA_ALIGN             1
+#define XCHAL_CP1_SA_SIZE              0
+#define XCHAL_CP1_SA_ALIGN             1
+#define XCHAL_CP2_SA_SIZE              0
+#define XCHAL_CP2_SA_ALIGN             1
+#define XCHAL_CP3_SA_SIZE              0
+#define XCHAL_CP3_SA_ALIGN             1
+#define XCHAL_CP4_SA_SIZE              0
+#define XCHAL_CP4_SA_ALIGN             1
+#define XCHAL_CP5_SA_SIZE              0
+#define XCHAL_CP5_SA_ALIGN             1
+#define XCHAL_CP6_SA_SIZE              0
+#define XCHAL_CP6_SA_ALIGN             1
+
+/*  Save area for non-coprocessor optional and custom (TIE) state:  */
+#define XCHAL_NCP_SA_SIZE              32
+#define XCHAL_NCP_SA_ALIGN             4
+
+/*  Total save area for optional and custom state (NCP + CPn):  */
+#define XCHAL_TOTAL_SA_SIZE            32      /* with 16-byte align padding */
+#define XCHAL_TOTAL_SA_ALIGN           4       /* actual minimum alignment */
+
+/*
+ * Detailed contents of save areas.
+ * NOTE:  caller must define the XCHAL_SA_REG macro (not defined here)
+ * before expanding the XCHAL_xxx_SA_LIST() macros.
+ *
+ * XCHAL_SA_REG(s,ccused,abikind,kind,opt,name,galign,align,asize,
+ *             dbnum,base,regnum,bitsz,gapsz,reset,x...)
+ *
+ *     s = passed from XCHAL_*_LIST(s), eg. to select how to expand
+ *     ccused = set if used by compiler without special options or code
+ *     abikind = 0 (caller-saved), 1 (callee-saved), or 2 (thread-global)
+ *     kind = 0 (special reg), 1 (TIE user reg), or 2 (TIE regfile reg)
+ *     opt = 0 (custom TIE extension or coprocessor), or 1 (optional reg)
+ *     name = lowercase reg name (no quotes)
+ *     galign = group byte alignment (power of 2) (galign >= align)
+ *     align = register byte alignment (power of 2)
+ *     asize = allocated size in bytes (asize*8 == bitsz + gapsz + padsz)
+ *       (not including any pad bytes required to galign this or next reg)
+ *     dbnum = unique target number f/debug (see <xtensa-libdb-macros.h>)
+ *     base = reg shortname w/o index (or sr=special, ur=TIE user reg)
+ *     regnum = reg index in regfile, or special/TIE-user reg number
+ *     bitsz = number of significant bits (regfile width, or ur/sr mask bits)
+ *     gapsz = intervening bits, if bitsz bits not stored contiguously
+ *     (padsz = pad bits at end [TIE regfile] or at msbits [ur,sr] of asize)
+ *     reset = register reset value (or 0 if undefined at reset)
+ *     x = reserved for future use (0 until then)
+ *
+ *  To filter out certain registers, e.g. to expand only the non-global
+ *  registers used by the compiler, you can do something like this:
+ *
+ *  #define XCHAL_SA_REG(s,ccused,p...)        SELCC##ccused(p)
+ *  #define SELCC0(p...)
+ *  #define SELCC1(abikind,p...)       SELAK##abikind(p)
+ *  #define SELAK0(p...)               REG(p)
+ *  #define SELAK1(p...)               REG(p)
+ *  #define SELAK2(p...)
+ *  #define REG(kind,tie,name,galn,aln,asz,csz,dbnum,base,rnum,bsz,rst,x...) \
+ *             ...what you want to expand...
+ */
+
+#define XCHAL_NCP_SA_NUM       8
+#define XCHAL_NCP_SA_LIST(s)   \
+ XCHAL_SA_REG(s,1,0,0,1,          acclo, 4, 4, 4,0x0210,  sr,16 , 32,0,0,0) \
+ XCHAL_SA_REG(s,1,0,0,1,          acchi, 4, 4, 4,0x0211,  sr,17 ,  8,0,0,0) \
+ XCHAL_SA_REG(s,0,0,0,1,             m0, 4, 4, 4,0x0220,  sr,32 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,0,1,             m1, 4, 4, 4,0x0221,  sr,33 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,0,1,             m2, 4, 4, 4,0x0222,  sr,34 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,0,1,             m3, 4, 4, 4,0x0223,  sr,35 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,0,1,      scompare1, 4, 4, 4,0x020C,  sr,12 , 32,0,0,0) \
+ XCHAL_SA_REG(s,1,2,1,1,      threadptr, 4, 4, 4,0x03E7,  ur,231, 32,0,0,0)
+
+#define XCHAL_CP0_SA_NUM       0
+#define XCHAL_CP0_SA_LIST(s)   /* empty */
+
+#define XCHAL_CP1_SA_NUM       0
+#define XCHAL_CP1_SA_LIST(s)   /* empty */
+
+#define XCHAL_CP2_SA_NUM       0
+#define XCHAL_CP2_SA_LIST(s)   /* empty */
+
+#define XCHAL_CP3_SA_NUM       0
+#define XCHAL_CP3_SA_LIST(s)   /* empty */
+
+#define XCHAL_CP4_SA_NUM       0
+#define XCHAL_CP4_SA_LIST(s)   /* empty */
+
+#define XCHAL_CP5_SA_NUM       0
+#define XCHAL_CP5_SA_LIST(s)   /* empty */
+
+#define XCHAL_CP6_SA_NUM       0
+#define XCHAL_CP6_SA_LIST(s)   /* empty */
+
+#define XCHAL_CP7_SA_NUM       0
+#define XCHAL_CP7_SA_LIST(s)   /* empty */
+
+/* Byte length of instruction from its first nibble (op0 field), per FLIX.  */
+#define XCHAL_OP0_FORMAT_LENGTHS       3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3
+
+#endif /*_XTENSA_CORE_TIE_H*/
+
index 702f79dad16a98a3638957bf64423c5b128423ce..fd6a452b0ceb2dd5b809631cbd12d1dc77c31b92 100644 (file)
@@ -94,18 +94,10 @@ int acpi_parse_mcfg (struct acpi_table_header *header);
 void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);
 
 /* the following four functions are architecture-dependent */
-#ifdef CONFIG_HAVE_ARCH_PARSE_SRAT
-#define NR_NODE_MEMBLKS MAX_NUMNODES
-#define acpi_numa_slit_init(slit) do {} while (0)
-#define acpi_numa_processor_affinity_init(pa) do {} while (0)
-#define acpi_numa_memory_affinity_init(ma) do {} while (0)
-#define acpi_numa_arch_fixup() do {} while (0)
-#else
 void acpi_numa_slit_init (struct acpi_table_slit *slit);
 void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa);
 void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
 void acpi_numa_arch_fixup(void);
-#endif
 
 #ifdef CONFIG_ACPI_HOTPLUG_CPU
 /* Arch dependent functions for cpu hotplug support */
index f2518141de88fbc8f89ababec557f37cd32a86fc..f7df1eefc1071ac71a985650343ec1ca2bfbf9ac 100644 (file)
@@ -10,7 +10,6 @@
 #if defined(CONFIG_PCIEAER)
 /* pci-e port driver needs this function to enable aer */
 extern int pci_enable_pcie_error_reporting(struct pci_dev *dev);
-extern int pci_find_aer_capability(struct pci_dev *dev);
 extern int pci_disable_pcie_error_reporting(struct pci_dev *dev);
 extern int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev);
 #else
@@ -18,10 +17,6 @@ static inline int pci_enable_pcie_error_reporting(struct pci_dev *dev)
 {
        return -EINVAL;
 }
-static inline int pci_find_aer_capability(struct pci_dev *dev)
-{
-       return 0;
-}
 static inline int pci_disable_pcie_error_reporting(struct pci_dev *dev)
 {
        return -EINVAL;
index 1abfe664c4446a9a64ea182ce680e6c08d1a3086..a08c33a26ca938eeb7835a3e568f3a94fc0de70b 100644 (file)
@@ -129,6 +129,7 @@ extern void bitmap_fold(unsigned long *dst, const unsigned long *orig,
 extern int bitmap_find_free_region(unsigned long *bitmap, int bits, int order);
 extern void bitmap_release_region(unsigned long *bitmap, int pos, int order);
 extern int bitmap_allocate_region(unsigned long *bitmap, int pos, int order);
+extern void bitmap_copy_le(void *dst, const unsigned long *src, int nbits);
 
 #define BITMAP_LAST_WORD_MASK(nbits)                                   \
 (                                                                      \
index b4fe68fe3a573b8b0e94a4c17153c76880a06f01..a135256b272c79f6a7b462826e59735ce3b4d620 100644 (file)
@@ -717,10 +717,10 @@ extern void blk_plug_device(struct request_queue *);
 extern void blk_plug_device_unlocked(struct request_queue *);
 extern int blk_remove_plug(struct request_queue *);
 extern void blk_recount_segments(struct request_queue *, struct bio *);
-extern int scsi_cmd_ioctl(struct file *, struct request_queue *,
-                         struct gendisk *, unsigned int, void __user *);
-extern int sg_scsi_ioctl(struct file *, struct request_queue *,
-               struct gendisk *, struct scsi_ioctl_command __user *);
+extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t,
+                         unsigned int, void __user *);
+extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t,
+                        struct scsi_ioctl_command __user *);
 
 /*
  * Temporary export, until SCSI gets fixed up.
@@ -910,7 +910,8 @@ static inline int sb_issue_discard(struct super_block *sb,
 * command filter functions
 */
 extern int blk_verify_command(struct blk_cmd_filter *filter,
-                             unsigned char *cmd, int has_write_perm);
+                             unsigned char *cmd, fmode_t has_write_perm);
+extern void blk_unregister_filter(struct gendisk *disk);
 extern void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter);
 
 #define MAX_PHYS_SEGMENTS 128
@@ -1056,6 +1057,22 @@ static inline int blk_integrity_rq(struct request *rq)
 
 #endif /* CONFIG_BLK_DEV_INTEGRITY */
 
+struct block_device_operations {
+       int (*open) (struct block_device *, fmode_t);
+       int (*release) (struct gendisk *, fmode_t);
+       int (*locked_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
+       int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
+       int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
+       int (*direct_access) (struct block_device *, sector_t,
+                                               void **, unsigned long *);
+       int (*media_changed) (struct gendisk *);
+       int (*revalidate_disk) (struct gendisk *);
+       int (*getgeo)(struct block_device *, struct hd_geometry *);
+       struct module *owner;
+};
+
+extern int __blkdev_driver_ioctl(struct block_device *, fmode_t, unsigned int,
+                                unsigned long);
 #else /* CONFIG_BLOCK */
 /*
  * stubs for when the block layer is configured out
index 5db265ea60f625a8e281f3ae004a7d90f15f6e00..0b49e08d3cb0d9187649996012ab4503c5c73852 100644 (file)
@@ -987,11 +987,11 @@ struct cdrom_device_ops {
 };
 
 /* the general block_device operations structure: */
-extern int cdrom_open(struct cdrom_device_info *cdi, struct inode *ip,
-                       struct file *fp);
-extern int cdrom_release(struct cdrom_device_info *cdi, struct file *fp);
-extern int cdrom_ioctl(struct file *file, struct cdrom_device_info *cdi,
-               struct inode *ip, unsigned int cmd, unsigned long arg);
+extern int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev,
+                       fmode_t mode);
+extern void cdrom_release(struct cdrom_device_info *cdi, fmode_t mode);
+extern int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev,
+                      fmode_t mode, unsigned int cmd, unsigned long arg);
 extern int cdrom_media_changed(struct cdrom_device_info *);
 
 extern int register_cdrom(struct cdrom_device_info *cdi);
index 55e434feec993d9656ccf6bcd31964005daa9667..f88d32f8ff7c8a0d242763328c8e14f39445006d 100644 (file)
@@ -45,7 +45,8 @@ struct clocksource;
  * @read:              returns a cycle value
  * @mask:              bitmask for two's complement
  *                     subtraction of non 64 bit counters
- * @mult:              cycle to nanosecond multiplier
+ * @mult:              cycle to nanosecond multiplier (adjusted by NTP)
+ * @mult_orig:         cycle to nanosecond multiplier (unadjusted by NTP)
  * @shift:             cycle to nanosecond divisor (power of two)
  * @flags:             flags describing special properties
  * @vread:             vsyscall based read
@@ -63,6 +64,7 @@ struct clocksource {
        cycle_t (*read)(void);
        cycle_t mask;
        u32 mult;
+       u32 mult_orig;
        u32 shift;
        unsigned long flags;
        cycle_t (*vread)(void);
@@ -77,6 +79,7 @@ struct clocksource {
        /* timekeeping specific data, ignore */
        cycle_t cycle_interval;
        u64     xtime_interval;
+       u32     raw_interval;
        /*
         * Second part is written at each timer interrupt
         * Keep it in a different cache line to dirty no
@@ -85,6 +88,7 @@ struct clocksource {
        cycle_t cycle_last ____cacheline_aligned_in_smp;
        u64 xtime_nsec;
        s64 error;
+       struct timespec raw_time;
 
 #ifdef CONFIG_CLOCKSOURCE_WATCHDOG
        /* Watchdog related data, used by the framework */
@@ -201,17 +205,19 @@ static inline void clocksource_calculate_interval(struct clocksource *c,
 {
        u64 tmp;
 
-       /* XXX - All of this could use a whole lot of optimization */
+       /* Do the ns -> cycle conversion first, using original mult */
        tmp = length_nsec;
        tmp <<= c->shift;
-       tmp += c->mult/2;
-       do_div(tmp, c->mult);
+       tmp += c->mult_orig/2;
+       do_div(tmp, c->mult_orig);
 
        c->cycle_interval = (cycle_t)tmp;
        if (c->cycle_interval == 0)
                c->cycle_interval = 1;
 
+       /* Go back from cycles -> shifted ns, this time use ntp adjused mult */
        c->xtime_interval = (u64)c->cycle_interval * c->mult;
+       c->raw_interval = ((u64)c->cycle_interval * c->mult_orig) >> c->shift;
 }
 
 
index 8322141ee480c802ee6919d0f13a86218e45bfc4..98115d9d04daa6c8008b528bee3014a8cee11078 100644 (file)
@@ -44,6 +44,8 @@ extern void __chk_io_ptr(const volatile void __iomem *);
 # error Sorry, your compiler is too old/not recognized.
 #endif
 
+#define notrace __attribute__((no_instrument_function))
+
 /* Intel compiler defines __GNUC__. So we will overwrite implementations
  * coming from above header files here
  */
index 0acf3b737e2ea179c30d9c9fa69076fbdf488a1c..2dac064d8359046c178f0d98bd9ea915ca369eaa 100644 (file)
@@ -14,8 +14,6 @@ extern unsigned long long elfcorehdr_addr;
 
 extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
                                                unsigned long, int);
-extern const struct file_operations proc_vmcore_operations;
-extern struct proc_dir_entry *proc_vmcore;
 
 /* Architecture code defines this if there are other possible ELF
  * machine types, e.g. on bi-arch capable hardware. */
index efba1de629acfe29f808ff840f75be3083a9667a..a37359d0bad11613d7baa9ee0401fa79106c5576 100644 (file)
@@ -228,9 +228,9 @@ extern void d_delete(struct dentry *);
 
 /* allocate/de-allocate */
 extern struct dentry * d_alloc(struct dentry *, const struct qstr *);
-extern struct dentry * d_alloc_anon(struct inode *);
 extern struct dentry * d_splice_alias(struct inode *, struct dentry *);
 extern struct dentry * d_add_ci(struct dentry *, struct inode *, struct qstr *);
+extern struct dentry * d_obtain_alias(struct inode *);
 extern void shrink_dcache_sb(struct super_block *);
 extern void shrink_dcache_parent(struct dentry *);
 extern void shrink_dcache_for_umount(struct super_block *);
@@ -287,6 +287,7 @@ static inline struct dentry *d_add_unique(struct dentry *entry, struct inode *in
 
 /* used for rename() and baskets */
 extern void d_move(struct dentry *, struct dentry *);
+extern struct dentry *d_ancestor(struct dentry *, struct dentry *);
 
 /* appendix may either be NULL or be used for transname suffixes */
 extern struct dentry * d_lookup(struct dentry *, struct qstr *);
index 08d783592b73ef4ef6bf8f2b03c8b1359ebe5b40..c17fd334e574ec759285c892616ab01108ec0e13 100644 (file)
@@ -69,8 +69,7 @@ typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type,
 
 typedef int (*dm_message_fn) (struct dm_target *ti, unsigned argc, char **argv);
 
-typedef int (*dm_ioctl_fn) (struct dm_target *ti, struct inode *inode,
-                           struct file *filp, unsigned int cmd,
+typedef int (*dm_ioctl_fn) (struct dm_target *ti, unsigned int cmd,
                            unsigned long arg);
 
 typedef int (*dm_merge_fn) (struct dm_target *ti, struct bvec_merge_data *bvm,
@@ -85,7 +84,7 @@ void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev);
 
 struct dm_dev {
        struct block_device *bdev;
-       int mode;
+       fmode_t mode;
        char name[16];
 };
 
@@ -95,7 +94,7 @@ struct dm_dev {
  * FIXME: too many arguments.
  */
 int dm_get_device(struct dm_target *ti, const char *path, sector_t start,
-                 sector_t len, int mode, struct dm_dev **result);
+                 sector_t len, fmode_t mode, struct dm_dev **result);
 void dm_put_device(struct dm_target *ti, struct dm_dev *d);
 
 /*
@@ -223,7 +222,7 @@ int dm_set_geometry(struct mapped_device *md, struct hd_geometry *geo);
 /*
  * First create an empty table.
  */
-int dm_table_create(struct dm_table **result, int mode,
+int dm_table_create(struct dm_table **result, fmode_t mode,
                    unsigned num_targets, struct mapped_device *md);
 
 /*
@@ -254,7 +253,7 @@ void dm_table_put(struct dm_table *t);
  */
 sector_t dm_table_get_size(struct dm_table *t);
 unsigned int dm_table_get_num_targets(struct dm_table *t);
-int dm_table_get_mode(struct dm_table *t);
+fmode_t dm_table_get_mode(struct dm_table *t);
 struct mapped_device *dm_table_get_md(struct dm_table *t);
 
 /*
@@ -354,6 +353,9 @@ void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size);
  */
 #define dm_round_up(n, sz) (dm_div_up((n), (sz)) * (sz))
 
+#define dm_array_too_big(fixed, obj, num) \
+       ((num) > (UINT_MAX - (fixed)) / (obj))
+
 static inline sector_t to_sector(unsigned long n)
 {
        return (n >> SECTOR_SHIFT);
index 987f5912720a2d6ffd6d32a33a062e3b4ef27892..1a3686d15f98f4877dcaad25b393201f6c95640b 100644 (file)
@@ -450,7 +450,7 @@ static inline void set_dev_node(struct device *dev, int node)
 }
 #endif
 
-static inline void *dev_get_drvdata(struct device *dev)
+static inline void *dev_get_drvdata(const struct device *dev)
 {
        return dev->driver_data;
 }
diff --git a/include/linux/dm-region-hash.h b/include/linux/dm-region-hash.h
new file mode 100644 (file)
index 0000000..a9e652a
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2003 Sistina Software Limited.
+ * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
+ *
+ * Device-Mapper dirty region hash interface.
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef DM_REGION_HASH_H
+#define DM_REGION_HASH_H
+
+#include <linux/dm-dirty-log.h>
+
+/*-----------------------------------------------------------------
+ * Region hash
+ *----------------------------------------------------------------*/
+struct dm_region_hash;
+struct dm_region;
+
+/*
+ * States a region can have.
+ */
+enum dm_rh_region_states {
+       DM_RH_CLEAN      = 0x01,        /* No writes in flight. */
+       DM_RH_DIRTY      = 0x02,        /* Writes in flight. */
+       DM_RH_NOSYNC     = 0x04,        /* Out of sync. */
+       DM_RH_RECOVERING = 0x08,        /* Under resynchronization. */
+};
+
+/*
+ * Region hash create/destroy.
+ */
+struct bio_list;
+struct dm_region_hash *dm_region_hash_create(
+               void *context, void (*dispatch_bios)(void *context,
+                                                    struct bio_list *bios),
+               void (*wakeup_workers)(void *context),
+               void (*wakeup_all_recovery_waiters)(void *context),
+               sector_t target_begin, unsigned max_recovery,
+               struct dm_dirty_log *log, uint32_t region_size,
+               region_t nr_regions);
+void dm_region_hash_destroy(struct dm_region_hash *rh);
+
+struct dm_dirty_log *dm_rh_dirty_log(struct dm_region_hash *rh);
+
+/*
+ * Conversion functions.
+ */
+region_t dm_rh_bio_to_region(struct dm_region_hash *rh, struct bio *bio);
+sector_t dm_rh_region_to_sector(struct dm_region_hash *rh, region_t region);
+void *dm_rh_region_context(struct dm_region *reg);
+
+/*
+ * Get region size and key (ie. number of the region).
+ */
+sector_t dm_rh_get_region_size(struct dm_region_hash *rh);
+region_t dm_rh_get_region_key(struct dm_region *reg);
+
+/*
+ * Get/set/update region state (and dirty log).
+ *
+ */
+int dm_rh_get_state(struct dm_region_hash *rh, region_t region, int may_block);
+void dm_rh_set_state(struct dm_region_hash *rh, region_t region,
+                    enum dm_rh_region_states state, int may_block);
+
+/* Non-zero errors_handled leaves the state of the region NOSYNC */
+void dm_rh_update_states(struct dm_region_hash *rh, int errors_handled);
+
+/* Flush the region hash and dirty log. */
+int dm_rh_flush(struct dm_region_hash *rh);
+
+/* Inc/dec pending count on regions. */
+void dm_rh_inc_pending(struct dm_region_hash *rh, struct bio_list *bios);
+void dm_rh_dec(struct dm_region_hash *rh, region_t region);
+
+/* Delay bios on regions. */
+void dm_rh_delay(struct dm_region_hash *rh, struct bio *bio);
+
+void dm_rh_mark_nosync(struct dm_region_hash *rh,
+                      struct bio *bio, unsigned done, int error);
+
+/*
+ * Region recovery control.
+ */
+
+/* Prepare some regions for recovery by starting to quiesce them. */
+void dm_rh_recovery_prepare(struct dm_region_hash *rh);
+
+/* Try fetching a quiesced region for recovery. */
+struct dm_region *dm_rh_recovery_start(struct dm_region_hash *rh);
+
+/* Report recovery end on a region. */
+void dm_rh_recovery_end(struct dm_region *reg, int error);
+
+/* Returns number of regions with recovery work outstanding. */
+int dm_rh_recovery_in_flight(struct dm_region_hash *rh);
+
+/* Start/stop recovery. */
+void dm_rh_start_recovery(struct dm_region_hash *rh);
+void dm_rh_stop_recovery(struct dm_region_hash *rh);
+
+#endif /* DM_REGION_HASH_H */
index bff5c65f81dc2733a36e1d4e14ab585876299ef7..952df39c989d6bcb4624537c256b4c264c7345f5 100644 (file)
@@ -2,15 +2,14 @@
 #define _DMA_REMAPPING_H
 
 /*
- * We need a fixed PAGE_SIZE of 4K irrespective of
- * arch PAGE_SIZE for IOMMU page tables.
+ * VT-d hardware uses 4KiB page size regardless of host page size.
  */
-#define PAGE_SHIFT_4K          (12)
-#define PAGE_SIZE_4K           (1UL << PAGE_SHIFT_4K)
-#define PAGE_MASK_4K           (((u64)-1) << PAGE_SHIFT_4K)
-#define PAGE_ALIGN_4K(addr)    (((addr) + PAGE_SIZE_4K - 1) & PAGE_MASK_4K)
+#define VTD_PAGE_SHIFT         (12)
+#define VTD_PAGE_SIZE          (1UL << VTD_PAGE_SHIFT)
+#define VTD_PAGE_MASK          (((u64)-1) << VTD_PAGE_SHIFT)
+#define VTD_PAGE_ALIGN(addr)   (((addr) + VTD_PAGE_SIZE - 1) & VTD_PAGE_MASK)
 
-#define IOVA_PFN(addr)         ((addr) >> PAGE_SHIFT_4K)
+#define IOVA_PFN(addr)         ((addr) >> PAGE_SHIFT)
 #define DMA_32BIT_PFN          IOVA_PFN(DMA_32BIT_MASK)
 #define DMA_64BIT_PFN          IOVA_PFN(DMA_64BIT_MASK)
 
@@ -25,7 +24,7 @@ struct root_entry {
        u64     val;
        u64     rsvd1;
 };
-#define ROOT_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct root_entry))
+#define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry))
 static inline bool root_present(struct root_entry *root)
 {
        return (root->val & 1);
@@ -36,7 +35,7 @@ static inline void set_root_present(struct root_entry *root)
 }
 static inline void set_root_value(struct root_entry *root, unsigned long value)
 {
-       root->val |= value & PAGE_MASK_4K;
+       root->val |= value & VTD_PAGE_MASK;
 }
 
 struct context_entry;
@@ -45,7 +44,7 @@ get_context_addr_from_root(struct root_entry *root)
 {
        return (struct context_entry *)
                (root_present(root)?phys_to_virt(
-               root->val & PAGE_MASK_4K):
+               root->val & VTD_PAGE_MASK) :
                NULL);
 }
 
@@ -67,7 +66,7 @@ struct context_entry {
 #define context_present(c) ((c).lo & 1)
 #define context_fault_disable(c) (((c).lo >> 1) & 1)
 #define context_translation_type(c) (((c).lo >> 2) & 3)
-#define context_address_root(c) ((c).lo & PAGE_MASK_4K)
+#define context_address_root(c) ((c).lo & VTD_PAGE_MASK)
 #define context_address_width(c) ((c).hi &  7)
 #define context_domain_id(c) (((c).hi >> 8) & ((1 << 16) - 1))
 
@@ -81,7 +80,7 @@ struct context_entry {
        } while (0)
 #define CONTEXT_TT_MULTI_LEVEL 0
 #define context_set_address_root(c, val) \
-       do {(c).lo |= (val) & PAGE_MASK_4K;} while (0)
+       do {(c).lo |= (val) & VTD_PAGE_MASK; } while (0)
 #define context_set_address_width(c, val) do {(c).hi |= (val) & 7;} while (0)
 #define context_set_domain_id(c, val) \
        do {(c).hi |= ((val) & ((1 << 16) - 1)) << 8;} while (0)
@@ -107,9 +106,9 @@ struct dma_pte {
 #define dma_set_pte_writable(p) do {(p).val |= DMA_PTE_WRITE;} while (0)
 #define dma_set_pte_prot(p, prot) \
                do {(p).val = ((p).val & ~3) | ((prot) & 3); } while (0)
-#define dma_pte_addr(p) ((p).val & PAGE_MASK_4K)
+#define dma_pte_addr(p) ((p).val & VTD_PAGE_MASK)
 #define dma_set_pte_addr(p, addr) do {\
-               (p).val |= ((addr) & PAGE_MASK_4K); } while (0)
+               (p).val |= ((addr) & VTD_PAGE_MASK); } while (0)
 #define dma_pte_present(p) (((p).val & 3) != 0)
 
 struct intel_iommu;
index c360c558e59eb5b58952955e3172658ed86f8848..f1984fc3e06d54e21646c79c591169c5a3f84aeb 100644 (file)
@@ -45,7 +45,6 @@ extern struct list_head dmar_drhd_units;
        list_for_each_entry(drhd, &dmar_drhd_units, list)
 
 extern int dmar_table_init(void);
-extern int early_dmar_detect(void);
 extern int dmar_dev_scope_init(void);
 
 /* Intel IOMMU detection */
index 807373d467f7485a03dfa1417f16a62097108e17..bb66feb164bd86596b527cce7398070343b8e26f 100644 (file)
@@ -208,6 +208,9 @@ typedef efi_status_t efi_set_virtual_address_map_t (unsigned long memory_map_siz
 #define EFI_GLOBAL_VARIABLE_GUID \
     EFI_GUID(  0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c )
 
+#define UV_SYSTEM_TABLE_GUID \
+    EFI_GUID(  0x3b13a7d4, 0x633e, 0x11dd, 0x93, 0xec, 0xda, 0x25, 0x56, 0xd8, 0x95, 0x93 )
+
 typedef struct {
        efi_guid_t guid;
        unsigned long table;
@@ -255,6 +258,7 @@ extern struct efi {
        unsigned long boot_info;        /* boot info table */
        unsigned long hcdp;             /* HCDP table */
        unsigned long uga;              /* UGA table */
+       unsigned long uv_systab;        /* UV system table */
        efi_get_time_t *get_time;
        efi_set_time_t *set_time;
        efi_get_wakeup_time_t *get_wakeup_time;
index a20259e248a5ac6d641713512d1891e05154abcd..335a0a5c316e4b8fa66864af63059fa59c3ad506 100644 (file)
@@ -19,10 +19,10 @@ struct file_operations;
 struct vfsmount;
 struct dentry;
 extern int init_file(struct file *, struct vfsmount *mnt,
-               struct dentry *dentry, mode_t mode,
+               struct dentry *dentry, fmode_t mode,
                const struct file_operations *fop);
 extern struct file *alloc_file(struct vfsmount *, struct dentry *dentry,
-               mode_t mode, const struct file_operations *fop);
+               fmode_t mode, const struct file_operations *fop);
 
 static inline void fput_light(struct file *file, int fput_needed)
 {
index a6a625be13fce0c66ca8d034ec69a2ca956be356..5b248d61430c92de2db9df74b6825fefa30fb710 100644 (file)
@@ -63,18 +63,23 @@ extern int dir_notify_enable;
 #define MAY_ACCESS 16
 #define MAY_OPEN 32
 
-#define FMODE_READ 1
-#define FMODE_WRITE 2
+#define FMODE_READ ((__force fmode_t)1)
+#define FMODE_WRITE ((__force fmode_t)2)
 
 /* Internal kernel extensions */
-#define FMODE_LSEEK    4
-#define FMODE_PREAD    8
+#define FMODE_LSEEK    ((__force fmode_t)4)
+#define FMODE_PREAD    ((__force fmode_t)8)
 #define FMODE_PWRITE   FMODE_PREAD     /* These go hand in hand */
 
 /* File is being opened for execution. Primary users of this flag are
    distributed filesystems that can use it to achieve correct ETXTBUSY
    behavior for cross-node execution/opening_for_writing of files */
-#define FMODE_EXEC     16
+#define FMODE_EXEC     ((__force fmode_t)16)
+
+#define FMODE_NDELAY   ((__force fmode_t)32)
+#define FMODE_EXCL     ((__force fmode_t)64)
+#define FMODE_WRITE_IOCTL      ((__force fmode_t)128)
+#define FMODE_NDELAY_NOW       ((__force fmode_t)256)
 
 #define RW_MASK                1
 #define RWA_MASK       2
@@ -136,7 +141,7 @@ extern int dir_notify_enable;
 /*
  * Superblock flags that can be altered by MS_REMOUNT
  */
-#define MS_RMT_MASK    (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK)
+#define MS_RMT_MASK    (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION)
 
 /*
  * Old magic mount flag and mask
@@ -825,7 +830,7 @@ struct file {
        const struct file_operations    *f_op;
        atomic_long_t           f_count;
        unsigned int            f_flags;
-       mode_t                  f_mode;
+       fmode_t                 f_mode;
        loff_t                  f_pos;
        struct fown_struct      f_owner;
        unsigned int            f_uid, f_gid;
@@ -1037,7 +1042,6 @@ extern int vfs_setlease(struct file *, long, struct file_lock **);
 extern int lease_modify(struct file_lock **, int);
 extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
 extern int lock_may_write(struct inode *, loff_t start, unsigned long count);
-extern struct seq_operations locks_seq_operations;
 #else /* !CONFIG_FILE_LOCKING */
 #define fcntl_getlk(a, b) ({ -EINVAL; })
 #define fcntl_setlk(a, b, c, d) ({ -EACCES; })
@@ -1152,6 +1156,7 @@ struct super_block {
        char s_id[32];                          /* Informational name */
 
        void                    *s_fs_info;     /* Filesystem private info */
+       fmode_t                 s_mode;
 
        /*
         * The next field is for VFS *only*. No filesystems have any business
@@ -1266,20 +1271,7 @@ int generic_osync_inode(struct inode *, struct address_space *, int);
  * to have different dirent layouts depending on the binary type.
  */
 typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned);
-
-struct block_device_operations {
-       int (*open) (struct inode *, struct file *);
-       int (*release) (struct inode *, struct file *);
-       int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);
-       long (*unlocked_ioctl) (struct file *, unsigned, unsigned long);
-       long (*compat_ioctl) (struct file *, unsigned, unsigned long);
-       int (*direct_access) (struct block_device *, sector_t,
-                                               void **, unsigned long *);
-       int (*media_changed) (struct gendisk *);
-       int (*revalidate_disk) (struct gendisk *);
-       int (*getgeo)(struct block_device *, struct hd_geometry *);
-       struct module *owner;
-};
+struct block_device_operations;
 
 /* These macros are for out of kernel modules to test that
  * the kernel supports the unlocked_ioctl and compat_ioctl
@@ -1593,7 +1585,6 @@ extern int get_sb_pseudo(struct file_system_type *, char *,
        struct vfsmount *mnt);
 extern int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb);
 int __put_super_and_need_restart(struct super_block *sb);
-void unnamed_dev_init(void);
 
 /* Alas, no aliases. Too much hassle with bringing module.h everywhere */
 #define fops_get(fops) \
@@ -1714,7 +1705,7 @@ extern struct block_device *bdget(dev_t);
 extern void bd_set_size(struct block_device *, loff_t size);
 extern void bd_forget(struct inode *inode);
 extern void bdput(struct block_device *);
-extern struct block_device *open_by_devnum(dev_t, unsigned);
+extern struct block_device *open_by_devnum(dev_t, fmode_t);
 #else
 static inline void bd_forget(struct inode *inode) {}
 #endif
@@ -1724,13 +1715,10 @@ extern const struct file_operations bad_sock_fops;
 extern const struct file_operations def_fifo_fops;
 #ifdef CONFIG_BLOCK
 extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long);
-extern int blkdev_ioctl(struct inode *, struct file *, unsigned, unsigned long);
-extern int blkdev_driver_ioctl(struct inode *inode, struct file *file,
-                              struct gendisk *disk, unsigned cmd,
-                              unsigned long arg);
+extern int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long);
 extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long);
-extern int blkdev_get(struct block_device *, mode_t, unsigned);
-extern int blkdev_put(struct block_device *);
+extern int blkdev_get(struct block_device *, fmode_t);
+extern int blkdev_put(struct block_device *, fmode_t);
 extern int bd_claim(struct block_device *, void *);
 extern void bd_release(struct block_device *);
 #ifdef CONFIG_SYSFS
@@ -1761,9 +1749,10 @@ extern void chrdev_show(struct seq_file *,off_t);
 extern const char *__bdevname(dev_t, char *buffer);
 extern const char *bdevname(struct block_device *bdev, char *buffer);
 extern struct block_device *lookup_bdev(const char *);
-extern struct block_device *open_bdev_excl(const char *, int, void *);
-extern void close_bdev_excl(struct block_device *);
+extern struct block_device *open_bdev_exclusive(const char *, fmode_t, void *);
+extern void close_bdev_exclusive(struct block_device *, fmode_t);
 extern void blkdev_show(struct seq_file *,off_t);
+
 #else
 #define BLKDEV_MAJOR_HASH_SIZE 0
 #endif
@@ -1852,6 +1841,11 @@ extern int inode_permission(struct inode *, int);
 extern int generic_permission(struct inode *, int,
                int (*check_acl)(struct inode *, int));
 
+static inline bool execute_ok(struct inode *inode)
+{
+       return (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode);
+}
+
 extern int get_write_access(struct inode *);
 extern int deny_write_access(struct file *);
 static inline void put_write_access(struct inode * inode)
index a89513188ce7a85c076f11e512d994b0447b384e..00fbd5b245c996400d40e8fd41ddea814af8998a 100644 (file)
@@ -188,7 +188,7 @@ static inline void fsnotify_close(struct file *file)
        struct dentry *dentry = file->f_path.dentry;
        struct inode *inode = dentry->d_inode;
        const char *name = dentry->d_name.name;
-       mode_t mode = file->f_mode;
+       fmode_t mode = file->f_mode;
        u32 mask = (mode & FMODE_WRITE) ? IN_CLOSE_WRITE : IN_CLOSE_NOWRITE;
 
        if (S_ISDIR(inode->i_mode))
index bb384068272e1ef5ef9f4aa4a04572e48dcbfca5..a3d46151be195cec1d701b7058ec98662860e65b 100644 (file)
@@ -1,10 +1,14 @@
 #ifndef _LINUX_FTRACE_H
 #define _LINUX_FTRACE_H
 
-#ifdef CONFIG_FTRACE
-
 #include <linux/linkage.h>
 #include <linux/fs.h>
+#include <linux/ktime.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/kallsyms.h>
+
+#ifdef CONFIG_FTRACE
 
 extern int ftrace_enabled;
 extern int
@@ -36,6 +40,7 @@ extern void ftrace_stub(unsigned long a0, unsigned long a1);
 # define register_ftrace_function(ops) do { } while (0)
 # define unregister_ftrace_function(ops) do { } while (0)
 # define clear_ftrace_function(ops) do { } while (0)
+static inline void ftrace_kill_atomic(void) { }
 #endif /* CONFIG_FTRACE */
 
 #ifdef CONFIG_DYNAMIC_FTRACE
@@ -76,8 +81,10 @@ extern void mcount_call(void);
 
 extern int skip_trace(unsigned long ip);
 
-void ftrace_disable_daemon(void);
-void ftrace_enable_daemon(void);
+extern void ftrace_release(void *start, unsigned long size);
+
+extern void ftrace_disable_daemon(void);
+extern void ftrace_enable_daemon(void);
 
 #else
 # define skip_trace(ip)                                ({ 0; })
@@ -85,6 +92,7 @@ void ftrace_enable_daemon(void);
 # 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 void ftrace_release(void *start, unsigned long size) { }
 #endif /* CONFIG_DYNAMIC_FTRACE */
 
 /* totally disable ftrace - can not re-enable after this */
@@ -98,9 +106,11 @@ static inline void tracer_disable(void)
 #endif
 }
 
-/* Ftrace disable/restore without lock. Some synchronization mechanism
+/*
+ * Ftrace disable/restore without lock. Some synchronization mechanism
  * must be used to prevent ftrace_enabled to be changed between
- * disable/restore. */
+ * disable/restore.
+ */
 static inline int __ftrace_enabled_save(void)
 {
 #ifdef CONFIG_FTRACE
@@ -157,9 +167,71 @@ static inline void __ftrace_enabled_restore(int enabled)
 #ifdef CONFIG_TRACING
 extern void
 ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3);
+
+/**
+ * ftrace_printk - printf formatting in the ftrace buffer
+ * @fmt: the printf format for printing
+ *
+ * Note: __ftrace_printk is an internal function for ftrace_printk and
+ *       the @ip is passed in via the ftrace_printk macro.
+ *
+ * This function allows a kernel developer to debug fast path sections
+ * that printk is not appropriate for. By scattering in various
+ * printk like tracing in the code, a developer can quickly see
+ * where problems are occurring.
+ *
+ * This is intended as a debugging tool for the developer only.
+ * Please refrain from leaving ftrace_printks scattered around in
+ * your code.
+ */
+# define ftrace_printk(fmt...) __ftrace_printk(_THIS_IP_, fmt)
+extern int
+__ftrace_printk(unsigned long ip, const char *fmt, ...)
+       __attribute__ ((format (printf, 2, 3)));
+extern void ftrace_dump(void);
 #else
 static inline void
 ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { }
+static inline int
+ftrace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 0)));
+
+static inline int
+ftrace_printk(const char *fmt, ...)
+{
+       return 0;
+}
+static inline void ftrace_dump(void) { }
 #endif
 
+#ifdef CONFIG_FTRACE_MCOUNT_RECORD
+extern void ftrace_init(void);
+extern void ftrace_init_module(unsigned long *start, unsigned long *end);
+#else
+static inline void ftrace_init(void) { }
+static inline void
+ftrace_init_module(unsigned long *start, unsigned long *end) { }
+#endif
+
+
+struct boot_trace {
+       pid_t                   caller;
+       char                    func[KSYM_NAME_LEN];
+       int                     result;
+       unsigned long long      duration;               /* usecs */
+       ktime_t                 calltime;
+       ktime_t                 rettime;
+};
+
+#ifdef CONFIG_BOOT_TRACER
+extern void trace_boot(struct boot_trace *it, initcall_t fn);
+extern void start_boot_trace(void);
+extern void stop_boot_trace(void);
+#else
+static inline void trace_boot(struct boot_trace *it, initcall_t fn) { }
+static inline void start_boot_trace(void) { }
+static inline void stop_boot_trace(void) { }
+#endif
+
+
+
 #endif /* _LINUX_FTRACE_H */
index 265635dc990812a319dcd632131e8c9f79051f1d..350fe9767bbc77d755718afe43513e6c8513a4e8 100644 (file)
  *  - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in
  *  - add blksize field to fuse_attr
  *  - add file flags field to fuse_read_in and fuse_write_in
+ *
+ * 7.10
+ *  - add nonseekable open flag
  */
 
+#ifndef _LINUX_FUSE_H
+#define _LINUX_FUSE_H
+
 #include <asm/types.h>
 #include <linux/major.h>
 
@@ -26,7 +32,7 @@
 #define FUSE_KERNEL_VERSION 7
 
 /** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 9
+#define FUSE_KERNEL_MINOR_VERSION 10
 
 /** The node ID of the root inode */
 #define FUSE_ROOT_ID 1
@@ -98,9 +104,11 @@ struct fuse_file_lock {
  *
  * FOPEN_DIRECT_IO: bypass page cache for this open file
  * FOPEN_KEEP_CACHE: don't invalidate the data cache on open
+ * FOPEN_NONSEEKABLE: the file is not seekable
  */
 #define FOPEN_DIRECT_IO                (1 << 0)
 #define FOPEN_KEEP_CACHE       (1 << 1)
+#define FOPEN_NONSEEKABLE      (1 << 2)
 
 /**
  * INIT request/reply flags
@@ -409,3 +417,5 @@ struct fuse_dirent {
 #define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1))
 #define FUSE_DIRENT_SIZE(d) \
        FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
+
+#endif /* _LINUX_FUSE_H */
index 206cdf96c3a751fb926750fcd29c5cf828464392..e439e6aed832f3fc98b3a7944521f108e5740fbb 100644 (file)
@@ -25,9 +25,6 @@ extern struct device_type part_type;
 extern struct kobject *block_depr;
 extern struct class block_class;
 
-extern const struct seq_operations partitions_op;
-extern const struct seq_operations diskstats_op;
-
 enum {
 /* These three have identical behaviour; use the second one if DOS FDISK gets
    confused about extended/logical partitions starting past cylinder 1023. */
index 2f245fe63bda5611ad909c1452aa8a79c4f29eb4..2b3645b1acf4609e55fa36f22368cca34d439a2a 100644 (file)
@@ -20,6 +20,8 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/wait.h>
+#include <linux/percpu.h>
+
 
 struct hrtimer_clock_base;
 struct hrtimer_cpu_base;
@@ -101,9 +103,14 @@ enum hrtimer_cb_mode {
 /**
  * struct hrtimer - the basic hrtimer structure
  * @node:      red black tree node for time ordered insertion
- * @expires:   the absolute expiry time in the hrtimers internal
+ * @_expires:  the absolute expiry time in the hrtimers internal
  *             representation. The time is related to the clock on
- *             which the timer is based.
+ *             which the timer is based. Is setup by adding
+ *             slack to the _softexpires value. For non range timers
+ *             identical to _softexpires.
+ * @_softexpires: the absolute earliest expiry time of the hrtimer.
+ *             The time which was given as expiry time when the timer
+ *             was armed.
  * @function:  timer expiry callback function
  * @base:      pointer to the timer base (per cpu and per clock)
  * @state:     state information (See bit values above)
@@ -121,16 +128,17 @@ enum hrtimer_cb_mode {
  */
 struct hrtimer {
        struct rb_node                  node;
-       ktime_t                         expires;
+       ktime_t                         _expires;
+       ktime_t                         _softexpires;
        enum hrtimer_restart            (*function)(struct hrtimer *);
        struct hrtimer_clock_base       *base;
        unsigned long                   state;
-       enum hrtimer_cb_mode            cb_mode;
        struct list_head                cb_entry;
+       enum hrtimer_cb_mode            cb_mode;
 #ifdef CONFIG_TIMER_STATS
+       int                             start_pid;
        void                            *start_site;
        char                            start_comm[16];
-       int                             start_pid;
 #endif
 };
 
@@ -155,10 +163,8 @@ struct hrtimer_sleeper {
  * @first:             pointer to the timer node which expires first
  * @resolution:                the resolution of the clock, in nanoseconds
  * @get_time:          function to retrieve the current time of the clock
- * @get_softirq_time:  function to retrieve the current time from the softirq
  * @softirq_time:      the time when running the hrtimer queue in the softirq
  * @offset:            offset of this clock to the monotonic base
- * @reprogram:         function to reprogram the timer event
  */
 struct hrtimer_clock_base {
        struct hrtimer_cpu_base *cpu_base;
@@ -167,13 +173,9 @@ struct hrtimer_clock_base {
        struct rb_node          *first;
        ktime_t                 resolution;
        ktime_t                 (*get_time)(void);
-       ktime_t                 (*get_softirq_time)(void);
        ktime_t                 softirq_time;
 #ifdef CONFIG_HIGH_RES_TIMERS
        ktime_t                 offset;
-       int                     (*reprogram)(struct hrtimer *t,
-                                            struct hrtimer_clock_base *b,
-                                            ktime_t n);
 #endif
 };
 
@@ -207,6 +209,71 @@ struct hrtimer_cpu_base {
 #endif
 };
 
+static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time)
+{
+       timer->_expires = time;
+       timer->_softexpires = time;
+}
+
+static inline void hrtimer_set_expires_range(struct hrtimer *timer, ktime_t time, ktime_t delta)
+{
+       timer->_softexpires = time;
+       timer->_expires = ktime_add_safe(time, delta);
+}
+
+static inline void hrtimer_set_expires_range_ns(struct hrtimer *timer, ktime_t time, unsigned long delta)
+{
+       timer->_softexpires = time;
+       timer->_expires = ktime_add_safe(time, ns_to_ktime(delta));
+}
+
+static inline void hrtimer_set_expires_tv64(struct hrtimer *timer, s64 tv64)
+{
+       timer->_expires.tv64 = tv64;
+       timer->_softexpires.tv64 = tv64;
+}
+
+static inline void hrtimer_add_expires(struct hrtimer *timer, ktime_t time)
+{
+       timer->_expires = ktime_add_safe(timer->_expires, time);
+       timer->_softexpires = ktime_add_safe(timer->_softexpires, time);
+}
+
+static inline void hrtimer_add_expires_ns(struct hrtimer *timer, unsigned long ns)
+{
+       timer->_expires = ktime_add_ns(timer->_expires, ns);
+       timer->_softexpires = ktime_add_ns(timer->_softexpires, ns);
+}
+
+static inline ktime_t hrtimer_get_expires(const struct hrtimer *timer)
+{
+       return timer->_expires;
+}
+
+static inline ktime_t hrtimer_get_softexpires(const struct hrtimer *timer)
+{
+       return timer->_softexpires;
+}
+
+static inline s64 hrtimer_get_expires_tv64(const struct hrtimer *timer)
+{
+       return timer->_expires.tv64;
+}
+static inline s64 hrtimer_get_softexpires_tv64(const struct hrtimer *timer)
+{
+       return timer->_softexpires.tv64;
+}
+
+static inline s64 hrtimer_get_expires_ns(const struct hrtimer *timer)
+{
+       return ktime_to_ns(timer->_expires);
+}
+
+static inline ktime_t hrtimer_expires_remaining(const struct hrtimer *timer)
+{
+    return ktime_sub(timer->_expires, timer->base->get_time());
+}
+
 #ifdef CONFIG_HIGH_RES_TIMERS
 struct clock_event_device;
 
@@ -227,6 +294,8 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer)
        return timer->base->cpu_base->hres_active;
 }
 
+extern void hrtimer_peek_ahead_timers(void);
+
 /*
  * The resolution of the clocks. The resolution value is returned in
  * the clock_getres() system call to give application programmers an
@@ -249,6 +318,7 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer)
  * is expired in the next softirq when the clock was advanced.
  */
 static inline void clock_was_set(void) { }
+static inline void hrtimer_peek_ahead_timers(void) { }
 
 static inline void hres_timers_resume(void) { }
 
@@ -270,6 +340,10 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer)
 extern ktime_t ktime_get(void);
 extern ktime_t ktime_get_real(void);
 
+
+DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
+
+
 /* Exported timer functions: */
 
 /* Initialize timers: */
@@ -294,12 +368,25 @@ static inline void destroy_hrtimer_on_stack(struct hrtimer *timer) { }
 /* Basic timer operations: */
 extern int hrtimer_start(struct hrtimer *timer, ktime_t tim,
                         const enum hrtimer_mode mode);
+extern int hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
+                       unsigned long range_ns, const enum hrtimer_mode mode);
 extern int hrtimer_cancel(struct hrtimer *timer);
 extern int hrtimer_try_to_cancel(struct hrtimer *timer);
 
+static inline int hrtimer_start_expires(struct hrtimer *timer,
+                                               enum hrtimer_mode mode)
+{
+       unsigned long delta;
+       ktime_t soft, hard;
+       soft = hrtimer_get_softexpires(timer);
+       hard = hrtimer_get_expires(timer);
+       delta = ktime_to_ns(ktime_sub(hard, soft));
+       return hrtimer_start_range_ns(timer, soft, delta, mode);
+}
+
 static inline int hrtimer_restart(struct hrtimer *timer)
 {
-       return hrtimer_start(timer, timer->expires, HRTIMER_MODE_ABS);
+       return hrtimer_start_expires(timer, HRTIMER_MODE_ABS);
 }
 
 /* Query timers: */
@@ -356,6 +443,10 @@ extern long hrtimer_nanosleep_restart(struct restart_block *restart_block);
 extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl,
                                 struct task_struct *tsk);
 
+extern int schedule_hrtimeout_range(ktime_t *expires, unsigned long delta,
+                                               const enum hrtimer_mode mode);
+extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode);
+
 /* Soft interrupt function to run the hrtimer queues: */
 extern void hrtimer_run_queues(void);
 extern void hrtimer_run_pending(void);
index 32e0ef0f6e1fcdd7f67d83ffe985e6cbe8eb9a08..e1c8afc002c0c6957f4e752f09b35dd72b67aea0 100644 (file)
@@ -27,7 +27,7 @@ void unmap_hugepage_range(struct vm_area_struct *,
 void __unmap_hugepage_range(struct vm_area_struct *,
                        unsigned long, unsigned long, struct page *);
 int hugetlb_prefault(struct address_space *, struct vm_area_struct *);
-int hugetlb_report_meminfo(char *);
+void hugetlb_report_meminfo(struct seq_file *);
 int hugetlb_report_node_meminfo(int, char *);
 unsigned long hugetlb_total_pages(void);
 int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
@@ -79,7 +79,9 @@ static inline unsigned long hugetlb_total_pages(void)
 #define copy_hugetlb_page_range(src, dst, vma) ({ BUG(); 0; })
 #define hugetlb_prefault(mapping, vma)         ({ BUG(); 0; })
 #define unmap_hugepage_range(vma, start, end, page)    BUG()
-#define hugetlb_report_meminfo(buf)            0
+static inline void hugetlb_report_meminfo(struct seq_file *m)
+{
+}
 #define hugetlb_report_node_meminfo(n, buf)    0
 #define follow_huge_pmd(mm, addr, pmd, write)  NULL
 #define follow_huge_pud(mm, addr, pud, write)  NULL
index 0177d280f733df0837f7635b6413b2ff0a23202a..0f91a957a690930cd365937e3d62a411b1f83cdf 100644 (file)
@@ -31,7 +31,10 @@ struct i2c_algo_pcf_data {
        int  (*getpcf) (void *data, int ctl);
        int  (*getown) (void *data);
        int  (*getclock) (void *data);
-       void (*waitforpin) (void);
+       void (*waitforpin) (void *data);
+
+       void (*xfer_begin) (void *data);
+       void (*xfer_end) (void *data);
 
        /* Multi-master lost arbitration back-off delay (msecs)
         * This should be set by the bus adapter or knowledgable client
index 06115128047f24274002b87345af680314e8e3a8..33a5992d493651383e00832b13b69f396d77bfff 100644 (file)
@@ -53,45 +53,44 @@ struct i2c_board_info;
  * transmit one message at a time, a more complex version can be used to
  * transmit an arbitrary number of messages without interruption.
  */
-extern int i2c_master_send(struct i2c_client *,const char* ,int);
-extern int i2c_master_recv(struct i2c_client *,char* ,int);
+extern int i2c_master_send(struct i2c_client *client, const char *buf,
+                          int count);
+extern int i2c_master_recv(struct i2c_client *client, char *buf, int count);
 
 /* Transfer num messages.
  */
-extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num);
-
+extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+                       int num);
 
 /* This is the very generalized SMBus access routine. You probably do not
    want to use this, though; one of the functions below may be much easier,
    and probably just as fast.
    Note that we use i2c_adapter here, because you do not need a specific
    smbus adapter to call this function. */
-extern s32 i2c_smbus_xfer (struct i2c_adapter * adapter, u16 addr,
-                           unsigned short flags,
-                           char read_write, u8 command, int size,
-                           union i2c_smbus_data * data);
+extern s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
+                         unsigned short flags, char read_write, u8 command,
+                         int size, union i2c_smbus_data *data);
 
 /* Now follow the 'nice' access routines. These also document the calling
    conventions of i2c_smbus_xfer. */
 
-extern s32 i2c_smbus_read_byte(struct i2c_client * client);
-extern s32 i2c_smbus_write_byte(struct i2c_client * client, u8 value);
-extern s32 i2c_smbus_read_byte_data(struct i2c_client * client, u8 command);
-extern s32 i2c_smbus_write_byte_data(struct i2c_client * client,
-                                     u8 command, u8 value);
-extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command);
-extern s32 i2c_smbus_write_word_data(struct i2c_client * client,
-                                     u8 command, u16 value);
+extern s32 i2c_smbus_read_byte(struct i2c_client *client);
+extern s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value);
+extern s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command);
+extern s32 i2c_smbus_write_byte_data(struct i2c_client *client,
+                                    u8 command, u8 value);
+extern s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command);
+extern s32 i2c_smbus_write_word_data(struct i2c_client *client,
+                                    u8 command, u16 value);
 /* Returns the number of read bytes */
 extern s32 i2c_smbus_read_block_data(struct i2c_client *client,
                                     u8 command, u8 *values);
-extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
-                                     u8 command, u8 length,
-                                     const u8 *values);
+extern s32 i2c_smbus_write_block_data(struct i2c_client *client,
+                                     u8 command, u8 length, const u8 *values);
 /* Returns the number of read bytes */
-extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
+extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client,
                                         u8 command, u8 length, u8 *values);
-extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
+extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client,
                                          u8 command, u8 length,
                                          const u8 *values);
 
@@ -169,7 +168,7 @@ struct i2c_driver {
        /* a ioctl like command that can be used to perform specific functions
         * with the device.
         */
-       int (*command)(struct i2c_client *client,unsigned int cmd, void *arg);
+       int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
 
        struct device_driver driver;
        const struct i2c_device_id *id_table;
@@ -224,14 +223,14 @@ static inline struct i2c_client *kobj_to_i2c_client(struct kobject *kobj)
        return to_i2c_client(dev);
 }
 
-static inline void *i2c_get_clientdata (struct i2c_client *dev)
+static inline void *i2c_get_clientdata(const struct i2c_client *dev)
 {
-       return dev_get_drvdata (&dev->dev);
+       return dev_get_drvdata(&dev->dev);
 }
 
-static inline void i2c_set_clientdata (struct i2c_client *dev, void *data)
+static inline void i2c_set_clientdata(struct i2c_client *dev, void *data)
 {
-       dev_set_drvdata (&dev->dev, data);
+       dev_set_drvdata(&dev->dev, data);
 }
 
 /**
@@ -240,6 +239,7 @@ static inline void i2c_set_clientdata (struct i2c_client *dev, void *data)
  * @flags: to initialize i2c_client.flags
  * @addr: stored in i2c_client.addr
  * @platform_data: stored in i2c_client.dev.platform_data
+ * @archdata: copied into i2c_client.dev.archdata
  * @irq: stored in i2c_client.irq
  *
  * I2C doesn't actually support hardware probing, although controllers and
@@ -259,6 +259,7 @@ struct i2c_board_info {
        unsigned short  flags;
        unsigned short  addr;
        void            *platform_data;
+       struct dev_archdata     *archdata;
        int             irq;
 };
 
@@ -272,7 +273,7 @@ struct i2c_board_info {
  * fields (such as associated irq, or device-specific platform_data)
  * are provided using conventional syntax.
  */
-#define I2C_BOARD_INFO(dev_type,dev_addr) \
+#define I2C_BOARD_INFO(dev_type, dev_addr) \
        .type = (dev_type), .addr = (dev_addr)
 
 
@@ -306,10 +307,12 @@ extern void i2c_unregister_device(struct i2c_client *);
  */
 #ifdef CONFIG_I2C_BOARDINFO
 extern int
-i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned n);
+i2c_register_board_info(int busnum, struct i2c_board_info const *info,
+                       unsigned n);
 #else
 static inline int
-i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned n)
+i2c_register_board_info(int busnum, struct i2c_board_info const *info,
+                       unsigned n)
 {
        return 0;
 }
@@ -328,11 +331,11 @@ struct i2c_algorithm {
           using common I2C messages */
        /* master_xfer should return the number of messages successfully
           processed, or a negative value on error */
-       int (*master_xfer)(struct i2c_adapter *adap,struct i2c_msg *msgs,
-                          int num);
+       int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
+                          int num);
        int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
-                          unsigned short flags, char read_write,
-                          u8 command, int size, union i2c_smbus_data * data);
+                          unsigned short flags, char read_write,
+                          u8 command, int size, union i2c_smbus_data *data);
 
        /* To determine what the adapter supports */
        u32 (*functionality) (struct i2c_adapter *);
@@ -345,7 +348,7 @@ struct i2c_algorithm {
 struct i2c_adapter {
        struct module *owner;
        unsigned int id;
-       unsigned int class;
+       unsigned int class;               /* classes to allow probing for */
        const struct i2c_algorithm *algo; /* the algorithm to access the bus */
        void *algo_data;
 
@@ -369,14 +372,14 @@ struct i2c_adapter {
 };
 #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
 
-static inline void *i2c_get_adapdata (struct i2c_adapter *dev)
+static inline void *i2c_get_adapdata(const struct i2c_adapter *dev)
 {
-       return dev_get_drvdata (&dev->dev);
+       return dev_get_drvdata(&dev->dev);
 }
 
-static inline void i2c_set_adapdata (struct i2c_adapter *dev, void *data)
+static inline void i2c_set_adapdata(struct i2c_adapter *dev, void *data)
 {
-       dev_set_drvdata (&dev->dev, data);
+       dev_set_drvdata(&dev->dev, data);
 }
 
 /*flags for the client struct: */
@@ -449,7 +452,7 @@ extern int i2c_probe(struct i2c_adapter *adapter,
                const struct i2c_client_address_data *address_data,
                int (*found_proc) (struct i2c_adapter *, int, int));
 
-extern struct i2c_adapteri2c_get_adapter(int id);
+extern struct i2c_adapter *i2c_get_adapter(int id);
 extern void i2c_put_adapter(struct i2c_adapter *adap);
 
 
@@ -465,7 +468,7 @@ static inline int i2c_check_functionality(struct i2c_adapter *adap, u32 func)
        return (func & i2c_get_functionality(adap)) == func;
 }
 
-/* Return id number for a specific adapter */
+/* Return the adapter number for a specific adapter */
 static inline int i2c_adapter_id(struct i2c_adapter *adap)
 {
        return adap->nr;
@@ -526,7 +529,7 @@ struct i2c_msg {
 
 #define I2C_FUNC_I2C                   0x00000001
 #define I2C_FUNC_10BIT_ADDR            0x00000002
-#define I2C_FUNC_PROTOCOL_MANGLING     0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */
+#define I2C_FUNC_PROTOCOL_MANGLING     0x00000004 /* I2C_M_NOSTART etc. */
 #define I2C_FUNC_SMBUS_PEC             0x00000008
 #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */
 #define I2C_FUNC_SMBUS_QUICK           0x00010000
@@ -541,30 +544,26 @@ struct i2c_msg {
 #define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
 #define I2C_FUNC_SMBUS_READ_I2C_BLOCK  0x04000000 /* I2C-like block xfer  */
 #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */
-#define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2         0x10000000 /* I2C-like block xfer  */
-#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 0x20000000 /* w/ 2-byte reg. addr. */
-
-#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \
-                             I2C_FUNC_SMBUS_WRITE_BYTE)
-#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \
-                                  I2C_FUNC_SMBUS_WRITE_BYTE_DATA)
-#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \
-                                  I2C_FUNC_SMBUS_WRITE_WORD_DATA)
-#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \
-                                   I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)
-#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \
-                                  I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)
-#define I2C_FUNC_SMBUS_I2C_BLOCK_2 (I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 | \
-                                    I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2)
-
-#define I2C_FUNC_SMBUS_EMUL (I2C_FUNC_SMBUS_QUICK | \
-                             I2C_FUNC_SMBUS_BYTE | \
-                             I2C_FUNC_SMBUS_BYTE_DATA | \
-                             I2C_FUNC_SMBUS_WORD_DATA | \
-                             I2C_FUNC_SMBUS_PROC_CALL | \
-                             I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \
-                            I2C_FUNC_SMBUS_I2C_BLOCK | \
-                            I2C_FUNC_SMBUS_PEC)
+
+#define I2C_FUNC_SMBUS_BYTE            (I2C_FUNC_SMBUS_READ_BYTE | \
+                                        I2C_FUNC_SMBUS_WRITE_BYTE)
+#define I2C_FUNC_SMBUS_BYTE_DATA       (I2C_FUNC_SMBUS_READ_BYTE_DATA | \
+                                        I2C_FUNC_SMBUS_WRITE_BYTE_DATA)
+#define I2C_FUNC_SMBUS_WORD_DATA       (I2C_FUNC_SMBUS_READ_WORD_DATA | \
+                                        I2C_FUNC_SMBUS_WRITE_WORD_DATA)
+#define I2C_FUNC_SMBUS_BLOCK_DATA      (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \
+                                        I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)
+#define I2C_FUNC_SMBUS_I2C_BLOCK       (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \
+                                        I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)
+
+#define I2C_FUNC_SMBUS_EMUL            (I2C_FUNC_SMBUS_QUICK | \
+                                        I2C_FUNC_SMBUS_BYTE | \
+                                        I2C_FUNC_SMBUS_BYTE_DATA | \
+                                        I2C_FUNC_SMBUS_WORD_DATA | \
+                                        I2C_FUNC_SMBUS_PROC_CALL | \
+                                        I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \
+                                        I2C_FUNC_SMBUS_I2C_BLOCK | \
+                                        I2C_FUNC_SMBUS_PEC)
 
 /*
  * Data for SMBus Messages
@@ -574,7 +573,7 @@ union i2c_smbus_data {
        __u8 byte;
        __u16 word;
        __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */
-                              /* and one more for user-space compatibility */
+                              /* and one more for user-space compatibility */
 };
 
 /* i2c_smbus_xfer read or write markers */
@@ -602,21 +601,21 @@ union i2c_smbus_data {
 
 /* Default fill of many variables */
 #define I2C_CLIENT_DEFAULTS {I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
-                          I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
-                          I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
-                          I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
-                          I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
-                          I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
-                          I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
-                          I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
-                          I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
-                          I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
-                          I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
-                          I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
-                          I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
-                          I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
-                          I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
-                          I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END}
+                            I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
+                            I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
+                            I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
+                            I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
+                            I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
+                            I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
+                            I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
+                            I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
+                            I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
+                            I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
+                            I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
+                            I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
+                            I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
+                            I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
+                            I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END}
 
 /* I2C_CLIENT_MODULE_PARM creates a module parameter, and puts it in the
    module header */
@@ -625,7 +624,7 @@ union i2c_smbus_data {
   static unsigned short var[I2C_CLIENT_MAX_OPTS] = I2C_CLIENT_DEFAULTS; \
   static unsigned int var##_num; \
   module_param_array(var, short, &var##_num, 0); \
-  MODULE_PARM_DESC(var,desc)
+  MODULE_PARM_DESC(var, desc)
 
 #define I2C_CLIENT_MODULE_PARM_FORCE(name)                             \
 I2C_CLIENT_MODULE_PARM(force_##name,                                   \
index cdb453162a97d5fcaaff803af1d96c3ac07301f1..fb604dcd38f19d89a817c8bc2397aa09d3ece62c 100644 (file)
@@ -228,6 +228,12 @@ struct twl4030_gpio_platform_data {
        int             gpio_base;
        unsigned        irq_base, irq_end;
 
+       /* package the two LED signals as output-only GPIOs? */
+       bool            use_leds;
+
+       /* gpio-n should control VMMC(n+1) if BIT(n) in mmc_cd is set */
+       u8              mmc_cd;
+
        /* For gpio-N, bit (1 << N) in "pullups" is set if that pullup
         * should be enabled.  Else, if that bit is set in "pulldowns",
         * that pulldown is enabled.  Don't waste power by letting any
@@ -277,6 +283,8 @@ struct twl4030_platform_data {
 
 /*----------------------------------------------------------------------*/
 
+int twl4030_sih_setup(int module);
+
 /*
  * FIXME completely stop using TWL4030_IRQ_BASE ... instead, pass the
  * IRQ data to subsidiary devices using platform device resources.
@@ -291,16 +299,16 @@ struct twl4030_platform_data {
 #define TWL4030_MODIRQ_BCI             (TWL4030_IRQ_BASE + 2)
 #define TWL4030_MODIRQ_MADC            (TWL4030_IRQ_BASE + 3)
 /* #define TWL4030_MODIRQ_USB          (TWL4030_IRQ_BASE + 4) */
-#define TWL4030_MODIRQ_PWR             (TWL4030_IRQ_BASE + 5)
+/* #define TWL4030_MODIRQ_PWR          (TWL4030_IRQ_BASE + 5) */
 
 #define TWL4030_PWRIRQ_PWRBTN          (TWL4030_PWR_IRQ_BASE + 0)
-#define TWL4030_PWRIRQ_CHG_PRES                (TWL4030_PWR_IRQ_BASE + 1)
-#define TWL4030_PWRIRQ_USB_PRES                (TWL4030_PWR_IRQ_BASE + 2)
-#define TWL4030_PWRIRQ_RTC             (TWL4030_PWR_IRQ_BASE + 3)
-#define TWL4030_PWRIRQ_HOT_DIE         (TWL4030_PWR_IRQ_BASE + 4)
-#define TWL4030_PWRIRQ_PWROK_TIMEOUT   (TWL4030_PWR_IRQ_BASE + 5)
-#define TWL4030_PWRIRQ_MBCHG           (TWL4030_PWR_IRQ_BASE + 6)
-#define TWL4030_PWRIRQ_SC_DETECT       (TWL4030_PWR_IRQ_BASE + 7)
+/* #define TWL4030_PWRIRQ_CHG_PRES             (TWL4030_PWR_IRQ_BASE + 1) */
+/* #define TWL4030_PWRIRQ_USB_PRES             (TWL4030_PWR_IRQ_BASE + 2) */
+/* #define TWL4030_PWRIRQ_RTC          (TWL4030_PWR_IRQ_BASE + 3) */
+/* #define TWL4030_PWRIRQ_HOT_DIE              (TWL4030_PWR_IRQ_BASE + 4) */
+/* #define TWL4030_PWRIRQ_PWROK_TIMEOUT        (TWL4030_PWR_IRQ_BASE + 5) */
+/* #define TWL4030_PWRIRQ_MBCHG                (TWL4030_PWR_IRQ_BASE + 6) */
+/* #define TWL4030_PWRIRQ_SC_DETECT    (TWL4030_PWR_IRQ_BASE + 7) */
 
 /* Rest are unsued currently*/
 
@@ -317,17 +325,13 @@ struct twl4030_platform_data {
 /* TWL4030 GPIO interrupt definitions */
 
 #define TWL4030_GPIO_IRQ_NO(n)         (TWL4030_GPIO_IRQ_BASE + (n))
-#define TWL4030_GPIO_IS_ENABLE         1
 
 /*
  * Exported TWL4030 GPIO APIs
  *
  * WARNING -- use standard GPIO and IRQ calls instead; these will vanish.
  */
-int twl4030_get_gpio_datain(int gpio);
-int twl4030_request_gpio(int gpio);
 int twl4030_set_gpio_debounce(int gpio, int enable);
-int twl4030_free_gpio(int gpio);
 
 #if defined(CONFIG_TWL4030_BCI_BATTERY) || \
        defined(CONFIG_TWL4030_BCI_BATTERY_MODULE)
index c47e371554c1ccb122945ab087eb4c9914480010..54525be4b5f87f8d0f43d21a40db8efee2ec10f5 100644 (file)
@@ -461,12 +461,26 @@ struct ide_acpi_drive_link;
 struct ide_acpi_hwif_link;
 #endif
 
+struct ide_drive_s;
+
+struct ide_disk_ops {
+       int             (*check)(struct ide_drive_s *, const char *);
+       int             (*get_capacity)(struct ide_drive_s *);
+       void            (*setup)(struct ide_drive_s *);
+       void            (*flush)(struct ide_drive_s *);
+       int             (*init_media)(struct ide_drive_s *, struct gendisk *);
+       int             (*set_doorlock)(struct ide_drive_s *, struct gendisk *,
+                                       int);
+       ide_startstop_t (*do_request)(struct ide_drive_s *, struct request *,
+                                     sector_t);
+       int             (*end_request)(struct ide_drive_s *, int, int);
+       int             (*ioctl)(struct ide_drive_s *, struct block_device *,
+                                fmode_t, unsigned int, unsigned long);
+};
+
 /* ATAPI device flags */
 enum {
        IDE_AFLAG_DRQ_INTERRUPT         = (1 << 0),
-       IDE_AFLAG_MEDIA_CHANGED         = (1 << 1),
-       /* Drive cannot lock the door. */
-       IDE_AFLAG_NO_DOORLOCK           = (1 << 2),
 
        /* ide-cd */
        /* Drive cannot eject the disc. */
@@ -498,14 +512,10 @@ enum {
        IDE_AFLAG_LE_SPEED_FIELDS       = (1 << 17),
 
        /* ide-floppy */
-       /* Format in progress */
-       IDE_AFLAG_FORMAT_IN_PROGRESS    = (1 << 18),
        /* Avoid commands not supported in Clik drive */
        IDE_AFLAG_CLIK_DRIVE            = (1 << 19),
        /* Requires BH algorithm for packets */
        IDE_AFLAG_ZIP_DRIVE             = (1 << 20),
-       /* Write protect */
-       IDE_AFLAG_WP                    = (1 << 21),
        /* Supports format progress report */
        IDE_AFLAG_SRFP                  = (1 << 22),
 
@@ -578,7 +588,11 @@ enum {
        /* don't unload heads */
        IDE_DFLAG_NO_UNLOAD             = (1 << 27),
        /* heads unloaded, please don't reset port */
-       IDE_DFLAG_PARKED                = (1 << 28)
+       IDE_DFLAG_PARKED                = (1 << 28),
+       IDE_DFLAG_MEDIA_CHANGED         = (1 << 29),
+       /* write protect */
+       IDE_DFLAG_WP                    = (1 << 30),
+       IDE_DFLAG_FORMAT_IN_PROGRESS    = (1 << 31),
 };
 
 struct ide_drive_s {
@@ -597,6 +611,8 @@ struct ide_drive_s {
 #endif
        struct hwif_s           *hwif;  /* actually (ide_hwif_t *) */
 
+       const struct ide_disk_ops *disk_ops;
+
        unsigned long dev_flags;
 
        unsigned long sleep;            /* sleep until this time */
@@ -1123,8 +1139,8 @@ struct ide_driver_s {
        void            (*resume)(ide_drive_t *);
        void            (*shutdown)(ide_drive_t *);
 #ifdef CONFIG_IDE_PROC_FS
-       ide_proc_entry_t                *proc;
-       const struct ide_proc_devset    *settings;
+       ide_proc_entry_t *              (*proc_entries)(ide_drive_t *);
+       const struct ide_proc_devset *  (*proc_devsets)(ide_drive_t *);
 #endif
 };
 
@@ -1142,8 +1158,7 @@ struct ide_ioctl_devset {
 int ide_setting_ioctl(ide_drive_t *, struct block_device *, unsigned int,
                      unsigned long, const struct ide_ioctl_devset *);
 
-int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *,
-                     unsigned, unsigned long);
+int generic_ide_ioctl(ide_drive_t *, struct block_device *, unsigned, unsigned long);
 
 extern int ide_vlb_clk;
 extern int ide_pci_clk;
index ad63824460e34d2838d0a77833f21121814251cd..0c1264668be0ccb32ffa98a304a706dd1009b6f3 100644 (file)
@@ -40,7 +40,7 @@
 
 /* These are for everybody (although not all archs will actually
    discard it in modules) */
-#define __init         __section(.init.text) __cold
+#define __init         __section(.init.text) __cold notrace
 #define __initdata     __section(.init.data)
 #define __initconst    __section(.init.rodata)
 #define __exitdata     __section(.exit.data)
index 021d8e720c7941f17cd6a541a63b7a9275f68c9c..23fd8909b9e52c143faf401030e8d282c559baeb 100644 (file)
@@ -170,6 +170,7 @@ extern struct group_info init_groups;
        .cpu_timers     = INIT_CPU_TIMERS(tsk.cpu_timers),              \
        .fs_excl        = ATOMIC_INIT(0),                               \
        .pi_lock        = __SPIN_LOCK_UNLOCKED(tsk.pi_lock),            \
+       .timer_slack_ns = 50000, /* 50 usec default slack */            \
        .pids = {                                                       \
                [PIDTYPE_PID]  = INIT_PID_LINK(PIDTYPE_PID),            \
                [PIDTYPE_PGID] = INIT_PID_LINK(PIDTYPE_PGID),           \
index 2e117f30a76ca8a18f328b96f884387534602f29..3d017cfd245b6a2ad690cd4579fd6413f6c22a42 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/io.h>
 #include <linux/dma_remapping.h>
 #include <asm/cacheflush.h>
+#include <asm/iommu.h>
 
 /*
  * Intel IOMMU register specification per version 1.0 public spec.
@@ -127,6 +128,7 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
 
 
 /* IOTLB_REG */
+#define DMA_TLB_FLUSH_GRANU_OFFSET  60
 #define DMA_TLB_GLOBAL_FLUSH (((u64)1) << 60)
 #define DMA_TLB_DSI_FLUSH (((u64)2) << 60)
 #define DMA_TLB_PSI_FLUSH (((u64)3) << 60)
@@ -140,6 +142,7 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
 #define DMA_TLB_MAX_SIZE (0x3f)
 
 /* INVALID_DESC */
+#define DMA_CCMD_INVL_GRANU_OFFSET  61
 #define DMA_ID_TLB_GLOBAL_FLUSH        (((u64)1) << 3)
 #define DMA_ID_TLB_DSI_FLUSH   (((u64)2) << 3)
 #define DMA_ID_TLB_PSI_FLUSH   (((u64)3) << 3)
@@ -200,22 +203,21 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
 #define dma_frcd_type(d) ((d >> 30) & 1)
 #define dma_frcd_fault_reason(c) (c & 0xff)
 #define dma_frcd_source_id(c) (c & 0xffff)
-#define dma_frcd_page_addr(d) (d & (((u64)-1) << 12)) /* low 64 bit */
-
-#define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000) /* 10sec */
-
-#define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \
-{\
-       cycles_t start_time = get_cycles();\
-       while (1) {\
-               sts = op (iommu->reg + offset);\
-               if (cond)\
-                       break;\
+/* low 64 bit */
+#define dma_frcd_page_addr(d) (d & (((u64)-1) << PAGE_SHIFT))
+
+#define IOMMU_WAIT_OP(iommu, offset, op, cond, sts)                    \
+do {                                                                   \
+       cycles_t start_time = get_cycles();                             \
+       while (1) {                                                     \
+               sts = op(iommu->reg + offset);                          \
+               if (cond)                                               \
+                       break;                                          \
                if (DMAR_OPERATION_TIMEOUT < (get_cycles() - start_time))\
-                       panic("DMAR hardware is malfunctioning\n");\
-               cpu_relax();\
-       }\
-}
+                       panic("DMAR hardware is malfunctioning\n");     \
+               cpu_relax();                                            \
+       }                                                               \
+} while (0)
 
 #define QI_LENGTH      256     /* queue length */
 
@@ -238,6 +240,19 @@ enum {
 #define QI_IWD_STATUS_DATA(d)  (((u64)d) << 32)
 #define QI_IWD_STATUS_WRITE    (((u64)1) << 5)
 
+#define QI_IOTLB_DID(did)      (((u64)did) << 16)
+#define QI_IOTLB_DR(dr)        (((u64)dr) << 7)
+#define QI_IOTLB_DW(dw)        (((u64)dw) << 6)
+#define QI_IOTLB_GRAN(gran)    (((u64)gran) >> (DMA_TLB_FLUSH_GRANU_OFFSET-4))
+#define QI_IOTLB_ADDR(addr)    (((u64)addr) & VTD_PAGE_MASK)
+#define QI_IOTLB_IH(ih)                (((u64)ih) << 6)
+#define QI_IOTLB_AM(am)                (((u8)am))
+
+#define QI_CC_FM(fm)           (((u64)fm) << 48)
+#define QI_CC_SID(sid)         (((u64)sid) << 32)
+#define QI_CC_DID(did)         (((u64)did) << 16)
+#define QI_CC_GRAN(gran)       (((u64)gran) >> (DMA_CCMD_INVL_GRANU_OFFSET-4))
+
 struct qi_desc {
        u64 low, high;
 };
@@ -263,6 +278,13 @@ struct ir_table {
 };
 #endif
 
+struct iommu_flush {
+       int (*flush_context)(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm,
+               u64 type, int non_present_entry_flush);
+       int (*flush_iotlb)(struct intel_iommu *iommu, u16 did, u64 addr,
+               unsigned int size_order, u64 type, int non_present_entry_flush);
+};
+
 struct intel_iommu {
        void __iomem    *reg; /* Pointer to hardware regs, virtual addr */
        u64             cap;
@@ -282,6 +304,7 @@ struct intel_iommu {
        unsigned char name[7];    /* Device Name */
        struct msi_msg saved_msg;
        struct sys_device sysdev;
+       struct iommu_flush flush;
 #endif
        struct q_inval  *qi;            /* Queued invalidation info */
 #ifdef CONFIG_INTR_REMAP
@@ -303,6 +326,12 @@ extern void free_iommu(struct intel_iommu *iommu);
 extern int dmar_enable_qi(struct intel_iommu *iommu);
 extern void qi_global_iec(struct intel_iommu *iommu);
 
+extern int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid,
+                               u8 fm, u64 type, int non_present_entry_flush);
+extern int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
+                         unsigned int size_order, u64 type,
+                         int non_present_entry_flush);
+
 extern void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu);
 
 void intel_iommu_domain_exit(struct dmar_domain *domain);
@@ -324,4 +353,11 @@ static inline int intel_iommu_found(void)
 }
 #endif /* CONFIG_DMAR */
 
+extern void *intel_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t);
+extern void intel_free_coherent(struct device *, size_t, void *, dma_addr_t);
+extern dma_addr_t intel_map_single(struct device *, phys_addr_t, size_t, int);
+extern void intel_unmap_single(struct device *, dma_addr_t, size_t, int);
+extern int intel_map_sg(struct device *, struct scatterlist *, int, int);
+extern void intel_unmap_sg(struct device *, struct scatterlist *, int, int);
+
 #endif
index 35a61dc60d51ac9878ea9ba6fad94b579403f652..f58a0cf8929a81fb14025ab8683ab32bf8ab539c 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/preempt.h>
 #include <linux/cpumask.h>
 #include <linux/irqreturn.h>
+#include <linux/irqnr.h>
 #include <linux/hardirq.h>
 #include <linux/sched.h>
 #include <linux/irqflags.h>
index 8d9411bc60f6f9356e0237cc601330576283d22a..d058c57be02d3508e27382e63980bfb593658649 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/spinlock.h>
 #include <linux/cpumask.h>
 #include <linux/irqreturn.h>
+#include <linux/irqnr.h>
 #include <linux/errno.h>
 
 #include <asm/irq.h>
@@ -152,6 +153,7 @@ struct irq_chip {
  * @name:              flow handler name for /proc/interrupts output
  */
 struct irq_desc {
+       unsigned int            irq;
        irq_flow_handler_t      handle_irq;
        struct irq_chip         *chip;
        struct msi_desc         *msi_desc;
@@ -170,7 +172,7 @@ struct irq_desc {
        cpumask_t               affinity;
        unsigned int            cpu;
 #endif
-#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)
+#ifdef CONFIG_GENERIC_PENDING_IRQ
        cpumask_t               pending_mask;
 #endif
 #ifdef CONFIG_PROC_FS
@@ -179,8 +181,14 @@ struct irq_desc {
        const char              *name;
 } ____cacheline_internodealigned_in_smp;
 
+
 extern struct irq_desc irq_desc[NR_IRQS];
 
+static inline struct irq_desc *irq_to_desc(unsigned int irq)
+{
+       return (irq < nr_irqs) ? irq_desc + irq : NULL;
+}
+
 /*
  * Migration helpers for obsolete names, they will go away:
  */
@@ -198,19 +206,15 @@ extern int setup_irq(unsigned int irq, struct irqaction *new);
 
 #ifdef CONFIG_GENERIC_HARDIRQS
 
-#ifndef handle_dynamic_tick
-# define handle_dynamic_tick(a)                do { } while (0)
-#endif
-
 #ifdef CONFIG_SMP
 
-#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)
+#ifdef CONFIG_GENERIC_PENDING_IRQ
 
 void set_pending_irq(unsigned int irq, cpumask_t mask);
 void move_native_irq(int irq);
 void move_masked_irq(int irq);
 
-#else /* CONFIG_GENERIC_PENDING_IRQ || CONFIG_IRQBALANCE */
+#else /* CONFIG_GENERIC_PENDING_IRQ */
 
 static inline void move_irq(int irq)
 {
@@ -237,19 +241,14 @@ static inline void set_pending_irq(unsigned int irq, cpumask_t mask)
 
 #endif /* CONFIG_SMP */
 
-#ifdef CONFIG_IRQBALANCE
-extern void set_balance_irq_affinity(unsigned int irq, cpumask_t mask);
-#else
-static inline void set_balance_irq_affinity(unsigned int irq, cpumask_t mask)
-{
-}
-#endif
-
 extern int no_irq_affinity;
 
 static inline int irq_balancing_disabled(unsigned int irq)
 {
-       return irq_desc[irq].status & IRQ_NO_BALANCING_MASK;
+       struct irq_desc *desc;
+
+       desc = irq_to_desc(irq);
+       return desc->status & IRQ_NO_BALANCING_MASK;
 }
 
 /* Handle irq action chains: */
@@ -279,10 +278,8 @@ extern unsigned int __do_IRQ(unsigned int irq);
  * irqchip-style controller then we call the ->handle_irq() handler,
  * and it calls __do_IRQ() if it's attached to an irqtype-style controller.
  */
-static inline void generic_handle_irq(unsigned int irq)
+static inline void generic_handle_irq_desc(unsigned int irq, struct irq_desc *desc)
 {
-       struct irq_desc *desc = irq_desc + irq;
-
 #ifdef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ
        desc->handle_irq(irq, desc);
 #else
@@ -293,6 +290,11 @@ static inline void generic_handle_irq(unsigned int irq)
 #endif
 }
 
+static inline void generic_handle_irq(unsigned int irq)
+{
+       generic_handle_irq_desc(irq, irq_to_desc(irq));
+}
+
 /* Handling of unhandled and spurious interrupts: */
 extern void note_interrupt(unsigned int irq, struct irq_desc *desc,
                           int action_ret);
@@ -325,7 +327,10 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
 static inline void __set_irq_handler_unlocked(int irq,
                                              irq_flow_handler_t handler)
 {
-       irq_desc[irq].handle_irq = handler;
+       struct irq_desc *desc;
+
+       desc = irq_to_desc(irq);
+       desc->handle_irq = handler;
 }
 
 /*
@@ -353,13 +358,14 @@ extern void set_irq_noprobe(unsigned int irq);
 extern void set_irq_probe(unsigned int irq);
 
 /* Handle dynamic irq creation and destruction */
+extern unsigned int create_irq_nr(unsigned int irq_want);
 extern int create_irq(void);
 extern void destroy_irq(unsigned int irq);
 
 /* Test to see if a driver has successfully requested an irq */
 static inline int irq_has_action(unsigned int irq)
 {
-       struct irq_desc *desc = irq_desc + irq;
+       struct irq_desc *desc = irq_to_desc(irq);
        return desc->action != NULL;
 }
 
@@ -374,10 +380,10 @@ extern int set_irq_chip_data(unsigned int irq, void *data);
 extern int set_irq_type(unsigned int irq, unsigned int type);
 extern int set_irq_msi(unsigned int irq, struct msi_desc *entry);
 
-#define get_irq_chip(irq)      (irq_desc[irq].chip)
-#define get_irq_chip_data(irq) (irq_desc[irq].chip_data)
-#define get_irq_data(irq)      (irq_desc[irq].handler_data)
-#define get_irq_msi(irq)       (irq_desc[irq].msi_desc)
+#define get_irq_chip(irq)      (irq_to_desc(irq)->chip)
+#define get_irq_chip_data(irq) (irq_to_desc(irq)->chip_data)
+#define get_irq_data(irq)      (irq_to_desc(irq)->handler_data)
+#define get_irq_msi(irq)       (irq_to_desc(irq)->msi_desc)
 
 #endif /* CONFIG_GENERIC_HARDIRQS */
 
diff --git a/include/linux/irqnr.h b/include/linux/irqnr.h
new file mode 100644 (file)
index 0000000..452c280
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef _LINUX_IRQNR_H
+#define _LINUX_IRQNR_H
+
+#ifndef CONFIG_GENERIC_HARDIRQS
+#include <asm/irq.h>
+# define nr_irqs               NR_IRQS
+
+# define for_each_irq_desc(irq, desc)          \
+       for (irq = 0; irq < nr_irqs; irq++)
+#else
+extern int nr_irqs;
+
+# define for_each_irq_desc(irq, desc)          \
+       for (irq = 0, desc = irq_desc; irq < nr_irqs; irq++, desc++)
+
+# define for_each_irq_desc_reverse(irq, desc)                          \
+       for (irq = nr_irqs - 1, desc = irq_desc + (nr_irqs - 1);        \
+            irq >= 0; irq--, desc--)
+#endif
+
+#define for_each_irq_nr(irq)                   \
+       for (irq = 0; irq < nr_irqs; irq++)
+
+#endif
index 35d4f6342fac82f3158b88e23790aa03a2140c79..346e2b80be7d0ec26c7b7637f58af3d03b201297 100644 (file)
@@ -911,7 +911,7 @@ extern int     journal_set_features
                   (journal_t *, unsigned long, unsigned long, unsigned long);
 extern int        journal_create     (journal_t *);
 extern int        journal_load       (journal_t *journal);
-extern void       journal_destroy    (journal_t *);
+extern int        journal_destroy    (journal_t *);
 extern int        journal_recover    (journal_t *journal);
 extern int        journal_wipe       (journal_t *, int);
 extern int        journal_skip_recovery        (journal_t *);
index 5a566b705ca9c4afe9720fc5f4c665617352f627..396a350b87a60b79935a9b738c34783581319a2b 100644 (file)
@@ -191,6 +191,30 @@ extern int kernel_text_address(unsigned long addr);
 struct pid;
 extern struct pid *session_of_pgrp(struct pid *pgrp);
 
+/*
+ * FW_BUG
+ * Add this to a message where you are sure the firmware is buggy or behaves
+ * really stupid or out of spec. Be aware that the responsible BIOS developer
+ * should be able to fix this issue or at least get a concrete idea of the
+ * problem by reading your message without the need of looking at the kernel
+ * code.
+ * 
+ * Use it for definite and high priority BIOS bugs.
+ *
+ * FW_WARN
+ * Use it for not that clear (e.g. could the kernel messed up things already?)
+ * and medium priority BIOS bugs.
+ *
+ * FW_INFO
+ * Use this one if you want to tell the user or vendor about something
+ * suspicious, but generally harmless related to the firmware.
+ *
+ * Use it for information or very low priority BIOS bugs.
+ */
+#define FW_BUG         "[Firmware Bug]: "
+#define FW_WARN                "[Firmware Warn]: "
+#define FW_INFO                "[Firmware Info]: "
+
 #ifdef CONFIG_PRINTK
 asmlinkage int vprintk(const char *fmt, va_list args)
        __attribute__ ((format (printf, 1, 0)));
@@ -496,4 +520,9 @@ struct sysinfo {
 #define NUMA_BUILD 0
 #endif
 
+/* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */
+#ifdef CONFIG_FTRACE_MCOUNT_RECORD
+# define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD
+#endif
+
 #endif
index cf9f40a91c9c79837753956b135e49c9ec984630..4a145caeee075d3209fa4e0d324dfed7f9a15fe7 100644 (file)
@@ -39,19 +39,34 @@ DECLARE_PER_CPU(struct kernel_stat, kstat);
 
 extern unsigned long long nr_context_switches(void);
 
+struct irq_desc;
+
+static inline void kstat_incr_irqs_this_cpu(unsigned int irq,
+                                           struct irq_desc *desc)
+{
+       kstat_this_cpu.irqs[irq]++;
+}
+
+static inline unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
+{
+       return kstat_cpu(cpu).irqs[irq];
+}
+
 /*
  * Number of interrupts per specific IRQ source, since bootup
  */
-static inline int kstat_irqs(int irq)
+static inline unsigned int kstat_irqs(unsigned int irq)
 {
-       int cpu, sum = 0;
+       unsigned int sum = 0;
+       int cpu;
 
        for_each_possible_cpu(cpu)
-               sum += kstat_cpu(cpu).irqs[irq];
+               sum += kstat_irqs_cpu(irq, cpu);
 
        return sum;
 }
 
+extern unsigned long long task_delta_exec(struct task_struct *);
 extern void account_user_time(struct task_struct *, cputime_t);
 extern void account_user_time_scaled(struct task_struct *, cputime_t);
 extern void account_system_time(struct task_struct *, int, cputime_t);
index 0be7795655fab4279d3b9b4a6fa110b01a4fc070..497b1d1f7a05421ed88c66496848715e9b84811f 100644 (file)
@@ -29,6 +29,7 @@
  *             <jkenisto@us.ibm.com>  and Prasanna S Panchamukhi
  *             <prasanna@in.ibm.com> added function-return probes.
  */
+#include <linux/linkage.h>
 #include <linux/list.h>
 #include <linux/notifier.h>
 #include <linux/smp.h>
@@ -47,7 +48,7 @@
 #define KPROBE_HIT_SSDONE      0x00000008
 
 /* Attach to insert probes on any functions which should be ignored*/
-#define __kprobes      __attribute__((__section__(".kprobes.text")))
+#define __kprobes      __attribute__((__section__(".kprobes.text"))) notrace
 
 struct kprobe;
 struct pt_regs;
@@ -256,7 +257,7 @@ void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head);
 
 #else /* CONFIG_KPROBES */
 
-#define __kprobes      /**/
+#define __kprobes      notrace
 struct jprobe;
 struct kretprobe;
 
index 947cf84e555d66acc7c4869fdc6595bb1141dfcb..507f53ef8038a7a7ffcbc8fb8a9655055553ec4c 100644 (file)
@@ -340,6 +340,9 @@ enum {
 
        ATA_EHI_DID_RESET       = ATA_EHI_DID_SOFTRESET | ATA_EHI_DID_HARDRESET,
 
+       /* mask of flags to transfer *to* the slave link */
+       ATA_EHI_TO_SLAVE_MASK   = ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET,
+
        /* max tries if error condition is still set after ->error_handler */
        ATA_EH_MAX_TRIES        = 5,
 
@@ -692,7 +695,6 @@ struct ata_port {
        unsigned int            cbl;    /* cable type; ATA_CBL_xxx */
 
        struct ata_queued_cmd   qcmd[ATA_MAX_QUEUE];
-       unsigned long           qc_allocated;
        unsigned int            qc_active;
        int                     nr_active_links; /* #links with active qcs */
 
index 56ba37394656c7f211eaebdadf5481eda844acca..9fd1f859021b5018baffdb440261379dab4a55b3 100644 (file)
@@ -4,8 +4,6 @@
 #include <linux/compiler.h>
 #include <asm/linkage.h>
 
-#define notrace __attribute__((no_instrument_function))
-
 #ifdef __cplusplus
 #define CPP_ASMLINKAGE extern "C"
 #else
index 1290653f924181333f6699d37b161238370b1515..889196c7fbb1e77cc5b4561e2b0b7f937b864434 100644 (file)
@@ -160,4 +160,11 @@ extern int marker_probe_unregister_private_data(marker_probe_func *probe,
 extern void *marker_get_private_data(const char *name, marker_probe_func *probe,
        int num);
 
+/*
+ * marker_synchronize_unregister must be called between the last marker probe
+ * unregistration and the end of module exit to make sure there is no caller
+ * executing a probe when it is freed.
+ */
+#define marker_synchronize_unregister() synchronize_sched()
+
 #endif
index 77323a72dd3cc0517bb167b0b25803704588eb7a..cf9c679ab38b59fe8cb9794e4837e50dd1c9445d 100644 (file)
@@ -132,6 +132,15 @@ enum {
        MLX4_MAILBOX_SIZE       =  4096
 };
 
+enum {
+       /* set port opcode modifiers */
+       MLX4_SET_PORT_GENERAL   = 0x0,
+       MLX4_SET_PORT_RQP_CALC  = 0x1,
+       MLX4_SET_PORT_MAC_TABLE = 0x2,
+       MLX4_SET_PORT_VLAN_TABLE = 0x3,
+       MLX4_SET_PORT_PRIO_MAP  = 0x4,
+};
+
 struct mlx4_dev;
 
 struct mlx4_cmd_mailbox {
index b2f944468313bb296bbdf83d7ff574615a588b1b..bd9977b894907f294b06817a01a42b3c29dd25bc 100644 (file)
@@ -60,6 +60,7 @@ enum {
        MLX4_DEV_CAP_FLAG_IPOIB_CSUM    = 1 <<  7,
        MLX4_DEV_CAP_FLAG_BAD_PKEY_CNTR = 1 <<  8,
        MLX4_DEV_CAP_FLAG_BAD_QKEY_CNTR = 1 <<  9,
+       MLX4_DEV_CAP_FLAG_DPDP          = 1 << 12,
        MLX4_DEV_CAP_FLAG_MEM_WINDOW    = 1 << 16,
        MLX4_DEV_CAP_FLAG_APM           = 1 << 17,
        MLX4_DEV_CAP_FLAG_ATOMIC        = 1 << 18,
@@ -145,6 +146,29 @@ enum {
        MLX4_MTT_FLAG_PRESENT           = 1
 };
 
+enum mlx4_qp_region {
+       MLX4_QP_REGION_FW = 0,
+       MLX4_QP_REGION_ETH_ADDR,
+       MLX4_QP_REGION_FC_ADDR,
+       MLX4_QP_REGION_FC_EXCH,
+       MLX4_NUM_QP_REGION
+};
+
+enum mlx4_port_type {
+       MLX4_PORT_TYPE_IB       = 1 << 0,
+       MLX4_PORT_TYPE_ETH      = 1 << 1,
+};
+
+enum mlx4_special_vlan_idx {
+       MLX4_NO_VLAN_IDX        = 0,
+       MLX4_VLAN_MISS_IDX,
+       MLX4_VLAN_REGULAR
+};
+
+enum {
+       MLX4_NUM_FEXCH          = 64 * 1024,
+};
+
 static inline u64 mlx4_fw_ver(u64 major, u64 minor, u64 subminor)
 {
        return (major << 32) | (minor << 16) | subminor;
@@ -154,7 +178,9 @@ struct mlx4_caps {
        u64                     fw_ver;
        int                     num_ports;
        int                     vl_cap[MLX4_MAX_PORTS + 1];
-       int                     mtu_cap[MLX4_MAX_PORTS + 1];
+       int                     ib_mtu_cap[MLX4_MAX_PORTS + 1];
+       u64                     def_mac[MLX4_MAX_PORTS + 1];
+       int                     eth_mtu_cap[MLX4_MAX_PORTS + 1];
        int                     gid_table_len[MLX4_MAX_PORTS + 1];
        int                     pkey_table_len[MLX4_MAX_PORTS + 1];
        int                     local_ca_ack_delay;
@@ -169,7 +195,6 @@ struct mlx4_caps {
        int                     max_rq_desc_sz;
        int                     max_qp_init_rdma;
        int                     max_qp_dest_rdma;
-       int                     reserved_qps;
        int                     sqp_start;
        int                     num_srqs;
        int                     max_srq_wqes;
@@ -201,6 +226,15 @@ struct mlx4_caps {
        u16                     stat_rate_support;
        u8                      port_width_cap[MLX4_MAX_PORTS + 1];
        int                     max_gso_sz;
+       int                     reserved_qps_cnt[MLX4_NUM_QP_REGION];
+       int                     reserved_qps;
+       int                     reserved_qps_base[MLX4_NUM_QP_REGION];
+       int                     log_num_macs;
+       int                     log_num_vlans;
+       int                     log_num_prios;
+       enum mlx4_port_type     port_type[MLX4_MAX_PORTS + 1];
+       u8                      supported_type[MLX4_MAX_PORTS + 1];
+       u32                     port_mask;
 };
 
 struct mlx4_buf_list {
@@ -355,6 +389,11 @@ struct mlx4_init_port_param {
        u64                     si_guid;
 };
 
+#define mlx4_foreach_port(port, dev, type)                             \
+       for ((port) = 1; (port) <= (dev)->caps.num_ports; (port)++)     \
+               if (((type) == MLX4_PORT_TYPE_IB ? (dev)->caps.port_mask : \
+                    ~(dev)->caps.port_mask) & 1 << ((port) - 1))
+
 int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct,
                   struct mlx4_buf *buf);
 void mlx4_buf_free(struct mlx4_dev *dev, int size, struct mlx4_buf *buf);
@@ -400,7 +439,10 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt,
                  int collapsed);
 void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq);
 
-int mlx4_qp_alloc(struct mlx4_dev *dev, int sqpn, struct mlx4_qp *qp);
+int mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align, int *base);
+void mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt);
+
+int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp);
 void mlx4_qp_free(struct mlx4_dev *dev, struct mlx4_qp *qp);
 
 int mlx4_srq_alloc(struct mlx4_dev *dev, u32 pdn, struct mlx4_mtt *mtt,
@@ -416,6 +458,12 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
                          int block_mcast_loopback);
 int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]);
 
+int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *index);
+void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, int index);
+
+int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index);
+void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index);
+
 int mlx4_map_phys_fmr(struct mlx4_dev *dev, struct mlx4_fmr *fmr, u64 *page_list,
                      int npages, u64 iova, u32 *lkey, u32 *rkey);
 int mlx4_fmr_alloc(struct mlx4_dev *dev, u32 pd, u32 access, int max_pages,
index 61d19e1b7a0b0684ec6799b1d2351e167f10a1ae..139d7c88d9c91ddebe065b1898916f17d2dc27f1 100644 (file)
@@ -34,11 +34,15 @@ extern void unregister_kmmio_probe(struct kmmio_probe *p);
 /* Called from page fault handler. */
 extern int kmmio_handler(struct pt_regs *regs, unsigned long addr);
 
-/* Called from ioremap.c */
 #ifdef CONFIG_MMIOTRACE
+/* Called from ioremap.c */
 extern void mmiotrace_ioremap(resource_size_t offset, unsigned long size,
                                                        void __iomem *addr);
 extern void mmiotrace_iounmap(volatile void __iomem *addr);
+
+/* For anyone to insert markers. Remember trailing newline. */
+extern int mmiotrace_printk(const char *fmt, ...)
+                               __attribute__ ((format (printf, 1, 2)));
 #else
 static inline void mmiotrace_ioremap(resource_size_t offset,
                                        unsigned long size, void __iomem *addr)
@@ -48,15 +52,22 @@ static inline void mmiotrace_ioremap(resource_size_t offset,
 static inline void mmiotrace_iounmap(volatile void __iomem *addr)
 {
 }
-#endif /* CONFIG_MMIOTRACE_HOOKS */
+
+static inline int mmiotrace_printk(const char *fmt, ...)
+                               __attribute__ ((format (printf, 1, 0)));
+
+static inline int mmiotrace_printk(const char *fmt, ...)
+{
+       return 0;
+}
+#endif /* CONFIG_MMIOTRACE */
 
 enum mm_io_opcode {
        MMIO_READ = 0x1,     /* struct mmiotrace_rw */
        MMIO_WRITE = 0x2,    /* struct mmiotrace_rw */
        MMIO_PROBE = 0x3,    /* struct mmiotrace_map */
        MMIO_UNPROBE = 0x4,  /* struct mmiotrace_map */
-       MMIO_MARKER = 0x5,   /* raw char data */
-       MMIO_UNKNOWN_OP = 0x6, /* struct mmiotrace_rw */
+       MMIO_UNKNOWN_OP = 0x5, /* struct mmiotrace_rw */
 };
 
 struct mmiotrace_rw {
@@ -81,5 +92,6 @@ extern void enable_mmiotrace(void);
 extern void disable_mmiotrace(void);
 extern void mmio_trace_rw(struct mmiotrace_rw *rw);
 extern void mmio_trace_mapping(struct mmiotrace_map *map);
+extern int mmio_trace_printk(const char *fmt, va_list args);
 
 #endif /* MMIOTRACE_H */
index a41555cbe00ae071a02dab3c88b3c57bf6c38d4b..3bfed013350b0e6bac488e7a91e77153926e37d8 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/kobject.h>
 #include <linux/moduleparam.h>
 #include <linux/marker.h>
+#include <linux/tracepoint.h>
 #include <asm/local.h>
 
 #include <asm/module.h>
@@ -28,7 +29,7 @@
 #define MODULE_SYMBOL_PREFIX ""
 #endif
 
-#define MODULE_NAME_LEN (64 - sizeof(unsigned long))
+#define MODULE_NAME_LEN MAX_PARAM_PREFIX_LEN
 
 struct kernel_symbol
 {
@@ -59,6 +60,7 @@ struct module_kobject
        struct kobject kobj;
        struct module *mod;
        struct kobject *drivers_dir;
+       struct module_param_attrs *mp;
 };
 
 /* These are either module local, or the kernel's dummy ones. */
@@ -241,7 +243,6 @@ struct module
 
        /* Sysfs stuff. */
        struct module_kobject mkobj;
-       struct module_param_attrs *param_attrs;
        struct module_attribute *modinfo_attrs;
        const char *version;
        const char *srcversion;
@@ -276,7 +277,7 @@ struct module
 
        /* Exception table */
        unsigned int num_exentries;
-       const struct exception_table_entry *extable;
+       struct exception_table_entry *extable;
 
        /* Startup function. */
        int (*init)(void);
@@ -331,6 +332,10 @@ struct module
        struct marker *markers;
        unsigned int num_markers;
 #endif
+#ifdef CONFIG_TRACEPOINTS
+       struct tracepoint *tracepoints;
+       unsigned int num_tracepoints;
+#endif
 
 #ifdef CONFIG_MODULE_UNLOAD
        /* What modules depend on me? */
@@ -453,6 +458,9 @@ extern void print_modules(void);
 
 extern void module_update_markers(void);
 
+extern void module_update_tracepoints(void);
+extern int module_get_iter_tracepoints(struct tracepoint_iter *iter);
+
 #else /* !CONFIG_MODULES... */
 #define EXPORT_SYMBOL(sym)
 #define EXPORT_SYMBOL_GPL(sym)
@@ -557,6 +565,15 @@ static inline void module_update_markers(void)
 {
 }
 
+static inline void module_update_tracepoints(void)
+{
+}
+
+static inline int module_get_iter_tracepoints(struct tracepoint_iter *iter)
+{
+       return 0;
+}
+
 #endif /* CONFIG_MODULES */
 
 struct device_driver;
index ec624381c844e26db58bbdd94eeee9e0b9de6962..e4af3399ef48ae862cdadd95832a96ac1bca2ffe 100644 (file)
@@ -13,6 +13,9 @@
 #define MODULE_PARAM_PREFIX KBUILD_MODNAME "."
 #endif
 
+/* Chosen so that structs with an unsigned long line up. */
+#define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long))
+
 #ifdef MODULE
 #define ___module_cat(a,b) __mod_ ## a ## b
 #define __module_cat(a,b) ___module_cat(a,b)
@@ -79,7 +82,8 @@ struct kparam_array
 #define __module_param_call(prefix, name, set, get, arg, perm)         \
        /* Default value instead of permissions? */                     \
        static int __param_perm_check_##name __attribute__((unused)) =  \
-       BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)); \
+       BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2))  \
+       + BUILD_BUG_ON_ZERO(sizeof(""prefix) > MAX_PARAM_PREFIX_LEN);   \
        static const char __param_str_##name[] = prefix #name;          \
        static struct kernel_param __moduleparam_const __param_##name   \
        __used                                                          \
@@ -100,6 +104,25 @@ struct kparam_array
 #define module_param(name, type, perm)                         \
        module_param_named(name, name, type, perm)
 
+#ifndef MODULE
+/**
+ * core_param - define a historical core kernel parameter.
+ * @name: the name of the cmdline and sysfs parameter (often the same as var)
+ * @var: the variable
+ * @type: the type (for param_set_##type and param_get_##type)
+ * @perm: visibility in sysfs
+ *
+ * core_param is just like module_param(), but cannot be modular and
+ * doesn't add a prefix (such as "printk.").  This is for compatibility
+ * with __setup(), and it makes sense as truly core parameters aren't
+ * tied to the particular file they're in.
+ */
+#define core_param(name, var, type, perm)                              \
+       param_check_##type(name, &(var));                               \
+       __module_param_call("", name, param_set_##type, param_get_##type, \
+                           &var, perm)
+#endif /* !MODULE */
+
 /* Actually copy string: maxlen param is usually sizeof(string). */
 #define module_param_string(name, string, len, perm)                   \
        static const struct kparam_string __param_string_##name         \
index 68f8c3203c89d4d7c42404e4084051342206b875..99eb80306dc5bba4fab74b9a1693222209d619ea 100644 (file)
@@ -51,8 +51,10 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
 /*
  * Intent data
  */
-#define LOOKUP_OPEN            (0x0100)
-#define LOOKUP_CREATE          (0x0200)
+#define LOOKUP_OPEN            0x0100
+#define LOOKUP_CREATE          0x0200
+#define LOOKUP_EXCL            0x0400
+#define LOOKUP_RENAME_TARGET   0x0800
 
 extern int user_path_at(int, const char __user *, unsigned, struct path *);
 
@@ -61,6 +63,8 @@ extern int user_path_at(int, const char __user *, unsigned, struct path *);
 #define user_path_dir(name, path) \
        user_path_at(AT_FDCWD, name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, path)
 
+extern int kern_path(const char *, unsigned, struct path *);
+
 extern int path_lookup(const char *, unsigned, struct nameidata *);
 extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
                           const char *, unsigned int, struct nameidata *);
index bcb8f725427c4868a6f4e6461a1ee720ed8b793c..5231861f357de5e3b2015ac4d8ca1d0badfefa70 100644 (file)
@@ -85,13 +85,6 @@ int oprofile_arch_init(struct oprofile_operations * ops);
  */
 void oprofile_arch_exit(void);
 
-/**
- * Add data to the event buffer.
- * The data passed is free-form, but typically consists of
- * file offsets, dcookies, context information, and ESCAPE codes.
- */
-void add_event_entry(unsigned long data);
-
 /**
  * Add a sample. This may be called from any context. Pass
  * smp_processor_id() as cpu.
@@ -162,5 +155,14 @@ int oprofilefs_ulong_from_user(unsigned long * val, char const __user * buf, siz
 
 /** lock for read/write safety */
 extern spinlock_t oprofilefs_lock;
+
+/**
+ * Add the contents of a circular buffer to the event buffer.
+ */
+void oprofile_put_buff(unsigned long *buf, unsigned int start,
+                       unsigned int stop, unsigned int max);
+
+unsigned long oprofile_get_cpu_buffer_size(void);
+void oprofile_cpu_buffer_inc_smpl_lost(void);
  
 #endif /* OPROFILE_H */
index 0fd39f2231ec36d9a18260e1221a9b2271627304..f546ad6fc028d82989217eda2e8c8bb9bd5afa82 100644 (file)
@@ -99,5 +99,10 @@ static inline struct page_cgroup *lookup_page_cgroup(struct page *page)
 {
        return NULL;
 }
+
+static inline void page_cgroup_init(void)
+{
+}
+
 #endif
 #endif
index acf8f24037cd0cd261772e23cbf8d86386318f2d..752def8a2ef4211c3486fa19e61b8f148f7d92cb 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/kobject.h>
 #include <asm/atomic.h>
 #include <linux/device.h>
+#include <linux/io.h>
 
 /* Include the ID list */
 #include <linux/pci_ids.h>
@@ -64,6 +65,11 @@ struct pci_slot {
        struct kobject kobj;
 };
 
+static inline const char *pci_slot_name(const struct pci_slot *slot)
+{
+       return kobject_name(&slot->kobj);
+}
+
 /* File state for mmap()s on /proc/bus/pci/X/Y */
 enum pci_mmap_state {
        pci_mmap_io,
@@ -214,6 +220,7 @@ struct pci_dev {
        unsigned int    broken_parity_status:1; /* Device generates false positive parity */
        unsigned int    msi_enabled:1;
        unsigned int    msix_enabled:1;
+       unsigned int    ari_enabled:1;  /* ARI forwarding */
        unsigned int    is_managed:1;
        unsigned int    is_pcie:1;
        pci_dev_flags_t dev_flags;
@@ -347,7 +354,6 @@ struct pci_bus_region {
 struct pci_dynids {
        spinlock_t lock;            /* protects list, index */
        struct list_head list;      /* for IDs added at runtime */
-       unsigned int use_driver_data:1; /* pci_device_id->driver_data is used */
 };
 
 /* ---------------------------------------------------------------- */
@@ -456,8 +462,8 @@ struct pci_driver {
 
 /**
  * PCI_VDEVICE - macro used to describe a specific pci device in short form
- * @vend: the vendor name
- * @dev: the 16 bit PCI Device ID
+ * @vendor: the vendor name
+ * @device: the 16 bit PCI Device ID
  *
  * This macro is used to create a struct pci_device_id that matches a
  * specific PCI device.  The subvendor, and subdevice fields will be set
@@ -509,9 +515,10 @@ struct pci_bus *pci_create_bus(struct device *parent, int bus,
 struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev,
                                int busnr);
 struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
-                                const char *name);
+                                const char *name,
+                                struct hotplug_slot *hotplug);
 void pci_destroy_slot(struct pci_slot *slot);
-void pci_update_slot_number(struct pci_slot *slot, int slot_nr);
+void pci_renumber_slot(struct pci_slot *slot, int slot_nr);
 int pci_scan_slot(struct pci_bus *bus, int devfn);
 struct pci_dev *pci_scan_single_device(struct pci_bus *bus, int devfn);
 void pci_device_add(struct pci_dev *dev, struct pci_bus *bus);
@@ -626,6 +633,8 @@ int pcix_get_mmrbc(struct pci_dev *dev);
 int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc);
 int pcie_get_readrq(struct pci_dev *dev);
 int pcie_set_readrq(struct pci_dev *dev, int rq);
+int pci_reset_function(struct pci_dev *dev);
+int pci_execute_reset_function(struct pci_dev *dev);
 void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
 int __must_check pci_assign_resource(struct pci_dev *dev, int i);
 int pci_select_bars(struct pci_dev *dev, unsigned long flags);
@@ -645,6 +654,7 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state);
 bool pci_pme_capable(struct pci_dev *dev, pci_power_t state);
 void pci_pme_active(struct pci_dev *dev, bool enable);
 int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable);
+int pci_wake_from_d3(struct pci_dev *dev, bool enable);
 pci_power_t pci_target_state(struct pci_dev *dev);
 int pci_prepare_to_sleep(struct pci_dev *dev);
 int pci_back_from_sleep(struct pci_dev *dev);
@@ -725,7 +735,7 @@ enum pci_dma_burst_strategy {
 };
 
 struct msix_entry {
-       u16     vector; /* kernel uses to write allocated vector */
+       u32     vector; /* kernel uses to write allocated vector */
        u16     entry;  /* driver uses to specify entry, OS writes */
 };
 
@@ -1118,5 +1128,20 @@ static inline void pci_mmcfg_early_init(void) { }
 static inline void pci_mmcfg_late_init(void) { }
 #endif
 
+#ifdef CONFIG_HAS_IOMEM
+static inline void * pci_ioremap_bar(struct pci_dev *pdev, int bar)
+{
+       /*
+        * Make sure the BAR is actually a memory resource, not an IO resource
+        */
+       if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) {
+               WARN_ON(1);
+               return NULL;
+       }
+       return ioremap_nocache(pci_resource_start(pdev, bar),
+                                    pci_resource_len(pdev, bar));
+}
+#endif
+
 #endif /* __KERNEL__ */
 #endif /* LINUX_PCI_H */
index a08cd06b541a190975d04ee7d1cdd8af73e0a9f5..a00bd1a0f156d729447d4d06d026f55d2287e930 100644 (file)
@@ -142,8 +142,6 @@ struct hotplug_slot_info {
 
 /**
  * struct hotplug_slot - used to register a physical slot with the hotplug pci core
- * @name: the name of the slot being registered.  This string must
- * be unique amoung slots registered on this system.
  * @ops: pointer to the &struct hotplug_slot_ops to be used for this slot
  * @info: pointer to the &struct hotplug_slot_info for the initial values for
  * this slot.
@@ -153,7 +151,6 @@ struct hotplug_slot_info {
  * needs.
  */
 struct hotplug_slot {
-       char                            *name;
        struct hotplug_slot_ops         *ops;
        struct hotplug_slot_info        *info;
        void (*release) (struct hotplug_slot *slot);
@@ -165,7 +162,13 @@ struct hotplug_slot {
 };
 #define to_hotplug_slot(n) container_of(n, struct hotplug_slot, kobj)
 
-extern int pci_hp_register(struct hotplug_slot *, struct pci_bus *, int nr);
+static inline const char *hotplug_slot_name(const struct hotplug_slot *slot)
+{
+       return pci_slot_name(slot->pci_slot);
+}
+
+extern int pci_hp_register(struct hotplug_slot *, struct pci_bus *, int nr,
+                          const char *name);
 extern int pci_hp_deregister(struct hotplug_slot *slot);
 extern int __must_check pci_hp_change_slot_info        (struct hotplug_slot *slot,
                                                 struct hotplug_slot_info *info);
index 8edddc240e4f61c133308d9af0af7da179b9c56b..1800f1d6e40dd1c22ff973e6f86f654ee27755f4 100644 (file)
 
 #define PCI_VENDOR_ID_OXSEMI           0x1415
 #define PCI_DEVICE_ID_OXSEMI_12PCI840  0x8403
+#define PCI_DEVICE_ID_OXSEMI_PCIe840           0xC000
+#define PCI_DEVICE_ID_OXSEMI_PCIe840_G         0xC004
+#define PCI_DEVICE_ID_OXSEMI_PCIe952_0         0xC100
+#define PCI_DEVICE_ID_OXSEMI_PCIe952_0_G       0xC104
+#define PCI_DEVICE_ID_OXSEMI_PCIe952_1         0xC110
+#define PCI_DEVICE_ID_OXSEMI_PCIe952_1_G       0xC114
+#define PCI_DEVICE_ID_OXSEMI_PCIe952_1_U       0xC118
+#define PCI_DEVICE_ID_OXSEMI_PCIe952_1_GU      0xC11C
 #define PCI_DEVICE_ID_OXSEMI_16PCI954  0x9501
 #define PCI_DEVICE_ID_OXSEMI_16PCI95N  0x9511
 #define PCI_DEVICE_ID_OXSEMI_16PCI954PP        0x9513
 #define PCI_DEVICE_ID_INTEL_MCH_PC1    0x359a
 #define PCI_DEVICE_ID_INTEL_E7525_MCH  0x359e
 #define PCI_DEVICE_ID_INTEL_IOAT_CNB   0x360b
+#define PCI_DEVICE_ID_INTEL_FBD_CNB    0x360c
 #define PCI_DEVICE_ID_INTEL_ICH10_0    0x3a14
 #define PCI_DEVICE_ID_INTEL_ICH10_1    0x3a16
 #define PCI_DEVICE_ID_INTEL_ICH10_2    0x3a18
 #define PCI_DEVICE_ID_INTEL_ICH10_3    0x3a1a
 #define PCI_DEVICE_ID_INTEL_ICH10_4    0x3a30
 #define PCI_DEVICE_ID_INTEL_ICH10_5    0x3a60
-#define PCI_DEVICE_ID_INTEL_PCH_0      0x3b10
-#define PCI_DEVICE_ID_INTEL_PCH_1      0x3b11
-#define PCI_DEVICE_ID_INTEL_PCH_2      0x3b30
+#define PCI_DEVICE_ID_INTEL_PCH_LPC_MIN        0x3b00
+#define PCI_DEVICE_ID_INTEL_PCH_LPC_MAX        0x3b1f
+#define PCI_DEVICE_ID_INTEL_PCH_SMBUS  0x3b30
 #define PCI_DEVICE_ID_INTEL_IOAT_SNB   0x402f
 #define PCI_DEVICE_ID_INTEL_5100_16    0x65f0
 #define PCI_DEVICE_ID_INTEL_5100_21    0x65f5
index 450684f7eaacd41e08d57b08b0698dadffab1281..e5effd47ed7458fc57fcd6e8f87559927717ce17 100644 (file)
 #define  PCI_EXP_DEVCAP_RBER   0x8000  /* Role-Based Error Reporting */
 #define  PCI_EXP_DEVCAP_PWR_VAL        0x3fc0000 /* Slot Power Limit Value */
 #define  PCI_EXP_DEVCAP_PWR_SCL        0xc000000 /* Slot Power Limit Scale */
+#define  PCI_EXP_DEVCAP_FLR     0x10000000 /* Function Level Reset */
 #define PCI_EXP_DEVCTL         8       /* Device Control */
 #define  PCI_EXP_DEVCTL_CERE   0x0001  /* Correctable Error Reporting En. */
 #define  PCI_EXP_DEVCTL_NFERE  0x0002  /* Non-Fatal Error Reporting Enable */
 #define  PCI_EXP_DEVCTL_AUX_PME        0x0400  /* Auxiliary Power PM Enable */
 #define  PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800  /* Enable No Snoop */
 #define  PCI_EXP_DEVCTL_READRQ 0x7000  /* Max_Read_Request_Size */
+#define  PCI_EXP_DEVCTL_BCR_FLR 0x8000  /* Bridge Configuration Retry / FLR */
 #define PCI_EXP_DEVSTA         10      /* Device Status */
 #define  PCI_EXP_DEVSTA_CED    0x01    /* Correctable Error Detected */
 #define  PCI_EXP_DEVSTA_NFED   0x02    /* Non-Fatal Error Detected */
 #define  PCI_EXP_RTCTL_CRSSVE  0x10    /* CRS Software Visibility Enable */
 #define PCI_EXP_RTCAP          30      /* Root Capabilities */
 #define PCI_EXP_RTSTA          32      /* Root Status */
+#define PCI_EXP_DEVCAP2                36      /* Device Capabilities 2 */
+#define  PCI_EXP_DEVCAP2_ARI   0x20    /* Alternative Routing-ID */
+#define PCI_EXP_DEVCTL2                40      /* Device Control 2 */
+#define  PCI_EXP_DEVCTL2_ARI   0x20    /* Alternative Routing-ID */
 
 /* Extended Capabilities (PCI-X 2.0 and Express) */
 #define PCI_EXT_CAP_ID(header)         (header & 0x0000ffff)
 #define PCI_EXT_CAP_ID_VC      2
 #define PCI_EXT_CAP_ID_DSN     3
 #define PCI_EXT_CAP_ID_PWR     4
+#define PCI_EXT_CAP_ID_ARI     14
 
 /* Advanced Error Reporting */
 #define PCI_ERR_UNCOR_STATUS   4       /* Uncorrectable Error Status */
 #define HT_CAPTYPE_GEN3                0xD0    /* Generation 3 hypertransport configuration */
 #define HT_CAPTYPE_PM          0xE0    /* Hypertransport powermanagement configuration */
 
+/* Alternative Routing-ID Interpretation */
+#define PCI_ARI_CAP            0x04    /* ARI Capability Register */
+#define  PCI_ARI_CAP_MFVC      0x0001  /* MFVC Function Groups Capability */
+#define  PCI_ARI_CAP_ACS       0x0002  /* ACS Function Groups Capability */
+#define  PCI_ARI_CAP_NFN(x)    (((x) >> 8) & 0xff) /* Next Function Number */
+#define PCI_ARI_CTRL           0x06    /* ARI Control Register */
+#define  PCI_ARI_CTRL_MFVC     0x0001  /* MFVC Function Groups Enable */
+#define  PCI_ARI_CTRL_ACS      0x0002  /* ACS Function Groups Enable */
+#define  PCI_ARI_CTRL_FG(x)    (((x) >> 4) & 7) /* Function Group */
 
 #endif /* LINUX_PCI_REGS_H */
index 53b70fd1d9a535d92639a66757646ce5620e21f9..ca3c88773028046f36a807741f2f6fa16b9c65fe 100644 (file)
@@ -485,14 +485,4 @@ static inline void pnp_unregister_driver(struct pnp_driver *drv) { }
 
 #endif /* CONFIG_PNP */
 
-#define pnp_err(format, arg...) printk(KERN_ERR "pnp: " format "\n" , ## arg)
-#define pnp_info(format, arg...) printk(KERN_INFO "pnp: " format "\n" , ## arg)
-#define pnp_warn(format, arg...) printk(KERN_WARNING "pnp: " format "\n" , ## arg)
-
-#ifdef CONFIG_PNP_DEBUG
-#define pnp_dbg(format, arg...) printk(KERN_DEBUG "pnp: " format "\n" , ## arg)
-#else
-#define pnp_dbg(format, arg...) do {} while (0)
-#endif
-
 #endif /* _LINUX_PNP_H */
index ef453828877a35aefc4bbdd1a4753734bbccd882..badd98ab06f662a43cf5fc3285aa80ac42c1d849 100644 (file)
@@ -114,11 +114,13 @@ void zero_fd_set(unsigned long nr, unsigned long *fdset)
 
 #define MAX_INT64_SECONDS (((s64)(~((u64)0)>>1)/HZ)-1)
 
-extern int do_select(int n, fd_set_bits *fds, s64 *timeout);
+extern int do_select(int n, fd_set_bits *fds, struct timespec *end_time);
 extern int do_sys_poll(struct pollfd __user * ufds, unsigned int nfds,
-                      s64 *timeout);
+                      struct timespec *end_time);
 extern int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
-                          fd_set __user *exp, s64 *timeout);
+                          fd_set __user *exp, struct timespec *end_time);
+
+extern int poll_select_set_timeout(struct timespec *to, long sec, long nsec);
 
 #endif /* KERNEL */
 
index a7dd38f30ade61d1cf6fba16d7f7f60b3e8cc944..a7c7213555492520e649a4920d9fc671e88460cd 100644 (file)
@@ -45,8 +45,6 @@ struct k_itimer {
        int it_requeue_pending;         /* waiting to requeue this timer */
 #define REQUEUE_PENDING 1
        int it_sigev_notify;            /* notify word of sigevent struct */
-       int it_sigev_signo;             /* signo word of sigevent struct */
-       sigval_t it_sigev_value;        /* value word of sigevent struct */
        struct task_struct *it_process; /* process to send signal to */
        struct sigqueue *sigq;          /* signal queue entry. */
        union {
@@ -115,4 +113,6 @@ void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx,
 
 long clock_nanosleep_restart(struct restart_block *restart_block);
 
+void update_rlimit_cpu(unsigned long rlim_new);
+
 #endif
index 5ad79198d6f99809343dd063131b0ba48db8a063..48d887e3c6e737317a7b29d2a418f8383ae910cb 100644 (file)
 #define PR_GET_SECUREBITS 27
 #define PR_SET_SECUREBITS 28
 
+/*
+ * Get/set the timerslack as used by poll/select/nanosleep
+ * A value of 0 means "use default"
+ */
+#define PR_SET_TIMERSLACK 29
+#define PR_GET_TIMERSLACK 30
+
 #endif /* _LINUX_PRCTL_H */
index 27d534f4470d2350cc7cd563e813e5b88ba25c37..b8bdb96eff78b8112ddf4717b651c4ef1126ead7 100644 (file)
@@ -97,12 +97,9 @@ struct vmcore {
 
 #ifdef CONFIG_PROC_FS
 
-extern struct proc_dir_entry *proc_root_kcore;
-
 extern spinlock_t proc_subdir_lock;
 
 extern void proc_root_init(void);
-extern void proc_misc_init(void);
 
 void proc_flush_task(struct task_struct *task);
 struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *);
@@ -138,8 +135,6 @@ extern struct inode *proc_get_inode(struct super_block *, unsigned int, struct p
 extern int proc_readdir(struct file *, void *, filldir_t);
 extern struct dentry *proc_lookup(struct inode *, struct dentry *, struct nameidata *);
 
-extern const struct file_operations proc_kcore_operations;
-
 extern int pid_ns_prepare_proc(struct pid_namespace *ns);
 extern void pid_ns_release_proc(struct pid_namespace *ns);
 
index 570045053ce9bf04bbda46d21a97feb3b76dadb2..a0fc32279fc09d53a94b73b4c9dc89645d637b54 100644 (file)
@@ -19,10 +19,16 @@ struct notifier_block;
 
 #if defined(CONFIG_PROFILING) && defined(CONFIG_PROC_FS)
 void create_prof_cpu_mask(struct proc_dir_entry *de);
+int create_proc_profile(void);
 #else
 static inline void create_prof_cpu_mask(struct proc_dir_entry *de)
 {
 }
+
+static inline int create_proc_profile(void)
+{
+       return 0;
+}
 #endif
 
 enum profile_type {
@@ -37,7 +43,6 @@ extern int prof_on __read_mostly;
 /* init basic kernel profiler */
 int profile_init(void);
 int profile_setup(char *str);
-int create_proc_profile(void);
 void profile_tick(int type);
 
 /*
index 315517e8bfa1cdd6704f4a9620ca8a3d8c7f5d2a..bda6b562a1e05dc5ee936ca52dfc8bfb14ae86a9 100644 (file)
@@ -178,6 +178,7 @@ struct reiserfs_journal {
        struct reiserfs_journal_cnode *j_first; /*  oldest journal block.  start here for traverse */
 
        struct block_device *j_dev_bd;
+       fmode_t j_dev_mode;
        int j_1st_reserved_block;       /* first block on s_dev of reserved area journal */
 
        unsigned long j_state;
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
new file mode 100644 (file)
index 0000000..536b0ca
--- /dev/null
@@ -0,0 +1,127 @@
+#ifndef _LINUX_RING_BUFFER_H
+#define _LINUX_RING_BUFFER_H
+
+#include <linux/mm.h>
+#include <linux/seq_file.h>
+
+struct ring_buffer;
+struct ring_buffer_iter;
+
+/*
+ * Don't reference this struct directly, use functions below.
+ */
+struct ring_buffer_event {
+       u32             type:2, len:3, time_delta:27;
+       u32             array[];
+};
+
+/**
+ * enum ring_buffer_type - internal ring buffer types
+ *
+ * @RINGBUF_TYPE_PADDING:      Left over page padding
+ *                              array is ignored
+ *                              size is variable depending on how much
+ *                               padding is needed
+ *
+ * @RINGBUF_TYPE_TIME_EXTEND:  Extend the time delta
+ *                              array[0] = time delta (28 .. 59)
+ *                              size = 8 bytes
+ *
+ * @RINGBUF_TYPE_TIME_STAMP:   Sync time stamp with external clock
+ *                              array[0] = tv_nsec
+ *                              array[1] = tv_sec
+ *                              size = 16 bytes
+ *
+ * @RINGBUF_TYPE_DATA:         Data record
+ *                              If len is zero:
+ *                               array[0] holds the actual length
+ *                               array[1..(length+3)/4-1] holds data
+ *                              else
+ *                               length = len << 2
+ *                               array[0..(length+3)/4] holds data
+ */
+enum ring_buffer_type {
+       RINGBUF_TYPE_PADDING,
+       RINGBUF_TYPE_TIME_EXTEND,
+       /* FIXME: RINGBUF_TYPE_TIME_STAMP not implemented */
+       RINGBUF_TYPE_TIME_STAMP,
+       RINGBUF_TYPE_DATA,
+};
+
+unsigned ring_buffer_event_length(struct ring_buffer_event *event);
+void *ring_buffer_event_data(struct ring_buffer_event *event);
+
+/**
+ * ring_buffer_event_time_delta - return the delta timestamp of the event
+ * @event: the event to get the delta timestamp of
+ *
+ * The delta timestamp is the 27 bit timestamp since the last event.
+ */
+static inline unsigned
+ring_buffer_event_time_delta(struct ring_buffer_event *event)
+{
+       return event->time_delta;
+}
+
+/*
+ * size is in bytes for each per CPU buffer.
+ */
+struct ring_buffer *
+ring_buffer_alloc(unsigned long size, unsigned flags);
+void ring_buffer_free(struct ring_buffer *buffer);
+
+int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size);
+
+struct ring_buffer_event *
+ring_buffer_lock_reserve(struct ring_buffer *buffer,
+                        unsigned long length,
+                        unsigned long *flags);
+int ring_buffer_unlock_commit(struct ring_buffer *buffer,
+                             struct ring_buffer_event *event,
+                             unsigned long flags);
+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);
+struct ring_buffer_event *
+ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts);
+
+struct ring_buffer_iter *
+ring_buffer_read_start(struct ring_buffer *buffer, int cpu);
+void ring_buffer_read_finish(struct ring_buffer_iter *iter);
+
+struct ring_buffer_event *
+ring_buffer_iter_peek(struct ring_buffer_iter *iter, u64 *ts);
+struct ring_buffer_event *
+ring_buffer_read(struct ring_buffer_iter *iter, u64 *ts);
+void ring_buffer_iter_reset(struct ring_buffer_iter *iter);
+int ring_buffer_iter_empty(struct ring_buffer_iter *iter);
+
+unsigned long ring_buffer_size(struct ring_buffer *buffer);
+
+void ring_buffer_reset_cpu(struct ring_buffer *buffer, int cpu);
+void ring_buffer_reset(struct ring_buffer *buffer);
+
+int ring_buffer_swap_cpu(struct ring_buffer *buffer_a,
+                        struct ring_buffer *buffer_b, int cpu);
+
+int ring_buffer_empty(struct ring_buffer *buffer);
+int ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu);
+
+void ring_buffer_record_disable(struct ring_buffer *buffer);
+void ring_buffer_record_enable(struct ring_buffer *buffer);
+void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu);
+void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu);
+
+unsigned long ring_buffer_entries(struct ring_buffer *buffer);
+unsigned long ring_buffer_overruns(struct ring_buffer *buffer);
+
+u64 ring_buffer_time_stamp(int cpu);
+void ring_buffer_normalize_time_stamp(int cpu, u64 *ts);
+
+enum ring_buffer_flags {
+       RB_FL_OVERWRITE         = 1 << 0,
+};
+
+#endif /* _LINUX_RING_BUFFER_H */
index f52dbd3587a78c4c031759f6934b5d03685b666a..8478f334d73293473199f6d97a6cc8aabb2d7521 100644 (file)
@@ -287,7 +287,6 @@ extern void trap_init(void);
 extern void account_process_tick(struct task_struct *task, int user);
 extern void update_process_times(int user);
 extern void scheduler_tick(void);
-extern void hrtick_resched(void);
 
 extern void sched_show_task(struct task_struct *p);
 
@@ -434,6 +433,39 @@ struct pacct_struct {
        unsigned long           ac_minflt, ac_majflt;
 };
 
+/**
+ * struct task_cputime - collected CPU time counts
+ * @utime:             time spent in user mode, in &cputime_t units
+ * @stime:             time spent in kernel mode, in &cputime_t units
+ * @sum_exec_runtime:  total time spent on the CPU, in nanoseconds
+ *
+ * This structure groups together three kinds of CPU time that are
+ * tracked for threads and thread groups.  Most things considering
+ * CPU time want to group these counts together and treat all three
+ * of them in parallel.
+ */
+struct task_cputime {
+       cputime_t utime;
+       cputime_t stime;
+       unsigned long long sum_exec_runtime;
+};
+/* Alternate field names when used to cache expirations. */
+#define prof_exp       stime
+#define virt_exp       utime
+#define sched_exp      sum_exec_runtime
+
+/**
+ * struct thread_group_cputime - thread group interval timer counts
+ * @totals:            thread group interval timers; substructure for
+ *                     uniprocessor kernel, per-cpu for SMP kernel.
+ *
+ * This structure contains the version of task_cputime, above, that is
+ * used for thread group CPU clock calculations.
+ */
+struct thread_group_cputime {
+       struct task_cputime *totals;
+};
+
 /*
  * NOTE! "signal_struct" does not have it's own
  * locking, because a shared signal_struct always
@@ -479,6 +511,17 @@ struct signal_struct {
        cputime_t it_prof_expires, it_virt_expires;
        cputime_t it_prof_incr, it_virt_incr;
 
+       /*
+        * Thread group totals for process CPU clocks.
+        * See thread_group_cputime(), et al, for details.
+        */
+       struct thread_group_cputime cputime;
+
+       /* Earliest-expiration cache. */
+       struct task_cputime cputime_expires;
+
+       struct list_head cpu_timers[3];
+
        /* job control IDs */
 
        /*
@@ -509,7 +552,7 @@ struct signal_struct {
         * Live threads maintain their own counters and add to these
         * in __exit_signal, except for the group leader.
         */
-       cputime_t utime, stime, cutime, cstime;
+       cputime_t cutime, cstime;
        cputime_t gtime;
        cputime_t cgtime;
        unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
@@ -517,14 +560,6 @@ struct signal_struct {
        unsigned long inblock, oublock, cinblock, coublock;
        struct task_io_accounting ioac;
 
-       /*
-        * Cumulative ns of scheduled CPU time for dead threads in the
-        * group, not including a zombie group leader.  (This only differs
-        * from jiffies_to_ns(utime + stime) if sched_clock uses something
-        * other than jiffies.)
-        */
-       unsigned long long sum_sched_runtime;
-
        /*
         * We don't bother to synchronize most readers of this at all,
         * because there is no reader checking a limit that actually needs
@@ -536,8 +571,6 @@ struct signal_struct {
         */
        struct rlimit rlim[RLIM_NLIMITS];
 
-       struct list_head cpu_timers[3];
-
        /* keep the process-shared keyrings here so that they do the right
         * thing in threads created with CLONE_THREAD */
 #ifdef CONFIG_KEYS
@@ -647,10 +680,6 @@ struct sched_info {
 };
 #endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */
 
-#ifdef CONFIG_SCHEDSTATS
-extern const struct file_operations proc_schedstat_operations;
-#endif /* CONFIG_SCHEDSTATS */
-
 #ifdef CONFIG_TASK_DELAY_ACCT
 struct task_delay_info {
        spinlock_t      lock;
@@ -1146,8 +1175,7 @@ struct task_struct {
 /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
        unsigned long min_flt, maj_flt;
 
-       cputime_t it_prof_expires, it_virt_expires;
-       unsigned long long it_sched_expires;
+       struct task_cputime cputime_expires;
        struct list_head cpu_timers[3];
 
 /* process credentials */
@@ -1313,6 +1341,12 @@ struct task_struct {
        int latency_record_count;
        struct latency_record latency_record[LT_SAVECOUNT];
 #endif
+       /*
+        * time slack values; these are used to round up poll() and
+        * select() etc timeout values. These are in nanoseconds.
+        */
+       unsigned long timer_slack_ns;
+       unsigned long default_timer_slack_ns;
 };
 
 /*
@@ -1597,6 +1631,7 @@ extern unsigned long long cpu_clock(int cpu);
 
 extern unsigned long long
 task_sched_runtime(struct task_struct *task);
+extern unsigned long long thread_group_sched_runtime(struct task_struct *task);
 
 /* sched_exec is called by processes performing an exec */
 #ifdef CONFIG_SMP
@@ -1631,6 +1666,7 @@ extern unsigned int sysctl_sched_features;
 extern unsigned int sysctl_sched_migration_cost;
 extern unsigned int sysctl_sched_nr_migrate;
 extern unsigned int sysctl_sched_shares_ratelimit;
+extern unsigned int sysctl_sched_shares_thresh;
 
 int sched_nr_latency_handler(struct ctl_table *table, int write,
                struct file *file, void __user *buffer, size_t *length,
@@ -2093,6 +2129,30 @@ static inline int spin_needbreak(spinlock_t *lock)
 #endif
 }
 
+/*
+ * Thread group CPU time accounting.
+ */
+
+extern int thread_group_cputime_alloc(struct task_struct *);
+extern void thread_group_cputime(struct task_struct *, struct task_cputime *);
+
+static inline void thread_group_cputime_init(struct signal_struct *sig)
+{
+       sig->cputime.totals = NULL;
+}
+
+static inline int thread_group_cputime_clone_thread(struct task_struct *curr)
+{
+       if (curr->signal->cputime.totals)
+               return 0;
+       return thread_group_cputime_alloc(curr);
+}
+
+static inline void thread_group_cputime_free(struct signal_struct *sig)
+{
+       free_percpu(sig->cputime.totals);
+}
+
 /*
  * Reevaluate whether the task has signals pending delivery.
  * Wake the task if so.
index 5ff9676c1e2ca83e93511891230189772fafe2a0..ba965c84ae0695b175da712a0951b6c3e0530b5c 100644 (file)
@@ -288,9 +288,4 @@ static inline void *kzalloc_node(size_t size, gfp_t flags, int node)
        return kmalloc_node(size, flags | __GFP_ZERO, node);
 }
 
-#ifdef CONFIG_SLABINFO
-extern const struct seq_operations slabinfo_op;
-ssize_t slabinfo_write(struct file *, const char __user *, size_t, loff_t *);
-#endif
-
 #endif /* _LINUX_SLAB_H */
index 38a56477f27ada34c3cd6e56c912205b066bc413..e6b820f8b56b8ae3bf50ac980d1e95ce3ad6536e 100644 (file)
@@ -38,6 +38,14 @@ struct restart_block {
 #endif
                        u64 expires;
                } nanosleep;
+               /* For poll */
+               struct {
+                       struct pollfd __user *ufds;
+                       int nfds;
+                       int has_timeout;
+                       unsigned long tv_sec;
+                       unsigned long tv_nsec;
+               } poll;
        };
 };
 
index 98921a3e1aa8db33b7e743e6711abb671485ea12..b6ec8189ac0c16673689f5327cde1d78b3ab49d6 100644 (file)
@@ -96,9 +96,11 @@ extern cpumask_t *tick_get_broadcast_oneshot_mask(void);
 extern void tick_clock_notify(void);
 extern int tick_check_oneshot_change(int allow_nohz);
 extern struct tick_sched *tick_get_tick_sched(int cpu);
+extern void tick_check_idle(int cpu);
 # else
 static inline void tick_clock_notify(void) { }
 static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
+static inline void tick_check_idle(int cpu) { }
 # endif
 
 #else /* CONFIG_GENERIC_CLOCKEVENTS */
@@ -106,26 +108,23 @@ static inline void tick_init(void) { }
 static inline void tick_cancel_sched_timer(int cpu) { }
 static inline void tick_clock_notify(void) { }
 static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
+static inline void tick_check_idle(int cpu) { }
 #endif /* !CONFIG_GENERIC_CLOCKEVENTS */
 
 # ifdef CONFIG_NO_HZ
 extern void tick_nohz_stop_sched_tick(int inidle);
 extern void tick_nohz_restart_sched_tick(void);
-extern void tick_nohz_update_jiffies(void);
 extern ktime_t tick_nohz_get_sleep_length(void);
-extern void tick_nohz_stop_idle(int cpu);
 extern u64 get_cpu_idle_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) { }
-static inline void tick_nohz_update_jiffies(void) { }
 static inline ktime_t tick_nohz_get_sleep_length(void)
 {
        ktime_t len = { .tv64 = NSEC_PER_SEC/HZ };
 
        return len;
 }
-static inline void tick_nohz_stop_idle(int cpu) { }
 static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; }
 # endif /* !NO_HZ */
 
index 51e883df0fa51fe598832747477533fc4303e30a..ce321ac5c8f8ceba2f0bdb7640dbc71a9eab6687 100644 (file)
@@ -40,6 +40,8 @@ extern struct timezone sys_tz;
 #define NSEC_PER_SEC   1000000000L
 #define FSEC_PER_SEC   1000000000000000L
 
+#define TIME_T_MAX     (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
+
 static inline int timespec_equal(const struct timespec *a,
                                  const struct timespec *b)
 {
@@ -74,6 +76,8 @@ extern unsigned long mktime(const unsigned int year, const unsigned int mon,
                            const unsigned int min, const unsigned int sec);
 
 extern void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec);
+extern struct timespec timespec_add_safe(const struct timespec lhs,
+                                        const struct timespec rhs);
 
 /*
  * sub = lhs - rhs, in normalized form
@@ -119,6 +123,7 @@ extern int do_setitimer(int which, struct itimerval *value,
 extern unsigned int alarm_setitimer(unsigned int seconds);
 extern int do_getitimer(int which, struct itimerval *value);
 extern void getnstimeofday(struct timespec *tv);
+extern void getrawmonotonic(struct timespec *ts);
 extern void getboottime(struct timespec *ts);
 extern void monotonic_to_bootbased(struct timespec *ts);
 
@@ -127,6 +132,9 @@ extern int timekeeping_valid_for_hres(void);
 extern void update_wall_time(void);
 extern void update_xtime_cache(u64 nsec);
 
+struct tms;
+extern void do_sys_times(struct tms *);
+
 /**
  * timespec_to_ns - Convert timespec to nanoseconds
  * @ts:                pointer to the timespec variable to be converted
@@ -216,6 +224,7 @@ struct itimerval {
 #define CLOCK_MONOTONIC                        1
 #define CLOCK_PROCESS_CPUTIME_ID       2
 #define CLOCK_THREAD_CPUTIME_ID                3
+#define CLOCK_MONOTONIC_RAW            4
 
 /*
  * The IDs of various hardware clocks:
index fc6035d29d568a018e5c43f6575e5b860379fa96..9007313b5b7168ae03ed85e63d80ce6afe0ce438 100644 (file)
@@ -82,7 +82,7 @@
  */
 #define SHIFT_USEC 16          /* frequency offset scale (shift) */
 #define PPM_SCALE (NSEC_PER_USEC << (NTP_SCALE_SHIFT - SHIFT_USEC))
-#define PPM_SCALE_INV_SHIFT 20
+#define PPM_SCALE_INV_SHIFT 19
 #define PPM_SCALE_INV ((1ll << (PPM_SCALE_INV_SHIFT + NTP_SCALE_SHIFT)) / \
                       PPM_SCALE + 1)
 
@@ -141,8 +141,15 @@ struct timex {
 #define ADJ_MICRO              0x1000  /* select microsecond resolution */
 #define ADJ_NANO               0x2000  /* select nanosecond resolution */
 #define ADJ_TICK               0x4000  /* tick value */
+
+#ifdef __KERNEL__
+#define ADJ_ADJTIME            0x8000  /* switch between adjtime/adjtimex modes */
+#define ADJ_OFFSET_SINGLESHOT  0x0001  /* old-fashioned adjtime */
+#define ADJ_OFFSET_READONLY    0x2000  /* read-only adjtime */
+#else
 #define ADJ_OFFSET_SINGLESHOT  0x8001  /* old-fashioned adjtime */
-#define ADJ_OFFSET_SS_READ     0xa001  /* read-only adjtime */
+#define ADJ_OFFSET_SS_READ     0xa001  /* read-only adjtime */
+#endif
 
 /* xntp 3.4 compatibility names */
 #define MOD_OFFSET     ADJ_OFFSET
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
new file mode 100644 (file)
index 0000000..c5bb39c
--- /dev/null
@@ -0,0 +1,137 @@
+#ifndef _LINUX_TRACEPOINT_H
+#define _LINUX_TRACEPOINT_H
+
+/*
+ * Kernel Tracepoint API.
+ *
+ * See Documentation/tracepoint.txt.
+ *
+ * (C) Copyright 2008 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ *
+ * Heavily inspired from the Linux Kernel Markers.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/rcupdate.h>
+
+struct module;
+struct tracepoint;
+
+struct tracepoint {
+       const char *name;               /* Tracepoint name */
+       int state;                      /* State. */
+       void **funcs;
+} __attribute__((aligned(8)));
+
+
+#define TPPROTO(args...)       args
+#define TPARGS(args...)                args
+
+#ifdef CONFIG_TRACEPOINTS
+
+/*
+ * it_func[0] is never NULL because there is at least one element in the array
+ * when the array itself is non NULL.
+ */
+#define __DO_TRACE(tp, proto, args)                                    \
+       do {                                                            \
+               void **it_func;                                         \
+                                                                       \
+               rcu_read_lock_sched();                                  \
+               it_func = rcu_dereference((tp)->funcs);                 \
+               if (it_func) {                                          \
+                       do {                                            \
+                               ((void(*)(proto))(*it_func))(args);     \
+                       } while (*(++it_func));                         \
+               }                                                       \
+               rcu_read_unlock_sched();                                \
+       } while (0)
+
+/*
+ * Make sure the alignment of the structure in the __tracepoints section will
+ * not add unwanted padding between the beginning of the section and the
+ * structure. Force alignment to the same alignment as the section start.
+ */
+#define DEFINE_TRACE(name, proto, args)                                        \
+       static inline void trace_##name(proto)                          \
+       {                                                               \
+               static const char __tpstrtab_##name[]                   \
+               __attribute__((section("__tracepoints_strings")))       \
+               = #name ":" #proto;                                     \
+               static struct tracepoint __tracepoint_##name            \
+               __attribute__((section("__tracepoints"), aligned(8))) = \
+               { __tpstrtab_##name, 0, NULL };                         \
+               if (unlikely(__tracepoint_##name.state))                \
+                       __DO_TRACE(&__tracepoint_##name,                \
+                               TPPROTO(proto), TPARGS(args));          \
+       }                                                               \
+       static inline int register_trace_##name(void (*probe)(proto))   \
+       {                                                               \
+               return tracepoint_probe_register(#name ":" #proto,      \
+                       (void *)probe);                                 \
+       }                                                               \
+       static inline void unregister_trace_##name(void (*probe)(proto))\
+       {                                                               \
+               tracepoint_probe_unregister(#name ":" #proto,           \
+                       (void *)probe);                                 \
+       }
+
+extern void tracepoint_update_probe_range(struct tracepoint *begin,
+       struct tracepoint *end);
+
+#else /* !CONFIG_TRACEPOINTS */
+#define DEFINE_TRACE(name, proto, args)                        \
+       static inline void _do_trace_##name(struct tracepoint *tp, proto) \
+       { }                                                             \
+       static inline void trace_##name(proto)                          \
+       { }                                                             \
+       static inline int register_trace_##name(void (*probe)(proto))   \
+       {                                                               \
+               return -ENOSYS;                                         \
+       }                                                               \
+       static inline void unregister_trace_##name(void (*probe)(proto))\
+       { }
+
+static inline void tracepoint_update_probe_range(struct tracepoint *begin,
+       struct tracepoint *end)
+{ }
+#endif /* CONFIG_TRACEPOINTS */
+
+/*
+ * 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);
+
+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();
+}
+
+#endif
index f24f7beb47df0bcad9a481f6b14b83df34d12a1a..1d98330b1f2c174fa239f8dbfc0b5533b4f99dc6 100644 (file)
@@ -190,6 +190,7 @@ typedef __u32 __bitwise __wsum;
 
 #ifdef __KERNEL__
 typedef unsigned __bitwise__ gfp_t;
+typedef unsigned __bitwise__ fmode_t;
 
 #ifdef CONFIG_PHYS_ADDR_T_64BIT
 typedef u64 phys_addr_t;
diff --git a/include/linux/usb/wusb-wa.h b/include/linux/usb/wusb-wa.h
new file mode 100644 (file)
index 0000000..a102561
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * Wireless USB Wire Adapter constants and structures.
+ *
+ * Copyright (C) 2005-2006 Intel Corporation.
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ * FIXME: organize properly, group logically
+ *
+ * All the event structures are defined in uwb/spec.h, as they are
+ * common to the WHCI and WUSB radio control interfaces.
+ *
+ * References:
+ *   [WUSB] Wireless Universal Serial Bus Specification, revision 1.0, ch8
+ */
+#ifndef __LINUX_USB_WUSB_WA_H
+#define __LINUX_USB_WUSB_WA_H
+
+/**
+ * Radio Command Request for the Radio Control Interface
+ *
+ * Radio Control Interface command and event codes are the same as
+ * WHCI, and listed in include/linux/uwb.h:UWB_RC_{CMD,EVT}_*
+ */
+enum {
+       WA_EXEC_RC_CMD = 40,    /* Radio Control command Request */
+};
+
+/* Wireless Adapter Requests ([WUSB] table 8-51) */
+enum {
+       WUSB_REQ_ADD_MMC_IE     = 20,
+       WUSB_REQ_REMOVE_MMC_IE  = 21,
+       WUSB_REQ_SET_NUM_DNTS   = 22,
+       WUSB_REQ_SET_CLUSTER_ID = 23,
+       WUSB_REQ_SET_DEV_INFO   = 24,
+       WUSB_REQ_GET_TIME       = 25,
+       WUSB_REQ_SET_STREAM_IDX = 26,
+       WUSB_REQ_SET_WUSB_MAS   = 27,
+};
+
+
+/* Wireless Adapter WUSB Channel Time types ([WUSB] table 8-52) */
+enum {
+       WUSB_TIME_ADJ   = 0,
+       WUSB_TIME_BPST  = 1,
+       WUSB_TIME_WUSB  = 2,
+};
+
+enum {
+       WA_ENABLE = 0x01,
+       WA_RESET = 0x02,
+       RPIPE_PAUSE = 0x1,
+};
+
+/* Responses from Get Status request ([WUSB] section 8.3.1.6) */
+enum {
+       WA_STATUS_ENABLED = 0x01,
+       WA_STATUS_RESETTING = 0x02
+};
+
+enum rpipe_crs {
+       RPIPE_CRS_CTL = 0x01,
+       RPIPE_CRS_ISO = 0x02,
+       RPIPE_CRS_BULK = 0x04,
+       RPIPE_CRS_INTR = 0x08
+};
+
+/**
+ * RPipe descriptor ([WUSB] section 8.5.2.11)
+ *
+ * FIXME: explain rpipes
+ */
+struct usb_rpipe_descriptor {
+       u8      bLength;
+       u8      bDescriptorType;
+       __le16  wRPipeIndex;
+       __le16  wRequests;
+       __le16  wBlocks;                /* rw if 0 */
+       __le16  wMaxPacketSize;         /* rw? */
+       u8      bHSHubAddress;          /* reserved: 0 */
+       u8      bHSHubPort;             /* ??? FIXME ??? */
+       u8      bSpeed;                 /* rw: xfer rate 'enum uwb_phy_rate' */
+       u8      bDeviceAddress;         /* rw: Target device address */
+       u8      bEndpointAddress;       /* rw: Target EP address */
+       u8      bDataSequence;          /* ro: Current Data sequence */
+       __le32  dwCurrentWindow;        /* ro */
+       u8      bMaxDataSequence;       /* ro?: max supported seq */
+       u8      bInterval;              /* rw:  */
+       u8      bOverTheAirInterval;    /* rw:  */
+       u8      bmAttribute;            /* ro?  */
+       u8      bmCharacteristics;      /* ro? enum rpipe_attr, supported xsactions */
+       u8      bmRetryOptions;         /* rw? */
+       __le16  wNumTransactionErrors;  /* rw */
+} __attribute__ ((packed));
+
+/**
+ * Wire Adapter Notification types ([WUSB] sections 8.4.5 & 8.5.4)
+ *
+ * These are the notifications coming on the notification endpoint of
+ * an HWA and a DWA.
+ */
+enum wa_notif_type {
+       DWA_NOTIF_RWAKE = 0x91,
+       DWA_NOTIF_PORTSTATUS = 0x92,
+       WA_NOTIF_TRANSFER = 0x93,
+       HWA_NOTIF_BPST_ADJ = 0x94,
+       HWA_NOTIF_DN = 0x95,
+};
+
+/**
+ * Wire Adapter notification header
+ *
+ * Notifications coming from a wire adapter use a common header
+ * defined in [WUSB] sections 8.4.5 & 8.5.4.
+ */
+struct wa_notif_hdr {
+       u8 bLength;
+       u8 bNotifyType;                 /* enum wa_notif_type */
+} __attribute__((packed));
+
+/**
+ * HWA DN Received notification [(WUSB] section 8.5.4.2)
+ *
+ * The DNData is specified in WUSB1.0[7.6]. For each device
+ * notification we received, we just need to dispatch it.
+ *
+ * @dndata:  this is really an array of notifications, but all start
+ *           with the same header.
+ */
+struct hwa_notif_dn {
+       struct wa_notif_hdr hdr;
+       u8 bSourceDeviceAddr;           /* from errata 2005/07 */
+       u8 bmAttributes;
+       struct wusb_dn_hdr dndata[];
+} __attribute__((packed));
+
+/* [WUSB] section 8.3.3 */
+enum wa_xfer_type {
+       WA_XFER_TYPE_CTL = 0x80,
+       WA_XFER_TYPE_BI = 0x81,         /* bulk/interrupt */
+       WA_XFER_TYPE_ISO = 0x82,
+       WA_XFER_RESULT = 0x83,
+       WA_XFER_ABORT = 0x84,
+};
+
+/* [WUSB] section 8.3.3 */
+struct wa_xfer_hdr {
+       u8 bLength;                     /* 0x18 */
+       u8 bRequestType;                /* 0x80 WA_REQUEST_TYPE_CTL */
+       __le16 wRPipe;                  /* RPipe index */
+       __le32 dwTransferID;            /* Host-assigned ID */
+       __le32 dwTransferLength;        /* Length of data to xfer */
+       u8 bTransferSegment;
+} __attribute__((packed));
+
+struct wa_xfer_ctl {
+       struct wa_xfer_hdr hdr;
+       u8 bmAttribute;
+       __le16 wReserved;
+       struct usb_ctrlrequest baSetupData;
+} __attribute__((packed));
+
+struct wa_xfer_bi {
+       struct wa_xfer_hdr hdr;
+       u8 bReserved;
+       __le16 wReserved;
+} __attribute__((packed));
+
+struct wa_xfer_hwaiso {
+       struct wa_xfer_hdr hdr;
+       u8 bReserved;
+       __le16 wPresentationTime;
+       __le32 dwNumOfPackets;
+       /* FIXME: u8 pktdata[]? */
+} __attribute__((packed));
+
+/* [WUSB] section 8.3.3.5 */
+struct wa_xfer_abort {
+       u8 bLength;
+       u8 bRequestType;
+       __le16 wRPipe;                  /* RPipe index */
+       __le32 dwTransferID;            /* Host-assigned ID */
+} __attribute__((packed));
+
+/**
+ * WA Transfer Complete notification ([WUSB] section 8.3.3.3)
+ *
+ */
+struct wa_notif_xfer {
+       struct wa_notif_hdr hdr;
+       u8 bEndpoint;
+       u8 Reserved;
+} __attribute__((packed));
+
+/** Transfer result basic codes [WUSB] table 8-15 */
+enum {
+       WA_XFER_STATUS_SUCCESS,
+       WA_XFER_STATUS_HALTED,
+       WA_XFER_STATUS_DATA_BUFFER_ERROR,
+       WA_XFER_STATUS_BABBLE,
+       WA_XFER_RESERVED,
+       WA_XFER_STATUS_NOT_FOUND,
+       WA_XFER_STATUS_INSUFFICIENT_RESOURCE,
+       WA_XFER_STATUS_TRANSACTION_ERROR,
+       WA_XFER_STATUS_ABORTED,
+       WA_XFER_STATUS_RPIPE_NOT_READY,
+       WA_XFER_INVALID_FORMAT,
+       WA_XFER_UNEXPECTED_SEGMENT_NUMBER,
+       WA_XFER_STATUS_RPIPE_TYPE_MISMATCH,
+};
+
+/** [WUSB] section 8.3.3.4 */
+struct wa_xfer_result {
+       struct wa_notif_hdr hdr;
+       __le32 dwTransferID;
+       __le32 dwTransferLength;
+       u8     bTransferSegment;
+       u8     bTransferStatus;
+       __le32 dwNumOfPackets;
+} __attribute__((packed));
+
+/**
+ * Wire Adapter Class Descriptor ([WUSB] section 8.5.2.7).
+ *
+ * NOTE: u16 fields are read Little Endian from the hardware.
+ *
+ * @bNumPorts is the original max number of devices that the host can
+ *            connect; we might chop this so the stack can handle
+ *            it. In case you need to access it, use wusbhc->ports_max
+ *            if it is a Wireless USB WA.
+ */
+struct usb_wa_descriptor {
+       u8      bLength;
+       u8      bDescriptorType;
+       u16     bcdWAVersion;
+       u8      bNumPorts;              /* don't use!! */
+       u8      bmAttributes;           /* Reserved == 0 */
+       u16     wNumRPipes;
+       u16     wRPipeMaxBlock;
+       u8      bRPipeBlockSize;
+       u8      bPwrOn2PwrGood;
+       u8      bNumMMCIEs;
+       u8      DeviceRemovable;        /* FIXME: in DWA this is up to 16 bytes */
+} __attribute__((packed));
+
+/**
+ * HWA Device Information Buffer (WUSB1.0[T8.54])
+ */
+struct hwa_dev_info {
+       u8      bmDeviceAvailability[32];       /* FIXME: ignored for now */
+       u8      bDeviceAddress;
+       __le16  wPHYRates;
+       u8      bmDeviceAttribute;
+} __attribute__((packed));
+
+#endif /* #ifndef __LINUX_USB_WUSB_WA_H */
diff --git a/include/linux/usb/wusb.h b/include/linux/usb/wusb.h
new file mode 100644 (file)
index 0000000..5f401b6
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+ * Wireless USB Standard Definitions
+ * Event Size Tables
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ * FIXME: organize properly, group logically
+ *
+ * All the event structures are defined in uwb/spec.h, as they are
+ * common to the WHCI and WUSB radio control interfaces.
+ */
+
+#ifndef __WUSB_H__
+#define __WUSB_H__
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/uwb/spec.h>
+#include <linux/usb/ch9.h>
+#include <linux/param.h>
+
+/**
+ * WUSB Information Element header
+ *
+ * I don't know why, they decided to make it different to the MBOA MAC
+ * IE Header; beats me.
+ */
+struct wuie_hdr {
+       u8 bLength;
+       u8 bIEIdentifier;
+} __attribute__((packed));
+
+enum {
+       WUIE_ID_WCTA = 0x80,
+       WUIE_ID_CONNECTACK,
+       WUIE_ID_HOST_INFO,
+       WUIE_ID_CHANGE_ANNOUNCE,
+       WUIE_ID_DEVICE_DISCONNECT,
+       WUIE_ID_HOST_DISCONNECT,
+       WUIE_ID_KEEP_ALIVE = 0x89,
+       WUIE_ID_ISOCH_DISCARD,
+       WUIE_ID_RESET_DEVICE,
+};
+
+/**
+ * Maximum number of array elements in a WUSB IE.
+ *
+ * WUSB1.0[7.5 before table 7-38] says that in WUSB IEs that
+ * are "arrays" have to limited to 4 elements. So we define it
+ * like that to ease up and submit only the neeed size.
+ */
+#define WUIE_ELT_MAX 4
+
+/**
+ * Wrapper for the data that defines a CHID, a CDID or a CK
+ *
+ * WUSB defines that CHIDs, CDIDs and CKs are a 16 byte string of
+ * data. In order to avoid confusion and enforce types, we wrap it.
+ *
+ * Make it packed, as we use it in some hw defintions.
+ */
+struct wusb_ckhdid {
+       u8 data[16];
+} __attribute__((packed));
+
+const static
+struct wusb_ckhdid wusb_ckhdid_zero = { .data = { 0 } };
+
+#define WUSB_CKHDID_STRSIZE (3 * sizeof(struct wusb_ckhdid) + 1)
+
+/**
+ * WUSB IE: Host Information (WUSB1.0[7.5.2])
+ *
+ * Used to provide information about the host to the Wireless USB
+ * devices in range (CHID can be used as an ASCII string).
+ */
+struct wuie_host_info {
+       struct wuie_hdr hdr;
+       __le16 attributes;
+       struct wusb_ckhdid CHID;
+} __attribute__((packed));
+
+/**
+ * WUSB IE: Connect Ack (WUSB1.0[7.5.1])
+ *
+ * Used to acknowledge device connect requests. See note for
+ * WUIE_ELT_MAX.
+ */
+struct wuie_connect_ack {
+       struct wuie_hdr hdr;
+       struct {
+               struct wusb_ckhdid CDID;
+               u8 bDeviceAddress;      /* 0 means unused */
+               u8 bReserved;
+       } blk[WUIE_ELT_MAX];
+} __attribute__((packed));
+
+/**
+ * WUSB IE Host Information Element, Connect Availability
+ *
+ * WUSB1.0[7.5.2], bmAttributes description
+ */
+enum {
+       WUIE_HI_CAP_RECONNECT = 0,
+       WUIE_HI_CAP_LIMITED,
+       WUIE_HI_CAP_RESERVED,
+       WUIE_HI_CAP_ALL,
+};
+
+/**
+ * WUSB IE: Channel Stop (WUSB1.0[7.5.8])
+ *
+ * Tells devices the host is going to stop sending MMCs and will dissapear.
+ */
+struct wuie_channel_stop {
+       struct wuie_hdr hdr;
+       u8 attributes;
+       u8 timestamp[3];
+} __attribute__((packed));
+
+/**
+ * WUSB IE: Keepalive (WUSB1.0[7.5.9])
+ *
+ * Ask device(s) to send keepalives.
+ */
+struct wuie_keep_alive {
+       struct wuie_hdr hdr;
+       u8 bDeviceAddress[WUIE_ELT_MAX];
+} __attribute__((packed));
+
+/**
+ * WUSB IE: Reset device (WUSB1.0[7.5.11])
+ *
+ * Tell device to reset; in all truth, we can fit 4 CDIDs, but we only
+ * use it for one at the time...
+ *
+ * In any case, this request is a wee bit silly: why don't they target
+ * by address??
+ */
+struct wuie_reset {
+       struct wuie_hdr hdr;
+       struct wusb_ckhdid CDID;
+} __attribute__((packed));
+
+/**
+ * WUSB IE: Disconnect device (WUSB1.0[7.5.11])
+ *
+ * Tell device to disconnect; we can fit 4 addresses, but we only use
+ * it for one at the time...
+ */
+struct wuie_disconnect {
+       struct wuie_hdr hdr;
+       u8 bDeviceAddress;
+       u8 padding;
+} __attribute__((packed));
+
+/**
+ * WUSB IE: Host disconnect ([WUSB] section 7.5.5)
+ *
+ * Tells all connected devices to disconnect.
+ */
+struct wuie_host_disconnect {
+       struct wuie_hdr hdr;
+} __attribute__((packed));
+
+/**
+ * WUSB Device Notification header (WUSB1.0[7.6])
+ */
+struct wusb_dn_hdr {
+       u8 bType;
+       u8 notifdata[];
+} __attribute__((packed));
+
+/** Device Notification codes (WUSB1.0[Table 7-54]) */
+enum WUSB_DN {
+       WUSB_DN_CONNECT = 0x01,
+       WUSB_DN_DISCONNECT = 0x02,
+       WUSB_DN_EPRDY = 0x03,
+       WUSB_DN_MASAVAILCHANGED = 0x04,
+       WUSB_DN_RWAKE = 0x05,
+       WUSB_DN_SLEEP = 0x06,
+       WUSB_DN_ALIVE = 0x07,
+};
+
+/** WUSB Device Notification Connect */
+struct wusb_dn_connect {
+       struct wusb_dn_hdr hdr;
+       __le16 attributes;
+       struct wusb_ckhdid CDID;
+} __attribute__((packed));
+
+static inline int wusb_dn_connect_prev_dev_addr(const struct wusb_dn_connect *dn)
+{
+       return le16_to_cpu(dn->attributes) & 0xff;
+}
+
+static inline int wusb_dn_connect_new_connection(const struct wusb_dn_connect *dn)
+{
+       return (le16_to_cpu(dn->attributes) >> 8) & 0x1;
+}
+
+static inline int wusb_dn_connect_beacon_behavior(const struct wusb_dn_connect *dn)
+{
+       return (le16_to_cpu(dn->attributes) >> 9) & 0x03;
+}
+
+/** Device is alive (aka: pong) (WUSB1.0[7.6.7]) */
+struct wusb_dn_alive {
+       struct wusb_dn_hdr hdr;
+} __attribute__((packed));
+
+/** Device is disconnecting (WUSB1.0[7.6.2]) */
+struct wusb_dn_disconnect {
+       struct wusb_dn_hdr hdr;
+} __attribute__((packed));
+
+/* General constants */
+enum {
+       WUSB_TRUST_TIMEOUT_MS = 4000,   /* [WUSB] section 4.15.1 */
+};
+
+static inline size_t ckhdid_printf(char *pr_ckhdid, size_t size,
+                                  const struct wusb_ckhdid *ckhdid)
+{
+       return scnprintf(pr_ckhdid, size,
+                        "%02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx "
+                        "%02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx",
+                        ckhdid->data[0],  ckhdid->data[1],
+                        ckhdid->data[2],  ckhdid->data[3],
+                        ckhdid->data[4],  ckhdid->data[5],
+                        ckhdid->data[6],  ckhdid->data[7],
+                        ckhdid->data[8],  ckhdid->data[9],
+                        ckhdid->data[10], ckhdid->data[11],
+                        ckhdid->data[12], ckhdid->data[13],
+                        ckhdid->data[14], ckhdid->data[15]);
+}
+
+/*
+ * WUSB Crypto stuff (WUSB1.0[6])
+ */
+
+extern const char *wusb_et_name(u8);
+
+/**
+ * WUSB key index WUSB1.0[7.3.2.4], for usage when setting keys for
+ * the host or the device.
+ */
+static inline u8 wusb_key_index(int index, int type, int originator)
+{
+       return (originator << 6) | (type << 4) | index;
+}
+
+#define WUSB_KEY_INDEX_TYPE_PTK                        0 /* for HWA only */
+#define WUSB_KEY_INDEX_TYPE_ASSOC              1
+#define WUSB_KEY_INDEX_TYPE_GTK                        2
+#define WUSB_KEY_INDEX_ORIGINATOR_HOST         0
+#define WUSB_KEY_INDEX_ORIGINATOR_DEVICE       1
+
+/* A CCM Nonce, defined in WUSB1.0[6.4.1] */
+struct aes_ccm_nonce {
+       u8 sfn[6];              /* Little Endian */
+       u8 tkid[3];             /* LE */
+       struct uwb_dev_addr dest_addr;
+       struct uwb_dev_addr src_addr;
+} __attribute__((packed));
+
+/* A CCM operation label, defined on WUSB1.0[6.5.x] */
+struct aes_ccm_label {
+       u8 data[14];
+} __attribute__((packed));
+
+/*
+ * Input to the key derivation sequence defined in
+ * WUSB1.0[6.5.1]. Rest of the data is in the CCM Nonce passed to the
+ * PRF function.
+ */
+struct wusb_keydvt_in {
+       u8 hnonce[16];
+       u8 dnonce[16];
+} __attribute__((packed));
+
+/*
+ * Output from the key derivation sequence defined in
+ * WUSB1.0[6.5.1].
+ */
+struct wusb_keydvt_out {
+       u8 kck[16];
+       u8 ptk[16];
+} __attribute__((packed));
+
+/* Pseudo Random Function WUSB1.0[6.5] */
+extern int wusb_crypto_init(void);
+extern void wusb_crypto_exit(void);
+extern ssize_t wusb_prf(void *out, size_t out_size,
+                       const u8 key[16], const struct aes_ccm_nonce *_n,
+                       const struct aes_ccm_label *a,
+                       const void *b, size_t blen, size_t len);
+
+static inline int wusb_prf_64(void *out, size_t out_size, const u8 key[16],
+                             const struct aes_ccm_nonce *n,
+                             const struct aes_ccm_label *a,
+                             const void *b, size_t blen)
+{
+       return wusb_prf(out, out_size, key, n, a, b, blen, 64);
+}
+
+static inline int wusb_prf_128(void *out, size_t out_size, const u8 key[16],
+                              const struct aes_ccm_nonce *n,
+                              const struct aes_ccm_label *a,
+                              const void *b, size_t blen)
+{
+       return wusb_prf(out, out_size, key, n, a, b, blen, 128);
+}
+
+static inline int wusb_prf_256(void *out, size_t out_size, const u8 key[16],
+                              const struct aes_ccm_nonce *n,
+                              const struct aes_ccm_label *a,
+                              const void *b, size_t blen)
+{
+       return wusb_prf(out, out_size, key, n, a, b, blen, 256);
+}
+
+/* Key derivation WUSB1.0[6.5.1] */
+static inline int wusb_key_derive(struct wusb_keydvt_out *keydvt_out,
+                                 const u8 key[16],
+                                 const struct aes_ccm_nonce *n,
+                                 const struct wusb_keydvt_in *keydvt_in)
+{
+       const struct aes_ccm_label a = { .data = "Pair-wise keys" };
+       return wusb_prf_256(keydvt_out, sizeof(*keydvt_out), key, n, &a,
+                           keydvt_in, sizeof(*keydvt_in));
+}
+
+/*
+ * Out-of-band MIC Generation WUSB1.0[6.5.2]
+ *
+ * Compute the MIC over @key, @n and @hs and place it in @mic_out.
+ *
+ * @mic_out:  Where to place the 8 byte MIC tag
+ * @key:      KCK from the derivation process
+ * @n:        CCM nonce, n->sfn == 0, TKID as established in the
+ *            process.
+ * @hs:       Handshake struct for phase 2 of the 4-way.
+ *            hs->bStatus and hs->bReserved are zero.
+ *            hs->bMessageNumber is 2 (WUSB1.0[7.3.2.5.2]
+ *            hs->dest_addr is the device's USB address padded with 0
+ *            hs->src_addr is the hosts's UWB device address
+ *            hs->mic is ignored (as we compute that value).
+ */
+static inline int wusb_oob_mic(u8 mic_out[8], const u8 key[16],
+                              const struct aes_ccm_nonce *n,
+                              const struct usb_handshake *hs)
+{
+       const struct aes_ccm_label a = { .data = "out-of-bandMIC" };
+       return wusb_prf_64(mic_out, 8, key, n, &a,
+                          hs, sizeof(*hs) - sizeof(hs->MIC));
+}
+
+#endif /* #ifndef __WUSB_H__ */
diff --git a/include/linux/uwb.h b/include/linux/uwb.h
new file mode 100644 (file)
index 0000000..f9ccbd9
--- /dev/null
@@ -0,0 +1,765 @@
+/*
+ * Ultra Wide Band
+ * UWB API
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: doc: overview of the API, different parts and pointers
+ */
+
+#ifndef __LINUX__UWB_H__
+#define __LINUX__UWB_H__
+
+#include <linux/limits.h>
+#include <linux/device.h>
+#include <linux/mutex.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
+#include <linux/uwb/spec.h>
+
+struct uwb_dev;
+struct uwb_beca_e;
+struct uwb_rc;
+struct uwb_rsv;
+struct uwb_dbg;
+
+/**
+ * struct uwb_dev - a UWB Device
+ * @rc: UWB Radio Controller that discovered the device (kind of its
+ *     parent).
+ * @bce: a beacon cache entry for this device; or NULL if the device
+ *     is a local radio controller.
+ * @mac_addr: the EUI-48 address of this device.
+ * @dev_addr: the current DevAddr used by this device.
+ * @beacon_slot: the slot number the beacon is using.
+ * @streams: bitmap of streams allocated to reservations targeted at
+ *     this device.  For an RC, this is the streams allocated for
+ *     reservations targeted at DevAddrs.
+ *
+ * A UWB device may either by a neighbor or part of a local radio
+ * controller.
+ */
+struct uwb_dev {
+       struct mutex mutex;
+       struct list_head list_node;
+       struct device dev;
+       struct uwb_rc *rc;              /* radio controller */
+       struct uwb_beca_e *bce;         /* Beacon Cache Entry */
+
+       struct uwb_mac_addr mac_addr;
+       struct uwb_dev_addr dev_addr;
+       int beacon_slot;
+       DECLARE_BITMAP(streams, UWB_NUM_STREAMS);
+};
+#define to_uwb_dev(d) container_of(d, struct uwb_dev, dev)
+
+/**
+ * UWB HWA/WHCI Radio Control {Command|Event} Block context IDs
+ *
+ * RC[CE]Bs have a 'context ID' field that matches the command with
+ * the event received to confirm it.
+ *
+ * Maximum number of context IDs
+ */
+enum { UWB_RC_CTX_MAX = 256 };
+
+
+/** Notification chain head for UWB generated events to listeners */
+struct uwb_notifs_chain {
+       struct list_head list;
+       struct mutex mutex;
+};
+
+/**
+ * struct uwb_mas_bm - a bitmap of all MAS in a superframe
+ * @bm: a bitmap of length #UWB_NUM_MAS
+ */
+struct uwb_mas_bm {
+       DECLARE_BITMAP(bm, UWB_NUM_MAS);
+};
+
+/**
+ * uwb_rsv_state - UWB Reservation state.
+ *
+ * NONE - reservation is not active (no DRP IE being transmitted).
+ *
+ * Owner reservation states:
+ *
+ * INITIATED - owner has sent an initial DRP request.
+ * PENDING - target responded with pending Reason Code.
+ * MODIFIED - reservation manager is modifying an established
+ * reservation with a different MAS allocation.
+ * ESTABLISHED - the reservation has been successfully negotiated.
+ *
+ * Target reservation states:
+ *
+ * DENIED - request is denied.
+ * ACCEPTED - request is accepted.
+ * PENDING - PAL has yet to make a decision to whether to accept or
+ * deny.
+ *
+ * FIXME: further target states TBD.
+ */
+enum uwb_rsv_state {
+       UWB_RSV_STATE_NONE,
+       UWB_RSV_STATE_O_INITIATED,
+       UWB_RSV_STATE_O_PENDING,
+       UWB_RSV_STATE_O_MODIFIED,
+       UWB_RSV_STATE_O_ESTABLISHED,
+       UWB_RSV_STATE_T_ACCEPTED,
+       UWB_RSV_STATE_T_DENIED,
+       UWB_RSV_STATE_T_PENDING,
+
+       UWB_RSV_STATE_LAST,
+};
+
+enum uwb_rsv_target_type {
+       UWB_RSV_TARGET_DEV,
+       UWB_RSV_TARGET_DEVADDR,
+};
+
+/**
+ * struct uwb_rsv_target - the target of a reservation.
+ *
+ * Reservations unicast and targeted at a single device
+ * (UWB_RSV_TARGET_DEV); or (e.g., in the case of WUSB) targeted at a
+ * specific (private) DevAddr (UWB_RSV_TARGET_DEVADDR).
+ */
+struct uwb_rsv_target {
+       enum uwb_rsv_target_type type;
+       union {
+               struct uwb_dev *dev;
+               struct uwb_dev_addr devaddr;
+       };
+};
+
+/*
+ * Number of streams reserved for reservations targeted at DevAddrs.
+ */
+#define UWB_NUM_GLOBAL_STREAMS 1
+
+typedef void (*uwb_rsv_cb_f)(struct uwb_rsv *rsv);
+
+/**
+ * struct uwb_rsv - a DRP reservation
+ *
+ * Data structure management:
+ *
+ * @rc:             the radio controller this reservation is for
+ *                  (as target or owner)
+ * @rc_node:        a list node for the RC
+ * @pal_node:       a list node for the PAL
+ *
+ * Owner and target parameters:
+ *
+ * @owner:          the UWB device owning this reservation
+ * @target:         the target UWB device
+ * @type:           reservation type
+ *
+ * Owner parameters:
+ *
+ * @max_mas:        maxiumum number of MAS
+ * @min_mas:        minimum number of MAS
+ * @sparsity:       owner selected sparsity
+ * @is_multicast:   true iff multicast
+ *
+ * @callback:       callback function when the reservation completes
+ * @pal_priv:       private data for the PAL making the reservation
+ *
+ * Reservation status:
+ *
+ * @status:         negotiation status
+ * @stream:         stream index allocated for this reservation
+ * @mas:            reserved MAS
+ * @drp_ie:         the DRP IE
+ * @ie_valid:       true iff the DRP IE matches the reservation parameters
+ *
+ * DRP reservations are uniquely identified by the owner, target and
+ * stream index.  However, when using a DevAddr as a target (e.g., for
+ * a WUSB cluster reservation) the responses may be received from
+ * devices with different DevAddrs.  In this case, reservations are
+ * uniquely identified by just the stream index.  A number of stream
+ * indexes (UWB_NUM_GLOBAL_STREAMS) are reserved for this.
+ */
+struct uwb_rsv {
+       struct uwb_rc *rc;
+       struct list_head rc_node;
+       struct list_head pal_node;
+
+       struct uwb_dev *owner;
+       struct uwb_rsv_target target;
+       enum uwb_drp_type type;
+       int max_mas;
+       int min_mas;
+       int sparsity;
+       bool is_multicast;
+
+       uwb_rsv_cb_f callback;
+       void *pal_priv;
+
+       enum uwb_rsv_state state;
+       u8 stream;
+       struct uwb_mas_bm mas;
+       struct uwb_ie_drp *drp_ie;
+       bool ie_valid;
+       struct timer_list timer;
+       bool expired;
+};
+
+static const
+struct uwb_mas_bm uwb_mas_bm_zero = { .bm = { 0 } };
+
+static inline void uwb_mas_bm_copy_le(void *dst, const struct uwb_mas_bm *mas)
+{
+       bitmap_copy_le(dst, mas->bm, UWB_NUM_MAS);
+}
+
+/**
+ * struct uwb_drp_avail - a radio controller's view of MAS usage
+ * @global:   MAS unused by neighbors (excluding reservations targetted
+ *            or owned by the local radio controller) or the beaon period
+ * @local:    MAS unused by local established reservations
+ * @pending:  MAS unused by local pending reservations
+ * @ie:       DRP Availability IE to be included in the beacon
+ * @ie_valid: true iff @ie is valid and does not need to regenerated from
+ *            @global and @local
+ *
+ * Each radio controller maintains a view of MAS usage or
+ * availability. MAS available for a new reservation are determined
+ * from the intersection of @global, @local, and @pending.
+ *
+ * The radio controller must transmit a DRP Availability IE that's the
+ * intersection of @global and @local.
+ *
+ * A set bit indicates the MAS is unused and available.
+ *
+ * rc->rsvs_mutex should be held before accessing this data structure.
+ *
+ * [ECMA-368] section 17.4.3.
+ */
+struct uwb_drp_avail {
+       DECLARE_BITMAP(global, UWB_NUM_MAS);
+       DECLARE_BITMAP(local, UWB_NUM_MAS);
+       DECLARE_BITMAP(pending, UWB_NUM_MAS);
+       struct uwb_ie_drp_avail ie;
+       bool ie_valid;
+};
+
+
+const char *uwb_rsv_state_str(enum uwb_rsv_state state);
+const char *uwb_rsv_type_str(enum uwb_drp_type type);
+
+struct uwb_rsv *uwb_rsv_create(struct uwb_rc *rc, uwb_rsv_cb_f cb,
+                              void *pal_priv);
+void uwb_rsv_destroy(struct uwb_rsv *rsv);
+
+int uwb_rsv_establish(struct uwb_rsv *rsv);
+int uwb_rsv_modify(struct uwb_rsv *rsv,
+                  int max_mas, int min_mas, int sparsity);
+void uwb_rsv_terminate(struct uwb_rsv *rsv);
+
+void uwb_rsv_accept(struct uwb_rsv *rsv, uwb_rsv_cb_f cb, void *pal_priv);
+
+/**
+ * Radio Control Interface instance
+ *
+ *
+ * Life cycle rules: those of the UWB Device.
+ *
+ * @index:    an index number for this radio controller, as used in the
+ *            device name.
+ * @version:  version of protocol supported by this device
+ * @priv:     Backend implementation; rw with uwb_dev.dev.sem taken.
+ * @cmd:      Backend implementation to execute commands; rw and call
+ *            only  with uwb_dev.dev.sem taken.
+ * @reset:    Hardware reset of radio controller and any PAL controllers.
+ * @filter:   Backend implementation to manipulate data to and from device
+ *            to be compliant to specification assumed by driver (WHCI
+ *            0.95).
+ *
+ *            uwb_dev.dev.mutex is used to execute commands and update
+ *            the corresponding structures; can't use a spinlock
+ *            because rc->cmd() can sleep.
+ * @ies:         This is a dynamically allocated array cacheing the
+ *               IEs (settable by the host) that the beacon of this
+ *               radio controller is currently sending.
+ *
+ *               In reality, we store here the full command we set to
+ *               the radio controller (which is basically a command
+ *               prefix followed by all the IEs the beacon currently
+ *               contains). This way we don't have to realloc and
+ *               memcpy when setting it.
+ *
+ *               We set this up in uwb_rc_ie_setup(), where we alloc
+ *               this struct, call get_ie() [so we know which IEs are
+ *               currently being sent, if any].
+ *
+ * @ies_capacity:Amount of space (in bytes) allocated in @ies. The
+ *               amount used is given by sizeof(*ies) plus ies->wIELength
+ *               (which is a little endian quantity all the time).
+ * @ies_mutex:   protect the IE cache
+ * @dbg:         information for the debug interface
+ */
+struct uwb_rc {
+       struct uwb_dev uwb_dev;
+       int index;
+       u16 version;
+
+       struct module *owner;
+       void *priv;
+       int (*start)(struct uwb_rc *rc);
+       void (*stop)(struct uwb_rc *rc);
+       int (*cmd)(struct uwb_rc *, const struct uwb_rccb *, size_t);
+       int (*reset)(struct uwb_rc *rc);
+       int (*filter_cmd)(struct uwb_rc *, struct uwb_rccb **, size_t *);
+       int (*filter_event)(struct uwb_rc *, struct uwb_rceb **, const size_t,
+                           size_t *, size_t *);
+
+       spinlock_t neh_lock;            /* protects neh_* and ctx_* */
+       struct list_head neh_list;      /* Open NE handles */
+       unsigned long ctx_bm[UWB_RC_CTX_MAX / 8 / sizeof(unsigned long)];
+       u8 ctx_roll;
+
+       int beaconing;                  /* Beaconing state [channel number] */
+       int scanning;
+       enum uwb_scan_type scan_type:3;
+       unsigned ready:1;
+       struct uwb_notifs_chain notifs_chain;
+
+       struct uwb_drp_avail drp_avail;
+       struct list_head reservations;
+       struct mutex rsvs_mutex;
+       struct workqueue_struct *rsv_workq;
+       struct work_struct rsv_update_work;
+
+       struct mutex ies_mutex;
+       struct uwb_rc_cmd_set_ie *ies;
+       size_t ies_capacity;
+
+       spinlock_t pal_lock;
+       struct list_head pals;
+
+       struct uwb_dbg *dbg;
+};
+
+
+/**
+ * struct uwb_pal - a UWB PAL
+ * @name:    descriptive name for this PAL (wushc, wlp, etc.).
+ * @device:  a device for the PAL.  Used to link the PAL and the radio
+ *           controller in sysfs.
+ * @new_rsv: called when a peer requests a reservation (may be NULL if
+ *           the PAL cannot accept reservation requests).
+ *
+ * A Protocol Adaptation Layer (PAL) is a user of the WiMedia UWB
+ * radio platform (e.g., WUSB, WLP or Bluetooth UWB AMP).
+ *
+ * The PALs using a radio controller must register themselves to
+ * permit the UWB stack to coordinate usage of the radio between the
+ * various PALs or to allow PALs to response to certain requests from
+ * peers.
+ *
+ * A struct uwb_pal should be embedded in a containing structure
+ * belonging to the PAL and initialized with uwb_pal_init()).  Fields
+ * should be set appropriately by the PAL before registering the PAL
+ * with uwb_pal_register().
+ */
+struct uwb_pal {
+       struct list_head node;
+       const char *name;
+       struct device *device;
+       void (*new_rsv)(struct uwb_rsv *rsv);
+};
+
+void uwb_pal_init(struct uwb_pal *pal);
+int uwb_pal_register(struct uwb_rc *rc, struct uwb_pal *pal);
+void uwb_pal_unregister(struct uwb_rc *rc, struct uwb_pal *pal);
+
+/*
+ * General public API
+ *
+ * This API can be used by UWB device drivers or by those implementing
+ * UWB Radio Controllers
+ */
+struct uwb_dev *uwb_dev_get_by_devaddr(struct uwb_rc *rc,
+                                      const struct uwb_dev_addr *devaddr);
+struct uwb_dev *uwb_dev_get_by_rc(struct uwb_dev *, struct uwb_rc *);
+static inline void uwb_dev_get(struct uwb_dev *uwb_dev)
+{
+       get_device(&uwb_dev->dev);
+}
+static inline void uwb_dev_put(struct uwb_dev *uwb_dev)
+{
+       put_device(&uwb_dev->dev);
+}
+struct uwb_dev *uwb_dev_try_get(struct uwb_rc *rc, struct uwb_dev *uwb_dev);
+
+/**
+ * Callback function for 'uwb_{dev,rc}_foreach()'.
+ *
+ * @dev:  Linux device instance
+ *        'uwb_dev = container_of(dev, struct uwb_dev, dev)'
+ * @priv: Data passed by the caller to 'uwb_{dev,rc}_foreach()'.
+ *
+ * @returns: 0 to continue the iterations, any other val to stop
+ *           iterating and return the value to the caller of
+ *           _foreach().
+ */
+typedef int (*uwb_dev_for_each_f)(struct device *dev, void *priv);
+int uwb_dev_for_each(struct uwb_rc *rc, uwb_dev_for_each_f func, void *priv);
+
+struct uwb_rc *uwb_rc_alloc(void);
+struct uwb_rc *uwb_rc_get_by_dev(const struct uwb_dev_addr *);
+struct uwb_rc *uwb_rc_get_by_grandpa(const struct device *);
+void uwb_rc_put(struct uwb_rc *rc);
+
+typedef void (*uwb_rc_cmd_cb_f)(struct uwb_rc *rc, void *arg,
+                                struct uwb_rceb *reply, ssize_t reply_size);
+
+int uwb_rc_cmd_async(struct uwb_rc *rc, const char *cmd_name,
+                    struct uwb_rccb *cmd, size_t cmd_size,
+                    u8 expected_type, u16 expected_event,
+                    uwb_rc_cmd_cb_f cb, void *arg);
+ssize_t uwb_rc_cmd(struct uwb_rc *rc, const char *cmd_name,
+                  struct uwb_rccb *cmd, size_t cmd_size,
+                  struct uwb_rceb *reply, size_t reply_size);
+ssize_t uwb_rc_vcmd(struct uwb_rc *rc, const char *cmd_name,
+                   struct uwb_rccb *cmd, size_t cmd_size,
+                   u8 expected_type, u16 expected_event,
+                   struct uwb_rceb **preply);
+ssize_t uwb_rc_get_ie(struct uwb_rc *, struct uwb_rc_evt_get_ie **);
+int uwb_bg_joined(struct uwb_rc *rc);
+
+size_t __uwb_addr_print(char *, size_t, const unsigned char *, int);
+
+int uwb_rc_dev_addr_set(struct uwb_rc *, const struct uwb_dev_addr *);
+int uwb_rc_dev_addr_get(struct uwb_rc *, struct uwb_dev_addr *);
+int uwb_rc_mac_addr_set(struct uwb_rc *, const struct uwb_mac_addr *);
+int uwb_rc_mac_addr_get(struct uwb_rc *, struct uwb_mac_addr *);
+int __uwb_mac_addr_assigned_check(struct device *, void *);
+int __uwb_dev_addr_assigned_check(struct device *, void *);
+
+/* Print in @buf a pretty repr of @addr */
+static inline size_t uwb_dev_addr_print(char *buf, size_t buf_size,
+                                       const struct uwb_dev_addr *addr)
+{
+       return __uwb_addr_print(buf, buf_size, addr->data, 0);
+}
+
+/* Print in @buf a pretty repr of @addr */
+static inline size_t uwb_mac_addr_print(char *buf, size_t buf_size,
+                                       const struct uwb_mac_addr *addr)
+{
+       return __uwb_addr_print(buf, buf_size, addr->data, 1);
+}
+
+/* @returns 0 if device addresses @addr2 and @addr1 are equal */
+static inline int uwb_dev_addr_cmp(const struct uwb_dev_addr *addr1,
+                                  const struct uwb_dev_addr *addr2)
+{
+       return memcmp(addr1, addr2, sizeof(*addr1));
+}
+
+/* @returns 0 if MAC addresses @addr2 and @addr1 are equal */
+static inline int uwb_mac_addr_cmp(const struct uwb_mac_addr *addr1,
+                                  const struct uwb_mac_addr *addr2)
+{
+       return memcmp(addr1, addr2, sizeof(*addr1));
+}
+
+/* @returns !0 if a MAC @addr is a broadcast address */
+static inline int uwb_mac_addr_bcast(const struct uwb_mac_addr *addr)
+{
+       struct uwb_mac_addr bcast = {
+               .data = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
+       };
+       return !uwb_mac_addr_cmp(addr, &bcast);
+}
+
+/* @returns !0 if a MAC @addr is all zeroes*/
+static inline int uwb_mac_addr_unset(const struct uwb_mac_addr *addr)
+{
+       struct uwb_mac_addr unset = {
+               .data = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+       };
+       return !uwb_mac_addr_cmp(addr, &unset);
+}
+
+/* @returns !0 if the address is in use. */
+static inline unsigned __uwb_dev_addr_assigned(struct uwb_rc *rc,
+                                              struct uwb_dev_addr *addr)
+{
+       return uwb_dev_for_each(rc, __uwb_dev_addr_assigned_check, addr);
+}
+
+/*
+ * UWB Radio Controller API
+ *
+ * This API is used (in addition to the general API) to implement UWB
+ * Radio Controllers.
+ */
+void uwb_rc_init(struct uwb_rc *);
+int uwb_rc_add(struct uwb_rc *, struct device *dev, void *rc_priv);
+void uwb_rc_rm(struct uwb_rc *);
+void uwb_rc_neh_grok(struct uwb_rc *, void *, size_t);
+void uwb_rc_neh_error(struct uwb_rc *, int);
+void uwb_rc_reset_all(struct uwb_rc *rc);
+
+/**
+ * uwb_rsv_is_owner - is the owner of this reservation the RC?
+ * @rsv: the reservation
+ */
+static inline bool uwb_rsv_is_owner(struct uwb_rsv *rsv)
+{
+       return rsv->owner == &rsv->rc->uwb_dev;
+}
+
+/**
+ * Events generated by UWB that can be passed to any listeners
+ *
+ * Higher layers can register callback functions with the radio
+ * controller using uwb_notifs_register(). The radio controller
+ * maintains a list of all registered handlers and will notify all
+ * nodes when an event occurs.
+ */
+enum uwb_notifs {
+       UWB_NOTIF_BG_JOIN = 0,  /* radio controller joined a beacon group */
+       UWB_NOTIF_BG_LEAVE = 1, /* radio controller left a beacon group */
+       UWB_NOTIF_ONAIR,
+       UWB_NOTIF_OFFAIR,
+};
+
+/* Callback function registered with UWB */
+struct uwb_notifs_handler {
+       struct list_head list_node;
+       void (*cb)(void *, struct uwb_dev *, enum uwb_notifs);
+       void *data;
+};
+
+int uwb_notifs_register(struct uwb_rc *, struct uwb_notifs_handler *);
+int uwb_notifs_deregister(struct uwb_rc *, struct uwb_notifs_handler *);
+
+
+/**
+ * UWB radio controller Event Size Entry (for creating entry tables)
+ *
+ * WUSB and WHCI define events and notifications, and they might have
+ * fixed or variable size.
+ *
+ * Each event/notification has a size which is not necessarily known
+ * in advance based on the event code. As well, vendor specific
+ * events/notifications will have a size impossible to determine
+ * unless we know about the device's specific details.
+ *
+ * It was way too smart of the spec writers not to think that it would
+ * be impossible for a generic driver to skip over vendor specific
+ * events/notifications if there are no LENGTH fields in the HEADER of
+ * each message...the transaction size cannot be counted on as the
+ * spec does not forbid to pack more than one event in a single
+ * transaction.
+ *
+ * Thus, we guess sizes with tables (or for events, when you know the
+ * size ahead of time you can use uwb_rc_neh_extra_size*()). We
+ * register tables with the known events and their sizes, and then we
+ * traverse those tables. For those with variable length, we provide a
+ * way to lookup the size inside the event/notification's
+ * payload. This allows device-specific event size tables to be
+ * registered.
+ *
+ * @size:   Size of the payload
+ *
+ * @offset: if != 0, at offset @offset-1 starts a field with a length
+ *          that has to be added to @size. The format of the field is
+ *          given by @type.
+ *
+ * @type:   Type and length of the offset field. Most common is LE 16
+ *          bits (that's why that is zero); others are there mostly to
+ *          cover for bugs and weirdos.
+ */
+struct uwb_est_entry {
+       size_t size;
+       unsigned offset;
+       enum { UWB_EST_16 = 0, UWB_EST_8 = 1 } type;
+};
+
+int uwb_est_register(u8 type, u8 code_high, u16 vendor, u16 product,
+                    const struct uwb_est_entry *, size_t entries);
+int uwb_est_unregister(u8 type, u8 code_high, u16 vendor, u16 product,
+                      const struct uwb_est_entry *, size_t entries);
+ssize_t uwb_est_find_size(struct uwb_rc *rc, const struct uwb_rceb *rceb,
+                         size_t len);
+
+/* -- Misc */
+
+enum {
+       EDC_MAX_ERRORS = 10,
+       EDC_ERROR_TIMEFRAME = HZ,
+};
+
+/* error density counter */
+struct edc {
+       unsigned long timestart;
+       u16 errorcount;
+};
+
+static inline
+void edc_init(struct edc *edc)
+{
+       edc->timestart = jiffies;
+}
+
+/* Called when an error occured.
+ * This is way to determine if the number of acceptable errors per time
+ * period has been exceeded. It is not accurate as there are cases in which
+ * this scheme will not work, for example if there are periodic occurences
+ * of errors that straddle updates to the start time. This scheme is
+ * sufficient for our usage.
+ *
+ * @returns 1 if maximum acceptable errors per timeframe has been exceeded.
+ */
+static inline int edc_inc(struct edc *err_hist, u16 max_err, u16 timeframe)
+{
+       unsigned long now;
+
+       now = jiffies;
+       if (now - err_hist->timestart > timeframe) {
+               err_hist->errorcount = 1;
+               err_hist->timestart = now;
+       } else if (++err_hist->errorcount > max_err) {
+                       err_hist->errorcount = 0;
+                       err_hist->timestart = now;
+                       return 1;
+       }
+       return 0;
+}
+
+
+/* Information Element handling */
+
+/* For representing the state of writing to a buffer when iterating */
+struct uwb_buf_ctx {
+       char *buf;
+       size_t bytes, size;
+};
+
+typedef int (*uwb_ie_f)(struct uwb_dev *, const struct uwb_ie_hdr *,
+                       size_t, void *);
+struct uwb_ie_hdr *uwb_ie_next(void **ptr, size_t *len);
+ssize_t uwb_ie_for_each(struct uwb_dev *uwb_dev, uwb_ie_f fn, void *data,
+                       const void *buf, size_t size);
+int uwb_ie_dump_hex(struct uwb_dev *, const struct uwb_ie_hdr *,
+                   size_t, void *);
+int uwb_rc_set_ie(struct uwb_rc *, struct uwb_rc_cmd_set_ie *);
+struct uwb_ie_hdr *uwb_ie_next(void **ptr, size_t *len);
+
+
+/*
+ * Transmission statistics
+ *
+ * UWB uses LQI and RSSI (one byte values) for reporting radio signal
+ * strength and line quality indication. We do quick and dirty
+ * averages of those. They are signed values, btw.
+ *
+ * For 8 bit quantities, we keep the min, the max, an accumulator
+ * (@sigma) and a # of samples. When @samples gets to 255, we compute
+ * the average (@sigma / @samples), place it in @sigma and reset
+ * @samples to 1 (so we use it as the first sample).
+ *
+ * Now, statistically speaking, probably I am kicking the kidneys of
+ * some books I have in my shelves collecting dust, but I just want to
+ * get an approx, not the Nobel.
+ *
+ * LOCKING: there is no locking per se, but we try to keep a lockless
+ * schema. Only _add_samples() modifies the values--as long as you
+ * have other locking on top that makes sure that no two calls of
+ * _add_sample() happen at the same time, then we are fine. Now, for
+ * resetting the values we just set @samples to 0 and that makes the
+ * next _add_sample() to start with defaults. Reading the values in
+ * _show() currently can race, so you need to make sure the calls are
+ * under the same lock that protects calls to _add_sample(). FIXME:
+ * currently unlocked (It is not ultraprecise but does the trick. Bite
+ * me).
+ */
+struct stats {
+       s8 min, max;
+       s16 sigma;
+       atomic_t samples;
+};
+
+static inline
+void stats_init(struct stats *stats)
+{
+       atomic_set(&stats->samples, 0);
+       wmb();
+}
+
+static inline
+void stats_add_sample(struct stats *stats, s8 sample)
+{
+       s8 min, max;
+       s16 sigma;
+       unsigned samples = atomic_read(&stats->samples);
+       if (samples == 0) {     /* it was zero before, so we initialize */
+               min = 127;
+               max = -128;
+               sigma = 0;
+       } else {
+               min = stats->min;
+               max = stats->max;
+               sigma = stats->sigma;
+       }
+
+       if (sample < min)       /* compute new values */
+               min = sample;
+       else if (sample > max)
+               max = sample;
+       sigma += sample;
+
+       stats->min = min;       /* commit */
+       stats->max = max;
+       stats->sigma = sigma;
+       if (atomic_add_return(1, &stats->samples) > 255) {
+               /* wrapped around! reset */
+               stats->sigma = sigma / 256;
+               atomic_set(&stats->samples, 1);
+       }
+}
+
+static inline ssize_t stats_show(struct stats *stats, char *buf)
+{
+       int min, max, avg;
+       int samples = atomic_read(&stats->samples);
+       if (samples == 0)
+               min = max = avg = 0;
+       else {
+               min = stats->min;
+               max = stats->max;
+               avg = stats->sigma / samples;
+       }
+       return scnprintf(buf, PAGE_SIZE, "%d %d %d\n", min, max, avg);
+}
+
+static inline ssize_t stats_store(struct stats *stats, const char *buf,
+                                 size_t size)
+{
+       stats_init(stats);
+       return size;
+}
+
+#endif /* #ifndef __LINUX__UWB_H__ */
diff --git a/include/linux/uwb/debug-cmd.h b/include/linux/uwb/debug-cmd.h
new file mode 100644 (file)
index 0000000..1141f41
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Ultra Wide Band
+ * Debug interface commands
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __LINUX__UWB__DEBUG_CMD_H__
+#define __LINUX__UWB__DEBUG_CMD_H__
+
+#include <linux/types.h>
+
+/*
+ * Debug interface commands
+ *
+ * UWB_DBG_CMD_RSV_ESTABLISH: Establish a new unicast reservation.
+ *
+ * UWB_DBG_CMD_RSV_TERMINATE: Terminate the Nth reservation.
+ */
+
+enum uwb_dbg_cmd_type {
+       UWB_DBG_CMD_RSV_ESTABLISH = 1,
+       UWB_DBG_CMD_RSV_TERMINATE = 2,
+};
+
+struct uwb_dbg_cmd_rsv_establish {
+       __u8  target[6];
+       __u8  type;
+       __u16 max_mas;
+       __u16 min_mas;
+       __u8  sparsity;
+};
+
+struct uwb_dbg_cmd_rsv_terminate {
+       int index;
+};
+
+struct uwb_dbg_cmd {
+       __u32 type;
+       union {
+               struct uwb_dbg_cmd_rsv_establish rsv_establish;
+               struct uwb_dbg_cmd_rsv_terminate rsv_terminate;
+       };
+};
+
+#endif /* #ifndef __LINUX__UWB__DEBUG_CMD_H__ */
diff --git a/include/linux/uwb/debug.h b/include/linux/uwb/debug.h
new file mode 100644 (file)
index 0000000..a86a73f
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Ultra Wide Band
+ * Debug Support
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: doc
+ * Invoke like:
+ *
+ * #define D_LOCAL 4
+ * #include <linux/uwb/debug.h>
+ *
+ * At the end of your include files.
+ */
+#include <linux/types.h>
+
+struct device;
+extern void dump_bytes(struct device *dev, const void *_buf, size_t rsize);
+
+/* Master debug switch; !0 enables, 0 disables */
+#define D_MASTER (!0)
+
+/* Local (per-file) debug switch; #define before #including */
+#ifndef D_LOCAL
+#define D_LOCAL 0
+#endif
+
+#undef __d_printf
+#undef d_fnstart
+#undef d_fnend
+#undef d_printf
+#undef d_dump
+
+#define __d_printf(l, _tag, _dev, f, a...)                             \
+do {                                                                   \
+       struct device *__dev = (_dev);                                  \
+       if (D_MASTER && D_LOCAL >= (l)) {                               \
+               char __head[64] = "";                                   \
+               if (_dev != NULL) {                                     \
+                       if ((unsigned long)__dev < 4096)                \
+                               printk(KERN_ERR "E: Corrupt dev %p\n",  \
+                                       __dev);                         \
+                       else                                            \
+                               snprintf(__head, sizeof(__head),        \
+                                        "%s %s: ",                     \
+                                        dev_driver_string(__dev),      \
+                                        __dev->bus_id);                \
+               }                                                       \
+               printk(KERN_ERR "%s%s" _tag ": " f, __head,             \
+                       __func__, ## a);                                \
+       }                                                               \
+} while (0 && _dev)
+
+#define d_fnstart(l, _dev, f, a...)    \
+       __d_printf(l, " FNSTART", _dev, f, ## a)
+#define d_fnend(l, _dev, f, a...)      \
+       __d_printf(l, " FNEND", _dev, f, ## a)
+#define d_printf(l, _dev, f, a...)     \
+       __d_printf(l, "", _dev, f, ## a)
+#define d_dump(l, _dev, ptr, size)             \
+do {                                           \
+       struct device *__dev = _dev;            \
+       if (D_MASTER && D_LOCAL >= (l))         \
+               dump_bytes(__dev, ptr, size);   \
+} while (0 && _dev)
+#define d_test(l) (D_MASTER && D_LOCAL >= (l))
diff --git a/include/linux/uwb/spec.h b/include/linux/uwb/spec.h
new file mode 100644 (file)
index 0000000..198c15f
--- /dev/null
@@ -0,0 +1,727 @@
+/*
+ * Ultra Wide Band
+ * UWB Standard definitions
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * All these definitions are based on the ECMA-368 standard.
+ *
+ * Note all definitions are Little Endian in the wire, and we will
+ * convert them to host order before operating on the bitfields (that
+ * yes, we use extensively).
+ */
+
+#ifndef __LINUX__UWB_SPEC_H__
+#define __LINUX__UWB_SPEC_H__
+
+#include <linux/types.h>
+#include <linux/bitmap.h>
+
+#define i1480_FW 0x00000303
+/* #define i1480_FW 0x00000302 */
+
+/**
+ * Number of Medium Access Slots in a superframe.
+ *
+ * UWB divides time in SuperFrames, each one divided in 256 pieces, or
+ * Medium Access Slots. See MBOA MAC[5.4.5] for details. The MAS is the
+ * basic bandwidth allocation unit in UWB.
+ */
+enum { UWB_NUM_MAS = 256 };
+
+/**
+ * Number of Zones in superframe.
+ *
+ * UWB divides the superframe into zones with numbering starting from BPST.
+ * See MBOA MAC[16.8.6]
+ */
+enum { UWB_NUM_ZONES = 16 };
+
+/*
+ * Number of MAS in a zone.
+ */
+#define UWB_MAS_PER_ZONE (UWB_NUM_MAS / UWB_NUM_ZONES)
+
+/*
+ * Number of streams per DRP reservation between a pair of devices.
+ *
+ * [ECMA-368] section 16.8.6.
+ */
+enum { UWB_NUM_STREAMS = 8 };
+
+/*
+ * mMasLength
+ *
+ * The length of a MAS in microseconds.
+ *
+ * [ECMA-368] section 17.16.
+ */
+enum { UWB_MAS_LENGTH_US = 256 };
+
+/*
+ * mBeaconSlotLength
+ *
+ * The length of the beacon slot in microseconds.
+ *
+ * [ECMA-368] section 17.16
+ */
+enum { UWB_BEACON_SLOT_LENGTH_US = 85 };
+
+/*
+ * mMaxLostBeacons
+ *
+ * The number beacons missing in consecutive superframes before a
+ * device can be considered as unreachable.
+ *
+ * [ECMA-368] section 17.16
+ */
+enum { UWB_MAX_LOST_BEACONS = 3 };
+
+/*
+ * Length of a superframe in microseconds.
+ */
+#define UWB_SUPERFRAME_LENGTH_US (UWB_MAS_LENGTH_US * UWB_NUM_MAS)
+
+/**
+ * UWB MAC address
+ *
+ * It is *imperative* that this struct is exactly 6 packed bytes (as
+ * it is also used to define headers sent down and up the wire/radio).
+ */
+struct uwb_mac_addr {
+       u8 data[6];
+} __attribute__((packed));
+
+
+/**
+ * UWB device address
+ *
+ * It is *imperative* that this struct is exactly 6 packed bytes (as
+ * it is also used to define headers sent down and up the wire/radio).
+ */
+struct uwb_dev_addr {
+       u8 data[2];
+} __attribute__((packed));
+
+
+/**
+ * Types of UWB addresses
+ *
+ * Order matters (by size).
+ */
+enum uwb_addr_type {
+       UWB_ADDR_DEV = 0,
+       UWB_ADDR_MAC = 1,
+};
+
+
+/** Size of a char buffer for printing a MAC/device address */
+enum { UWB_ADDR_STRSIZE = 32 };
+
+
+/** UWB WiMedia protocol IDs. */
+enum uwb_prid {
+       UWB_PRID_WLP_RESERVED   = 0x0000,
+       UWB_PRID_WLP            = 0x0001,
+       UWB_PRID_WUSB_BOT       = 0x0010,
+       UWB_PRID_WUSB           = 0x0010,
+       UWB_PRID_WUSB_TOP       = 0x001F,
+};
+
+
+/** PHY Rate (MBOA MAC[7.8.12, Table 61]) */
+enum uwb_phy_rate {
+       UWB_PHY_RATE_53 = 0,
+       UWB_PHY_RATE_80,
+       UWB_PHY_RATE_106,
+       UWB_PHY_RATE_160,
+       UWB_PHY_RATE_200,
+       UWB_PHY_RATE_320,
+       UWB_PHY_RATE_400,
+       UWB_PHY_RATE_480,
+       UWB_PHY_RATE_INVALID
+};
+
+
+/**
+ * Different ways to scan (MBOA MAC[6.2.2, Table 8], WUSB[Table 8-78])
+ */
+enum uwb_scan_type {
+       UWB_SCAN_ONLY = 0,
+       UWB_SCAN_OUTSIDE_BP,
+       UWB_SCAN_WHILE_INACTIVE,
+       UWB_SCAN_DISABLED,
+       UWB_SCAN_ONLY_STARTTIME,
+       UWB_SCAN_TOP
+};
+
+
+/** ACK Policy types (MBOA MAC[7.2.1.3]) */
+enum uwb_ack_pol {
+       UWB_ACK_NO = 0,
+       UWB_ACK_INM = 1,
+       UWB_ACK_B = 2,
+       UWB_ACK_B_REQ = 3,
+};
+
+
+/** DRP reservation types ([ECMA-368 table 106) */
+enum uwb_drp_type {
+       UWB_DRP_TYPE_ALIEN_BP = 0,
+       UWB_DRP_TYPE_HARD,
+       UWB_DRP_TYPE_SOFT,
+       UWB_DRP_TYPE_PRIVATE,
+       UWB_DRP_TYPE_PCA,
+};
+
+
+/** DRP Reason Codes ([ECMA-368] table 107) */
+enum uwb_drp_reason {
+       UWB_DRP_REASON_ACCEPTED = 0,
+       UWB_DRP_REASON_CONFLICT,
+       UWB_DRP_REASON_PENDING,
+       UWB_DRP_REASON_DENIED,
+       UWB_DRP_REASON_MODIFIED,
+};
+
+/**
+ *  DRP Notification Reason Codes (WHCI 0.95 [3.1.4.9])
+ */
+enum uwb_drp_notif_reason {
+       UWB_DRP_NOTIF_DRP_IE_RCVD = 0,
+       UWB_DRP_NOTIF_CONFLICT,
+       UWB_DRP_NOTIF_TERMINATE,
+};
+
+
+/** Allocation of MAS slots in a DRP request MBOA MAC[7.8.7] */
+struct uwb_drp_alloc {
+       __le16 zone_bm;
+       __le16 mas_bm;
+} __attribute__((packed));
+
+
+/** General MAC Header format (ECMA-368[16.2]) */
+struct uwb_mac_frame_hdr {
+       __le16 Frame_Control;
+       struct uwb_dev_addr DestAddr;
+       struct uwb_dev_addr SrcAddr;
+       __le16 Sequence_Control;
+       __le16 Access_Information;
+} __attribute__((packed));
+
+
+/**
+ * uwb_beacon_frame - a beacon frame including MAC headers
+ *
+ * [ECMA] section 16.3.
+ */
+struct uwb_beacon_frame {
+       struct uwb_mac_frame_hdr hdr;
+       struct uwb_mac_addr Device_Identifier;  /* may be a NULL EUI-48 */
+       u8 Beacon_Slot_Number;
+       u8 Device_Control;
+       u8 IEData[];
+} __attribute__((packed));
+
+
+/** Information Element codes (MBOA MAC[T54]) */
+enum uwb_ie {
+       UWB_PCA_AVAILABILITY = 2,
+       UWB_IE_DRP_AVAILABILITY = 8,
+       UWB_IE_DRP = 9,
+       UWB_BP_SWITCH_IE = 11,
+       UWB_MAC_CAPABILITIES_IE = 12,
+       UWB_PHY_CAPABILITIES_IE = 13,
+       UWB_APP_SPEC_PROBE_IE = 15,
+       UWB_IDENTIFICATION_IE = 19,
+       UWB_MASTER_KEY_ID_IE = 20,
+       UWB_IE_WLP = 250, /* WiMedia Logical Link Control Protocol WLP 0.99 */
+       UWB_APP_SPEC_IE = 255,
+};
+
+
+/**
+ * Header common to all Information Elements (IEs)
+ */
+struct uwb_ie_hdr {
+       u8 element_id;  /* enum uwb_ie */
+       u8 length;
+} __attribute__((packed));
+
+
+/** Dynamic Reservation Protocol IE (MBOA MAC[7.8.6]) */
+struct uwb_ie_drp {
+       struct uwb_ie_hdr       hdr;
+       __le16                  drp_control;
+       struct uwb_dev_addr     dev_addr;
+       struct uwb_drp_alloc    allocs[];
+} __attribute__((packed));
+
+static inline int uwb_ie_drp_type(struct uwb_ie_drp *ie)
+{
+       return (le16_to_cpu(ie->drp_control) >> 0) & 0x7;
+}
+
+static inline int uwb_ie_drp_stream_index(struct uwb_ie_drp *ie)
+{
+       return (le16_to_cpu(ie->drp_control) >> 3) & 0x7;
+}
+
+static inline int uwb_ie_drp_reason_code(struct uwb_ie_drp *ie)
+{
+       return (le16_to_cpu(ie->drp_control) >> 6) & 0x7;
+}
+
+static inline int uwb_ie_drp_status(struct uwb_ie_drp *ie)
+{
+       return (le16_to_cpu(ie->drp_control) >> 9) & 0x1;
+}
+
+static inline int uwb_ie_drp_owner(struct uwb_ie_drp *ie)
+{
+       return (le16_to_cpu(ie->drp_control) >> 10) & 0x1;
+}
+
+static inline int uwb_ie_drp_tiebreaker(struct uwb_ie_drp *ie)
+{
+       return (le16_to_cpu(ie->drp_control) >> 11) & 0x1;
+}
+
+static inline int uwb_ie_drp_unsafe(struct uwb_ie_drp *ie)
+{
+       return (le16_to_cpu(ie->drp_control) >> 12) & 0x1;
+}
+
+static inline void uwb_ie_drp_set_type(struct uwb_ie_drp *ie, enum uwb_drp_type type)
+{
+       u16 drp_control = le16_to_cpu(ie->drp_control);
+       drp_control = (drp_control & ~(0x7 << 0)) | (type << 0);
+       ie->drp_control = cpu_to_le16(drp_control);
+}
+
+static inline void uwb_ie_drp_set_stream_index(struct uwb_ie_drp *ie, int stream_index)
+{
+       u16 drp_control = le16_to_cpu(ie->drp_control);
+       drp_control = (drp_control & ~(0x7 << 3)) | (stream_index << 3);
+       ie->drp_control = cpu_to_le16(drp_control);
+}
+
+static inline void uwb_ie_drp_set_reason_code(struct uwb_ie_drp *ie,
+                                      enum uwb_drp_reason reason_code)
+{
+       u16 drp_control = le16_to_cpu(ie->drp_control);
+       drp_control = (ie->drp_control & ~(0x7 << 6)) | (reason_code << 6);
+       ie->drp_control = cpu_to_le16(drp_control);
+}
+
+static inline void uwb_ie_drp_set_status(struct uwb_ie_drp *ie, int status)
+{
+       u16 drp_control = le16_to_cpu(ie->drp_control);
+       drp_control = (drp_control & ~(0x1 << 9)) | (status << 9);
+       ie->drp_control = cpu_to_le16(drp_control);
+}
+
+static inline void uwb_ie_drp_set_owner(struct uwb_ie_drp *ie, int owner)
+{
+       u16 drp_control = le16_to_cpu(ie->drp_control);
+       drp_control = (drp_control & ~(0x1 << 10)) | (owner << 10);
+       ie->drp_control = cpu_to_le16(drp_control);
+}
+
+static inline void uwb_ie_drp_set_tiebreaker(struct uwb_ie_drp *ie, int tiebreaker)
+{
+       u16 drp_control = le16_to_cpu(ie->drp_control);
+       drp_control = (drp_control & ~(0x1 << 11)) | (tiebreaker << 11);
+       ie->drp_control = cpu_to_le16(drp_control);
+}
+
+static inline void uwb_ie_drp_set_unsafe(struct uwb_ie_drp *ie, int unsafe)
+{
+       u16 drp_control = le16_to_cpu(ie->drp_control);
+       drp_control = (drp_control & ~(0x1 << 12)) | (unsafe << 12);
+       ie->drp_control = cpu_to_le16(drp_control);
+}
+
+/** Dynamic Reservation Protocol IE (MBOA MAC[7.8.7]) */
+struct uwb_ie_drp_avail {
+       struct uwb_ie_hdr       hdr;
+       DECLARE_BITMAP(bmp, UWB_NUM_MAS);
+} __attribute__((packed));
+
+/**
+ * The Vendor ID is set to an OUI that indicates the vendor of the device.
+ * ECMA-368 [16.8.10]
+ */
+struct uwb_vendor_id {
+       u8 data[3];
+} __attribute__((packed));
+
+/**
+ * The device type ID
+ * FIXME: clarify what this means
+ * ECMA-368 [16.8.10]
+ */
+struct uwb_device_type_id {
+       u8 data[3];
+} __attribute__((packed));
+
+
+/**
+ * UWB device information types
+ * ECMA-368 [16.8.10]
+ */
+enum uwb_dev_info_type {
+       UWB_DEV_INFO_VENDOR_ID = 0,
+       UWB_DEV_INFO_VENDOR_TYPE,
+       UWB_DEV_INFO_NAME,
+};
+
+/**
+ * UWB device information found in Identification IE
+ * ECMA-368 [16.8.10]
+ */
+struct uwb_dev_info {
+       u8 type;        /* enum uwb_dev_info_type */
+       u8 length;
+       u8 data[];
+} __attribute__((packed));
+
+/**
+ * UWB Identification IE
+ * ECMA-368 [16.8.10]
+ */
+struct uwb_identification_ie {
+       struct uwb_ie_hdr hdr;
+       struct uwb_dev_info info[];
+} __attribute__((packed));
+
+/*
+ * UWB Radio Controller
+ *
+ * These definitions are common to the Radio Control layers as
+ * exported by the WUSB1.0 HWA and WHCI interfaces.
+ */
+
+/** Radio Control Command Block (WUSB1.0[Table 8-65] and WHCI 0.95) */
+struct uwb_rccb {
+       u8 bCommandType;                /* enum hwa_cet */
+       __le16 wCommand;                /* Command code */
+       u8 bCommandContext;             /* Context ID */
+} __attribute__((packed));
+
+
+/** Radio Control Event Block (WUSB[table 8-66], WHCI 0.95) */
+struct uwb_rceb {
+       u8 bEventType;                  /* enum hwa_cet */
+       __le16 wEvent;                  /* Event code */
+       u8 bEventContext;               /* Context ID */
+} __attribute__((packed));
+
+
+enum {
+       UWB_RC_CET_GENERAL = 0,         /* General Command/Event type */
+       UWB_RC_CET_EX_TYPE_1 = 1,       /* Extended Type 1 Command/Event type */
+};
+
+/* Commands to the radio controller */
+enum uwb_rc_cmd {
+       UWB_RC_CMD_CHANNEL_CHANGE = 16,
+       UWB_RC_CMD_DEV_ADDR_MGMT = 17,  /* Device Address Management */
+       UWB_RC_CMD_GET_IE = 18,         /* GET Information Elements */
+       UWB_RC_CMD_RESET = 19,
+       UWB_RC_CMD_SCAN = 20,           /* Scan management  */
+       UWB_RC_CMD_SET_BEACON_FILTER = 21,
+       UWB_RC_CMD_SET_DRP_IE = 22,     /* Dynamic Reservation Protocol IEs */
+       UWB_RC_CMD_SET_IE = 23,         /* Information Element management */
+       UWB_RC_CMD_SET_NOTIFICATION_FILTER = 24,
+       UWB_RC_CMD_SET_TX_POWER = 25,
+       UWB_RC_CMD_SLEEP = 26,
+       UWB_RC_CMD_START_BEACON = 27,
+       UWB_RC_CMD_STOP_BEACON = 28,
+       UWB_RC_CMD_BP_MERGE = 29,
+       UWB_RC_CMD_SEND_COMMAND_FRAME = 30,
+       UWB_RC_CMD_SET_ASIE_NOTIF = 31,
+};
+
+/* Notifications from the radio controller */
+enum uwb_rc_evt {
+       UWB_RC_EVT_IE_RCV = 0,
+       UWB_RC_EVT_BEACON = 1,
+       UWB_RC_EVT_BEACON_SIZE = 2,
+       UWB_RC_EVT_BPOIE_CHANGE = 3,
+       UWB_RC_EVT_BP_SLOT_CHANGE = 4,
+       UWB_RC_EVT_BP_SWITCH_IE_RCV = 5,
+       UWB_RC_EVT_DEV_ADDR_CONFLICT = 6,
+       UWB_RC_EVT_DRP_AVAIL = 7,
+       UWB_RC_EVT_DRP = 8,
+       UWB_RC_EVT_BP_SWITCH_STATUS = 9,
+       UWB_RC_EVT_CMD_FRAME_RCV = 10,
+       UWB_RC_EVT_CHANNEL_CHANGE_IE_RCV = 11,
+       /* Events (command responses) use the same code as the command */
+       UWB_RC_EVT_UNKNOWN_CMD_RCV = 65535,
+};
+
+enum uwb_rc_extended_type_1_cmd {
+       UWB_RC_SET_DAA_ENERGY_MASK = 32,
+       UWB_RC_SET_NOTIFICATION_FILTER_EX = 33,
+};
+
+enum uwb_rc_extended_type_1_evt {
+       UWB_RC_DAA_ENERGY_DETECTED = 0,
+};
+
+/* Radio Control Result Code. [WHCI] table 3-3. */
+enum {
+       UWB_RC_RES_SUCCESS = 0,
+       UWB_RC_RES_FAIL,
+       UWB_RC_RES_FAIL_HARDWARE,
+       UWB_RC_RES_FAIL_NO_SLOTS,
+       UWB_RC_RES_FAIL_BEACON_TOO_LARGE,
+       UWB_RC_RES_FAIL_INVALID_PARAMETER,
+       UWB_RC_RES_FAIL_UNSUPPORTED_PWR_LEVEL,
+       UWB_RC_RES_FAIL_INVALID_IE_DATA,
+       UWB_RC_RES_FAIL_BEACON_SIZE_EXCEEDED,
+       UWB_RC_RES_FAIL_CANCELLED,
+       UWB_RC_RES_FAIL_INVALID_STATE,
+       UWB_RC_RES_FAIL_INVALID_SIZE,
+       UWB_RC_RES_FAIL_ACK_NOT_RECEIVED,
+       UWB_RC_RES_FAIL_NO_MORE_ASIE_NOTIF,
+       UWB_RC_RES_FAIL_TIME_OUT = 255,
+};
+
+/* Confirm event. [WHCI] section 3.1.3.1 etc. */
+struct uwb_rc_evt_confirm {
+       struct uwb_rceb rceb;
+       u8 bResultCode;
+} __attribute__((packed));
+
+/* Device Address Management event. [WHCI] section 3.1.3.2. */
+struct uwb_rc_evt_dev_addr_mgmt {
+       struct uwb_rceb rceb;
+       u8 baAddr[6];
+       u8 bResultCode;
+} __attribute__((packed));
+
+
+/* Get IE Event. [WHCI] section 3.1.3.3. */
+struct uwb_rc_evt_get_ie {
+       struct uwb_rceb rceb;
+       __le16 wIELength;
+       u8 IEData[];
+} __attribute__((packed));
+
+/* Set DRP IE Event. [WHCI] section 3.1.3.7. */
+struct uwb_rc_evt_set_drp_ie {
+       struct uwb_rceb rceb;
+       __le16 wRemainingSpace;
+       u8 bResultCode;
+} __attribute__((packed));
+
+/* Set IE Event. [WHCI] section 3.1.3.8. */
+struct uwb_rc_evt_set_ie {
+       struct uwb_rceb rceb;
+       __le16 RemainingSpace;
+       u8 bResultCode;
+} __attribute__((packed));
+
+/* Scan command. [WHCI] 3.1.3.5. */
+struct uwb_rc_cmd_scan {
+       struct uwb_rccb rccb;
+       u8 bChannelNumber;
+       u8 bScanState;
+       __le16 wStartTime;
+} __attribute__((packed));
+
+/* Set DRP IE command. [WHCI] section 3.1.3.7. */
+struct uwb_rc_cmd_set_drp_ie {
+       struct uwb_rccb rccb;
+       __le16 wIELength;
+       struct uwb_ie_drp IEData[];
+} __attribute__((packed));
+
+/* Set IE command. [WHCI] section 3.1.3.8. */
+struct uwb_rc_cmd_set_ie {
+       struct uwb_rccb rccb;
+       __le16 wIELength;
+       u8 IEData[];
+} __attribute__((packed));
+
+/* Set DAA Energy Mask event. [WHCI 0.96] section 3.1.3.17. */
+struct uwb_rc_evt_set_daa_energy_mask {
+       struct uwb_rceb rceb;
+       __le16 wLength;
+       u8 result;
+} __attribute__((packed));
+
+/* Set Notification Filter Extended event. [WHCI 0.96] section 3.1.3.18. */
+struct uwb_rc_evt_set_notification_filter_ex {
+       struct uwb_rceb rceb;
+       __le16 wLength;
+       u8 result;
+} __attribute__((packed));
+
+/* IE Received notification. [WHCI] section 3.1.4.1. */
+struct uwb_rc_evt_ie_rcv {
+       struct uwb_rceb rceb;
+       struct uwb_dev_addr SrcAddr;
+       __le16 wIELength;
+       u8 IEData[];
+} __attribute__((packed));
+
+/* Type of the received beacon. [WHCI] section 3.1.4.2. */
+enum uwb_rc_beacon_type {
+       UWB_RC_BEACON_TYPE_SCAN = 0,
+       UWB_RC_BEACON_TYPE_NEIGHBOR,
+       UWB_RC_BEACON_TYPE_OL_ALIEN,
+       UWB_RC_BEACON_TYPE_NOL_ALIEN,
+};
+
+/* Beacon received notification. [WHCI] 3.1.4.2. */
+struct uwb_rc_evt_beacon {
+       struct uwb_rceb rceb;
+       u8      bChannelNumber;
+       u8      bBeaconType;
+       __le16  wBPSTOffset;
+       u8      bLQI;
+       u8      bRSSI;
+       __le16  wBeaconInfoLength;
+       u8      BeaconInfo[];
+} __attribute__((packed));
+
+
+/* Beacon Size Change notification. [WHCI] section 3.1.4.3 */
+struct uwb_rc_evt_beacon_size {
+       struct uwb_rceb rceb;
+       __le16 wNewBeaconSize;
+} __attribute__((packed));
+
+
+/* BPOIE Change notification. [WHCI] section 3.1.4.4. */
+struct uwb_rc_evt_bpoie_change {
+       struct uwb_rceb rceb;
+       __le16 wBPOIELength;
+       u8 BPOIE[];
+} __attribute__((packed));
+
+
+/* Beacon Slot Change notification. [WHCI] section 3.1.4.5. */
+struct uwb_rc_evt_bp_slot_change {
+       struct uwb_rceb rceb;
+       u8 slot_info;
+} __attribute__((packed));
+
+static inline int uwb_rc_evt_bp_slot_change_slot_num(
+       const struct uwb_rc_evt_bp_slot_change *evt)
+{
+       return evt->slot_info & 0x7f;
+}
+
+static inline int uwb_rc_evt_bp_slot_change_no_slot(
+       const struct uwb_rc_evt_bp_slot_change *evt)
+{
+       return (evt->slot_info & 0x80) >> 7;
+}
+
+/* BP Switch IE Received notification. [WHCI] section 3.1.4.6. */
+struct uwb_rc_evt_bp_switch_ie_rcv {
+       struct uwb_rceb rceb;
+       struct uwb_dev_addr wSrcAddr;
+       __le16 wIELength;
+       u8 IEData[];
+} __attribute__((packed));
+
+/* DevAddr Conflict notification. [WHCI] section 3.1.4.7. */
+struct uwb_rc_evt_dev_addr_conflict {
+       struct uwb_rceb rceb;
+} __attribute__((packed));
+
+/* DRP notification. [WHCI] section 3.1.4.9. */
+struct uwb_rc_evt_drp {
+       struct uwb_rceb           rceb;
+       struct uwb_dev_addr       src_addr;
+       u8                        reason;
+       u8                        beacon_slot_number;
+       __le16                    ie_length;
+       u8                        ie_data[];
+} __attribute__((packed));
+
+static inline enum uwb_drp_notif_reason uwb_rc_evt_drp_reason(struct uwb_rc_evt_drp *evt)
+{
+       return evt->reason & 0x0f;
+}
+
+
+/* DRP Availability Change notification. [WHCI] section 3.1.4.8. */
+struct uwb_rc_evt_drp_avail {
+       struct uwb_rceb rceb;
+       DECLARE_BITMAP(bmp, UWB_NUM_MAS);
+} __attribute__((packed));
+
+/* BP switch status notification. [WHCI] section 3.1.4.10. */
+struct uwb_rc_evt_bp_switch_status {
+       struct uwb_rceb rceb;
+       u8 status;
+       u8 slot_offset;
+       __le16 bpst_offset;
+       u8 move_countdown;
+} __attribute__((packed));
+
+/* Command Frame Received notification. [WHCI] section 3.1.4.11. */
+struct uwb_rc_evt_cmd_frame_rcv {
+       struct uwb_rceb rceb;
+       __le16 receive_time;
+       struct uwb_dev_addr wSrcAddr;
+       struct uwb_dev_addr wDstAddr;
+       __le16 control;
+       __le16 reserved;
+       __le16 dataLength;
+       u8 data[];
+} __attribute__((packed));
+
+/* Channel Change IE Received notification. [WHCI] section 3.1.4.12. */
+struct uwb_rc_evt_channel_change_ie_rcv {
+       struct uwb_rceb rceb;
+       struct uwb_dev_addr wSrcAddr;
+       __le16 wIELength;
+       u8 IEData[];
+} __attribute__((packed));
+
+/* DAA Energy Detected notification. [WHCI 0.96] section 3.1.4.14. */
+struct uwb_rc_evt_daa_energy_detected {
+       struct uwb_rceb rceb;
+       __le16 wLength;
+       u8 bandID;
+       u8 reserved;
+       u8 toneBmp[16];
+} __attribute__((packed));
+
+
+/**
+ * Radio Control Interface Class Descriptor
+ *
+ *  WUSB 1.0 [8.6.1.2]
+ */
+struct uwb_rc_control_intf_class_desc {
+       u8 bLength;
+       u8 bDescriptorType;
+       __le16 bcdRCIVersion;
+} __attribute__((packed));
+
+#endif /* #ifndef __LINUX__UWB_SPEC_H__ */
diff --git a/include/linux/uwb/umc.h b/include/linux/uwb/umc.h
new file mode 100644 (file)
index 0000000..36a39e3
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * UWB Multi-interface Controller support.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * This file is released under the GPLv2
+ *
+ * UMC (UWB Multi-interface Controller) capabilities (e.g., radio
+ * controller, host controller) are presented as devices on the "umc"
+ * bus.
+ *
+ * The radio controller is not strictly a UMC capability but it's
+ * useful to present it as such.
+ *
+ * References:
+ *
+ *   [WHCI] Wireless Host Controller Interface Specification for
+ *          Certified Wireless Universal Serial Bus, revision 0.95.
+ *
+ * How this works is kind of convoluted but simple. The whci.ko driver
+ * loads when WHCI devices are detected. These WHCI devices expose
+ * many devices in the same PCI function (they couldn't have reused
+ * functions, no), so for each PCI function that exposes these many
+ * devices, whci ceates a umc_dev [whci_probe() -> whci_add_cap()]
+ * with umc_device_create() and adds it to the bus with
+ * umc_device_register().
+ *
+ * umc_device_register() calls device_register() which will push the
+ * bus management code to load your UMC driver's somehting_probe()
+ * that you have registered for that capability code.
+ *
+ * Now when the WHCI device is removed, whci_remove() will go over
+ * each umc_dev assigned to each of the PCI function's capabilities
+ * and through whci_del_cap() call umc_device_unregister() each
+ * created umc_dev. Of course, if you are bound to the device, your
+ * driver's something_remove() will be called.
+ */
+
+#ifndef _LINUX_UWB_UMC_H_
+#define _LINUX_UWB_UMC_H_
+
+#include <linux/device.h>
+#include <linux/pci.h>
+
+/*
+ * UMC capability IDs.
+ *
+ * 0x00 is reserved so use it for the radio controller device.
+ *
+ * [WHCI] table 2-8
+ */
+#define UMC_CAP_ID_WHCI_RC      0x00 /* radio controller */
+#define UMC_CAP_ID_WHCI_WUSB_HC 0x01 /* WUSB host controller */
+
+/**
+ * struct umc_dev - UMC capability device
+ *
+ * @version:  version of the specification this capability conforms to.
+ * @cap_id:   capability ID.
+ * @bar:      PCI Bar (64 bit) where the resource lies
+ * @resource: register space resource.
+ * @irq:      interrupt line.
+ */
+struct umc_dev {
+       u16             version;
+       u8              cap_id;
+       u8              bar;
+       struct resource resource;
+       unsigned        irq;
+       struct device   dev;
+};
+
+#define to_umc_dev(d) container_of(d, struct umc_dev, dev)
+
+/**
+ * struct umc_driver - UMC capability driver
+ * @cap_id: supported capability ID.
+ * @match: driver specific capability matching function.
+ * @match_data: driver specific data for match() (e.g., a
+ * table of pci_device_id's if umc_match_pci_id() is used).
+ */
+struct umc_driver {
+       char *name;
+       u8 cap_id;
+       int (*match)(struct umc_driver *, struct umc_dev *);
+       const void *match_data;
+
+       int  (*probe)(struct umc_dev *);
+       void (*remove)(struct umc_dev *);
+       int  (*suspend)(struct umc_dev *, pm_message_t state);
+       int  (*resume)(struct umc_dev *);
+
+       struct device_driver driver;
+};
+
+#define to_umc_driver(d) container_of(d, struct umc_driver, driver)
+
+extern struct bus_type umc_bus_type;
+
+struct umc_dev *umc_device_create(struct device *parent, int n);
+int __must_check umc_device_register(struct umc_dev *umc);
+void umc_device_unregister(struct umc_dev *umc);
+
+int __must_check __umc_driver_register(struct umc_driver *umc_drv,
+                                      struct module *mod,
+                                      const char *mod_name);
+
+/**
+ * umc_driver_register - register a UMC capabiltity driver.
+ * @umc_drv:  pointer to the driver.
+ */
+static inline int __must_check umc_driver_register(struct umc_driver *umc_drv)
+{
+       return __umc_driver_register(umc_drv, THIS_MODULE, KBUILD_MODNAME);
+}
+void umc_driver_unregister(struct umc_driver *umc_drv);
+
+/*
+ * Utility function you can use to match (umc_driver->match) against a
+ * null-terminated array of 'struct pci_device_id' in
+ * umc_driver->match_data.
+ */
+int umc_match_pci_id(struct umc_driver *umc_drv, struct umc_dev *umc);
+
+/**
+ * umc_parent_pci_dev - return the UMC's parent PCI device or NULL if none
+ * @umc_dev: UMC device whose parent PCI device we are looking for
+ *
+ * DIRTY!!! DON'T RELY ON THIS
+ *
+ * FIXME: This is as dirty as it gets, but we need some way to check
+ * the correct type of umc_dev->parent (so that for example, we can
+ * cast to pci_dev). Casting to pci_dev is necesary because at some
+ * point we need to request resources from the device. Mapping is
+ * easily over come (ioremap and stuff are bus agnostic), but hooking
+ * up to some error handlers (such as pci error handlers) might need
+ * this.
+ *
+ * THIS might (probably will) be removed in the future, so don't count
+ * on it.
+ */
+static inline struct pci_dev *umc_parent_pci_dev(struct umc_dev *umc_dev)
+{
+       struct pci_dev *pci_dev = NULL;
+       if (umc_dev->dev.parent->bus == &pci_bus_type)
+               pci_dev = to_pci_dev(umc_dev->dev.parent);
+       return pci_dev;
+}
+
+/**
+ * umc_dev_get() - reference a UMC device.
+ * @umc_dev: Pointer to UMC device.
+ *
+ * NOTE: we are assuming in this whole scheme that the parent device
+ *       is referenced at _probe() time and unreferenced at _remove()
+ *       time by the parent's subsystem.
+ */
+static inline struct umc_dev *umc_dev_get(struct umc_dev *umc_dev)
+{
+       get_device(&umc_dev->dev);
+       return umc_dev;
+}
+
+/**
+ * umc_dev_put() - unreference a UMC device.
+ * @umc_dev: Pointer to UMC device.
+ */
+static inline void umc_dev_put(struct umc_dev *umc_dev)
+{
+       put_device(&umc_dev->dev);
+}
+
+/**
+ * umc_set_drvdata - set UMC device's driver data.
+ * @umc_dev: Pointer to UMC device.
+ * @data:    Data to set.
+ */
+static inline void umc_set_drvdata(struct umc_dev *umc_dev, void *data)
+{
+       dev_set_drvdata(&umc_dev->dev, data);
+}
+
+/**
+ * umc_get_drvdata - recover UMC device's driver data.
+ * @umc_dev: Pointer to UMC device.
+ */
+static inline void *umc_get_drvdata(struct umc_dev *umc_dev)
+{
+       return dev_get_drvdata(&umc_dev->dev);
+}
+
+int umc_controller_reset(struct umc_dev *umc);
+
+#endif /* #ifndef _LINUX_UWB_UMC_H_ */
diff --git a/include/linux/uwb/whci.h b/include/linux/uwb/whci.h
new file mode 100644 (file)
index 0000000..915ec23
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Wireless Host Controller Interface for Ultra-Wide-Band and Wireless USB
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ *
+ * References:
+ *   [WHCI] Wireless Host Controller Interface Specification for
+ *          Certified Wireless Universal Serial Bus, revision 0.95.
+ */
+#ifndef _LINUX_UWB_WHCI_H_
+#define _LINUX_UWB_WHCI_H_
+
+#include <linux/pci.h>
+
+/*
+ * UWB interface capability registers (offsets from UWBBASE)
+ *
+ * [WHCI] section 2.2
+ */
+#define UWBCAPINFO     0x00 /* == UWBCAPDATA(0) */
+#  define UWBCAPINFO_TO_N_CAPS(c)      (((c) >> 0)  & 0xFull)
+#define UWBCAPDATA(n)  (8*(n))
+#  define UWBCAPDATA_TO_VERSION(c)     (((c) >> 32) & 0xFFFFull)
+#  define UWBCAPDATA_TO_OFFSET(c)      (((c) >> 18) & 0x3FFFull)
+#  define UWBCAPDATA_TO_BAR(c)         (((c) >> 16) & 0x3ull)
+#  define UWBCAPDATA_TO_SIZE(c)                ((((c) >> 8) & 0xFFull) * sizeof(u32))
+#  define UWBCAPDATA_TO_CAP_ID(c)      (((c) >> 0)  & 0xFFull)
+
+/* Size of the WHCI capability data (including the RC capability) for
+   a device with n capabilities. */
+#define UWBCAPDATA_SIZE(n) (8 + 8*(n))
+
+
+/*
+ * URC registers (offsets from URCBASE)
+ *
+ * [WHCI] section 2.3
+ */
+#define URCCMD         0x00
+#  define URCCMD_RESET         (1 << 31)  /* UMC Hardware reset */
+#  define URCCMD_RS            (1 << 30)  /* Run/Stop */
+#  define URCCMD_EARV          (1 << 29)  /* Event Address Register Valid */
+#  define URCCMD_ACTIVE                (1 << 15)  /* Command is active */
+#  define URCCMD_IWR           (1 << 14)  /* Interrupt When Ready */
+#  define URCCMD_SIZE_MASK     0x00000fff /* Command size mask */
+#define URCSTS         0x04
+#  define URCSTS_EPS           (1 << 17)  /* Event Processing Status */
+#  define URCSTS_HALTED                (1 << 16)  /* RC halted */
+#  define URCSTS_HSE           (1 << 10)  /* Host System Error...fried */
+#  define URCSTS_ER            (1 <<  9)  /* Event Ready */
+#  define URCSTS_RCI           (1 <<  8)  /* Ready for Command Interrupt */
+#  define URCSTS_INT_MASK      0x00000700 /* URC interrupt sources */
+#  define URCSTS_ISI           0x000000ff /* Interrupt Source Identification */
+#define URCINTR                0x08
+#  define URCINTR_EN_ALL       0x000007ff /* Enable all interrupt sources */
+#define URCCMDADDR     0x10
+#define URCEVTADDR     0x18
+#  define URCEVTADDR_OFFSET_MASK 0xfff    /* Event pointer offset mask */
+
+
+/** Write 32 bit @value to little endian register at @addr */
+static inline
+void le_writel(u32 value, void __iomem *addr)
+{
+       iowrite32(value, addr);
+}
+
+
+/** Read from 32 bit little endian register at @addr */
+static inline
+u32 le_readl(void __iomem *addr)
+{
+       return ioread32(addr);
+}
+
+
+/** Write 64 bit @value to little endian register at @addr */
+static inline
+void le_writeq(u64 value, void __iomem *addr)
+{
+       iowrite32(value, addr);
+       iowrite32(value >> 32, addr + 4);
+}
+
+
+/** Read from 64 bit little endian register at @addr */
+static inline
+u64 le_readq(void __iomem *addr)
+{
+       u64 value;
+       value  = ioread32(addr);
+       value |= (u64)ioread32(addr + 4) << 32;
+       return value;
+}
+
+extern int whci_wait_for(struct device *dev, u32 __iomem *reg,
+                        u32 mask, u32 result,
+                        unsigned long max_ms,  const char *tag);
+
+#endif /* #ifndef _LINUX_UWB_WHCI_H_ */
index d4b03034ee73af53507e2ec15bb68235139b029d..4669d7e72e75c92e5499fe74100e88ce09eedec1 100644 (file)
@@ -315,6 +315,13 @@ struct v4l2_pix_format {
 /* see http://www.siliconimaging.com/RGB%20Bayer.htm */
 #define V4L2_PIX_FMT_SBGGR8  v4l2_fourcc('B', 'A', '8', '1') /*  8  BGBG.. GRGR.. */
 #define V4L2_PIX_FMT_SGBRG8  v4l2_fourcc('G', 'B', 'R', 'G') /*  8  GBGB.. RGRG.. */
+/*
+ * 10bit raw bayer, expanded to 16 bits
+ * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb...
+ */
+#define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0')
+/* 10bit raw bayer DPCM compressed to 8 bits */
+#define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0')
 #define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') /* 16  BGBG.. GRGR.. */
 
 /* compressed formats */
index 4c28c4d564e2da1e5e6112e0e5081d4f08ebd942..307b88577eaa475274598fd9f2c07cc86ad22cb7 100644 (file)
@@ -103,6 +103,4 @@ extern void free_vm_area(struct vm_struct *area);
 extern rwlock_t vmlist_lock;
 extern struct vm_struct *vmlist;
 
-extern const struct seq_operations vmalloc_op;
-
 #endif /* _LINUX_VMALLOC_H */
index 9cd3ab0f554d301224f518391b47fdd1752fc33d..524cd1b28ecb0ff62a9d3620f9d21d48f8c1e32e 100644 (file)
@@ -54,10 +54,6 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
                NR_VM_EVENT_ITEMS
 };
 
-extern const struct seq_operations fragmentation_op;
-extern const struct seq_operations pagetypeinfo_op;
-extern const struct seq_operations zoneinfo_op;
-extern const struct seq_operations vmstat_op;
 extern int sysctl_stat_interval;
 
 #ifdef CONFIG_VM_EVENT_COUNTERS
diff --git a/include/linux/wlp.h b/include/linux/wlp.h
new file mode 100644 (file)
index 0000000..033545e
--- /dev/null
@@ -0,0 +1,735 @@
+/*
+ * WiMedia Logical Link Control Protocol (WLP)
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Reinette Chatre <reinette.chatre@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * FIXME: docs
+ *
+ * - Does not (yet) include support for WLP control frames
+ *   WLP Draft 0.99 [6.5].
+ *
+ *   A visual representation of the data structures.
+ *
+ *                              wssidB      wssidB
+ *                               ^           ^
+ *                               |           |
+ *                              wssidA      wssidA
+ *   wlp interface {             ^           ^
+ *       ...                     |           |
+ *       ...               ...  wssid      wssid ...
+ *       wlp --- ...             |           |
+ *   };          neighbors --> neighbA --> neighbB
+ *               ...
+ *               wss
+ *               ...
+ *               eda cache  --> neighborA --> neighborB --> neighborC ...
+ */
+
+#ifndef __LINUX__WLP_H_
+#define __LINUX__WLP_H_
+
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/list.h>
+#include <linux/uwb.h>
+
+/**
+ * WLP Protocol ID
+ * WLP Draft 0.99 [6.2]
+ *
+ * The MUX header for all WLP frames
+ */
+#define WLP_PROTOCOL_ID 0x0100
+
+/**
+ * WLP Version
+ * WLP version placed in the association frames (WLP 0.99 [6.6])
+ */
+#define WLP_VERSION 0x10
+
+/**
+ * Bytes needed to print UUID as string
+ */
+#define WLP_WSS_UUID_STRSIZE 48
+
+/**
+ * Bytes needed to print nonce as string
+ */
+#define WLP_WSS_NONCE_STRSIZE 48
+
+
+/**
+ * Size used for WLP name size
+ *
+ * The WSS name is set to 65 bytes, 1 byte larger than the maximum
+ * allowed by the WLP spec. This is to have a null terminated string
+ * for display to the user. A maximum of 64 bytes will still be used
+ * when placing the WSS name field in association frames.
+ */
+#define WLP_WSS_NAME_SIZE 65
+
+/**
+ * Number of bytes added by WLP to data frame
+ *
+ * A data frame transmitted from a host will be placed in a Standard or
+ * Abbreviated WLP frame. These have an extra 4 bytes of header (struct
+ * wlp_frame_std_abbrv_hdr).
+ * When the stack sends this data frame for transmission it needs to ensure
+ * there is enough headroom for this header.
+ */
+#define WLP_DATA_HLEN 4
+
+/**
+ * State of device regarding WLP Service Set
+ *
+ * WLP_WSS_STATE_NONE: the host does not participate in any WSS
+ * WLP_WSS_STATE_PART_ENROLLED: used as part of the enrollment sequence
+ *                            ("Partial Enroll"). This state is used to
+ *                            indicate the first part of enrollment that is
+ *                            unsecure. If the WSS is unsecure then the
+ *                            state will promptly go to WLP_WSS_STATE_ENROLLED,
+ *                            if the WSS is not secure then the enrollment
+ *                            procedure is a few more steps before we are
+ *                            enrolled.
+ * WLP_WSS_STATE_ENROLLED: the host is enrolled in a WSS
+ * WLP_WSS_STATE_ACTIVE: WSS is activated
+ * WLP_WSS_STATE_CONNECTED: host is connected to neighbor in WSS
+ *
+ */
+enum wlp_wss_state {
+       WLP_WSS_STATE_NONE = 0,
+       WLP_WSS_STATE_PART_ENROLLED,
+       WLP_WSS_STATE_ENROLLED,
+       WLP_WSS_STATE_ACTIVE,
+       WLP_WSS_STATE_CONNECTED,
+};
+
+/**
+ * WSS Secure status
+ * WLP 0.99 Table 6
+ *
+ * Set to one if the WSS is secure, zero if it is not secure
+ */
+enum wlp_wss_sec_status {
+       WLP_WSS_UNSECURE = 0,
+       WLP_WSS_SECURE,
+};
+
+/**
+ * WLP frame type
+ * WLP Draft 0.99 [6.2 Table 1]
+ */
+enum wlp_frame_type {
+       WLP_FRAME_STANDARD = 0,
+       WLP_FRAME_ABBREVIATED,
+       WLP_FRAME_CONTROL,
+       WLP_FRAME_ASSOCIATION,
+};
+
+/**
+ * WLP Association Message Type
+ * WLP Draft 0.99 [6.6.1.2 Table 8]
+ */
+enum wlp_assoc_type {
+       WLP_ASSOC_D1 = 2,
+       WLP_ASSOC_D2 = 3,
+       WLP_ASSOC_M1 = 4,
+       WLP_ASSOC_M2 = 5,
+       WLP_ASSOC_M3 = 7,
+       WLP_ASSOC_M4 = 8,
+       WLP_ASSOC_M5 = 9,
+       WLP_ASSOC_M6 = 10,
+       WLP_ASSOC_M7 = 11,
+       WLP_ASSOC_M8 = 12,
+       WLP_ASSOC_F0 = 14,
+       WLP_ASSOC_E1 = 32,
+       WLP_ASSOC_E2 = 33,
+       WLP_ASSOC_C1 = 34,
+       WLP_ASSOC_C2 = 35,
+       WLP_ASSOC_C3 = 36,
+       WLP_ASSOC_C4 = 37,
+};
+
+/**
+ * WLP Attribute Type
+ * WLP Draft 0.99 [6.6.1 Table 6]
+ */
+enum wlp_attr_type {
+       WLP_ATTR_AUTH           = 0x1005, /* Authenticator */
+       WLP_ATTR_DEV_NAME       = 0x1011, /* Device Name */
+       WLP_ATTR_DEV_PWD_ID     = 0x1012, /* Device Password ID */
+       WLP_ATTR_E_HASH1        = 0x1014, /* E-Hash1 */
+       WLP_ATTR_E_HASH2        = 0x1015, /* E-Hash2 */
+       WLP_ATTR_E_SNONCE1      = 0x1016, /* E-SNonce1 */
+       WLP_ATTR_E_SNONCE2      = 0x1017, /* E-SNonce2 */
+       WLP_ATTR_ENCR_SET       = 0x1018, /* Encrypted Settings */
+       WLP_ATTR_ENRL_NONCE     = 0x101A, /* Enrollee Nonce */
+       WLP_ATTR_KEYWRAP_AUTH   = 0x101E, /* Key Wrap Authenticator */
+       WLP_ATTR_MANUF          = 0x1021, /* Manufacturer */
+       WLP_ATTR_MSG_TYPE       = 0x1022, /* Message Type */
+       WLP_ATTR_MODEL_NAME     = 0x1023, /* Model Name */
+       WLP_ATTR_MODEL_NR       = 0x1024, /* Model Number */
+       WLP_ATTR_PUB_KEY        = 0x1032, /* Public Key */
+       WLP_ATTR_REG_NONCE      = 0x1039, /* Registrar Nonce */
+       WLP_ATTR_R_HASH1        = 0x103D, /* R-Hash1 */
+       WLP_ATTR_R_HASH2        = 0x103E, /* R-Hash2 */
+       WLP_ATTR_R_SNONCE1      = 0x103F, /* R-SNonce1 */
+       WLP_ATTR_R_SNONCE2      = 0x1040, /* R-SNonce2 */
+       WLP_ATTR_SERIAL         = 0x1042, /* Serial number */
+       WLP_ATTR_UUID_E         = 0x1047, /* UUID-E */
+       WLP_ATTR_UUID_R         = 0x1048, /* UUID-R */
+       WLP_ATTR_PRI_DEV_TYPE   = 0x1054, /* Primary Device Type */
+       WLP_ATTR_SEC_DEV_TYPE   = 0x1055, /* Secondary Device Type */
+       WLP_ATTR_PORT_DEV       = 0x1056, /* Portable Device */
+       WLP_ATTR_APP_EXT        = 0x1058, /* Application Extension */
+       WLP_ATTR_WLP_VER        = 0x2000, /* WLP Version */
+       WLP_ATTR_WSSID          = 0x2001, /* WSSID */
+       WLP_ATTR_WSS_NAME       = 0x2002, /* WSS Name */
+       WLP_ATTR_WSS_SEC_STAT   = 0x2003, /* WSS Secure Status */
+       WLP_ATTR_WSS_BCAST      = 0x2004, /* WSS Broadcast Address */
+       WLP_ATTR_WSS_M_KEY      = 0x2005, /* WSS Master Key */
+       WLP_ATTR_ACC_ENRL       = 0x2006, /* Accepting Enrollment */
+       WLP_ATTR_WSS_INFO       = 0x2007, /* WSS Information */
+       WLP_ATTR_WSS_SEL_MTHD   = 0x2008, /* WSS Selection Method */
+       WLP_ATTR_ASSC_MTHD_LIST = 0x2009, /* Association Methods List */
+       WLP_ATTR_SEL_ASSC_MTHD  = 0x200A, /* Selected Association Method */
+       WLP_ATTR_ENRL_HASH_COMM = 0x200B, /* Enrollee Hash Commitment */
+       WLP_ATTR_WSS_TAG        = 0x200C, /* WSS Tag */
+       WLP_ATTR_WSS_VIRT       = 0x200D, /* WSS Virtual EUI-48 */
+       WLP_ATTR_WLP_ASSC_ERR   = 0x200E, /* WLP Association Error */
+       WLP_ATTR_VNDR_EXT       = 0x200F, /* Vendor Extension */
+};
+
+/**
+ * WLP Category ID of primary/secondary device
+ * WLP Draft 0.99 [6.6.1.8 Table 12]
+ */
+enum wlp_dev_category_id {
+       WLP_DEV_CAT_COMPUTER = 1,
+       WLP_DEV_CAT_INPUT,
+       WLP_DEV_CAT_PRINT_SCAN_FAX_COPIER,
+       WLP_DEV_CAT_CAMERA,
+       WLP_DEV_CAT_STORAGE,
+       WLP_DEV_CAT_INFRASTRUCTURE,
+       WLP_DEV_CAT_DISPLAY,
+       WLP_DEV_CAT_MULTIM,
+       WLP_DEV_CAT_GAMING,
+       WLP_DEV_CAT_TELEPHONE,
+       WLP_DEV_CAT_OTHER = 65535,
+};
+
+/**
+ * WLP WSS selection method
+ * WLP Draft 0.99 [6.6.1.6 Table 10]
+ */
+enum wlp_wss_sel_mthd {
+       WLP_WSS_ENRL_SELECT = 1,        /* Enrollee selects */
+       WLP_WSS_REG_SELECT,             /* Registrar selects */
+};
+
+/**
+ * WLP association error values
+ * WLP Draft 0.99 [6.6.1.5 Table 9]
+ */
+enum wlp_assc_error {
+       WLP_ASSOC_ERROR_NONE,
+       WLP_ASSOC_ERROR_AUTH,           /* Authenticator Failure */
+       WLP_ASSOC_ERROR_ROGUE,          /* Rogue activity suspected */
+       WLP_ASSOC_ERROR_BUSY,           /* Device busy */
+       WLP_ASSOC_ERROR_LOCK,           /* Setup Locked */
+       WLP_ASSOC_ERROR_NOT_READY,      /* Registrar not ready */
+       WLP_ASSOC_ERROR_INV,            /* Invalid WSS selection */
+       WLP_ASSOC_ERROR_MSG_TIME,       /* Message timeout */
+       WLP_ASSOC_ERROR_ENR_TIME,       /* Enrollment session timeout */
+       WLP_ASSOC_ERROR_PW,             /* Device password invalid */
+       WLP_ASSOC_ERROR_VER,            /* Unsupported version */
+       WLP_ASSOC_ERROR_INT,            /* Internal error */
+       WLP_ASSOC_ERROR_UNDEF,          /* Undefined error */
+       WLP_ASSOC_ERROR_NUM,            /* Numeric comparison failure */
+       WLP_ASSOC_ERROR_WAIT,           /* Waiting for user input */
+};
+
+/**
+ * WLP Parameters
+ * WLP 0.99 [7.7]
+ */
+enum wlp_parameters {
+       WLP_PER_MSG_TIMEOUT = 15,       /* Seconds to wait for response to
+                                          association message. */
+};
+
+/**
+ * WLP IE
+ *
+ * The WLP IE should be included in beacons by all devices.
+ *
+ * The driver can set only a few of the fields in this information element,
+ * most fields are managed by the device self. When the driver needs to set
+ * a field it will only provide values for the fields of interest, the rest
+ * will be filled with zeroes. The fields of interest are:
+ *
+ * Element ID
+ * Length
+ * Capabilities (only to include WSSID Hash list length)
+ * WSSID Hash List fields
+ *
+ * WLP 0.99 [6.7]
+ *
+ * Only the fields that will be used are detailed in this structure, rest
+ * are not detailed or marked as "notused".
+ */
+struct wlp_ie {
+       struct uwb_ie_hdr hdr;
+       __le16 capabilities;
+       __le16 cycle_param;
+       __le16 acw_anchor_addr;
+       u8 wssid_hash_list[];
+} __attribute__((packed));
+
+static inline int wlp_ie_hash_length(struct wlp_ie *ie)
+{
+       return (le16_to_cpu(ie->capabilities) >> 12) & 0xf;
+}
+
+static inline void wlp_ie_set_hash_length(struct wlp_ie *ie, int hash_length)
+{
+       u16 caps = le16_to_cpu(ie->capabilities);
+       caps = (caps & ~(0xf << 12)) | (hash_length << 12);
+       ie->capabilities = cpu_to_le16(caps);
+}
+
+/**
+ * WLP nonce
+ * WLP Draft 0.99 [6.6.1 Table 6]
+ *
+ * A 128-bit random number often used (E-SNonce1, E-SNonce2, Enrollee
+ * Nonce, Registrar Nonce, R-SNonce1, R-SNonce2). It is passed to HW so
+ * it is packed.
+ */
+struct wlp_nonce {
+       u8 data[16];
+} __attribute__((packed));
+
+/**
+ * WLP UUID
+ * WLP Draft 0.99 [6.6.1 Table 6]
+ *
+ * Universally Unique Identifier (UUID) encoded as an octet string in the
+ * order the octets are shown in string representation in RFC4122. A UUID
+ * is often used (UUID-E, UUID-R, WSSID). It is passed to HW so it is packed.
+ */
+struct wlp_uuid {
+       u8 data[16];
+} __attribute__((packed));
+
+
+/**
+ * Primary and secondary device type attributes
+ * WLP Draft 0.99 [6.6.1.8]
+ */
+struct wlp_dev_type {
+       enum wlp_dev_category_id category:16;
+       u8 OUI[3];
+       u8 OUIsubdiv;
+       __le16 subID;
+} __attribute__((packed));
+
+/**
+ * WLP frame header
+ * WLP Draft 0.99 [6.2]
+ */
+struct wlp_frame_hdr {
+       __le16 mux_hdr;                 /* WLP_PROTOCOL_ID */
+       enum wlp_frame_type type:8;
+} __attribute__((packed));
+
+/**
+ * WLP attribute field header
+ * WLP Draft 0.99 [6.6.1]
+ *
+ * Header of each attribute found in an association frame
+ */
+struct wlp_attr_hdr {
+       __le16 type;
+       __le16 length;
+} __attribute__((packed));
+
+/**
+ * Device information commonly used together
+ *
+ * Each of these device information elements has a specified range in which it
+ * should fit (WLP 0.99 [Table 6]). This range provided in the spec does not
+ * include the termination null '\0' character (when used in the
+ * association protocol the attribute fields are accompanied
+ * with a "length" field so the full range from the spec can be used for
+ * the value). We thus allocate an extra byte to be able to store a string
+ * of max length with a terminating '\0'.
+ */
+struct wlp_device_info {
+       char name[33];
+       char model_name[33];
+       char manufacturer[65];
+       char model_nr[33];
+       char serial[33];
+       struct wlp_dev_type prim_dev_type;
+};
+
+/**
+ * Macros for the WLP attributes
+ *
+ * There are quite a few attributes (total is 43). The attribute layout can be
+ * in one of three categories: one value, an array, an enum forced to 8 bits.
+ * These macros help with their definitions.
+ */
+#define wlp_attr(type, name)                                           \
+struct wlp_attr_##name {                                               \
+       struct wlp_attr_hdr hdr;                                        \
+       type name;                                                      \
+} __attribute__((packed));
+
+#define wlp_attr_array(type, name)                                     \
+struct wlp_attr_##name {                                               \
+       struct wlp_attr_hdr hdr;                                        \
+       type name[];                                                    \
+} __attribute__((packed));
+
+/**
+ * WLP association attribute fields
+ * WLP Draft 0.99 [6.6.1 Table 6]
+ *
+ * Attributes appear in same order as the Table in the spec
+ * FIXME Does not define all attributes yet
+ */
+
+/* Device name: Friendly name of sending device */
+wlp_attr_array(u8, dev_name)
+
+/* Enrollee Nonce: Random number generated by enrollee for an enrollment
+ * session */
+wlp_attr(struct wlp_nonce, enonce)
+
+/* Manufacturer name: Name of manufacturer of the sending device */
+wlp_attr_array(u8, manufacturer)
+
+/* WLP Message Type */
+wlp_attr(u8, msg_type)
+
+/* WLP Model name: Model name of sending device */
+wlp_attr_array(u8, model_name)
+
+/* WLP Model number: Model number of sending device */
+wlp_attr_array(u8, model_nr)
+
+/* Registrar Nonce: Random number generated by registrar for an enrollment
+ * session */
+wlp_attr(struct wlp_nonce, rnonce)
+
+/* Serial number of device */
+wlp_attr_array(u8, serial)
+
+/* UUID of enrollee */
+wlp_attr(struct wlp_uuid, uuid_e)
+
+/* UUID of registrar */
+wlp_attr(struct wlp_uuid, uuid_r)
+
+/* WLP Primary device type */
+wlp_attr(struct wlp_dev_type, prim_dev_type)
+
+/* WLP Secondary device type */
+wlp_attr(struct wlp_dev_type, sec_dev_type)
+
+/* WLP protocol version */
+wlp_attr(u8, version)
+
+/* WLP service set identifier */
+wlp_attr(struct wlp_uuid, wssid)
+
+/* WLP WSS name */
+wlp_attr_array(u8, wss_name)
+
+/* WLP WSS Secure Status */
+wlp_attr(u8, wss_sec_status)
+
+/* WSS Broadcast Address */
+wlp_attr(struct uwb_mac_addr, wss_bcast)
+
+/* WLP Accepting Enrollment */
+wlp_attr(u8, accept_enrl)
+
+/**
+ * WSS information attributes
+ * WLP Draft 0.99 [6.6.3 Table 15]
+ */
+struct wlp_wss_info {
+       struct wlp_attr_wssid wssid;
+       struct wlp_attr_wss_name name;
+       struct wlp_attr_accept_enrl accept;
+       struct wlp_attr_wss_sec_status sec_stat;
+       struct wlp_attr_wss_bcast bcast;
+} __attribute__((packed));
+
+/* WLP WSS Information */
+wlp_attr_array(struct wlp_wss_info, wss_info)
+
+/* WLP WSS Selection method */
+wlp_attr(u8, wss_sel_mthd)
+
+/* WLP WSS tag */
+wlp_attr(u8, wss_tag)
+
+/* WSS Virtual Address */
+wlp_attr(struct uwb_mac_addr, wss_virt)
+
+/* WLP association error */
+wlp_attr(u8, wlp_assc_err)
+
+/**
+ * WLP standard and abbreviated frames
+ *
+ * WLP Draft 0.99 [6.3] and [6.4]
+ *
+ * The difference between the WLP standard frame and the WLP
+ * abbreviated frame is that the standard frame includes the src
+ * and dest addresses from the Ethernet header, the abbreviated frame does
+ * not.
+ * The src/dest (as well as the type/length and client data) are already
+ * defined as part of the Ethernet header, we do not do this here.
+ * From this perspective the standard and abbreviated frames appear the
+ * same - they will be treated differently though.
+ *
+ * The size of this header is also captured in WLP_DATA_HLEN to enable
+ * interfaces to prepare their headroom.
+ */
+struct wlp_frame_std_abbrv_hdr {
+       struct wlp_frame_hdr hdr;
+       u8 tag;
+} __attribute__((packed));
+
+/**
+ * WLP association frames
+ *
+ * WLP Draft 0.99 [6.6]
+ */
+struct wlp_frame_assoc {
+       struct wlp_frame_hdr hdr;
+       enum wlp_assoc_type type:8;
+       struct wlp_attr_version version;
+       struct wlp_attr_msg_type msg_type;
+       u8 attr[];
+} __attribute__((packed));
+
+/* Ethernet to dev address mapping */
+struct wlp_eda {
+       spinlock_t lock;
+       struct list_head cache; /* Eth<->Dev Addr cache */
+};
+
+/**
+ * WSS information temporary storage
+ *
+ * This information is only stored temporarily during discovery. It should
+ * not be stored unless the device is enrolled in the advertised WSS. This
+ * is done mainly because we follow the letter of the spec in this regard.
+ * See WLP 0.99 [7.2.3].
+ * When the device does become enrolled in a WSS the WSS information will
+ * be stored as part of the more comprehensive struct wlp_wss.
+ */
+struct wlp_wss_tmp_info {
+       char name[WLP_WSS_NAME_SIZE];
+       u8 accept_enroll;
+       u8 sec_status;
+       struct uwb_mac_addr bcast;
+};
+
+struct wlp_wssid_e {
+       struct list_head node;
+       struct wlp_uuid wssid;
+       struct wlp_wss_tmp_info *info;
+};
+
+/**
+ * A cache entry of WLP neighborhood
+ *
+ * @node: head of list is wlp->neighbors
+ * @wssid: list of wssids of this neighbor, element is wlp_wssid_e
+ * @info:  temporary storage for information learned during discovery. This
+ *         storage is used together with the wssid_e temporary storage
+ *         during discovery.
+ */
+struct wlp_neighbor_e {
+       struct list_head node;
+       struct wlp_uuid uuid;
+       struct uwb_dev *uwb_dev;
+       struct list_head wssid; /* Elements are wlp_wssid_e */
+       struct wlp_device_info *info;
+};
+
+struct wlp;
+/**
+ * Information for an association session in progress.
+ *
+ * @exp_message: The type of the expected message. Both this message and a
+ *               F0 message (which can be sent in response to any
+ *               association frame) will be accepted as a valid message for
+ *               this session.
+ * @cb:          The function that will be called upon receipt of this
+ *               message.
+ * @cb_priv:     Private data of callback
+ * @data:        Data used in association process (always a sk_buff?)
+ * @neighbor:    Address of neighbor with which association session is in
+ *               progress.
+ */
+struct wlp_session {
+       enum wlp_assoc_type exp_message;
+       void (*cb)(struct wlp *);
+       void *cb_priv;
+       void *data;
+       struct uwb_dev_addr neighbor_addr;
+};
+
+/**
+ * WLP Service Set
+ *
+ * @mutex: used to protect entire WSS structure.
+ *
+ * @name: The WSS name is set to 65 bytes, 1 byte larger than the maximum
+ *        allowed by the WLP spec. This is to have a null terminated string
+ *        for display to the user. A maximum of 64 bytes will still be used
+ *        when placing the WSS name field in association frames.
+ *
+ * @accept_enroll: Accepting enrollment: Set to one if registrar is
+ *                 accepting enrollment in WSS, or zero otherwise.
+ *
+ * Global and local information for each WSS in which we are enrolled.
+ * WLP 0.99 Section 7.2.1 and Section 7.2.2
+ */
+struct wlp_wss {
+       struct mutex mutex;
+       struct kobject kobj;
+       /* Global properties. */
+       struct wlp_uuid wssid;
+       u8 hash;
+       char name[WLP_WSS_NAME_SIZE];
+       struct uwb_mac_addr bcast;
+       u8 secure_status:1;
+       u8 master_key[16];
+       /* Local properties. */
+       u8 tag;
+       struct uwb_mac_addr virtual_addr;
+       /* Extra */
+       u8 accept_enroll:1;
+       enum wlp_wss_state state;
+};
+
+/**
+ * WLP main structure
+ * @mutex: protect changes to WLP structure. We only allow changes to the
+ *         uuid, so currently this mutex only protects this field.
+ */
+struct wlp {
+       struct mutex mutex;
+       struct uwb_rc *rc;              /* UWB radio controller */
+       struct uwb_pal pal;
+       struct wlp_eda eda;
+       struct wlp_uuid uuid;
+       struct wlp_session *session;
+       struct wlp_wss wss;
+       struct mutex nbmutex; /* Neighbor mutex protects neighbors list */
+       struct list_head neighbors; /* Elements are wlp_neighbor_e */
+       struct uwb_notifs_handler uwb_notifs_handler;
+       struct wlp_device_info *dev_info;
+       void (*fill_device_info)(struct wlp *wlp, struct wlp_device_info *info);
+       int (*xmit_frame)(struct wlp *, struct sk_buff *,
+                         struct uwb_dev_addr *);
+       void (*stop_queue)(struct wlp *);
+       void (*start_queue)(struct wlp *);
+};
+
+/* sysfs */
+
+
+struct wlp_wss_attribute {
+       struct attribute attr;
+       ssize_t (*show)(struct wlp_wss *wss, char *buf);
+       ssize_t (*store)(struct wlp_wss *wss, const char *buf, size_t count);
+};
+
+#define WSS_ATTR(_name, _mode, _show, _store) \
+static struct wlp_wss_attribute wss_attr_##_name = __ATTR(_name, _mode,        \
+                                                         _show, _store)
+
+extern int wlp_setup(struct wlp *, struct uwb_rc *);
+extern void wlp_remove(struct wlp *);
+extern ssize_t wlp_neighborhood_show(struct wlp *, char *);
+extern int wlp_wss_setup(struct net_device *, struct wlp_wss *);
+extern void wlp_wss_remove(struct wlp_wss *);
+extern ssize_t wlp_wss_activate_show(struct wlp_wss *, char *);
+extern ssize_t wlp_wss_activate_store(struct wlp_wss *, const char *, size_t);
+extern ssize_t wlp_eda_show(struct wlp *, char *);
+extern ssize_t wlp_eda_store(struct wlp *, const char *, size_t);
+extern ssize_t wlp_uuid_show(struct wlp *, char *);
+extern ssize_t wlp_uuid_store(struct wlp *, const char *, size_t);
+extern ssize_t wlp_dev_name_show(struct wlp *, char *);
+extern ssize_t wlp_dev_name_store(struct wlp *, const char *, size_t);
+extern ssize_t wlp_dev_manufacturer_show(struct wlp *, char *);
+extern ssize_t wlp_dev_manufacturer_store(struct wlp *, const char *, size_t);
+extern ssize_t wlp_dev_model_name_show(struct wlp *, char *);
+extern ssize_t wlp_dev_model_name_store(struct wlp *, const char *, size_t);
+extern ssize_t wlp_dev_model_nr_show(struct wlp *, char *);
+extern ssize_t wlp_dev_model_nr_store(struct wlp *, const char *, size_t);
+extern ssize_t wlp_dev_serial_show(struct wlp *, char *);
+extern ssize_t wlp_dev_serial_store(struct wlp *, const char *, size_t);
+extern ssize_t wlp_dev_prim_category_show(struct wlp *, char *);
+extern ssize_t wlp_dev_prim_category_store(struct wlp *, const char *,
+                                          size_t);
+extern ssize_t wlp_dev_prim_OUI_show(struct wlp *, char *);
+extern ssize_t wlp_dev_prim_OUI_store(struct wlp *, const char *, size_t);
+extern ssize_t wlp_dev_prim_OUI_sub_show(struct wlp *, char *);
+extern ssize_t wlp_dev_prim_OUI_sub_store(struct wlp *, const char *,
+                                         size_t);
+extern ssize_t wlp_dev_prim_subcat_show(struct wlp *, char *);
+extern ssize_t wlp_dev_prim_subcat_store(struct wlp *, const char *,
+                                        size_t);
+extern int wlp_receive_frame(struct device *, struct wlp *, struct sk_buff *,
+                            struct uwb_dev_addr *);
+extern int wlp_prepare_tx_frame(struct device *, struct wlp *,
+                              struct sk_buff *, struct uwb_dev_addr *);
+void wlp_reset_all(struct wlp *wlp);
+
+/**
+ * Initialize WSS
+ */
+static inline
+void wlp_wss_init(struct wlp_wss *wss)
+{
+       mutex_init(&wss->mutex);
+}
+
+static inline
+void wlp_init(struct wlp *wlp)
+{
+       INIT_LIST_HEAD(&wlp->neighbors);
+       mutex_init(&wlp->mutex);
+       mutex_init(&wlp->nbmutex);
+       wlp_wss_init(&wlp->wss);
+}
+
+
+#endif /* #ifndef __LINUX__WLP_H_ */
index 5c158c477ac76c688cc53fa17bc61bae4e04dd43..89a5a1231ffb28bcff53a4261e187b4a8d77a5df 100644 (file)
@@ -149,11 +149,11 @@ struct execute_work {
 
 extern struct workqueue_struct *
 __create_workqueue_key(const char *name, int singlethread,
-                      int freezeable, struct lock_class_key *key,
+                      int freezeable, int rt, struct lock_class_key *key,
                       const char *lock_name);
 
 #ifdef CONFIG_LOCKDEP
-#define __create_workqueue(name, singlethread, freezeable)     \
+#define __create_workqueue(name, singlethread, freezeable, rt) \
 ({                                                             \
        static struct lock_class_key __key;                     \
        const char *__lock_name;                                \
@@ -164,17 +164,19 @@ __create_workqueue_key(const char *name, int singlethread,
                __lock_name = #name;                            \
                                                                \
        __create_workqueue_key((name), (singlethread),          \
-                              (freezeable), &__key,            \
+                              (freezeable), (rt), &__key,      \
                               __lock_name);                    \
 })
 #else
-#define __create_workqueue(name, singlethread, freezeable)     \
-       __create_workqueue_key((name), (singlethread), (freezeable), NULL, NULL)
+#define __create_workqueue(name, singlethread, freezeable, rt) \
+       __create_workqueue_key((name), (singlethread), (freezeable), (rt), \
+                              NULL, NULL)
 #endif
 
-#define create_workqueue(name) __create_workqueue((name), 0, 0)
-#define create_freezeable_workqueue(name) __create_workqueue((name), 1, 1)
-#define create_singlethread_workqueue(name) __create_workqueue((name), 1, 0)
+#define create_workqueue(name) __create_workqueue((name), 0, 0, 0)
+#define create_rt_workqueue(name) __create_workqueue((name), 0, 0, 1)
+#define create_freezeable_workqueue(name) __create_workqueue((name), 1, 1, 0)
+#define create_singlethread_workqueue(name) __create_workqueue((name), 1, 0, 0)
 
 extern void destroy_workqueue(struct workqueue_struct *wq);
 
index c8b80e0f065199e01102933d0ad4074075632782..9c2df41dbf92b7900a4966f26e0aedbec3f10099 100644 (file)
@@ -84,6 +84,8 @@ struct v4l2_int_device {
        void *priv;
 };
 
+void v4l2_int_device_try_attach_all(void);
+
 int v4l2_int_device_register(struct v4l2_int_device *d);
 void v4l2_int_device_unregister(struct v4l2_int_device *d);
 
@@ -96,6 +98,12 @@ int v4l2_int_ioctl_1(struct v4l2_int_device *d, int cmd, void *arg);
  *
  */
 
+enum v4l2_power {
+       V4L2_POWER_OFF = 0,
+       V4L2_POWER_ON,
+       V4L2_POWER_STANDBY,
+};
+
 /* Slave interface type. */
 enum v4l2_if_type {
        /*
@@ -170,6 +178,9 @@ enum v4l2_int_ioctl_num {
        vidioc_int_queryctrl_num,
        vidioc_int_g_ctrl_num,
        vidioc_int_s_ctrl_num,
+       vidioc_int_cropcap_num,
+       vidioc_int_g_crop_num,
+       vidioc_int_s_crop_num,
        vidioc_int_g_parm_num,
        vidioc_int_s_parm_num,
 
@@ -182,12 +193,19 @@ enum v4l2_int_ioctl_num {
        vidioc_int_dev_init_num = 1000,
        /* Delinitialise the device at slave detach. */
        vidioc_int_dev_exit_num,
-       /* Set device power state: 0 is off, non-zero is on. */
+       /* Set device power state. */
        vidioc_int_s_power_num,
+       /*
+       * Get slave private data, e.g. platform-specific slave
+       * configuration used by the master.
+       */
+       vidioc_int_g_priv_num,
        /* Get slave interface parameters. */
        vidioc_int_g_ifparm_num,
        /* Does the slave need to be reset after VIDIOC_DQBUF? */
        vidioc_int_g_needs_reset_num,
+       vidioc_int_enum_framesizes_num,
+       vidioc_int_enum_frameintervals_num,
 
        /*
         *
@@ -261,14 +279,20 @@ V4L2_INT_WRAPPER_1(try_fmt_cap, struct v4l2_format, *);
 V4L2_INT_WRAPPER_1(queryctrl, struct v4l2_queryctrl, *);
 V4L2_INT_WRAPPER_1(g_ctrl, struct v4l2_control, *);
 V4L2_INT_WRAPPER_1(s_ctrl, struct v4l2_control, *);
+V4L2_INT_WRAPPER_1(cropcap, struct v4l2_cropcap, *);
+V4L2_INT_WRAPPER_1(g_crop, struct v4l2_crop, *);
+V4L2_INT_WRAPPER_1(s_crop, struct v4l2_crop, *);
 V4L2_INT_WRAPPER_1(g_parm, struct v4l2_streamparm, *);
 V4L2_INT_WRAPPER_1(s_parm, struct v4l2_streamparm, *);
 
 V4L2_INT_WRAPPER_0(dev_init);
 V4L2_INT_WRAPPER_0(dev_exit);
-V4L2_INT_WRAPPER_1(s_power, int, );
+V4L2_INT_WRAPPER_1(s_power, enum v4l2_power, );
+V4L2_INT_WRAPPER_1(g_priv, void, *);
 V4L2_INT_WRAPPER_1(g_ifparm, struct v4l2_ifparm, *);
 V4L2_INT_WRAPPER_1(g_needs_reset, void, *);
+V4L2_INT_WRAPPER_1(enum_framesizes, struct v4l2_frmsizeenum, *);
+V4L2_INT_WRAPPER_1(enum_frameintervals, struct v4l2_frmivalenum, *);
 
 V4L2_INT_WRAPPER_0(reset);
 V4L2_INT_WRAPPER_0(init);
index 0bef03add7968c1b26053be42b52ffbc5da132d3..e6ba25b3d7c8bd345b5c5c30732f2c4f78d59f5a 100644 (file)
@@ -271,26 +271,38 @@ extern const char *v4l2_field_names[];
 extern const char *v4l2_type_names[];
 
 /*  Compatibility layer interface  --  v4l1-compat module */
-typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file,
+typedef int (*v4l2_kioctl)(struct file *file,
                           unsigned int cmd, void *arg);
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
-int v4l_compat_translate_ioctl(struct inode *inode, struct file *file,
+int v4l_compat_translate_ioctl(struct file *file,
                               int cmd, void *arg, v4l2_kioctl driver_ioctl);
 #else
-#define v4l_compat_translate_ioctl(inode, file, cmd, arg, ioctl) (-EINVAL)
+#define v4l_compat_translate_ioctl(file, cmd, arg, ioctl) (-EINVAL)
 #endif
 
 /* 32 Bits compatibility layer for 64 bits processors */
 extern long v4l_compat_ioctl32(struct file *file, unsigned int cmd,
                                unsigned long arg);
 
-extern int video_ioctl2(struct inode *inode, struct file *file,
-                         unsigned int cmd, unsigned long arg);
-
 /* Include support for obsoleted stuff */
 extern int video_usercopy(struct inode *inode, struct file *file,
                          unsigned int cmd, unsigned long arg,
                          int (*func)(struct inode *inode, struct file *file,
                                      unsigned int cmd, void *arg));
 
+/* Standard handlers for V4L ioctl's */
+
+/* This prototype is used on fops.unlocked_ioctl */
+extern int __video_ioctl2(struct file *file,
+                       unsigned int cmd, unsigned long arg);
+
+/* This prototype is used on fops.ioctl
+ * Since fops.ioctl enables Kernel Big Lock, it is preferred
+ * to use __video_ioctl2 instead.
+ * It should be noticed that there's no lock code inside
+ * video_ioctl2().
+ */
+extern int video_ioctl2(struct inode *inode, struct file *file,
+                       unsigned int cmd, unsigned long arg);
+
 #endif /* _V4L2_IOCTL_H */
index 80471c2b63436d3dc45a8cb730782552b8849f55..6ba4f1271d237f7af4c5166040992f7ad8a96200 100644 (file)
@@ -47,6 +47,7 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
 void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f);
 
 struct videobuf_dvb_frontend * videobuf_dvb_alloc_frontend(struct videobuf_dvb_frontends *f, int id);
+void videobuf_dvb_dealloc_frontends(struct videobuf_dvb_frontends *f);
 
 struct videobuf_dvb_frontend * videobuf_dvb_get_frontend(struct videobuf_dvb_frontends *f, int id);
 int videobuf_dvb_find_frontend(struct videobuf_dvb_frontends *f, struct dvb_frontend *p);
index d2c60c73619dc38827ea57af9b4761addbe1f3f9..b77c1478c99fcce80dbaf2f5bd877269e96a086e 100644 (file)
@@ -56,9 +56,9 @@ enum p9_debug_flags {
        P9_DEBUG_PKT =          (1<<10),
 };
 
+#ifdef CONFIG_NET_9P_DEBUG
 extern unsigned int p9_debug_level;
 
-#ifdef CONFIG_NET_9P_DEBUG
 #define P9_DPRINTK(level, format, arg...) \
 do {  \
        if ((p9_debug_level & level) == level) {\
index 1f17f3d93727ee4873e3c7c8a7c61c8cdcbb0204..4012e07162e51e772081ad6af9261f52bd9a88cd 100644 (file)
@@ -182,6 +182,7 @@ struct p9_fid {
        struct list_head dlist; /* list of all fids attached to a dentry */
 };
 
+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);
@@ -206,6 +207,7 @@ int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst);
 struct p9_req_t *p9_tag_lookup(struct p9_client *, u16);
 void p9_client_cb(struct p9_client *c, struct p9_req_t *req);
 
+int p9_parse_header(struct p9_fcall *, int32_t *, int8_t *, int16_t *, int);
 int p9stat_read(char *, int, struct p9_wstat *, int);
 void p9stat_free(struct p9_wstat *);
 
index edb9525386dadc40b38788787d6c92586dcf5e82..b9006848b8134412cc29f67208890cbfdc2f370b 100644 (file)
@@ -42,7 +42,7 @@ typedef struct scsi_fctargaddress {
 
 extern int scsi_ioctl(struct scsi_device *, int, void __user *);
 extern int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd,
-                                  void __user *arg, struct file *filp);
+                                  void __user *arg, int ndelay);
 
 #endif /* __KERNEL__ */
 #endif /* _SCSI_IOCTL_H */
diff --git a/include/trace/sched.h b/include/trace/sched.h
new file mode 100644 (file)
index 0000000..ad47369
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef _TRACE_SCHED_H
+#define _TRACE_SCHED_H
+
+#include <linux/sched.h>
+#include <linux/tracepoint.h>
+
+DEFINE_TRACE(sched_kthread_stop,
+       TPPROTO(struct task_struct *t),
+               TPARGS(t));
+
+DEFINE_TRACE(sched_kthread_stop_ret,
+       TPPROTO(int ret),
+               TPARGS(ret));
+
+DEFINE_TRACE(sched_wait_task,
+       TPPROTO(struct rq *rq, struct task_struct *p),
+               TPARGS(rq, p));
+
+DEFINE_TRACE(sched_wakeup,
+       TPPROTO(struct rq *rq, struct task_struct *p),
+               TPARGS(rq, p));
+
+DEFINE_TRACE(sched_wakeup_new,
+       TPPROTO(struct rq *rq, struct task_struct *p),
+               TPARGS(rq, p));
+
+DEFINE_TRACE(sched_switch,
+       TPPROTO(struct rq *rq, struct task_struct *prev,
+               struct task_struct *next),
+               TPARGS(rq, prev, next));
+
+DEFINE_TRACE(sched_migrate_task,
+       TPPROTO(struct rq *rq, struct task_struct *p, int dest_cpu),
+               TPARGS(rq, p, dest_cpu));
+
+DEFINE_TRACE(sched_process_free,
+       TPPROTO(struct task_struct *p),
+               TPARGS(p));
+
+DEFINE_TRACE(sched_process_exit,
+       TPPROTO(struct task_struct *p),
+               TPARGS(p));
+
+DEFINE_TRACE(sched_process_wait,
+       TPPROTO(struct pid *pid),
+               TPARGS(pid));
+
+DEFINE_TRACE(sched_process_fork,
+       TPPROTO(struct task_struct *parent, struct task_struct *child),
+               TPARGS(parent, child));
+
+DEFINE_TRACE(sched_signal_send,
+       TPPROTO(int sig, struct task_struct *p),
+               TPARGS(sig, p));
+
+#endif
index 8828ed0b2051f16df1d3a491419d3e868ac8d014..44e9208f9c78c850593109e62b112485d4baa8f4 100644 (file)
@@ -737,6 +737,15 @@ config VM_EVENT_COUNTERS
          on EMBEDDED systems.  /proc/vmstat will only show page counts
          if VM event counters are disabled.
 
+config PCI_QUIRKS
+       default y
+       bool "Enable PCI quirk workarounds" if EMBEDDED
+       depends on PCI
+       help
+         This enables workarounds for various PCI chipset
+          bugs/quirks. Disable this only if your target machine is
+          unaffected by PCI quirks.
+
 config SLUB_DEBUG
        default y
        bool "Enable SLUB debugging support" if EMBEDDED
@@ -786,6 +795,13 @@ config PROFILING
          Say Y here to enable the extended profiling support mechanisms used
          by profilers such as OProfile.
 
+#
+# Place an empty function call at each tracepoint site. Can be
+# dynamically changed for a probe function.
+#
+config TRACEPOINTS
+       bool
+
 config MARKERS
        bool "Activate markers"
        help
index 4371d11721f618f45ccfc65b799fbbdfebbf8140..130d1a0eef113ef62f873d386f689f8533591d28 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/key.h>
 #include <linux/unwind.h>
 #include <linux/buffer_head.h>
+#include <linux/page_cgroup.h>
 #include <linux/debug_locks.h>
 #include <linux/debugobjects.h>
 #include <linux/lockdep.h>
@@ -61,6 +62,7 @@
 #include <linux/sched.h>
 #include <linux/signal.h>
 #include <linux/idr.h>
+#include <linux/ftrace.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -646,6 +648,7 @@ asmlinkage void __init start_kernel(void)
        vmalloc_init();
        vfs_caches_init_early();
        cpuset_init_early();
+       page_cgroup_init();
        mem_init();
        enable_debug_pagealloc();
        cpu_hotplug_init();
@@ -669,7 +672,6 @@ asmlinkage void __init start_kernel(void)
        fork_init(num_physpages);
        proc_caches_init();
        buffer_init();
-       unnamed_dev_init();
        key_init();
        security_init();
        vfs_caches_init(num_physpages);
@@ -689,46 +691,43 @@ asmlinkage void __init start_kernel(void)
 
        acpi_early_init(); /* before LAPIC and SMP init */
 
+       ftrace_init();
+
        /* Do the rest non-__init'ed, we're now alive */
        rest_init();
 }
 
 static int initcall_debug;
-
-static int __init initcall_debug_setup(char *str)
-{
-       initcall_debug = 1;
-       return 1;
-}
-__setup("initcall_debug", initcall_debug_setup);
+core_param(initcall_debug, initcall_debug, bool, 0644);
 
 int do_one_initcall(initcall_t fn)
 {
        int count = preempt_count();
-       ktime_t t0, t1, delta;
+       ktime_t delta;
        char msgbuf[64];
-       int result;
+       struct boot_trace it;
 
        if (initcall_debug) {
-               printk("calling  %pF @ %i\n", fn, task_pid_nr(current));
-               t0 = ktime_get();
+               it.caller = task_pid_nr(current);
+               printk("calling  %pF @ %i\n", fn, it.caller);
+               it.calltime = ktime_get();
        }
 
-       result = fn();
+       it.result = fn();
 
        if (initcall_debug) {
-               t1 = ktime_get();
-               delta = ktime_sub(t1, t0);
-
-               printk("initcall %pF returned %d after %Ld msecs\n",
-                       fn, result,
-                       (unsigned long long) delta.tv64 >> 20);
+               it.rettime = ktime_get();
+               delta = ktime_sub(it.rettime, it.calltime);
+               it.duration = (unsigned long long) delta.tv64 >> 10;
+               printk("initcall %pF returned %d after %Ld usecs\n", fn,
+                       it.result, it.duration);
+               trace_boot(&it, fn);
        }
 
        msgbuf[0] = 0;
 
-       if (result && result != -ENODEV && initcall_debug)
-               sprintf(msgbuf, "error code %d ", result);
+       if (it.result && it.result != -ENODEV && initcall_debug)
+               sprintf(msgbuf, "error code %d ", it.result);
 
        if (preempt_count() != count) {
                strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
@@ -742,7 +741,7 @@ int do_one_initcall(initcall_t fn)
                printk("initcall %pF returned with %s\n", fn, msgbuf);
        }
 
-       return result;
+       return it.result;
 }
 
 
@@ -769,8 +768,6 @@ static void __init do_initcalls(void)
 static void __init do_basic_setup(void)
 {
        rcu_init_sched(); /* needed by module_init stage. */
-       /* drivers will send hotplug events */
-       init_workqueues();
        usermodehelper_init();
        driver_init();
        init_irq_proc();
@@ -854,9 +851,12 @@ static int __init kernel_init(void * unused)
 
        cad_pid = task_pid(current);
 
+       init_workqueues();
+
        smp_prepare_cpus(setup_max_cpus);
 
        do_pre_smp_initcalls();
+       start_boot_trace();
 
        smp_init();
        sched_init_smp();
@@ -883,6 +883,7 @@ static int __init kernel_init(void * unused)
         * we're essentially up and running. Get rid of the
         * initmem segments and start the user-mode stuff..
         */
+       stop_boot_trace();
        init_post();
        return 0;
 }
index 0add3fa5f54774d15eb81330a3f52ea9a5ddb084..867e5d6a55c23ec64361db7e9eb2e1cf93b4f559 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -817,7 +817,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
        struct ipc_namespace *ns;
        struct shm_file_data *sfd;
        struct path path;
-       mode_t f_mode;
+       fmode_t f_mode;
 
        err = -EINVAL;
        if (shmid < 0)
index 066550aa61c5018a32dff60fcd75e6ffdebbdedd..305f11dbef216cd9cb5efba14483492b59a26354 100644 (file)
@@ -85,6 +85,7 @@ obj-$(CONFIG_SYSCTL) += utsname_sysctl.o
 obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
 obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
 obj-$(CONFIG_MARKERS) += marker.o
+obj-$(CONFIG_TRACEPOINTS) += tracepoint.o
 obj-$(CONFIG_LATENCYTOP) += latencytop.o
 obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
 obj-$(CONFIG_FTRACE) += trace/
index f7921a2ecf16c07537971fd62624ef1a40046812..8ba0e0d934f23137762f74525f6757e27a129056 100644 (file)
@@ -532,7 +532,7 @@ void audit_trim_trees(void)
        list_add(&cursor, &tree_list);
        while (cursor.next != &tree_list) {
                struct audit_tree *tree;
-               struct nameidata nd;
+               struct path path;
                struct vfsmount *root_mnt;
                struct node *node;
                struct list_head list;
@@ -544,12 +544,12 @@ void audit_trim_trees(void)
                list_add(&cursor, &tree->list);
                mutex_unlock(&audit_filter_mutex);
 
-               err = path_lookup(tree->pathname, 0, &nd);
+               err = kern_path(tree->pathname, 0, &path);
                if (err)
                        goto skip_it;
 
-               root_mnt = collect_mounts(nd.path.mnt, nd.path.dentry);
-               path_put(&nd.path);
+               root_mnt = collect_mounts(path.mnt, path.dentry);
+               path_put(&path);
                if (!root_mnt)
                        goto skip_it;
 
@@ -580,19 +580,19 @@ skip_it:
 }
 
 static int is_under(struct vfsmount *mnt, struct dentry *dentry,
-                   struct nameidata *nd)
+                   struct path *path)
 {
-       if (mnt != nd->path.mnt) {
+       if (mnt != path->mnt) {
                for (;;) {
                        if (mnt->mnt_parent == mnt)
                                return 0;
-                       if (mnt->mnt_parent == nd->path.mnt)
+                       if (mnt->mnt_parent == path->mnt)
                                        break;
                        mnt = mnt->mnt_parent;
                }
                dentry = mnt->mnt_mountpoint;
        }
-       return is_subdir(dentry, nd->path.dentry);
+       return is_subdir(dentry, path->dentry);
 }
 
 int audit_make_tree(struct audit_krule *rule, char *pathname, u32 op)
@@ -618,7 +618,7 @@ void audit_put_tree(struct audit_tree *tree)
 int audit_add_tree_rule(struct audit_krule *rule)
 {
        struct audit_tree *seed = rule->tree, *tree;
-       struct nameidata nd;
+       struct path path;
        struct vfsmount *mnt, *p;
        struct list_head list;
        int err;
@@ -637,11 +637,11 @@ int audit_add_tree_rule(struct audit_krule *rule)
        /* do not set rule->tree yet */
        mutex_unlock(&audit_filter_mutex);
 
-       err = path_lookup(tree->pathname, 0, &nd);
+       err = kern_path(tree->pathname, 0, &path);
        if (err)
                goto Err;
-       mnt = collect_mounts(nd.path.mnt, nd.path.dentry);
-       path_put(&nd.path);
+       mnt = collect_mounts(path.mnt, path.dentry);
+       path_put(&path);
        if (!mnt) {
                err = -ENOMEM;
                goto Err;
@@ -690,29 +690,29 @@ int audit_tag_tree(char *old, char *new)
 {
        struct list_head cursor, barrier;
        int failed = 0;
-       struct nameidata nd;
+       struct path path;
        struct vfsmount *tagged;
        struct list_head list;
        struct vfsmount *mnt;
        struct dentry *dentry;
        int err;
 
-       err = path_lookup(new, 0, &nd);
+       err = kern_path(new, 0, &path);
        if (err)
                return err;
-       tagged = collect_mounts(nd.path.mnt, nd.path.dentry);
-       path_put(&nd.path);
+       tagged = collect_mounts(path.mnt, path.dentry);
+       path_put(&path);
        if (!tagged)
                return -ENOMEM;
 
-       err = path_lookup(old, 0, &nd);
+       err = kern_path(old, 0, &path);
        if (err) {
                drop_collected_mounts(tagged);
                return err;
        }
-       mnt = mntget(nd.path.mnt);
-       dentry = dget(nd.path.dentry);
-       path_put(&nd.path);
+       mnt = mntget(path.mnt);
+       dentry = dget(path.dentry);
+       path_put(&path);
 
        if (dentry == tagged->mnt_root && dentry == mnt->mnt_root)
                follow_up(&mnt, &dentry);
@@ -733,7 +733,7 @@ int audit_tag_tree(char *old, char *new)
                list_add(&cursor, &tree->list);
                mutex_unlock(&audit_filter_mutex);
 
-               err = path_lookup(tree->pathname, 0, &nd);
+               err = kern_path(tree->pathname, 0, &path);
                if (err) {
                        put_tree(tree);
                        mutex_lock(&audit_filter_mutex);
@@ -741,15 +741,15 @@ int audit_tag_tree(char *old, char *new)
                }
 
                spin_lock(&vfsmount_lock);
-               if (!is_under(mnt, dentry, &nd)) {
+               if (!is_under(mnt, dentry, &path)) {
                        spin_unlock(&vfsmount_lock);
-                       path_put(&nd.path);
+                       path_put(&path);
                        put_tree(tree);
                        mutex_lock(&audit_filter_mutex);
                        continue;
                }
                spin_unlock(&vfsmount_lock);
-               path_put(&nd.path);
+               path_put(&path);
 
                list_for_each_entry(p, &list, mnt_list) {
                        failed = tag_chunk(p->mnt_root->d_inode, tree);
index 143990e48cb9aab2af2f04d93a372d63dc570882..8eafe3eb50d9feb76dce5b289a4a7278321e4d8a 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/timex.h>
 #include <linux/migrate.h>
 #include <linux/posix-timers.h>
+#include <linux/times.h>
 
 #include <asm/uaccess.h>
 
@@ -208,49 +209,23 @@ asmlinkage long compat_sys_setitimer(int which,
        return 0;
 }
 
+static compat_clock_t clock_t_to_compat_clock_t(clock_t x)
+{
+       return compat_jiffies_to_clock_t(clock_t_to_jiffies(x));
+}
+
 asmlinkage long compat_sys_times(struct compat_tms __user *tbuf)
 {
-       /*
-        *      In the SMP world we might just be unlucky and have one of
-        *      the times increment as we use it. Since the value is an
-        *      atomically safe type this is just fine. Conceptually its
-        *      as if the syscall took an instant longer to occur.
-        */
        if (tbuf) {
+               struct tms tms;
                struct compat_tms tmp;
-               struct task_struct *tsk = current;
-               struct task_struct *t;
-               cputime_t utime, stime, cutime, cstime;
-
-               read_lock(&tasklist_lock);
-               utime = tsk->signal->utime;
-               stime = tsk->signal->stime;
-               t = tsk;
-               do {
-                       utime = cputime_add(utime, t->utime);
-                       stime = cputime_add(stime, t->stime);
-                       t = next_thread(t);
-               } while (t != tsk);
-
-               /*
-                * While we have tasklist_lock read-locked, no dying thread
-                * can be updating current->signal->[us]time.  Instead,
-                * we got their counts included in the live thread loop.
-                * However, another thread can come in right now and
-                * do a wait call that updates current->signal->c[us]time.
-                * To make sure we always see that pair updated atomically,
-                * we take the siglock around fetching them.
-                */
-               spin_lock_irq(&tsk->sighand->siglock);
-               cutime = tsk->signal->cutime;
-               cstime = tsk->signal->cstime;
-               spin_unlock_irq(&tsk->sighand->siglock);
-               read_unlock(&tasklist_lock);
-
-               tmp.tms_utime = compat_jiffies_to_clock_t(cputime_to_jiffies(utime));
-               tmp.tms_stime = compat_jiffies_to_clock_t(cputime_to_jiffies(stime));
-               tmp.tms_cutime = compat_jiffies_to_clock_t(cputime_to_jiffies(cutime));
-               tmp.tms_cstime = compat_jiffies_to_clock_t(cputime_to_jiffies(cstime));
+
+               do_sys_times(&tms);
+               /* Convert our struct tms to the compat version. */
+               tmp.tms_utime = clock_t_to_compat_clock_t(tms.tms_utime);
+               tmp.tms_stime = clock_t_to_compat_clock_t(tms.tms_stime);
+               tmp.tms_cutime = clock_t_to_compat_clock_t(tms.tms_cutime);
+               tmp.tms_cstime = clock_t_to_compat_clock_t(tms.tms_cstime);
                if (copy_to_user(tbuf, &tmp, sizeof(tmp)))
                        return -EFAULT;
        }
index 0d407e886735d0b35c36a836f3bc97afa15ad9c6..0511716e94247a86873bb095e1136d45aa362c2c 100644 (file)
@@ -12,7 +12,9 @@
 #include <linux/kmod.h>
 #include <linux/module.h>
 #include <linux/personality.h>
+#include <linux/proc_fs.h>
 #include <linux/sched.h>
+#include <linux/seq_file.h>
 #include <linux/syscalls.h>
 #include <linux/sysctl.h>
 #include <linux/types.h>
@@ -173,20 +175,39 @@ __set_personality(u_long personality)
        return 0;
 }
 
-int
-get_exec_domain_list(char *page)
+#ifdef CONFIG_PROC_FS
+static int execdomains_proc_show(struct seq_file *m, void *v)
 {
        struct exec_domain      *ep;
-       int                     len = 0;
 
        read_lock(&exec_domains_lock);
-       for (ep = exec_domains; ep && len < PAGE_SIZE - 80; ep = ep->next)
-               len += sprintf(page + len, "%d-%d\t%-16s\t[%s]\n",
+       for (ep = exec_domains; ep; ep = ep->next)
+               seq_printf(m, "%d-%d\t%-16s\t[%s]\n",
                               ep->pers_low, ep->pers_high, ep->name,
                               module_name(ep->module));
        read_unlock(&exec_domains_lock);
-       return (len);
+       return 0;
+}
+
+static int execdomains_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, execdomains_proc_show, NULL);
+}
+
+static const struct file_operations execdomains_proc_fops = {
+       .open           = execdomains_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int __init proc_execdomains_init(void)
+{
+       proc_create("execdomains", 0, NULL, &execdomains_proc_fops);
+       return 0;
 }
+module_init(proc_execdomains_init);
+#endif
 
 asmlinkage long
 sys_personality(u_long personality)
index 0ef4673e351bddd4e738f88941511efa02f062fa..80137a5d9467811ba4dab35c6e95790002a5f12a 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/blkdev.h>
 #include <linux/task_io_accounting_ops.h>
 #include <linux/tracehook.h>
+#include <trace/sched.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -112,8 +113,6 @@ static void __exit_signal(struct task_struct *tsk)
                 * We won't ever get here for the group leader, since it
                 * will have been the last reference on the signal_struct.
                 */
-               sig->utime = cputime_add(sig->utime, task_utime(tsk));
-               sig->stime = cputime_add(sig->stime, task_stime(tsk));
                sig->gtime = cputime_add(sig->gtime, task_gtime(tsk));
                sig->min_flt += tsk->min_flt;
                sig->maj_flt += tsk->maj_flt;
@@ -122,7 +121,6 @@ static void __exit_signal(struct task_struct *tsk)
                sig->inblock += task_io_get_inblock(tsk);
                sig->oublock += task_io_get_oublock(tsk);
                task_io_accounting_add(&sig->ioac, &tsk->ioac);
-               sig->sum_sched_runtime += tsk->se.sum_exec_runtime;
                sig = NULL; /* Marker for below. */
        }
 
@@ -149,7 +147,10 @@ static void __exit_signal(struct task_struct *tsk)
 
 static void delayed_put_task_struct(struct rcu_head *rhp)
 {
-       put_task_struct(container_of(rhp, struct task_struct, rcu));
+       struct task_struct *tsk = container_of(rhp, struct task_struct, rcu);
+
+       trace_sched_process_free(tsk);
+       put_task_struct(tsk);
 }
 
 
@@ -1073,6 +1074,8 @@ NORET_TYPE void do_exit(long code)
 
        if (group_dead)
                acct_process();
+       trace_sched_process_exit(tsk);
+
        exit_sem(tsk);
        exit_files(tsk);
        exit_fs(tsk);
@@ -1301,6 +1304,7 @@ static int wait_task_zombie(struct task_struct *p, int options,
        if (likely(!traced)) {
                struct signal_struct *psig;
                struct signal_struct *sig;
+               struct task_cputime cputime;
 
                /*
                 * The resource counters for the group leader are in its
@@ -1316,20 +1320,23 @@ static int wait_task_zombie(struct task_struct *p, int options,
                 * need to protect the access to p->parent->signal fields,
                 * as other threads in the parent group can be right
                 * here reaping other children at the same time.
+                *
+                * We use thread_group_cputime() to get times for the thread
+                * group, which consolidates times for all threads in the
+                * group including the group leader.
                 */
                spin_lock_irq(&p->parent->sighand->siglock);
                psig = p->parent->signal;
                sig = p->signal;
+               thread_group_cputime(p, &cputime);
                psig->cutime =
                        cputime_add(psig->cutime,
-                       cputime_add(p->utime,
-                       cputime_add(sig->utime,
-                                   sig->cutime)));
+                       cputime_add(cputime.utime,
+                                   sig->cutime));
                psig->cstime =
                        cputime_add(psig->cstime,
-                       cputime_add(p->stime,
-                       cputime_add(sig->stime,
-                                   sig->cstime)));
+                       cputime_add(cputime.stime,
+                                   sig->cstime));
                psig->cgtime =
                        cputime_add(psig->cgtime,
                        cputime_add(p->gtime,
@@ -1674,6 +1681,8 @@ static long do_wait(enum pid_type type, struct pid *pid, int options,
        struct task_struct *tsk;
        int retval;
 
+       trace_sched_process_wait(pid);
+
        add_wait_queue(&current->signal->wait_chldexit,&wait);
 repeat:
        /*
index 30de644a40c4d4d9617d650589f4c90da1e977a2..f6083561dfe0a9f8d2a13138f7332bc358a51653 100644 (file)
@@ -58,6 +58,7 @@
 #include <linux/tty.h>
 #include <linux/proc_fs.h>
 #include <linux/blkdev.h>
+#include <trace/sched.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -759,15 +760,44 @@ void __cleanup_sighand(struct sighand_struct *sighand)
                kmem_cache_free(sighand_cachep, sighand);
 }
 
+
+/*
+ * Initialize POSIX timer handling for a thread group.
+ */
+static void posix_cpu_timers_init_group(struct signal_struct *sig)
+{
+       /* Thread group counters. */
+       thread_group_cputime_init(sig);
+
+       /* Expiration times and increments. */
+       sig->it_virt_expires = cputime_zero;
+       sig->it_virt_incr = cputime_zero;
+       sig->it_prof_expires = cputime_zero;
+       sig->it_prof_incr = cputime_zero;
+
+       /* Cached expiration times. */
+       sig->cputime_expires.prof_exp = cputime_zero;
+       sig->cputime_expires.virt_exp = cputime_zero;
+       sig->cputime_expires.sched_exp = 0;
+
+       /* The timer lists. */
+       INIT_LIST_HEAD(&sig->cpu_timers[0]);
+       INIT_LIST_HEAD(&sig->cpu_timers[1]);
+       INIT_LIST_HEAD(&sig->cpu_timers[2]);
+}
+
 static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
 {
        struct signal_struct *sig;
        int ret;
 
        if (clone_flags & CLONE_THREAD) {
-               atomic_inc(&current->signal->count);
-               atomic_inc(&current->signal->live);
-               return 0;
+               ret = thread_group_cputime_clone_thread(current);
+               if (likely(!ret)) {
+                       atomic_inc(&current->signal->count);
+                       atomic_inc(&current->signal->live);
+               }
+               return ret;
        }
        sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
        tsk->signal = sig;
@@ -795,40 +825,25 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
        sig->it_real_incr.tv64 = 0;
        sig->real_timer.function = it_real_fn;
 
-       sig->it_virt_expires = cputime_zero;
-       sig->it_virt_incr = cputime_zero;
-       sig->it_prof_expires = cputime_zero;
-       sig->it_prof_incr = cputime_zero;
-
        sig->leader = 0;        /* session leadership doesn't inherit */
        sig->tty_old_pgrp = NULL;
        sig->tty = NULL;
 
-       sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero;
+       sig->cutime = sig->cstime = cputime_zero;
        sig->gtime = cputime_zero;
        sig->cgtime = cputime_zero;
        sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
        sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
        sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0;
        task_io_accounting_init(&sig->ioac);
-       sig->sum_sched_runtime = 0;
-       INIT_LIST_HEAD(&sig->cpu_timers[0]);
-       INIT_LIST_HEAD(&sig->cpu_timers[1]);
-       INIT_LIST_HEAD(&sig->cpu_timers[2]);
        taskstats_tgid_init(sig);
 
        task_lock(current->group_leader);
        memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim);
        task_unlock(current->group_leader);
 
-       if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) {
-               /*
-                * New sole thread in the process gets an expiry time
-                * of the whole CPU time limit.
-                */
-               tsk->it_prof_expires =
-                       secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur);
-       }
+       posix_cpu_timers_init_group(sig);
+
        acct_init_pacct(&sig->pacct);
 
        tty_audit_fork(sig);
@@ -838,6 +853,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
 
 void __cleanup_signal(struct signal_struct *sig)
 {
+       thread_group_cputime_free(sig);
        exit_thread_group_keys(sig);
        tty_kref_put(sig->tty);
        kmem_cache_free(signal_cachep, sig);
@@ -887,6 +903,19 @@ void mm_init_owner(struct mm_struct *mm, struct task_struct *p)
 }
 #endif /* CONFIG_MM_OWNER */
 
+/*
+ * Initialize POSIX timer handling for a single task.
+ */
+static void posix_cpu_timers_init(struct task_struct *tsk)
+{
+       tsk->cputime_expires.prof_exp = cputime_zero;
+       tsk->cputime_expires.virt_exp = cputime_zero;
+       tsk->cputime_expires.sched_exp = 0;
+       INIT_LIST_HEAD(&tsk->cpu_timers[0]);
+       INIT_LIST_HEAD(&tsk->cpu_timers[1]);
+       INIT_LIST_HEAD(&tsk->cpu_timers[2]);
+}
+
 /*
  * This creates a new process as a copy of the old one,
  * but does not actually start it yet.
@@ -989,6 +1018,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        p->prev_utime = cputime_zero;
        p->prev_stime = cputime_zero;
 
+       p->default_timer_slack_ns = current->timer_slack_ns;
+
 #ifdef CONFIG_DETECT_SOFTLOCKUP
        p->last_switch_count = 0;
        p->last_switch_timestamp = 0;
@@ -997,12 +1028,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        task_io_accounting_init(&p->ioac);
        acct_clear_integrals(p);
 
-       p->it_virt_expires = cputime_zero;
-       p->it_prof_expires = cputime_zero;
-       p->it_sched_expires = 0;
-       INIT_LIST_HEAD(&p->cpu_timers[0]);
-       INIT_LIST_HEAD(&p->cpu_timers[1]);
-       INIT_LIST_HEAD(&p->cpu_timers[2]);
+       posix_cpu_timers_init(p);
 
        p->lock_depth = -1;             /* -1 = no lock */
        do_posix_clock_monotonic_gettime(&p->start_time);
@@ -1203,21 +1229,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        if (clone_flags & CLONE_THREAD) {
                p->group_leader = current->group_leader;
                list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group);
-
-               if (!cputime_eq(current->signal->it_virt_expires,
-                               cputime_zero) ||
-                   !cputime_eq(current->signal->it_prof_expires,
-                               cputime_zero) ||
-                   current->signal->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY ||
-                   !list_empty(&current->signal->cpu_timers[0]) ||
-                   !list_empty(&current->signal->cpu_timers[1]) ||
-                   !list_empty(&current->signal->cpu_timers[2])) {
-                       /*
-                        * Have child wake up on its first tick to check
-                        * for process CPU timers.
-                        */
-                       p->it_prof_expires = jiffies_to_cputime(1);
-               }
        }
 
        if (likely(p->pid)) {
@@ -1364,6 +1375,8 @@ long do_fork(unsigned long clone_flags,
        if (!IS_ERR(p)) {
                struct completion vfork;
 
+               trace_sched_process_fork(current, p);
+
                nr = task_pid_vnr(p);
 
                if (clone_flags & CLONE_PARENT_SETTID)
index 7d1136e97c142d198b897dab1846acd99f1f655f..8af10027514bb1cc9cb2702051330e52bf43a533 100644 (file)
@@ -1296,13 +1296,16 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared,
                if (!abs_time)
                        schedule();
                else {
+                       unsigned long slack;
+                       slack = current->timer_slack_ns;
+                       if (rt_task(current))
+                               slack = 0;
                        hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC,
                                                HRTIMER_MODE_ABS);
                        hrtimer_init_sleeper(&t, current);
-                       t.timer.expires = *abs_time;
+                       hrtimer_set_expires_range_ns(&t.timer, *abs_time, slack);
 
-                       hrtimer_start(&t.timer, t.timer.expires,
-                                               HRTIMER_MODE_ABS);
+                       hrtimer_start_expires(&t.timer, HRTIMER_MODE_ABS);
                        if (!hrtimer_active(&t.timer))
                                t.task = NULL;
 
@@ -1404,7 +1407,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
                hrtimer_init_on_stack(&to->timer, CLOCK_REALTIME,
                                      HRTIMER_MODE_ABS);
                hrtimer_init_sleeper(to, current);
-               to->timer.expires = *time;
+               hrtimer_set_expires(&to->timer, *time);
        }
 
        q.pi_state = NULL;
index cdec83e722fa1b80ee0af0f828d8e47532431a20..2b465dfde4269b6d4609957999c9eecb0a148a36 100644 (file)
@@ -517,7 +517,7 @@ static void hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base)
                if (!base->first)
                        continue;
                timer = rb_entry(base->first, struct hrtimer, node);
-               expires = ktime_sub(timer->expires, base->offset);
+               expires = ktime_sub(hrtimer_get_expires(timer), base->offset);
                if (expires.tv64 < cpu_base->expires_next.tv64)
                        cpu_base->expires_next = expires;
        }
@@ -539,10 +539,10 @@ static int hrtimer_reprogram(struct hrtimer *timer,
                             struct hrtimer_clock_base *base)
 {
        ktime_t *expires_next = &__get_cpu_var(hrtimer_bases).expires_next;
-       ktime_t expires = ktime_sub(timer->expires, base->offset);
+       ktime_t expires = ktime_sub(hrtimer_get_expires(timer), base->offset);
        int res;
 
-       WARN_ON_ONCE(timer->expires.tv64 < 0);
+       WARN_ON_ONCE(hrtimer_get_expires_tv64(timer) < 0);
 
        /*
         * When the callback is running, we do not reprogram the clock event
@@ -795,7 +795,7 @@ u64 hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval)
        u64 orun = 1;
        ktime_t delta;
 
-       delta = ktime_sub(now, timer->expires);
+       delta = ktime_sub(now, hrtimer_get_expires(timer));
 
        if (delta.tv64 < 0)
                return 0;
@@ -807,8 +807,8 @@ u64 hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval)
                s64 incr = ktime_to_ns(interval);
 
                orun = ktime_divns(delta, incr);
-               timer->expires = ktime_add_ns(timer->expires, incr * orun);
-               if (timer->expires.tv64 > now.tv64)
+               hrtimer_add_expires_ns(timer, incr * orun);
+               if (hrtimer_get_expires_tv64(timer) > now.tv64)
                        return orun;
                /*
                 * This (and the ktime_add() below) is the
@@ -816,7 +816,7 @@ u64 hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval)
                 */
                orun++;
        }
-       timer->expires = ktime_add_safe(timer->expires, interval);
+       hrtimer_add_expires(timer, interval);
 
        return orun;
 }
@@ -848,7 +848,8 @@ static void enqueue_hrtimer(struct hrtimer *timer,
                 * We dont care about collisions. Nodes with
                 * the same expiry time stay together.
                 */
-               if (timer->expires.tv64 < entry->expires.tv64) {
+               if (hrtimer_get_expires_tv64(timer) <
+                               hrtimer_get_expires_tv64(entry)) {
                        link = &(*link)->rb_left;
                } else {
                        link = &(*link)->rb_right;
@@ -945,9 +946,10 @@ remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base)
 }
 
 /**
- * hrtimer_start - (re)start an relative timer on the current CPU
+ * hrtimer_start_range_ns - (re)start an hrtimer on the current CPU
  * @timer:     the timer to be added
  * @tim:       expiry time
+ * @delta_ns:  "slack" range for the timer
  * @mode:      expiry mode: absolute (HRTIMER_ABS) or relative (HRTIMER_REL)
  *
  * Returns:
@@ -955,7 +957,8 @@ remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base)
  *  1 when the timer was active
  */
 int
-hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
+hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, unsigned long delta_ns,
+                       const enum hrtimer_mode mode)
 {
        struct hrtimer_clock_base *base, *new_base;
        unsigned long flags;
@@ -983,7 +986,7 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
 #endif
        }
 
-       timer->expires = tim;
+       hrtimer_set_expires_range_ns(timer, tim, delta_ns);
 
        timer_stats_hrtimer_set_start_info(timer);
 
@@ -1016,8 +1019,26 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(hrtimer_start_range_ns);
+
+/**
+ * hrtimer_start - (re)start an hrtimer on the current CPU
+ * @timer:     the timer to be added
+ * @tim:       expiry time
+ * @mode:      expiry mode: absolute (HRTIMER_ABS) or relative (HRTIMER_REL)
+ *
+ * Returns:
+ *  0 on success
+ *  1 when the timer was active
+ */
+int
+hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
+{
+       return hrtimer_start_range_ns(timer, tim, 0, mode);
+}
 EXPORT_SYMBOL_GPL(hrtimer_start);
 
+
 /**
  * hrtimer_try_to_cancel - try to deactivate a timer
  * @timer:     hrtimer to stop
@@ -1077,7 +1098,7 @@ ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
        ktime_t rem;
 
        base = lock_hrtimer_base(timer, &flags);
-       rem = ktime_sub(timer->expires, base->get_time());
+       rem = hrtimer_expires_remaining(timer);
        unlock_hrtimer_base(timer, &flags);
 
        return rem;
@@ -1109,7 +1130,7 @@ ktime_t hrtimer_get_next_event(void)
                                continue;
 
                        timer = rb_entry(base->first, struct hrtimer, node);
-                       delta.tv64 = timer->expires.tv64;
+                       delta.tv64 = hrtimer_get_expires_tv64(timer);
                        delta = ktime_sub(delta, base->get_time());
                        if (delta.tv64 < mindelta.tv64)
                                mindelta.tv64 = delta.tv64;
@@ -1310,10 +1331,23 @@ void hrtimer_interrupt(struct clock_event_device *dev)
 
                        timer = rb_entry(node, struct hrtimer, node);
 
-                       if (basenow.tv64 < timer->expires.tv64) {
+                       /*
+                        * The immediate goal for using the softexpires is
+                        * minimizing wakeups, not running timers at the
+                        * earliest interrupt after their soft expiration.
+                        * This allows us to avoid using a Priority Search
+                        * Tree, which can answer a stabbing querry for
+                        * overlapping intervals and instead use the simple
+                        * BST we already have.
+                        * We don't add extra wakeups by delaying timers that
+                        * are right-of a not yet expired timer, because that
+                        * timer will have to trigger a wakeup anyway.
+                        */
+
+                       if (basenow.tv64 < hrtimer_get_softexpires_tv64(timer)) {
                                ktime_t expires;
 
-                               expires = ktime_sub(timer->expires,
+                               expires = ktime_sub(hrtimer_get_expires(timer),
                                                    base->offset);
                                if (expires.tv64 < expires_next.tv64)
                                        expires_next = expires;
@@ -1349,6 +1383,30 @@ void hrtimer_interrupt(struct clock_event_device *dev)
                raise_softirq(HRTIMER_SOFTIRQ);
 }
 
+/**
+ * hrtimer_peek_ahead_timers -- run soft-expired timers now
+ *
+ * hrtimer_peek_ahead_timers will peek at the timer queue of
+ * the current cpu and check if there are any timers for which
+ * the soft expires time has passed. If any such timers exist,
+ * they are run immediately and then removed from the timer queue.
+ *
+ */
+void hrtimer_peek_ahead_timers(void)
+{
+       struct tick_device *td;
+       unsigned long flags;
+
+       if (!hrtimer_hres_active())
+               return;
+
+       local_irq_save(flags);
+       td = &__get_cpu_var(tick_cpu_device);
+       if (td && td->evtdev)
+               hrtimer_interrupt(td->evtdev);
+       local_irq_restore(flags);
+}
+
 static void run_hrtimer_softirq(struct softirq_action *h)
 {
        run_hrtimer_pending(&__get_cpu_var(hrtimer_bases));
@@ -1403,9 +1461,7 @@ void hrtimer_run_queues(void)
                if (!base->first)
                        continue;
 
-               if (base->get_softirq_time)
-                       base->softirq_time = base->get_softirq_time();
-               else if (gettime) {
+               if (gettime) {
                        hrtimer_get_softirq_time(cpu_base);
                        gettime = 0;
                }
@@ -1416,7 +1472,8 @@ void hrtimer_run_queues(void)
                        struct hrtimer *timer;
 
                        timer = rb_entry(node, struct hrtimer, node);
-                       if (base->softirq_time.tv64 <= timer->expires.tv64)
+                       if (base->softirq_time.tv64 <=
+                                       hrtimer_get_expires_tv64(timer))
                                break;
 
                        if (timer->cb_mode == HRTIMER_CB_SOFTIRQ) {
@@ -1464,7 +1521,7 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod
 
        do {
                set_current_state(TASK_INTERRUPTIBLE);
-               hrtimer_start(&t->timer, t->timer.expires, mode);
+               hrtimer_start_expires(&t->timer, mode);
                if (!hrtimer_active(&t->timer))
                        t->task = NULL;
 
@@ -1486,7 +1543,7 @@ static int update_rmtp(struct hrtimer *timer, struct timespec __user *rmtp)
        struct timespec rmt;
        ktime_t rem;
 
-       rem = ktime_sub(timer->expires, timer->base->get_time());
+       rem = hrtimer_expires_remaining(timer);
        if (rem.tv64 <= 0)
                return 0;
        rmt = ktime_to_timespec(rem);
@@ -1505,7 +1562,7 @@ long __sched hrtimer_nanosleep_restart(struct restart_block *restart)
 
        hrtimer_init_on_stack(&t.timer, restart->nanosleep.index,
                                HRTIMER_MODE_ABS);
-       t.timer.expires.tv64 = restart->nanosleep.expires;
+       hrtimer_set_expires_tv64(&t.timer, restart->nanosleep.expires);
 
        if (do_nanosleep(&t, HRTIMER_MODE_ABS))
                goto out;
@@ -1530,9 +1587,14 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
        struct restart_block *restart;
        struct hrtimer_sleeper t;
        int ret = 0;
+       unsigned long slack;
+
+       slack = current->timer_slack_ns;
+       if (rt_task(current))
+               slack = 0;
 
        hrtimer_init_on_stack(&t.timer, clockid, mode);
-       t.timer.expires = timespec_to_ktime(*rqtp);
+       hrtimer_set_expires_range_ns(&t.timer, timespec_to_ktime(*rqtp), slack);
        if (do_nanosleep(&t, mode))
                goto out;
 
@@ -1552,7 +1614,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
        restart->fn = hrtimer_nanosleep_restart;
        restart->nanosleep.index = t.timer.base->index;
        restart->nanosleep.rmtp = rmtp;
-       restart->nanosleep.expires = t.timer.expires.tv64;
+       restart->nanosleep.expires = hrtimer_get_expires_tv64(&t.timer);
 
        ret = -ERESTART_RESTARTBLOCK;
 out:
@@ -1688,9 +1750,11 @@ static void migrate_hrtimers(int cpu)
        new_base = &get_cpu_var(hrtimer_bases);
 
        tick_cancel_sched_timer(cpu);
-
-       local_irq_disable();
-       spin_lock(&new_base->lock);
+       /*
+        * The caller is globally serialized and nobody else
+        * takes two locks at once, deadlock is not possible.
+        */
+       spin_lock_irq(&new_base->lock);
        spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING);
 
        for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
@@ -1703,8 +1767,7 @@ static void migrate_hrtimers(int cpu)
                raise = 1;
 
        spin_unlock(&old_base->lock);
-       spin_unlock(&new_base->lock);
-       local_irq_enable();
+       spin_unlock_irq(&new_base->lock);
        put_cpu_var(hrtimer_bases);
 
        if (raise)
@@ -1753,3 +1816,103 @@ void __init hrtimers_init(void)
 #endif
 }
 
+/**
+ * schedule_hrtimeout_range - sleep until timeout
+ * @expires:   timeout value (ktime_t)
+ * @delta:     slack in expires timeout (ktime_t)
+ * @mode:      timer mode, HRTIMER_MODE_ABS or HRTIMER_MODE_REL
+ *
+ * Make the current task sleep until the given expiry time has
+ * elapsed. The routine will return immediately unless
+ * the current task state has been set (see set_current_state()).
+ *
+ * The @delta argument gives the kernel the freedom to schedule the
+ * actual wakeup to a time that is both power and performance friendly.
+ * The kernel give the normal best effort behavior for "@expires+@delta",
+ * but may decide to fire the timer earlier, but no earlier than @expires.
+ *
+ * You can set the task state as follows -
+ *
+ * %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to
+ * pass before the routine returns.
+ *
+ * %TASK_INTERRUPTIBLE - the routine may return early if a signal is
+ * delivered to the current task.
+ *
+ * The current task state is guaranteed to be TASK_RUNNING when this
+ * routine returns.
+ *
+ * Returns 0 when the timer has expired otherwise -EINTR
+ */
+int __sched schedule_hrtimeout_range(ktime_t *expires, unsigned long delta,
+                              const enum hrtimer_mode mode)
+{
+       struct hrtimer_sleeper t;
+
+       /*
+        * Optimize when a zero timeout value is given. It does not
+        * matter whether this is an absolute or a relative time.
+        */
+       if (expires && !expires->tv64) {
+               __set_current_state(TASK_RUNNING);
+               return 0;
+       }
+
+       /*
+        * A NULL parameter means "inifinte"
+        */
+       if (!expires) {
+               schedule();
+               __set_current_state(TASK_RUNNING);
+               return -EINTR;
+       }
+
+       hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, mode);
+       hrtimer_set_expires_range_ns(&t.timer, *expires, delta);
+
+       hrtimer_init_sleeper(&t, current);
+
+       hrtimer_start_expires(&t.timer, mode);
+       if (!hrtimer_active(&t.timer))
+               t.task = NULL;
+
+       if (likely(t.task))
+               schedule();
+
+       hrtimer_cancel(&t.timer);
+       destroy_hrtimer_on_stack(&t.timer);
+
+       __set_current_state(TASK_RUNNING);
+
+       return !t.task ? 0 : -EINTR;
+}
+EXPORT_SYMBOL_GPL(schedule_hrtimeout_range);
+
+/**
+ * schedule_hrtimeout - sleep until timeout
+ * @expires:   timeout value (ktime_t)
+ * @mode:      timer mode, HRTIMER_MODE_ABS or HRTIMER_MODE_REL
+ *
+ * Make the current task sleep until the given expiry time has
+ * elapsed. The routine will return immediately unless
+ * the current task state has been set (see set_current_state()).
+ *
+ * You can set the task state as follows -
+ *
+ * %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to
+ * pass before the routine returns.
+ *
+ * %TASK_INTERRUPTIBLE - the routine may return early if a signal is
+ * delivered to the current task.
+ *
+ * The current task state is guaranteed to be TASK_RUNNING when this
+ * routine returns.
+ *
+ * Returns 0 when the timer has expired otherwise -EINTR
+ */
+int __sched schedule_hrtimeout(ktime_t *expires,
+                              const enum hrtimer_mode mode)
+{
+       return schedule_hrtimeout_range(expires, 0, mode);
+}
+EXPORT_SYMBOL_GPL(schedule_hrtimeout);
index 533068cfb607fad10202210b916909efd314cbb7..cc0f7321b8cede4192a4ceb9ffc97311ec9cc7d0 100644 (file)
@@ -30,17 +30,16 @@ static DEFINE_MUTEX(probing_active);
 unsigned long probe_irq_on(void)
 {
        struct irq_desc *desc;
-       unsigned long mask;
-       unsigned int i;
+       unsigned long mask = 0;
+       unsigned int status;
+       int i;
 
        mutex_lock(&probing_active);
        /*
         * something may have generated an irq long ago and we want to
         * flush such a longstanding irq before considering it as spurious.
         */
-       for (i = NR_IRQS-1; i > 0; i--) {
-               desc = irq_desc + i;
-
+       for_each_irq_desc_reverse(i, desc) {
                spin_lock_irq(&desc->lock);
                if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
                        /*
@@ -68,9 +67,7 @@ unsigned long probe_irq_on(void)
         * (we must startup again here because if a longstanding irq
         * happened in the previous stage, it may have masked itself)
         */
-       for (i = NR_IRQS-1; i > 0; i--) {
-               desc = irq_desc + i;
-
+       for_each_irq_desc_reverse(i, desc) {
                spin_lock_irq(&desc->lock);
                if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
                        desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
@@ -88,11 +85,7 @@ unsigned long probe_irq_on(void)
        /*
         * Now filter out any obviously spurious interrupts
         */
-       mask = 0;
-       for (i = 0; i < NR_IRQS; i++) {
-               unsigned int status;
-
-               desc = irq_desc + i;
+       for_each_irq_desc(i, desc) {
                spin_lock_irq(&desc->lock);
                status = desc->status;
 
@@ -126,14 +119,11 @@ EXPORT_SYMBOL(probe_irq_on);
  */
 unsigned int probe_irq_mask(unsigned long val)
 {
-       unsigned int mask;
+       unsigned int status, mask = 0;
+       struct irq_desc *desc;
        int i;
 
-       mask = 0;
-       for (i = 0; i < NR_IRQS; i++) {
-               struct irq_desc *desc = irq_desc + i;
-               unsigned int status;
-
+       for_each_irq_desc(i, desc) {
                spin_lock_irq(&desc->lock);
                status = desc->status;
 
@@ -171,20 +161,19 @@ EXPORT_SYMBOL(probe_irq_mask);
  */
 int probe_irq_off(unsigned long val)
 {
-       int i, irq_found = 0, nr_irqs = 0;
-
-       for (i = 0; i < NR_IRQS; i++) {
-               struct irq_desc *desc = irq_desc + i;
-               unsigned int status;
+       int i, irq_found = 0, nr_of_irqs = 0;
+       struct irq_desc *desc;
+       unsigned int status;
 
+       for_each_irq_desc(i, desc) {
                spin_lock_irq(&desc->lock);
                status = desc->status;
 
                if (status & IRQ_AUTODETECT) {
                        if (!(status & IRQ_WAITING)) {
-                               if (!nr_irqs)
+                               if (!nr_of_irqs)
                                        irq_found = i;
-                               nr_irqs++;
+                               nr_of_irqs++;
                        }
                        desc->status = status & ~IRQ_AUTODETECT;
                        desc->chip->shutdown(i);
@@ -193,7 +182,7 @@ int probe_irq_off(unsigned long val)
        }
        mutex_unlock(&probing_active);
 
-       if (nr_irqs > 1)
+       if (nr_of_irqs > 1)
                irq_found = -irq_found;
 
        return irq_found;
index 3cd441ebf5d2178fcd2d9bdd49573706d6c78b51..10b5092e9bfe749da57b2ab408e3f6d38ae81d75 100644 (file)
  */
 void dynamic_irq_init(unsigned int irq)
 {
-       struct irq_desc *desc;
+       struct irq_desc *desc = irq_to_desc(irq);
        unsigned long flags;
 
-       if (irq >= NR_IRQS) {
+       if (!desc) {
                WARN(1, KERN_ERR "Trying to initialize invalid IRQ%d\n", irq);
                return;
        }
 
        /* Ensure we don't have left over values from a previous use of this irq */
-       desc = irq_desc + irq;
        spin_lock_irqsave(&desc->lock, flags);
        desc->status = IRQ_DISABLED;
        desc->chip = &no_irq_chip;
@@ -57,15 +56,14 @@ void dynamic_irq_init(unsigned int irq)
  */
 void dynamic_irq_cleanup(unsigned int irq)
 {
-       struct irq_desc *desc;
+       struct irq_desc *desc = irq_to_desc(irq);
        unsigned long flags;
 
-       if (irq >= NR_IRQS) {
+       if (!desc) {
                WARN(1, KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq);
                return;
        }
 
-       desc = irq_desc + irq;
        spin_lock_irqsave(&desc->lock, flags);
        if (desc->action) {
                spin_unlock_irqrestore(&desc->lock, flags);
@@ -78,6 +76,7 @@ void dynamic_irq_cleanup(unsigned int irq)
        desc->chip_data = NULL;
        desc->handle_irq = handle_bad_irq;
        desc->chip = &no_irq_chip;
+       desc->name = NULL;
        spin_unlock_irqrestore(&desc->lock, flags);
 }
 
@@ -89,10 +88,10 @@ void dynamic_irq_cleanup(unsigned int irq)
  */
 int set_irq_chip(unsigned int irq, struct irq_chip *chip)
 {
-       struct irq_desc *desc;
+       struct irq_desc *desc = irq_to_desc(irq);
        unsigned long flags;
 
-       if (irq >= NR_IRQS) {
+       if (!desc) {
                WARN(1, KERN_ERR "Trying to install chip for IRQ%d\n", irq);
                return -EINVAL;
        }
@@ -100,7 +99,6 @@ int set_irq_chip(unsigned int irq, struct irq_chip *chip)
        if (!chip)
                chip = &no_irq_chip;
 
-       desc = irq_desc + irq;
        spin_lock_irqsave(&desc->lock, flags);
        irq_chip_set_defaults(chip);
        desc->chip = chip;
@@ -111,27 +109,27 @@ int set_irq_chip(unsigned int irq, struct irq_chip *chip)
 EXPORT_SYMBOL(set_irq_chip);
 
 /**
- *     set_irq_type - set the irq type for an irq
+ *     set_irq_type - set the irq trigger type for an irq
  *     @irq:   irq number
- *     @type:  interrupt type - see include/linux/interrupt.h
+ *     @type:  IRQ_TYPE_{LEVEL,EDGE}_* value - see include/linux/irq.h
  */
 int set_irq_type(unsigned int irq, unsigned int type)
 {
-       struct irq_desc *desc;
+       struct irq_desc *desc = irq_to_desc(irq);
        unsigned long flags;
        int ret = -ENXIO;
 
-       if (irq >= NR_IRQS) {
+       if (!desc) {
                printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq);
                return -ENODEV;
        }
 
-       desc = irq_desc + irq;
-       if (desc->chip->set_type) {
-               spin_lock_irqsave(&desc->lock, flags);
-               ret = desc->chip->set_type(irq, type);
-               spin_unlock_irqrestore(&desc->lock, flags);
-       }
+       if (type == IRQ_TYPE_NONE)
+               return 0;
+
+       spin_lock_irqsave(&desc->lock, flags);
+       ret = __irq_set_trigger(desc, irq, type);
+       spin_unlock_irqrestore(&desc->lock, flags);
        return ret;
 }
 EXPORT_SYMBOL(set_irq_type);
@@ -145,16 +143,15 @@ EXPORT_SYMBOL(set_irq_type);
  */
 int set_irq_data(unsigned int irq, void *data)
 {
-       struct irq_desc *desc;
+       struct irq_desc *desc = irq_to_desc(irq);
        unsigned long flags;
 
-       if (irq >= NR_IRQS) {
+       if (!desc) {
                printk(KERN_ERR
                       "Trying to install controller data for IRQ%d\n", irq);
                return -EINVAL;
        }
 
-       desc = irq_desc + irq;
        spin_lock_irqsave(&desc->lock, flags);
        desc->handler_data = data;
        spin_unlock_irqrestore(&desc->lock, flags);
@@ -171,15 +168,15 @@ EXPORT_SYMBOL(set_irq_data);
  */
 int set_irq_msi(unsigned int irq, struct msi_desc *entry)
 {
-       struct irq_desc *desc;
+       struct irq_desc *desc = irq_to_desc(irq);
        unsigned long flags;
 
-       if (irq >= NR_IRQS) {
+       if (!desc) {
                printk(KERN_ERR
                       "Trying to install msi data for IRQ%d\n", irq);
                return -EINVAL;
        }
-       desc = irq_desc + irq;
+
        spin_lock_irqsave(&desc->lock, flags);
        desc->msi_desc = entry;
        if (entry)
@@ -197,10 +194,16 @@ int set_irq_msi(unsigned int irq, struct msi_desc *entry)
  */
 int set_irq_chip_data(unsigned int irq, void *data)
 {
-       struct irq_desc *desc = irq_desc + irq;
+       struct irq_desc *desc = irq_to_desc(irq);
        unsigned long flags;
 
-       if (irq >= NR_IRQS || !desc->chip) {
+       if (!desc) {
+               printk(KERN_ERR
+                      "Trying to install chip data for IRQ%d\n", irq);
+               return -EINVAL;
+       }
+
+       if (!desc->chip) {
                printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", irq);
                return -EINVAL;
        }
@@ -218,7 +221,7 @@ EXPORT_SYMBOL(set_irq_chip_data);
  */
 static void default_enable(unsigned int irq)
 {
-       struct irq_desc *desc = irq_desc + irq;
+       struct irq_desc *desc = irq_to_desc(irq);
 
        desc->chip->unmask(irq);
        desc->status &= ~IRQ_MASKED;
@@ -236,8 +239,9 @@ static void default_disable(unsigned int irq)
  */
 static unsigned int default_startup(unsigned int irq)
 {
-       irq_desc[irq].chip->enable(irq);
+       struct irq_desc *desc = irq_to_desc(irq);
 
+       desc->chip->enable(irq);
        return 0;
 }
 
@@ -246,7 +250,7 @@ static unsigned int default_startup(unsigned int irq)
  */
 static void default_shutdown(unsigned int irq)
 {
-       struct irq_desc *desc = irq_desc + irq;
+       struct irq_desc *desc = irq_to_desc(irq);
 
        desc->chip->mask(irq);
        desc->status |= IRQ_MASKED;
@@ -305,14 +309,13 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc)
 {
        struct irqaction *action;
        irqreturn_t action_ret;
-       const unsigned int cpu = smp_processor_id();
 
        spin_lock(&desc->lock);
 
        if (unlikely(desc->status & IRQ_INPROGRESS))
                goto out_unlock;
        desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
-       kstat_cpu(cpu).irqs[irq]++;
+       kstat_incr_irqs_this_cpu(irq, desc);
 
        action = desc->action;
        if (unlikely(!action || (desc->status & IRQ_DISABLED)))
@@ -344,7 +347,6 @@ out_unlock:
 void
 handle_level_irq(unsigned int irq, struct irq_desc *desc)
 {
-       unsigned int cpu = smp_processor_id();
        struct irqaction *action;
        irqreturn_t action_ret;
 
@@ -354,7 +356,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
        if (unlikely(desc->status & IRQ_INPROGRESS))
                goto out_unlock;
        desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
-       kstat_cpu(cpu).irqs[irq]++;
+       kstat_incr_irqs_this_cpu(irq, desc);
 
        /*
         * If its disabled or no action available
@@ -392,7 +394,6 @@ out_unlock:
 void
 handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
 {
-       unsigned int cpu = smp_processor_id();
        struct irqaction *action;
        irqreturn_t action_ret;
 
@@ -402,7 +403,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
                goto out;
 
        desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
-       kstat_cpu(cpu).irqs[irq]++;
+       kstat_incr_irqs_this_cpu(irq, desc);
 
        /*
         * If its disabled or no action available
@@ -451,8 +452,6 @@ out:
 void
 handle_edge_irq(unsigned int irq, struct irq_desc *desc)
 {
-       const unsigned int cpu = smp_processor_id();
-
        spin_lock(&desc->lock);
 
        desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
@@ -468,8 +467,7 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
                mask_ack_irq(desc, irq);
                goto out_unlock;
        }
-
-       kstat_cpu(cpu).irqs[irq]++;
+       kstat_incr_irqs_this_cpu(irq, desc);
 
        /* Start handling the irq */
        desc->chip->ack(irq);
@@ -524,7 +522,7 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc)
 {
        irqreturn_t action_ret;
 
-       kstat_this_cpu.irqs[irq]++;
+       kstat_incr_irqs_this_cpu(irq, desc);
 
        if (desc->chip->ack)
                desc->chip->ack(irq);
@@ -541,17 +539,15 @@ void
 __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
                  const char *name)
 {
-       struct irq_desc *desc;
+       struct irq_desc *desc = irq_to_desc(irq);
        unsigned long flags;
 
-       if (irq >= NR_IRQS) {
+       if (!desc) {
                printk(KERN_ERR
                       "Trying to install type control for IRQ%d\n", irq);
                return;
        }
 
-       desc = irq_desc + irq;
-
        if (!handle)
                handle = handle_bad_irq;
        else if (desc->chip == &no_irq_chip) {
@@ -583,7 +579,7 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
                desc->status &= ~IRQ_DISABLED;
                desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE;
                desc->depth = 0;
-               desc->chip->unmask(irq);
+               desc->chip->startup(irq);
        }
        spin_unlock_irqrestore(&desc->lock, flags);
 }
@@ -606,17 +602,14 @@ set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
 
 void __init set_irq_noprobe(unsigned int irq)
 {
-       struct irq_desc *desc;
+       struct irq_desc *desc = irq_to_desc(irq);
        unsigned long flags;
 
-       if (irq >= NR_IRQS) {
+       if (!desc) {
                printk(KERN_ERR "Trying to mark IRQ%d non-probeable\n", irq);
-
                return;
        }
 
-       desc = irq_desc + irq;
-
        spin_lock_irqsave(&desc->lock, flags);
        desc->status |= IRQ_NOPROBE;
        spin_unlock_irqrestore(&desc->lock, flags);
@@ -624,17 +617,14 @@ void __init set_irq_noprobe(unsigned int irq)
 
 void __init set_irq_probe(unsigned int irq)
 {
-       struct irq_desc *desc;
+       struct irq_desc *desc = irq_to_desc(irq);
        unsigned long flags;
 
-       if (irq >= NR_IRQS) {
+       if (!desc) {
                printk(KERN_ERR "Trying to mark IRQ%d probeable\n", irq);
-
                return;
        }
 
-       desc = irq_desc + irq;
-
        spin_lock_irqsave(&desc->lock, flags);
        desc->status &= ~IRQ_NOPROBE;
        spin_unlock_irqrestore(&desc->lock, flags);
index 5fa6198e91394a935bcb8f51d70cdef9222c261f..c815b42d0f5bf12baed5e25eb92c7f2d5e4b4472 100644 (file)
  *
  * Handles spurious and unhandled IRQ's. It also prints a debugmessage.
  */
-void
-handle_bad_irq(unsigned int irq, struct irq_desc *desc)
+void handle_bad_irq(unsigned int irq, struct irq_desc *desc)
 {
        print_irq_desc(irq, desc);
-       kstat_this_cpu.irqs[irq]++;
+       kstat_incr_irqs_this_cpu(irq, desc);
        ack_bad_irq(irq);
 }
 
@@ -47,6 +46,9 @@ handle_bad_irq(unsigned int irq, struct irq_desc *desc)
  *
  * Controller mappings for all interrupt sources:
  */
+int nr_irqs = NR_IRQS;
+EXPORT_SYMBOL_GPL(nr_irqs);
+
 struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
        [0 ... NR_IRQS-1] = {
                .status = IRQ_DISABLED,
@@ -66,7 +68,9 @@ struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
  */
 static void ack_bad(unsigned int irq)
 {
-       print_irq_desc(irq, irq_desc + irq);
+       struct irq_desc *desc = irq_to_desc(irq);
+
+       print_irq_desc(irq, desc);
        ack_bad_irq(irq);
 }
 
@@ -131,8 +135,6 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
        irqreturn_t ret, retval = IRQ_NONE;
        unsigned int status = 0;
 
-       handle_dynamic_tick(action);
-
        if (!(action->flags & IRQF_DISABLED))
                local_irq_enable_in_hardirq();
 
@@ -165,11 +167,12 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
  */
 unsigned int __do_IRQ(unsigned int irq)
 {
-       struct irq_desc *desc = irq_desc + irq;
+       struct irq_desc *desc = irq_to_desc(irq);
        struct irqaction *action;
        unsigned int status;
 
-       kstat_this_cpu.irqs[irq]++;
+       kstat_incr_irqs_this_cpu(irq, desc);
+
        if (CHECK_IRQ_PER_CPU(desc->status)) {
                irqreturn_t action_ret;
 
@@ -256,8 +259,8 @@ out:
 }
 #endif
 
-#ifdef CONFIG_TRACE_IRQFLAGS
 
+#ifdef CONFIG_TRACE_IRQFLAGS
 /*
  * lockdep: we want to handle all irq_desc locks as a single lock-class:
  */
@@ -265,10 +268,10 @@ static struct lock_class_key irq_desc_lock_class;
 
 void early_init_irq_lock_class(void)
 {
+       struct irq_desc *desc;
        int i;
 
-       for (i = 0; i < NR_IRQS; i++)
-               lockdep_set_class(&irq_desc[i].lock, &irq_desc_lock_class);
+       for_each_irq_desc(i, desc)
+               lockdep_set_class(&desc->lock, &irq_desc_lock_class);
 }
-
 #endif
index 08a849a224475102084ca807de6861b6ab7286b5..c9767e641980e1b2ae91454fe723088ad9cc5f83 100644 (file)
@@ -10,12 +10,15 @@ extern void irq_chip_set_defaults(struct irq_chip *chip);
 /* Set default handler: */
 extern void compat_irq_chip_set_default_handler(struct irq_desc *desc);
 
+extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
+               unsigned long flags);
+
 #ifdef CONFIG_PROC_FS
-extern void register_irq_proc(unsigned int irq);
+extern void register_irq_proc(unsigned int irq, struct irq_desc *desc);
 extern void register_handler_proc(unsigned int irq, struct irqaction *action);
 extern void unregister_handler_proc(unsigned int irq, struct irqaction *action);
 #else
-static inline void register_irq_proc(unsigned int irq) { }
+static inline void register_irq_proc(unsigned int irq, struct irq_desc *desc) { }
 static inline void register_handler_proc(unsigned int irq,
                                         struct irqaction *action) { }
 static inline void unregister_handler_proc(unsigned int irq,
index 60c49e324390bca07f9109fc2bb09d0ecf18f5c6..c498a1b8c621e02894974b7f0e0cda8e96d81011 100644 (file)
@@ -31,10 +31,10 @@ cpumask_t irq_default_affinity = CPU_MASK_ALL;
  */
 void synchronize_irq(unsigned int irq)
 {
-       struct irq_desc *desc = irq_desc + irq;
+       struct irq_desc *desc = irq_to_desc(irq);
        unsigned int status;
 
-       if (irq >= NR_IRQS)
+       if (!desc)
                return;
 
        do {
@@ -64,7 +64,7 @@ EXPORT_SYMBOL(synchronize_irq);
  */
 int irq_can_set_affinity(unsigned int irq)
 {
-       struct irq_desc *desc = irq_desc + irq;
+       struct irq_desc *desc = irq_to_desc(irq);
 
        if (CHECK_IRQ_PER_CPU(desc->status) || !desc->chip ||
            !desc->chip->set_affinity)
@@ -81,18 +81,17 @@ int irq_can_set_affinity(unsigned int irq)
  */
 int irq_set_affinity(unsigned int irq, cpumask_t cpumask)
 {
-       struct irq_desc *desc = irq_desc + irq;
+       struct irq_desc *desc = irq_to_desc(irq);
 
        if (!desc->chip->set_affinity)
                return -EINVAL;
 
-       set_balance_irq_affinity(irq, cpumask);
-
 #ifdef CONFIG_GENERIC_PENDING_IRQ
-       if (desc->status & IRQ_MOVE_PCNTXT) {
+       if (desc->status & IRQ_MOVE_PCNTXT || desc->status & IRQ_DISABLED) {
                unsigned long flags;
 
                spin_lock_irqsave(&desc->lock, flags);
+               desc->affinity = cpumask;
                desc->chip->set_affinity(irq, cpumask);
                spin_unlock_irqrestore(&desc->lock, flags);
        } else
@@ -111,16 +110,17 @@ int irq_set_affinity(unsigned int irq, cpumask_t cpumask)
 int irq_select_affinity(unsigned int irq)
 {
        cpumask_t mask;
+       struct irq_desc *desc;
 
        if (!irq_can_set_affinity(irq))
                return 0;
 
        cpus_and(mask, cpu_online_map, irq_default_affinity);
 
-       irq_desc[irq].affinity = mask;
-       irq_desc[irq].chip->set_affinity(irq, mask);
+       desc = irq_to_desc(irq);
+       desc->affinity = mask;
+       desc->chip->set_affinity(irq, mask);
 
-       set_balance_irq_affinity(irq, mask);
        return 0;
 }
 #endif
@@ -140,10 +140,10 @@ int irq_select_affinity(unsigned int irq)
  */
 void disable_irq_nosync(unsigned int irq)
 {
-       struct irq_desc *desc = irq_desc + irq;
+       struct irq_desc *desc = irq_to_desc(irq);
        unsigned long flags;
 
-       if (irq >= NR_IRQS)
+       if (!desc)
                return;
 
        spin_lock_irqsave(&desc->lock, flags);
@@ -169,9 +169,9 @@ EXPORT_SYMBOL(disable_irq_nosync);
  */
 void disable_irq(unsigned int irq)
 {
-       struct irq_desc *desc = irq_desc + irq;
+       struct irq_desc *desc = irq_to_desc(irq);
 
-       if (irq >= NR_IRQS)
+       if (!desc)
                return;
 
        disable_irq_nosync(irq);
@@ -211,10 +211,10 @@ static void __enable_irq(struct irq_desc *desc, unsigned int irq)
  */
 void enable_irq(unsigned int irq)
 {
-       struct irq_desc *desc = irq_desc + irq;
+       struct irq_desc *desc = irq_to_desc(irq);
        unsigned long flags;
 
-       if (irq >= NR_IRQS)
+       if (!desc)
                return;
 
        spin_lock_irqsave(&desc->lock, flags);
@@ -223,9 +223,9 @@ void enable_irq(unsigned int irq)
 }
 EXPORT_SYMBOL(enable_irq);
 
-int set_irq_wake_real(unsigned int irq, unsigned int on)
+static int set_irq_wake_real(unsigned int irq, unsigned int on)
 {
-       struct irq_desc *desc = irq_desc + irq;
+       struct irq_desc *desc = irq_to_desc(irq);
        int ret = -ENXIO;
 
        if (desc->chip->set_wake)
@@ -248,7 +248,7 @@ int set_irq_wake_real(unsigned int irq, unsigned int on)
  */
 int set_irq_wake(unsigned int irq, unsigned int on)
 {
-       struct irq_desc *desc = irq_desc + irq;
+       struct irq_desc *desc = irq_to_desc(irq);
        unsigned long flags;
        int ret = 0;
 
@@ -288,12 +288,16 @@ EXPORT_SYMBOL(set_irq_wake);
  */
 int can_request_irq(unsigned int irq, unsigned long irqflags)
 {
+       struct irq_desc *desc = irq_to_desc(irq);
        struct irqaction *action;
 
-       if (irq >= NR_IRQS || irq_desc[irq].status & IRQ_NOREQUEST)
+       if (!desc)
+               return 0;
+
+       if (desc->status & IRQ_NOREQUEST)
                return 0;
 
-       action = irq_desc[irq].action;
+       action = desc->action;
        if (action)
                if (irqflags & action->flags & IRQF_SHARED)
                        action = NULL;
@@ -312,10 +316,11 @@ void compat_irq_chip_set_default_handler(struct irq_desc *desc)
                desc->handle_irq = NULL;
 }
 
-static int __irq_set_trigger(struct irq_chip *chip, unsigned int irq,
+int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
                unsigned long flags)
 {
        int ret;
+       struct irq_chip *chip = desc->chip;
 
        if (!chip || !chip->set_type) {
                /*
@@ -333,6 +338,11 @@ static int __irq_set_trigger(struct irq_chip *chip, unsigned int irq,
                pr_err("setting trigger mode %d for irq %u failed (%pF)\n",
                                (int)(flags & IRQF_TRIGGER_MASK),
                                irq, chip->set_type);
+       else {
+               /* note that IRQF_TRIGGER_MASK == IRQ_TYPE_SENSE_MASK */
+               desc->status &= ~IRQ_TYPE_SENSE_MASK;
+               desc->status |= flags & IRQ_TYPE_SENSE_MASK;
+       }
 
        return ret;
 }
@@ -341,16 +351,16 @@ static int __irq_set_trigger(struct irq_chip *chip, unsigned int irq,
  * Internal function to register an irqaction - typically used to
  * allocate special interrupts that are part of the architecture.
  */
-int setup_irq(unsigned int irq, struct irqaction *new)
+static int
+__setup_irq(unsigned int irq, struct irq_desc * desc, struct irqaction *new)
 {
-       struct irq_desc *desc = irq_desc + irq;
        struct irqaction *old, **p;
        const char *old_name = NULL;
        unsigned long flags;
        int shared = 0;
        int ret;
 
-       if (irq >= NR_IRQS)
+       if (!desc)
                return -EINVAL;
 
        if (desc->chip == &no_irq_chip)
@@ -411,7 +421,7 @@ int setup_irq(unsigned int irq, struct irqaction *new)
 
                /* Setup the type (level, edge polarity) if configured: */
                if (new->flags & IRQF_TRIGGER_MASK) {
-                       ret = __irq_set_trigger(desc->chip, irq, new->flags);
+                       ret = __irq_set_trigger(desc, irq, new->flags);
 
                        if (ret) {
                                spin_unlock_irqrestore(&desc->lock, flags);
@@ -430,16 +440,21 @@ int setup_irq(unsigned int irq, struct irqaction *new)
                if (!(desc->status & IRQ_NOAUTOEN)) {
                        desc->depth = 0;
                        desc->status &= ~IRQ_DISABLED;
-                       if (desc->chip->startup)
-                               desc->chip->startup(irq);
-                       else
-                               desc->chip->enable(irq);
+                       desc->chip->startup(irq);
                } else
                        /* Undo nested disables: */
                        desc->depth = 1;
 
                /* Set default affinity mask once everything is setup */
                irq_select_affinity(irq);
+
+       } else if ((new->flags & IRQF_TRIGGER_MASK)
+                       && (new->flags & IRQF_TRIGGER_MASK)
+                               != (desc->status & IRQ_TYPE_SENSE_MASK)) {
+               /* hope the handler works with the actual trigger mode... */
+               pr_warning("IRQ %d uses trigger mode %d; requested %d\n",
+                               irq, (int)(desc->status & IRQ_TYPE_SENSE_MASK),
+                               (int)(new->flags & IRQF_TRIGGER_MASK));
        }
 
        *p = new;
@@ -464,7 +479,7 @@ int setup_irq(unsigned int irq, struct irqaction *new)
        spin_unlock_irqrestore(&desc->lock, flags);
 
        new->irq = irq;
-       register_irq_proc(irq);
+       register_irq_proc(irq, desc);
        new->dir = NULL;
        register_handler_proc(irq, new);
 
@@ -483,6 +498,20 @@ mismatch:
        return -EBUSY;
 }
 
+/**
+ *     setup_irq - setup an interrupt
+ *     @irq: Interrupt line to setup
+ *     @act: irqaction for the interrupt
+ *
+ * Used to statically setup interrupts in the early boot process.
+ */
+int setup_irq(unsigned int irq, struct irqaction *act)
+{
+       struct irq_desc *desc = irq_to_desc(irq);
+
+       return __setup_irq(irq, desc, act);
+}
+
 /**
  *     free_irq - free an interrupt
  *     @irq: Interrupt line to free
@@ -499,15 +528,15 @@ mismatch:
  */
 void free_irq(unsigned int irq, void *dev_id)
 {
-       struct irq_desc *desc;
+       struct irq_desc *desc = irq_to_desc(irq);
        struct irqaction **p;
        unsigned long flags;
 
        WARN_ON(in_interrupt());
-       if (irq >= NR_IRQS)
+
+       if (!desc)
                return;
 
-       desc = irq_desc + irq;
        spin_lock_irqsave(&desc->lock, flags);
        p = &desc->action;
        for (;;) {
@@ -596,12 +625,14 @@ EXPORT_SYMBOL(free_irq);
  *     IRQF_SHARED             Interrupt is shared
  *     IRQF_DISABLED   Disable local interrupts while processing
  *     IRQF_SAMPLE_RANDOM      The interrupt can be used for entropy
+ *     IRQF_TRIGGER_*          Specify active edge(s) or level
  *
  */
 int request_irq(unsigned int irq, irq_handler_t handler,
                unsigned long irqflags, const char *devname, void *dev_id)
 {
        struct irqaction *action;
+       struct irq_desc *desc;
        int retval;
 
 #ifdef CONFIG_LOCKDEP
@@ -618,9 +649,12 @@ int request_irq(unsigned int irq, irq_handler_t handler,
         */
        if ((irqflags & IRQF_SHARED) && !dev_id)
                return -EINVAL;
-       if (irq >= NR_IRQS)
+
+       desc = irq_to_desc(irq);
+       if (!desc)
                return -EINVAL;
-       if (irq_desc[irq].status & IRQ_NOREQUEST)
+
+       if (desc->status & IRQ_NOREQUEST)
                return -EINVAL;
        if (!handler)
                return -EINVAL;
@@ -636,26 +670,29 @@ int request_irq(unsigned int irq, irq_handler_t handler,
        action->next = NULL;
        action->dev_id = dev_id;
 
+       retval = __setup_irq(irq, desc, action);
+       if (retval)
+               kfree(action);
+
 #ifdef CONFIG_DEBUG_SHIRQ
        if (irqflags & IRQF_SHARED) {
                /*
                 * It's a shared IRQ -- the driver ought to be prepared for it
                 * to happen immediately, so let's make sure....
-                * We do this before actually registering it, to make sure that
-                * a 'real' IRQ doesn't run in parallel with our fake
+                * We disable the irq to make sure that a 'real' IRQ doesn't
+                * run in parallel with our fake.
                 */
                unsigned long flags;
 
+               disable_irq(irq);
                local_irq_save(flags);
+
                handler(irq, dev_id);
+
                local_irq_restore(flags);
+               enable_irq(irq);
        }
 #endif
-
-       retval = setup_irq(irq, action);
-       if (retval)
-               kfree(action);
-
        return retval;
 }
 EXPORT_SYMBOL(request_irq);
index 77b7acc875c5df6755954161736b72918fff49ad..90b920d3f52b3ca29f69cc204ab2481f4d95d4f6 100644 (file)
@@ -3,18 +3,18 @@
 
 void set_pending_irq(unsigned int irq, cpumask_t mask)
 {
-       struct irq_desc *desc = irq_desc + irq;
+       struct irq_desc *desc = irq_to_desc(irq);
        unsigned long flags;
 
        spin_lock_irqsave(&desc->lock, flags);
        desc->status |= IRQ_MOVE_PENDING;
-       irq_desc[irq].pending_mask = mask;
+       desc->pending_mask = mask;
        spin_unlock_irqrestore(&desc->lock, flags);
 }
 
 void move_masked_irq(int irq)
 {
-       struct irq_desc *desc = irq_desc + irq;
+       struct irq_desc *desc = irq_to_desc(irq);
        cpumask_t tmp;
 
        if (likely(!(desc->status & IRQ_MOVE_PENDING)))
@@ -30,7 +30,7 @@ void move_masked_irq(int irq)
 
        desc->status &= ~IRQ_MOVE_PENDING;
 
-       if (unlikely(cpus_empty(irq_desc[irq].pending_mask)))
+       if (unlikely(cpus_empty(desc->pending_mask)))
                return;
 
        if (!desc->chip->set_affinity)
@@ -38,7 +38,7 @@ void move_masked_irq(int irq)
 
        assert_spin_locked(&desc->lock);
 
-       cpus_and(tmp, irq_desc[irq].pending_mask, cpu_online_map);
+       cpus_and(tmp, desc->pending_mask, cpu_online_map);
 
        /*
         * If there was a valid mask to work with, please
@@ -55,12 +55,12 @@ void move_masked_irq(int irq)
        if (likely(!cpus_empty(tmp))) {
                desc->chip->set_affinity(irq,tmp);
        }
-       cpus_clear(irq_desc[irq].pending_mask);
+       cpus_clear(desc->pending_mask);
 }
 
 void move_native_irq(int irq)
 {
-       struct irq_desc *desc = irq_desc + irq;
+       struct irq_desc *desc = irq_to_desc(irq);
 
        if (likely(!(desc->status & IRQ_MOVE_PENDING)))
                return;
index a09dd29c2fd748dea1dd83fd00b73751aa649316..fac014a81b244f232409e5c717a2e1c76f7ac1ba 100644 (file)
@@ -19,7 +19,7 @@ static struct proc_dir_entry *root_irq_dir;
 
 static int irq_affinity_proc_show(struct seq_file *m, void *v)
 {
-       struct irq_desc *desc = irq_desc + (long)m->private;
+       struct irq_desc *desc = irq_to_desc((long)m->private);
        cpumask_t *mask = &desc->affinity;
 
 #ifdef CONFIG_GENERIC_PENDING_IRQ
@@ -43,7 +43,7 @@ static ssize_t irq_affinity_proc_write(struct file *file,
        cpumask_t new_value;
        int err;
 
-       if (!irq_desc[irq].chip->set_affinity || no_irq_affinity ||
+       if (!irq_to_desc(irq)->chip->set_affinity || no_irq_affinity ||
            irq_balancing_disabled(irq))
                return -EIO;
 
@@ -132,20 +132,20 @@ static const struct file_operations default_affinity_proc_fops = {
 static int irq_spurious_read(char *page, char **start, off_t off,
                                  int count, int *eof, void *data)
 {
-       struct irq_desc *d = &irq_desc[(long) data];
+       struct irq_desc *desc = irq_to_desc((long) data);
        return sprintf(page, "count %u\n"
                             "unhandled %u\n"
                             "last_unhandled %u ms\n",
-                       d->irq_count,
-                       d->irqs_unhandled,
-                       jiffies_to_msecs(d->last_unhandled));
+                       desc->irq_count,
+                       desc->irqs_unhandled,
+                       jiffies_to_msecs(desc->last_unhandled));
 }
 
 #define MAX_NAMELEN 128
 
 static int name_unique(unsigned int irq, struct irqaction *new_action)
 {
-       struct irq_desc *desc = irq_desc + irq;
+       struct irq_desc *desc = irq_to_desc(irq);
        struct irqaction *action;
        unsigned long flags;
        int ret = 1;
@@ -165,8 +165,9 @@ static int name_unique(unsigned int irq, struct irqaction *new_action)
 void register_handler_proc(unsigned int irq, struct irqaction *action)
 {
        char name [MAX_NAMELEN];
+       struct irq_desc *desc = irq_to_desc(irq);
 
-       if (!irq_desc[irq].dir || action->dir || !action->name ||
+       if (!desc->dir || action->dir || !action->name ||
                                        !name_unique(irq, action))
                return;
 
@@ -174,36 +175,34 @@ void register_handler_proc(unsigned int irq, struct irqaction *action)
        snprintf(name, MAX_NAMELEN, "%s", action->name);
 
        /* create /proc/irq/1234/handler/ */
-       action->dir = proc_mkdir(name, irq_desc[irq].dir);
+       action->dir = proc_mkdir(name, desc->dir);
 }
 
 #undef MAX_NAMELEN
 
 #define MAX_NAMELEN 10
 
-void register_irq_proc(unsigned int irq)
+void register_irq_proc(unsigned int irq, struct irq_desc *desc)
 {
        char name [MAX_NAMELEN];
        struct proc_dir_entry *entry;
 
-       if (!root_irq_dir ||
-               (irq_desc[irq].chip == &no_irq_chip) ||
-                       irq_desc[irq].dir)
+       if (!root_irq_dir || (desc->chip == &no_irq_chip) || desc->dir)
                return;
 
        memset(name, 0, MAX_NAMELEN);
        sprintf(name, "%d", irq);
 
        /* create /proc/irq/1234 */
-       irq_desc[irq].dir = proc_mkdir(name, root_irq_dir);
+       desc->dir = proc_mkdir(name, root_irq_dir);
 
 #ifdef CONFIG_SMP
        /* create /proc/irq/<irq>/smp_affinity */
-       proc_create_data("smp_affinity", 0600, irq_desc[irq].dir,
+       proc_create_data("smp_affinity", 0600, desc->dir,
                         &irq_affinity_proc_fops, (void *)(long)irq);
 #endif
 
-       entry = create_proc_entry("spurious", 0444, irq_desc[irq].dir);
+       entry = create_proc_entry("spurious", 0444, desc->dir);
        if (entry) {
                entry->data = (void *)(long)irq;
                entry->read_proc = irq_spurious_read;
@@ -214,8 +213,11 @@ void register_irq_proc(unsigned int irq)
 
 void unregister_handler_proc(unsigned int irq, struct irqaction *action)
 {
-       if (action->dir)
-               remove_proc_entry(action->dir->name, irq_desc[irq].dir);
+       if (action->dir) {
+               struct irq_desc *desc = irq_to_desc(irq);
+
+               remove_proc_entry(action->dir->name, desc->dir);
+       }
 }
 
 void register_default_affinity_proc(void)
@@ -228,7 +230,8 @@ void register_default_affinity_proc(void)
 
 void init_irq_proc(void)
 {
-       int i;
+       unsigned int irq;
+       struct irq_desc *desc;
 
        /* create /proc/irq */
        root_irq_dir = proc_mkdir("irq", NULL);
@@ -240,7 +243,7 @@ void init_irq_proc(void)
        /*
         * Create entries for all existing IRQs.
         */
-       for (i = 0; i < NR_IRQS; i++)
-               register_irq_proc(i);
+       for_each_irq_desc(irq, desc)
+               register_irq_proc(irq, desc);
 }
 
index a8046791ba2d3fde84853ac7a7bfbb0bbca07b84..89c7117acf2beffa3a1ca189b3ad721fd4ee047f 100644 (file)
@@ -33,10 +33,10 @@ static void resend_irqs(unsigned long arg)
        struct irq_desc *desc;
        int irq;
 
-       while (!bitmap_empty(irqs_resend, NR_IRQS)) {
-               irq = find_first_bit(irqs_resend, NR_IRQS);
+       while (!bitmap_empty(irqs_resend, nr_irqs)) {
+               irq = find_first_bit(irqs_resend, nr_irqs);
                clear_bit(irq, irqs_resend);
-               desc = irq_desc + irq;
+               desc = irq_to_desc(irq);
                local_irq_disable();
                desc->handle_irq(irq, desc);
                local_irq_enable();
index c66d3f10e85326ab1041a29202047734769b9b10..dd364c11e56e0f82e0e923fcc3b60d17524e991d 100644 (file)
 #include <linux/kallsyms.h>
 #include <linux/interrupt.h>
 #include <linux/moduleparam.h>
+#include <linux/timer.h>
 
 static int irqfixup __read_mostly;
 
+#define POLL_SPURIOUS_IRQ_INTERVAL (HZ/10)
+static void poll_spurious_irqs(unsigned long dummy);
+static DEFINE_TIMER(poll_spurious_irq_timer, poll_spurious_irqs, 0, 0);
+
 /*
  * Recovery handler for misrouted interrupts.
  */
-static int misrouted_irq(int irq)
+static int try_one_irq(int irq, struct irq_desc *desc)
 {
-       int i;
-       int ok = 0;
-       int work = 0;   /* Did we do work for a real IRQ */
-
-       for (i = 1; i < NR_IRQS; i++) {
-               struct irq_desc *desc = irq_desc + i;
-               struct irqaction *action;
-
-               if (i == irq)   /* Already tried */
-                       continue;
+       struct irqaction *action;
+       int ok = 0, work = 0;
 
-               spin_lock(&desc->lock);
-               /* Already running on another processor */
-               if (desc->status & IRQ_INPROGRESS) {
-                       /*
-                        * Already running: If it is shared get the other
-                        * CPU to go looking for our mystery interrupt too
-                        */
-                       if (desc->action && (desc->action->flags & IRQF_SHARED))
-                               desc->status |= IRQ_PENDING;
-                       spin_unlock(&desc->lock);
-                       continue;
-               }
-               /* Honour the normal IRQ locking */
-               desc->status |= IRQ_INPROGRESS;
-               action = desc->action;
+       spin_lock(&desc->lock);
+       /* Already running on another processor */
+       if (desc->status & IRQ_INPROGRESS) {
+               /*
+                * Already running: If it is shared get the other
+                * CPU to go looking for our mystery interrupt too
+                */
+               if (desc->action && (desc->action->flags & IRQF_SHARED))
+                       desc->status |= IRQ_PENDING;
                spin_unlock(&desc->lock);
+               return ok;
+       }
+       /* Honour the normal IRQ locking */
+       desc->status |= IRQ_INPROGRESS;
+       action = desc->action;
+       spin_unlock(&desc->lock);
 
-               while (action) {
-                       /* Only shared IRQ handlers are safe to call */
-                       if (action->flags & IRQF_SHARED) {
-                               if (action->handler(i, action->dev_id) ==
-                                               IRQ_HANDLED)
-                                       ok = 1;
-                       }
-                       action = action->next;
+       while (action) {
+               /* Only shared IRQ handlers are safe to call */
+               if (action->flags & IRQF_SHARED) {
+                       if (action->handler(irq, action->dev_id) ==
+                               IRQ_HANDLED)
+                               ok = 1;
                }
-               local_irq_disable();
-               /* Now clean up the flags */
-               spin_lock(&desc->lock);
-               action = desc->action;
+               action = action->next;
+       }
+       local_irq_disable();
+       /* Now clean up the flags */
+       spin_lock(&desc->lock);
+       action = desc->action;
 
+       /*
+        * While we were looking for a fixup someone queued a real
+        * IRQ clashing with our walk:
+        */
+       while ((desc->status & IRQ_PENDING) && action) {
                /*
-                * While we were looking for a fixup someone queued a real
-                * IRQ clashing with our walk:
-                */
-               while ((desc->status & IRQ_PENDING) && action) {
-                       /*
-                        * Perform real IRQ processing for the IRQ we deferred
-                        */
-                       work = 1;
-                       spin_unlock(&desc->lock);
-                       handle_IRQ_event(i, action);
-                       spin_lock(&desc->lock);
-                       desc->status &= ~IRQ_PENDING;
-               }
-               desc->status &= ~IRQ_INPROGRESS;
-               /*
-                * If we did actual work for the real IRQ line we must let the
-                * IRQ controller clean up too
+                * Perform real IRQ processing for the IRQ we deferred
                 */
-               if (work && desc->chip && desc->chip->end)
-                       desc->chip->end(i);
+               work = 1;
                spin_unlock(&desc->lock);
+               handle_IRQ_event(irq, action);
+               spin_lock(&desc->lock);
+               desc->status &= ~IRQ_PENDING;
+       }
+       desc->status &= ~IRQ_INPROGRESS;
+       /*
+        * If we did actual work for the real IRQ line we must let the
+        * IRQ controller clean up too
+        */
+       if (work && desc->chip && desc->chip->end)
+               desc->chip->end(irq);
+       spin_unlock(&desc->lock);
+
+       return ok;
+}
+
+static int misrouted_irq(int irq)
+{
+       struct irq_desc *desc;
+       int i, ok = 0;
+
+       for_each_irq_desc(i, desc) {
+               if (!i)
+                        continue;
+
+               if (i == irq)   /* Already tried */
+                       continue;
+
+               if (try_one_irq(i, desc))
+                       ok = 1;
        }
        /* So the caller can adjust the irq error counts */
        return ok;
 }
 
+static void poll_spurious_irqs(unsigned long dummy)
+{
+       struct irq_desc *desc;
+       int i;
+
+       for_each_irq_desc(i, desc) {
+               unsigned int status;
+
+               if (!i)
+                        continue;
+
+               /* Racy but it doesn't matter */
+               status = desc->status;
+               barrier();
+               if (!(status & IRQ_SPURIOUS_DISABLED))
+                       continue;
+
+               try_one_irq(i, desc);
+       }
+
+       mod_timer(&poll_spurious_irq_timer,
+                 jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
+}
+
 /*
  * If 99,900 of the previous 100,000 interrupts have not been handled
  * then assume that the IRQ is stuck in some manner. Drop a diagnostic
@@ -137,7 +176,9 @@ report_bad_irq(unsigned int irq, struct irq_desc *desc, irqreturn_t action_ret)
        }
 }
 
-static inline int try_misrouted_irq(unsigned int irq, struct irq_desc *desc, irqreturn_t action_ret)
+static inline int
+try_misrouted_irq(unsigned int irq, struct irq_desc *desc,
+                 irqreturn_t action_ret)
 {
        struct irqaction *action;
 
@@ -212,6 +253,9 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc,
                desc->status |= IRQ_DISABLED | IRQ_SPURIOUS_DISABLED;
                desc->depth++;
                desc->chip->disable(irq);
+
+               mod_timer(&poll_spurious_irq_timer,
+                         jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
        }
        desc->irqs_unhandled = 0;
 }
@@ -241,7 +285,7 @@ static int __init irqfixup_setup(char *str)
 
 __setup("irqfixup", irqfixup_setup);
 module_param(irqfixup, int, 0644);
-MODULE_PARM_DESC("irqfixup", "0: No fixup, 1: irqfixup mode 2: irqpoll mode");
+MODULE_PARM_DESC("irqfixup", "0: No fixup, 1: irqfixup mode, 2: irqpoll mode");
 
 static int __init irqpoll_setup(char *str)
 {
index ab982747d9bd8121c19b3327b96c7760adb7577e..db7c358b9a02f1cc50954517124c8272b5eed463 100644 (file)
@@ -55,17 +55,15 @@ int do_getitimer(int which, struct itimerval *value)
                spin_unlock_irq(&tsk->sighand->siglock);
                break;
        case ITIMER_VIRTUAL:
-               read_lock(&tasklist_lock);
                spin_lock_irq(&tsk->sighand->siglock);
                cval = tsk->signal->it_virt_expires;
                cinterval = tsk->signal->it_virt_incr;
                if (!cputime_eq(cval, cputime_zero)) {
-                       struct task_struct *t = tsk;
-                       cputime_t utime = tsk->signal->utime;
-                       do {
-                               utime = cputime_add(utime, t->utime);
-                               t = next_thread(t);
-                       } while (t != tsk);
+                       struct task_cputime cputime;
+                       cputime_t utime;
+
+                       thread_group_cputime(tsk, &cputime);
+                       utime = cputime.utime;
                        if (cputime_le(cval, utime)) { /* about to fire */
                                cval = jiffies_to_cputime(1);
                        } else {
@@ -73,25 +71,19 @@ int do_getitimer(int which, struct itimerval *value)
                        }
                }
                spin_unlock_irq(&tsk->sighand->siglock);
-               read_unlock(&tasklist_lock);
                cputime_to_timeval(cval, &value->it_value);
                cputime_to_timeval(cinterval, &value->it_interval);
                break;
        case ITIMER_PROF:
-               read_lock(&tasklist_lock);
                spin_lock_irq(&tsk->sighand->siglock);
                cval = tsk->signal->it_prof_expires;
                cinterval = tsk->signal->it_prof_incr;
                if (!cputime_eq(cval, cputime_zero)) {
-                       struct task_struct *t = tsk;
-                       cputime_t ptime = cputime_add(tsk->signal->utime,
-                                                     tsk->signal->stime);
-                       do {
-                               ptime = cputime_add(ptime,
-                                                   cputime_add(t->utime,
-                                                               t->stime));
-                               t = next_thread(t);
-                       } while (t != tsk);
+                       struct task_cputime times;
+                       cputime_t ptime;
+
+                       thread_group_cputime(tsk, &times);
+                       ptime = cputime_add(times.utime, times.stime);
                        if (cputime_le(cval, ptime)) { /* about to fire */
                                cval = jiffies_to_cputime(1);
                        } else {
@@ -99,7 +91,6 @@ int do_getitimer(int which, struct itimerval *value)
                        }
                }
                spin_unlock_irq(&tsk->sighand->siglock);
-               read_unlock(&tasklist_lock);
                cputime_to_timeval(cval, &value->it_value);
                cputime_to_timeval(cinterval, &value->it_interval);
                break;
@@ -185,7 +176,6 @@ again:
        case ITIMER_VIRTUAL:
                nval = timeval_to_cputime(&value->it_value);
                ninterval = timeval_to_cputime(&value->it_interval);
-               read_lock(&tasklist_lock);
                spin_lock_irq(&tsk->sighand->siglock);
                cval = tsk->signal->it_virt_expires;
                cinterval = tsk->signal->it_virt_incr;
@@ -200,7 +190,6 @@ again:
                tsk->signal->it_virt_expires = nval;
                tsk->signal->it_virt_incr = ninterval;
                spin_unlock_irq(&tsk->sighand->siglock);
-               read_unlock(&tasklist_lock);
                if (ovalue) {
                        cputime_to_timeval(cval, &ovalue->it_value);
                        cputime_to_timeval(cinterval, &ovalue->it_interval);
@@ -209,7 +198,6 @@ again:
        case ITIMER_PROF:
                nval = timeval_to_cputime(&value->it_value);
                ninterval = timeval_to_cputime(&value->it_interval);
-               read_lock(&tasklist_lock);
                spin_lock_irq(&tsk->sighand->siglock);
                cval = tsk->signal->it_prof_expires;
                cinterval = tsk->signal->it_prof_incr;
@@ -224,7 +212,6 @@ again:
                tsk->signal->it_prof_expires = nval;
                tsk->signal->it_prof_incr = ninterval;
                spin_unlock_irq(&tsk->sighand->siglock);
-               read_unlock(&tasklist_lock);
                if (ovalue) {
                        cputime_to_timeval(cval, &ovalue->it_value);
                        cputime_to_timeval(cinterval, &ovalue->it_interval);
index 777ac458ac993b8195a3c3cb7042a941ba611339..ac0fde7b54d082ee9ee327a0e57a7664f5cb72e7 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/pm.h>
 #include <linux/cpu.h>
 #include <linux/console.h>
+#include <linux/vmalloc.h>
 
 #include <asm/page.h>
 #include <asm/uaccess.h>
index 14ec64fe175ad5a742aac30718362a1f6875e9af..8e7a7ce3ed0a642f99dc7f73c220722c936e88ac 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/file.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <trace/sched.h>
 
 #define KTHREAD_NICE_LEVEL (-5)
 
@@ -205,6 +206,8 @@ int kthread_stop(struct task_struct *k)
        /* It could exit after stop_info.k set, but before wake_up_process. */
        get_task_struct(k);
 
+       trace_sched_kthread_stop(k);
+
        /* Must init completion *before* thread sees kthread_stop_info.k */
        init_completion(&kthread_stop_info.done);
        smp_wmb();
@@ -220,6 +223,8 @@ int kthread_stop(struct task_struct *k)
        ret = kthread_stop_info.err;
        mutex_unlock(&kthread_stop_lock);
 
+       trace_sched_kthread_stop_ret(ret);
+
        return ret;
 }
 EXPORT_SYMBOL(kthread_stop);
index 7d1faecd7a51bd643cc1e10f0f2048765136bf16..e9c6b2bc9400627cf183382ee55933333f0ee83b 100644 (file)
@@ -62,7 +62,7 @@ struct marker_entry {
        int refcount;   /* Number of times armed. 0 if disarmed. */
        struct rcu_head rcu;
        void *oldptr;
-       unsigned char rcu_pending:1;
+       int rcu_pending;
        unsigned char ptype:1;
        char name[0];   /* Contains name'\0'format'\0' */
 };
@@ -103,11 +103,11 @@ void marker_probe_cb(const struct marker *mdata, void *call_private, ...)
        char ptype;
 
        /*
-        * preempt_disable does two things : disabling preemption to make sure
-        * the teardown of the callbacks can be done correctly when they are in
-        * modules and they insure RCU read coherency.
+        * rcu_read_lock_sched does two things : disabling preemption to make
+        * sure the teardown of the callbacks can be done correctly when they
+        * are in modules and they insure RCU read coherency.
         */
-       preempt_disable();
+       rcu_read_lock_sched();
        ptype = mdata->ptype;
        if (likely(!ptype)) {
                marker_probe_func *func;
@@ -145,7 +145,7 @@ void marker_probe_cb(const struct marker *mdata, void *call_private, ...)
                        va_end(args);
                }
        }
-       preempt_enable();
+       rcu_read_unlock_sched();
 }
 EXPORT_SYMBOL_GPL(marker_probe_cb);
 
@@ -162,7 +162,7 @@ void marker_probe_cb_noarg(const struct marker *mdata, void *call_private, ...)
        va_list args;   /* not initialized */
        char ptype;
 
-       preempt_disable();
+       rcu_read_lock_sched();
        ptype = mdata->ptype;
        if (likely(!ptype)) {
                marker_probe_func *func;
@@ -195,7 +195,7 @@ void marker_probe_cb_noarg(const struct marker *mdata, void *call_private, ...)
                        multi[i].func(multi[i].probe_private, call_private,
                                mdata->format, &args);
        }
-       preempt_enable();
+       rcu_read_unlock_sched();
 }
 EXPORT_SYMBOL_GPL(marker_probe_cb_noarg);
 
@@ -560,7 +560,7 @@ static int set_marker(struct marker_entry **entry, struct marker *elem,
  * Disable a marker and its probe callback.
  * Note: only waiting an RCU period after setting elem->call to the empty
  * function insures that the original callback is not used anymore. This insured
- * by preempt_disable around the call site.
+ * by rcu_read_lock_sched around the call site.
  */
 static void disable_marker(struct marker *elem)
 {
@@ -653,11 +653,17 @@ int marker_probe_register(const char *name, const char *format,
        entry = get_marker(name);
        if (!entry) {
                entry = add_marker(name, format);
-               if (IS_ERR(entry)) {
+               if (IS_ERR(entry))
                        ret = PTR_ERR(entry);
-                       goto end;
-               }
+       } else if (format) {
+               if (!entry->format)
+                       ret = marker_set_format(&entry, format);
+               else if (strcmp(entry->format, format))
+                       ret = -EPERM;
        }
+       if (ret)
+               goto end;
+
        /*
         * If we detect that a call_rcu is pending for this marker,
         * make sure it's executed now.
@@ -674,6 +680,8 @@ int marker_probe_register(const char *name, const char *format,
        mutex_lock(&markers_mutex);
        entry = get_marker(name);
        WARN_ON(!entry);
+       if (entry->rcu_pending)
+               rcu_barrier_sched();
        entry->oldptr = old;
        entry->rcu_pending = 1;
        /* write rcu_pending before calling the RCU callback */
@@ -717,6 +725,8 @@ int marker_probe_unregister(const char *name,
        entry = get_marker(name);
        if (!entry)
                goto end;
+       if (entry->rcu_pending)
+               rcu_barrier_sched();
        entry->oldptr = old;
        entry->rcu_pending = 1;
        /* write rcu_pending before calling the RCU callback */
@@ -795,6 +805,8 @@ int marker_probe_unregister_private_data(marker_probe_func *probe,
        mutex_lock(&markers_mutex);
        entry = get_marker_from_private_data(probe, probe_private);
        WARN_ON(!entry);
+       if (entry->rcu_pending)
+               rcu_barrier_sched();
        entry->oldptr = old;
        entry->rcu_pending = 1;
        /* write rcu_pending before calling the RCU callback */
index 25bc9ac9e226ae02dce8ff39a7c1d914684b4e3e..1f4cc00e0c200b7c69272694d121558fd6a10d06 100644 (file)
 #include <linux/moduleloader.h>
 #include <linux/init.h>
 #include <linux/kallsyms.h>
+#include <linux/fs.h>
 #include <linux/sysfs.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/elf.h>
+#include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/syscalls.h>
 #include <linux/fcntl.h>
 #include <linux/string.h>
 #include <linux/mutex.h>
 #include <linux/unwind.h>
+#include <linux/rculist.h>
 #include <asm/uaccess.h>
 #include <asm/cacheflush.h>
 #include <linux/license.h>
 #include <asm/sections.h>
+#include <linux/tracepoint.h>
+#include <linux/ftrace.h>
 
 #if 0
 #define DEBUGP printk
@@ -61,7 +66,7 @@
 #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))
 
 /* List of modules, protected by module_mutex or preempt_disable
- * (add/delete uses stop_machine). */
+ * (delete uses stop_machine/add uses RCU list operations). */
 static DEFINE_MUTEX(module_mutex);
 static LIST_HEAD(modules);
 
@@ -130,6 +135,29 @@ static unsigned int find_sec(Elf_Ehdr *hdr,
        return 0;
 }
 
+/* Find a module section, or NULL. */
+static void *section_addr(Elf_Ehdr *hdr, Elf_Shdr *shdrs,
+                         const char *secstrings, const char *name)
+{
+       /* Section 0 has sh_addr 0. */
+       return (void *)shdrs[find_sec(hdr, shdrs, secstrings, name)].sh_addr;
+}
+
+/* Find a module section, or NULL.  Fill in number of "objects" in section. */
+static void *section_objs(Elf_Ehdr *hdr,
+                         Elf_Shdr *sechdrs,
+                         const char *secstrings,
+                         const char *name,
+                         size_t object_size,
+                         unsigned int *num)
+{
+       unsigned int sec = find_sec(hdr, sechdrs, secstrings, name);
+
+       /* Section 0 has sh_addr 0 and sh_size 0. */
+       *num = sechdrs[sec].sh_size / object_size;
+       return (void *)sechdrs[sec].sh_addr;
+}
+
 /* Provided by the linker */
 extern const struct kernel_symbol __start___ksymtab[];
 extern const struct kernel_symbol __stop___ksymtab[];
@@ -216,7 +244,7 @@ static bool each_symbol(bool (*fn)(const struct symsearch *arr,
        if (each_symbol_in_section(arr, ARRAY_SIZE(arr), NULL, fn, data))
                return true;
 
-       list_for_each_entry(mod, &modules, list) {
+       list_for_each_entry_rcu(mod, &modules, list) {
                struct symsearch arr[] = {
                        { mod->syms, mod->syms + mod->num_syms, mod->crcs,
                          NOT_GPL_ONLY, false },
@@ -1391,17 +1419,6 @@ static void mod_kobject_remove(struct module *mod)
        mod_sysfs_fini(mod);
 }
 
-/*
- * link the module with the whole machine is stopped with interrupts off
- * - this defends against kallsyms not taking locks
- */
-static int __link_module(void *_mod)
-{
-       struct module *mod = _mod;
-       list_add(&mod->list, &modules);
-       return 0;
-}
-
 /*
  * unlink the module with the whole machine is stopped with interrupts off
  * - this defends against kallsyms not taking locks
@@ -1430,6 +1447,9 @@ static void free_module(struct module *mod)
        /* Module unload stuff */
        module_unload_free(mod);
 
+       /* release any pointers to mcount in this module */
+       ftrace_release(mod->module_core, mod->core_size);
+
        /* This may be NULL, but that's OK */
        module_free(mod, mod->module_init);
        kfree(mod->args);
@@ -1784,32 +1804,20 @@ static inline void add_kallsyms(struct module *mod,
 }
 #endif /* CONFIG_KALLSYMS */
 
-#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
-static void dynamic_printk_setup(Elf_Shdr *sechdrs, unsigned int verboseindex)
+static void dynamic_printk_setup(struct mod_debug *debug, unsigned int num)
 {
-       struct mod_debug *debug_info;
-       unsigned long pos, end;
-       unsigned int num_verbose;
-
-       pos = sechdrs[verboseindex].sh_addr;
-       num_verbose = sechdrs[verboseindex].sh_size /
-                               sizeof(struct mod_debug);
-       end = pos + (num_verbose * sizeof(struct mod_debug));
+#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
+       unsigned int i;
 
-       for (; pos < end; pos += sizeof(struct mod_debug)) {
-               debug_info = (struct mod_debug *)pos;
-               register_dynamic_debug_module(debug_info->modname,
-                       debug_info->type, debug_info->logical_modname,
-                       debug_info->flag_names, debug_info->hash,
-                       debug_info->hash2);
+       for (i = 0; i < num; i++) {
+               register_dynamic_debug_module(debug[i].modname,
+                                             debug[i].type,
+                                             debug[i].logical_modname,
+                                             debug[i].flag_names,
+                                             debug[i].hash, debug[i].hash2);
        }
-}
-#else
-static inline void dynamic_printk_setup(Elf_Shdr *sechdrs,
-                                       unsigned int verboseindex)
-{
-}
 #endif /* CONFIG_DYNAMIC_PRINTK_DEBUG */
+}
 
 static void *module_alloc_update_bounds(unsigned long size)
 {
@@ -1838,33 +1846,14 @@ static noinline struct module *load_module(void __user *umod,
        unsigned int i;
        unsigned int symindex = 0;
        unsigned int strindex = 0;
-       unsigned int setupindex;
-       unsigned int exindex;
-       unsigned int exportindex;
-       unsigned int modindex;
-       unsigned int obsparmindex;
-       unsigned int infoindex;
-       unsigned int gplindex;
-       unsigned int crcindex;
-       unsigned int gplcrcindex;
-       unsigned int versindex;
-       unsigned int pcpuindex;
-       unsigned int gplfutureindex;
-       unsigned int gplfuturecrcindex;
+       unsigned int modindex, versindex, infoindex, pcpuindex;
        unsigned int unwindex = 0;
-#ifdef CONFIG_UNUSED_SYMBOLS
-       unsigned int unusedindex;
-       unsigned int unusedcrcindex;
-       unsigned int unusedgplindex;
-       unsigned int unusedgplcrcindex;
-#endif
-       unsigned int markersindex;
-       unsigned int markersstringsindex;
-       unsigned int verboseindex;
+       unsigned int num_kp, num_mcount;
+       struct kernel_param *kp;
        struct module *mod;
        long err = 0;
        void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
-       struct exception_table_entry *extable;
+       unsigned long *mseg;
        mm_segment_t old_fs;
 
        DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
@@ -1928,6 +1917,7 @@ static noinline struct module *load_module(void __user *umod,
                err = -ENOEXEC;
                goto free_hdr;
        }
+       /* This is temporary: point mod into copy of data. */
        mod = (void *)sechdrs[modindex].sh_addr;
 
        if (symindex == 0) {
@@ -1937,22 +1927,6 @@ static noinline struct module *load_module(void __user *umod,
                goto free_hdr;
        }
 
-       /* Optional sections */
-       exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab");
-       gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl");
-       gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future");
-       crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab");
-       gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl");
-       gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future");
-#ifdef CONFIG_UNUSED_SYMBOLS
-       unusedindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused");
-       unusedgplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused_gpl");
-       unusedcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused");
-       unusedgplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused_gpl");
-#endif
-       setupindex = find_sec(hdr, sechdrs, secstrings, "__param");
-       exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table");
-       obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm");
        versindex = find_sec(hdr, sechdrs, secstrings, "__versions");
        infoindex = find_sec(hdr, sechdrs, secstrings, ".modinfo");
        pcpuindex = find_pcpusec(hdr, sechdrs, secstrings);
@@ -2108,42 +2082,57 @@ static noinline struct module *load_module(void __user *umod,
        if (err < 0)
                goto cleanup;
 
-       /* Set up EXPORTed & EXPORT_GPLed symbols (section 0 is 0 length) */
-       mod->num_syms = sechdrs[exportindex].sh_size / sizeof(*mod->syms);
-       mod->syms = (void *)sechdrs[exportindex].sh_addr;
-       if (crcindex)
-               mod->crcs = (void *)sechdrs[crcindex].sh_addr;
-       mod->num_gpl_syms = sechdrs[gplindex].sh_size / sizeof(*mod->gpl_syms);
-       mod->gpl_syms = (void *)sechdrs[gplindex].sh_addr;
-       if (gplcrcindex)
-               mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr;
-       mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size /
-                                       sizeof(*mod->gpl_future_syms);
-       mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr;
-       if (gplfuturecrcindex)
-               mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr;
+       /* Now we've got everything in the final locations, we can
+        * find optional sections. */
+       kp = section_objs(hdr, sechdrs, secstrings, "__param", sizeof(*kp),
+                         &num_kp);
+       mod->syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab",
+                                sizeof(*mod->syms), &mod->num_syms);
+       mod->crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab");
+       mod->gpl_syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab_gpl",
+                                    sizeof(*mod->gpl_syms),
+                                    &mod->num_gpl_syms);
+       mod->gpl_crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab_gpl");
+       mod->gpl_future_syms = section_objs(hdr, sechdrs, secstrings,
+                                           "__ksymtab_gpl_future",
+                                           sizeof(*mod->gpl_future_syms),
+                                           &mod->num_gpl_future_syms);
+       mod->gpl_future_crcs = section_addr(hdr, sechdrs, secstrings,
+                                           "__kcrctab_gpl_future");
 
 #ifdef CONFIG_UNUSED_SYMBOLS
-       mod->num_unused_syms = sechdrs[unusedindex].sh_size /
-                                       sizeof(*mod->unused_syms);
-       mod->num_unused_gpl_syms = sechdrs[unusedgplindex].sh_size /
-                                       sizeof(*mod->unused_gpl_syms);
-       mod->unused_syms = (void *)sechdrs[unusedindex].sh_addr;
-       if (unusedcrcindex)
-               mod->unused_crcs = (void *)sechdrs[unusedcrcindex].sh_addr;
-       mod->unused_gpl_syms = (void *)sechdrs[unusedgplindex].sh_addr;
-       if (unusedgplcrcindex)
-               mod->unused_gpl_crcs
-                       = (void *)sechdrs[unusedgplcrcindex].sh_addr;
+       mod->unused_syms = section_objs(hdr, sechdrs, secstrings,
+                                       "__ksymtab_unused",
+                                       sizeof(*mod->unused_syms),
+                                       &mod->num_unused_syms);
+       mod->unused_crcs = section_addr(hdr, sechdrs, secstrings,
+                                       "__kcrctab_unused");
+       mod->unused_gpl_syms = section_objs(hdr, sechdrs, secstrings,
+                                           "__ksymtab_unused_gpl",
+                                           sizeof(*mod->unused_gpl_syms),
+                                           &mod->num_unused_gpl_syms);
+       mod->unused_gpl_crcs = section_addr(hdr, sechdrs, secstrings,
+                                           "__kcrctab_unused_gpl");
+#endif
+
+#ifdef CONFIG_MARKERS
+       mod->markers = section_objs(hdr, sechdrs, secstrings, "__markers",
+                                   sizeof(*mod->markers), &mod->num_markers);
+#endif
+#ifdef CONFIG_TRACEPOINTS
+       mod->tracepoints = section_objs(hdr, sechdrs, secstrings,
+                                       "__tracepoints",
+                                       sizeof(*mod->tracepoints),
+                                       &mod->num_tracepoints);
 #endif
 
 #ifdef CONFIG_MODVERSIONS
-       if ((mod->num_syms && !crcindex)
-           || (mod->num_gpl_syms && !gplcrcindex)
-           || (mod->num_gpl_future_syms && !gplfuturecrcindex)
+       if ((mod->num_syms && !mod->crcs)
+           || (mod->num_gpl_syms && !mod->gpl_crcs)
+           || (mod->num_gpl_future_syms && !mod->gpl_future_crcs)
 #ifdef CONFIG_UNUSED_SYMBOLS
-           || (mod->num_unused_syms && !unusedcrcindex)
-           || (mod->num_unused_gpl_syms && !unusedgplcrcindex)
+           || (mod->num_unused_syms && !mod->unused_crcs)
+           || (mod->num_unused_gpl_syms && !mod->unused_gpl_crcs)
 #endif
                ) {
                printk(KERN_WARNING "%s: No versions for exported symbols.\n", mod->name);
@@ -2152,10 +2141,6 @@ static noinline struct module *load_module(void __user *umod,
                        goto cleanup;
        }
 #endif
-       markersindex = find_sec(hdr, sechdrs, secstrings, "__markers");
-       markersstringsindex = find_sec(hdr, sechdrs, secstrings,
-                                       "__markers_strings");
-       verboseindex = find_sec(hdr, sechdrs, secstrings, "__verbose");
 
        /* Now do relocations. */
        for (i = 1; i < hdr->e_shnum; i++) {
@@ -2178,22 +2163,16 @@ static noinline struct module *load_module(void __user *umod,
                if (err < 0)
                        goto cleanup;
        }
-#ifdef CONFIG_MARKERS
-       mod->markers = (void *)sechdrs[markersindex].sh_addr;
-       mod->num_markers =
-               sechdrs[markersindex].sh_size / sizeof(*mod->markers);
-#endif
 
         /* Find duplicate symbols */
        err = verify_export_symbols(mod);
-
        if (err < 0)
                goto cleanup;
 
        /* Set up and sort exception table */
-       mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable);
-       mod->extable = extable = (void *)sechdrs[exindex].sh_addr;
-       sort_extable(extable, extable + mod->num_exentries);
+       mod->extable = section_objs(hdr, sechdrs, secstrings, "__ex_table",
+                                   sizeof(*mod->extable), &mod->num_exentries);
+       sort_extable(mod->extable, mod->extable + mod->num_exentries);
 
        /* Finally, copy percpu area over. */
        percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr,
@@ -2201,12 +2180,29 @@ static noinline struct module *load_module(void __user *umod,
 
        add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
 
+       if (!mod->taints) {
+               struct mod_debug *debug;
+               unsigned int num_debug;
+
 #ifdef CONFIG_MARKERS
-       if (!mod->taints)
                marker_update_probe_range(mod->markers,
                        mod->markers + mod->num_markers);
 #endif
-       dynamic_printk_setup(sechdrs, verboseindex);
+               debug = section_objs(hdr, sechdrs, secstrings, "__verbose",
+                                    sizeof(*debug), &num_debug);
+               dynamic_printk_setup(debug, num_debug);
+
+#ifdef CONFIG_TRACEPOINTS
+               tracepoint_update_probe_range(mod->tracepoints,
+                       mod->tracepoints + mod->num_tracepoints);
+#endif
+       }
+
+       /* sechdrs[0].sh_size is always zero */
+       mseg = section_objs(hdr, sechdrs, secstrings, "__mcount_loc",
+                           sizeof(*mseg), &num_mcount);
+       ftrace_init_module(mseg, mseg + num_mcount);
+
        err = module_finalize(hdr, sechdrs, mod);
        if (err < 0)
                goto cleanup;
@@ -2230,30 +2226,24 @@ static noinline struct module *load_module(void __user *umod,
        set_fs(old_fs);
 
        mod->args = args;
-       if (obsparmindex)
+       if (section_addr(hdr, sechdrs, secstrings, "__obsparm"))
                printk(KERN_WARNING "%s: Ignoring obsolete parameters\n",
                       mod->name);
 
        /* Now sew it into the lists so we can get lockdep and oops
-         * info during argument parsing.  Noone should access us, since
-         * strong_try_module_get() will fail. */
-       stop_machine(__link_module, mod, NULL);
-
-       /* Size of section 0 is 0, so this works well if no params */
-       err = parse_args(mod->name, mod->args,
-                        (struct kernel_param *)
-                        sechdrs[setupindex].sh_addr,
-                        sechdrs[setupindex].sh_size
-                        / sizeof(struct kernel_param),
-                        NULL);
+        * info during argument parsing.  Noone should access us, since
+        * strong_try_module_get() will fail.
+        * lockdep/oops can run asynchronous, so use the RCU list insertion
+        * function to insert in a way safe to concurrent readers.
+        * The mutex protects against concurrent writers.
+        */
+       list_add_rcu(&mod->list, &modules);
+
+       err = parse_args(mod->name, mod->args, kp, num_kp, NULL);
        if (err < 0)
                goto unlink;
 
-       err = mod_sysfs_setup(mod,
-                             (struct kernel_param *)
-                             sechdrs[setupindex].sh_addr,
-                             sechdrs[setupindex].sh_size
-                             / sizeof(struct kernel_param));
+       err = mod_sysfs_setup(mod, kp, num_kp);
        if (err < 0)
                goto unlink;
        add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
@@ -2276,6 +2266,7 @@ static noinline struct module *load_module(void __user *umod,
  cleanup:
        kobject_del(&mod->mkobj.kobj);
        kobject_put(&mod->mkobj.kobj);
+       ftrace_release(mod->module_core, mod->core_size);
  free_unload:
        module_unload_free(mod);
        module_free(mod, mod->module_init);
@@ -2441,7 +2432,7 @@ const char *module_address_lookup(unsigned long addr,
        const char *ret = NULL;
 
        preempt_disable();
-       list_for_each_entry(mod, &modules, list) {
+       list_for_each_entry_rcu(mod, &modules, list) {
                if (within(addr, mod->module_init, mod->init_size)
                    || within(addr, mod->module_core, mod->core_size)) {
                        if (modname)
@@ -2464,7 +2455,7 @@ int lookup_module_symbol_name(unsigned long addr, char *symname)
        struct module *mod;
 
        preempt_disable();
-       list_for_each_entry(mod, &modules, list) {
+       list_for_each_entry_rcu(mod, &modules, list) {
                if (within(addr, mod->module_init, mod->init_size) ||
                    within(addr, mod->module_core, mod->core_size)) {
                        const char *sym;
@@ -2488,7 +2479,7 @@ int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size,
        struct module *mod;
 
        preempt_disable();
-       list_for_each_entry(mod, &modules, list) {
+       list_for_each_entry_rcu(mod, &modules, list) {
                if (within(addr, mod->module_init, mod->init_size) ||
                    within(addr, mod->module_core, mod->core_size)) {
                        const char *sym;
@@ -2515,7 +2506,7 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
        struct module *mod;
 
        preempt_disable();
-       list_for_each_entry(mod, &modules, list) {
+       list_for_each_entry_rcu(mod, &modules, list) {
                if (symnum < mod->num_symtab) {
                        *value = mod->symtab[symnum].st_value;
                        *type = mod->symtab[symnum].st_info;
@@ -2558,7 +2549,7 @@ unsigned long module_kallsyms_lookup_name(const char *name)
                        ret = mod_find_symname(mod, colon+1);
                *colon = ':';
        } else {
-               list_for_each_entry(mod, &modules, list)
+               list_for_each_entry_rcu(mod, &modules, list)
                        if ((ret = mod_find_symname(mod, name)) != 0)
                                break;
        }
@@ -2567,23 +2558,6 @@ unsigned long module_kallsyms_lookup_name(const char *name)
 }
 #endif /* CONFIG_KALLSYMS */
 
-/* Called by the /proc file system to return a list of modules. */
-static void *m_start(struct seq_file *m, loff_t *pos)
-{
-       mutex_lock(&module_mutex);
-       return seq_list_start(&modules, *pos);
-}
-
-static void *m_next(struct seq_file *m, void *p, loff_t *pos)
-{
-       return seq_list_next(p, &modules, pos);
-}
-
-static void m_stop(struct seq_file *m, void *p)
-{
-       mutex_unlock(&module_mutex);
-}
-
 static char *module_flags(struct module *mod, char *buf)
 {
        int bx = 0;
@@ -2617,6 +2591,24 @@ static char *module_flags(struct module *mod, char *buf)
        return buf;
 }
 
+#ifdef CONFIG_PROC_FS
+/* Called by the /proc file system to return a list of modules. */
+static void *m_start(struct seq_file *m, loff_t *pos)
+{
+       mutex_lock(&module_mutex);
+       return seq_list_start(&modules, *pos);
+}
+
+static void *m_next(struct seq_file *m, void *p, loff_t *pos)
+{
+       return seq_list_next(p, &modules, pos);
+}
+
+static void m_stop(struct seq_file *m, void *p)
+{
+       mutex_unlock(&module_mutex);
+}
+
 static int m_show(struct seq_file *m, void *p)
 {
        struct module *mod = list_entry(p, struct module, list);
@@ -2647,13 +2639,33 @@ static int m_show(struct seq_file *m, void *p)
    Where refcount is a number or -, and deps is a comma-separated list
    of depends or -.
 */
-const struct seq_operations modules_op = {
+static const struct seq_operations modules_op = {
        .start  = m_start,
        .next   = m_next,
        .stop   = m_stop,
        .show   = m_show
 };
 
+static int modules_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &modules_op);
+}
+
+static const struct file_operations proc_modules_operations = {
+       .open           = modules_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+static int __init proc_modules_init(void)
+{
+       proc_create("modules", 0, NULL, &proc_modules_operations);
+       return 0;
+}
+module_init(proc_modules_init);
+#endif
+
 /* Given an address, look for it in the module exception tables. */
 const struct exception_table_entry *search_module_extables(unsigned long addr)
 {
@@ -2661,7 +2673,7 @@ const struct exception_table_entry *search_module_extables(unsigned long addr)
        struct module *mod;
 
        preempt_disable();
-       list_for_each_entry(mod, &modules, list) {
+       list_for_each_entry_rcu(mod, &modules, list) {
                if (mod->num_exentries == 0)
                        continue;
 
@@ -2687,7 +2699,7 @@ int is_module_address(unsigned long addr)
 
        preempt_disable();
 
-       list_for_each_entry(mod, &modules, list) {
+       list_for_each_entry_rcu(mod, &modules, list) {
                if (within(addr, mod->module_core, mod->core_size)) {
                        preempt_enable();
                        return 1;
@@ -2708,7 +2720,7 @@ struct module *__module_text_address(unsigned long addr)
        if (addr < module_addr_min || addr > module_addr_max)
                return NULL;
 
-       list_for_each_entry(mod, &modules, list)
+       list_for_each_entry_rcu(mod, &modules, list)
                if (within(addr, mod->module_init, mod->init_text_size)
                    || within(addr, mod->module_core, mod->core_text_size))
                        return mod;
@@ -2733,8 +2745,11 @@ void print_modules(void)
        char buf[8];
 
        printk("Modules linked in:");
-       list_for_each_entry(mod, &modules, list)
+       /* Most callers should already have preempt disabled, but make sure */
+       preempt_disable();
+       list_for_each_entry_rcu(mod, &modules, list)
                printk(" %s%s", mod->name, module_flags(mod, buf));
+       preempt_enable();
        if (last_unloaded_module[0])
                printk(" [last unloaded: %s]", last_unloaded_module);
        printk("\n");
@@ -2759,3 +2774,50 @@ void module_update_markers(void)
        mutex_unlock(&module_mutex);
 }
 #endif
+
+#ifdef CONFIG_TRACEPOINTS
+void module_update_tracepoints(void)
+{
+       struct module *mod;
+
+       mutex_lock(&module_mutex);
+       list_for_each_entry(mod, &modules, list)
+               if (!mod->taints)
+                       tracepoint_update_probe_range(mod->tracepoints,
+                               mod->tracepoints + mod->num_tracepoints);
+       mutex_unlock(&module_mutex);
+}
+
+/*
+ * Returns 0 if current not found.
+ * Returns 1 if current found.
+ */
+int module_get_iter_tracepoints(struct tracepoint_iter *iter)
+{
+       struct module *iter_mod;
+       int found = 0;
+
+       mutex_lock(&module_mutex);
+       list_for_each_entry(iter_mod, &modules, list) {
+               if (!iter_mod->taints) {
+                       /*
+                        * Sorted module list
+                        */
+                       if (iter_mod < iter->module)
+                               continue;
+                       else if (iter_mod > iter->module)
+                               iter->tracepoint = NULL;
+                       found = tracepoint_get_iter_range(&iter->tracepoint,
+                               iter_mod->tracepoints,
+                               iter_mod->tracepoints
+                                       + iter_mod->num_tracepoints);
+                       if (found) {
+                               iter->module = iter_mod;
+                               break;
+                       }
+               }
+       }
+       mutex_unlock(&module_mutex);
+       return found;
+}
+#endif
index 823be11584efef8ef1d344f484cbf8c3d4f9617e..4282c0a40a57ada651b86c7dcce2389abf489448 100644 (file)
@@ -550,7 +550,7 @@ EXPORT_SYMBOL(unregister_reboot_notifier);
 
 static ATOMIC_NOTIFIER_HEAD(die_chain);
 
-int notify_die(enum die_val val, const char *str,
+int notrace notify_die(enum die_val val, const char *str,
               struct pt_regs *regs, long err, int trap, int sig)
 {
        struct die_args args = {
index bda561ef3cdf4e3f7f091fc6f4f215fe4b785b16..6513aac8e9924017bb82fa58a2c8285f7328097b 100644 (file)
@@ -34,13 +34,6 @@ ATOMIC_NOTIFIER_HEAD(panic_notifier_list);
 
 EXPORT_SYMBOL(panic_notifier_list);
 
-static int __init panic_setup(char *str)
-{
-       panic_timeout = simple_strtoul(str, NULL, 0);
-       return 1;
-}
-__setup("panic=", panic_setup);
-
 static long no_blink(long time)
 {
        return 0;
@@ -218,13 +211,6 @@ void add_taint(unsigned flag)
 }
 EXPORT_SYMBOL(add_taint);
 
-static int __init pause_on_oops_setup(char *str)
-{
-       pause_on_oops = simple_strtoul(str, NULL, 0);
-       return 1;
-}
-__setup("pause_on_oops=", pause_on_oops_setup);
-
 static void spin_msec(int msecs)
 {
        int i;
@@ -384,3 +370,6 @@ void __stack_chk_fail(void)
 }
 EXPORT_SYMBOL(__stack_chk_fail);
 #endif
+
+core_param(panic, panic_timeout, int, 0644);
+core_param(pause_on_oops, pause_on_oops, int, 0644);
index afc46a23eb6d15ebfb328f242979d75998d6d4c4..a1e3025b19a9aed003967a0a9e2ff3d05456428b 100644 (file)
@@ -373,6 +373,8 @@ int param_get_string(char *buffer, struct kernel_param *kp)
 }
 
 /* sysfs output in /sys/modules/XYZ/parameters/ */
+#define to_module_attr(n) container_of(n, struct module_attribute, attr);
+#define to_module_kobject(n) container_of(n, struct module_kobject, kobj);
 
 extern struct kernel_param __start___param[], __stop___param[];
 
@@ -384,6 +386,7 @@ struct param_attribute
 
 struct module_param_attrs
 {
+       unsigned int num;
        struct attribute_group grp;
        struct param_attribute attrs[0];
 };
@@ -434,93 +437,120 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
 
 #ifdef CONFIG_SYSFS
 /*
- * param_sysfs_setup - setup sysfs support for one module or KBUILD_MODNAME
- * @mk: struct module_kobject (contains parent kobject)
- * @kparam: array of struct kernel_param, the actual parameter definitions
- * @num_params: number of entries in array
- * @name_skip: offset where the parameter name start in kparam[].name. Needed for built-in "modules"
+ * add_sysfs_param - add a parameter to sysfs
+ * @mk: struct module_kobject
+ * @kparam: the actual parameter definition to add to sysfs
+ * @name: name of parameter
  *
- * Create a kobject for a (per-module) group of parameters, and create files
- * in sysfs. A pointer to the param_kobject is returned on success,
- * NULL if there's no parameter to export, or other ERR_PTR(err).
+ * Create a kobject if for a (per-module) parameter if mp NULL, and
+ * create file in sysfs.  Returns an error on out of memory.  Always cleans up
+ * if there's an error.
  */
-static __modinit struct module_param_attrs *
-param_sysfs_setup(struct module_kobject *mk,
-                 struct kernel_param *kparam,
-                 unsigned int num_params,
-                 unsigned int name_skip)
+static __modinit int add_sysfs_param(struct module_kobject *mk,
+                                    struct kernel_param *kp,
+                                    const char *name)
 {
-       struct module_param_attrs *mp;
-       unsigned int valid_attrs = 0;
-       unsigned int i, size[2];
-       struct param_attribute *pattr;
-       struct attribute **gattr;
-       int err;
-
-       for (i=0; i<num_params; i++) {
-               if (kparam[i].perm)
-                       valid_attrs++;
+       struct module_param_attrs *new;
+       struct attribute **attrs;
+       int err, num;
+
+       /* We don't bother calling this with invisible parameters. */
+       BUG_ON(!kp->perm);
+
+       if (!mk->mp) {
+               num = 0;
+               attrs = NULL;
+       } else {
+               num = mk->mp->num;
+               attrs = mk->mp->grp.attrs;
        }
 
-       if (!valid_attrs)
-               return NULL;
-
-       size[0] = ALIGN(sizeof(*mp) +
-                       valid_attrs * sizeof(mp->attrs[0]),
-                       sizeof(mp->grp.attrs[0]));
-       size[1] = (valid_attrs + 1) * sizeof(mp->grp.attrs[0]);
-
-       mp = kzalloc(size[0] + size[1], GFP_KERNEL);
-       if (!mp)
-               return ERR_PTR(-ENOMEM);
-
-       mp->grp.name = "parameters";
-       mp->grp.attrs = (void *)mp + size[0];
-
-       pattr = &mp->attrs[0];
-       gattr = &mp->grp.attrs[0];
-       for (i = 0; i < num_params; i++) {
-               struct kernel_param *kp = &kparam[i];
-               if (kp->perm) {
-                       pattr->param = kp;
-                       pattr->mattr.show = param_attr_show;
-                       pattr->mattr.store = param_attr_store;
-                       pattr->mattr.attr.name = (char *)&kp->name[name_skip];
-                       pattr->mattr.attr.mode = kp->perm;
-                       *(gattr++) = &(pattr++)->mattr.attr;
-               }
+       /* Enlarge. */
+       new = krealloc(mk->mp,
+                      sizeof(*mk->mp) + sizeof(mk->mp->attrs[0]) * (num+1),
+                      GFP_KERNEL);
+       if (!new) {
+               kfree(mk->mp);
+               err = -ENOMEM;
+               goto fail;
        }
-       *gattr = NULL;
-
-       if ((err = sysfs_create_group(&mk->kobj, &mp->grp))) {
-               kfree(mp);
-               return ERR_PTR(err);
+       attrs = krealloc(attrs, sizeof(new->grp.attrs[0])*(num+2), GFP_KERNEL);
+       if (!attrs) {
+               err = -ENOMEM;
+               goto fail_free_new;
        }
-       return mp;
+
+       /* Sysfs wants everything zeroed. */
+       memset(new, 0, sizeof(*new));
+       memset(&new->attrs[num], 0, sizeof(new->attrs[num]));
+       memset(&attrs[num], 0, sizeof(attrs[num]));
+       new->grp.name = "parameters";
+       new->grp.attrs = attrs;
+
+       /* Tack new one on the end. */
+       new->attrs[num].param = kp;
+       new->attrs[num].mattr.show = param_attr_show;
+       new->attrs[num].mattr.store = param_attr_store;
+       new->attrs[num].mattr.attr.name = (char *)name;
+       new->attrs[num].mattr.attr.mode = kp->perm;
+       new->num = num+1;
+
+       /* Fix up all the pointers, since krealloc can move us */
+       for (num = 0; num < new->num; num++)
+               new->grp.attrs[num] = &new->attrs[num].mattr.attr;
+       new->grp.attrs[num] = NULL;
+
+       mk->mp = new;
+       return 0;
+
+fail_free_new:
+       kfree(new);
+fail:
+       mk->mp = NULL;
+       return err;
 }
 
 #ifdef CONFIG_MODULES
+static void free_module_param_attrs(struct module_kobject *mk)
+{
+       kfree(mk->mp->grp.attrs);
+       kfree(mk->mp);
+       mk->mp = NULL;
+}
+
 /*
  * module_param_sysfs_setup - setup sysfs support for one module
  * @mod: module
  * @kparam: module parameters (array)
  * @num_params: number of module parameters
  *
- * Adds sysfs entries for module parameters, and creates a link from
- * /sys/module/[mod->name]/parameters to /sys/parameters/[mod->name]/
+ * Adds sysfs entries for module parameters under
+ * /sys/module/[mod->name]/parameters/
  */
 int module_param_sysfs_setup(struct module *mod,
                             struct kernel_param *kparam,
                             unsigned int num_params)
 {
-       struct module_param_attrs *mp;
+       int i, err;
+       bool params = false;
+
+       for (i = 0; i < num_params; i++) {
+               if (kparam[i].perm == 0)
+                       continue;
+               err = add_sysfs_param(&mod->mkobj, &kparam[i], kparam[i].name);
+               if (err)
+                       return err;
+               params = true;
+       }
 
-       mp = param_sysfs_setup(&mod->mkobj, kparam, num_params, 0);
-       if (IS_ERR(mp))
-               return PTR_ERR(mp);
+       if (!params)
+               return 0;
 
-       mod->param_attrs = mp;
-       return 0;
+       /* Create the param group. */
+       err = sysfs_create_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp);
+       if (err)
+               free_module_param_attrs(&mod->mkobj);
+       return err;
 }
 
 /*
@@ -532,43 +562,55 @@ int module_param_sysfs_setup(struct module *mod,
  */
 void module_param_sysfs_remove(struct module *mod)
 {
-       if (mod->param_attrs) {
-               sysfs_remove_group(&mod->mkobj.kobj,
-                                  &mod->param_attrs->grp);
+       if (mod->mkobj.mp) {
+               sysfs_remove_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp);
                /* We are positive that no one is using any param
                 * attrs at this point.  Deallocate immediately. */
-               kfree(mod->param_attrs);
-               mod->param_attrs = NULL;
+               free_module_param_attrs(&mod->mkobj);
        }
 }
 #endif
 
-/*
- * kernel_param_sysfs_setup - wrapper for built-in params support
- */
-static void __init kernel_param_sysfs_setup(const char *name,
-                                           struct kernel_param *kparam,
-                                           unsigned int num_params,
-                                           unsigned int name_skip)
+static void __init kernel_add_sysfs_param(const char *name,
+                                         struct kernel_param *kparam,
+                                         unsigned int name_skip)
 {
        struct module_kobject *mk;
-       int ret;
+       struct kobject *kobj;
+       int err;
 
-       mk = kzalloc(sizeof(struct module_kobject), GFP_KERNEL);
-       BUG_ON(!mk);
-
-       mk->mod = THIS_MODULE;
-       mk->kobj.kset = module_kset;
-       ret = kobject_init_and_add(&mk->kobj, &module_ktype, NULL, "%s", name);
-       if (ret) {
-               kobject_put(&mk->kobj);
-               printk(KERN_ERR "Module '%s' failed to be added to sysfs, "
-                     "error number %d\n", name, ret);
-               printk(KERN_ERR "The system will be unstable now.\n");
-               return;
+       kobj = kset_find_obj(module_kset, name);
+       if (kobj) {
+               /* We already have one.  Remove params so we can add more. */
+               mk = to_module_kobject(kobj);
+               /* We need to remove it before adding parameters. */
+               sysfs_remove_group(&mk->kobj, &mk->mp->grp);
+       } else {
+               mk = kzalloc(sizeof(struct module_kobject), GFP_KERNEL);
+               BUG_ON(!mk);
+
+               mk->mod = THIS_MODULE;
+               mk->kobj.kset = module_kset;
+               err = kobject_init_and_add(&mk->kobj, &module_ktype, NULL,
+                                          "%s", name);
+               if (err) {
+                       kobject_put(&mk->kobj);
+                       printk(KERN_ERR "Module '%s' failed add to sysfs, "
+                              "error number %d\n", name, err);
+                       printk(KERN_ERR "The system will be unstable now.\n");
+                       return;
+               }
+               /* So that exit path is even. */
+               kobject_get(&mk->kobj);
        }
-       param_sysfs_setup(mk, kparam, num_params, name_skip);
+
+       /* These should not fail at boot. */
+       err = add_sysfs_param(mk, kparam, kparam->name + name_skip);
+       BUG_ON(err);
+       err = sysfs_create_group(&mk->kobj, &mk->mp->grp);
+       BUG_ON(err);
        kobject_uevent(&mk->kobj, KOBJ_ADD);
+       kobject_put(&mk->kobj);
 }
 
 /*
@@ -579,60 +621,36 @@ static void __init kernel_param_sysfs_setup(const char *name,
  * The "module" name (KBUILD_MODNAME) is stored before a dot, the
  * "parameter" name is stored behind a dot in kernel_param->name. So,
  * extract the "module" name for all built-in kernel_param-eters,
- * and for all who have the same, call kernel_param_sysfs_setup.
+ * and for all who have the same, call kernel_add_sysfs_param.
  */
 static void __init param_sysfs_builtin(void)
 {
-       struct kernel_param *kp, *kp_begin = NULL;
-       unsigned int i, name_len, count = 0;
-       char modname[MODULE_NAME_LEN + 1] = "";
+       struct kernel_param *kp;
+       unsigned int name_len;
+       char modname[MODULE_NAME_LEN];
 
-       for (i=0; i < __stop___param - __start___param; i++) {
+       for (kp = __start___param; kp < __stop___param; kp++) {
                char *dot;
-               size_t max_name_len;
 
-               kp = &__start___param[i];
-               max_name_len =
-                       min_t(size_t, MODULE_NAME_LEN, strlen(kp->name));
+               if (kp->perm == 0)
+                       continue;
 
-               dot = memchr(kp->name, '.', max_name_len);
+               dot = strchr(kp->name, '.');
                if (!dot) {
-                       DEBUGP("couldn't find period in first %d characters "
-                              "of %s\n", MODULE_NAME_LEN, kp->name);
-                       continue;
-               }
-               name_len = dot - kp->name;
-
-               /* new kbuild_modname? */
-               if (strlen(modname) != name_len
-                   || strncmp(modname, kp->name, name_len) != 0) {
-                       /* add a new kobject for previous kernel_params. */
-                       if (count)
-                               kernel_param_sysfs_setup(modname,
-                                                        kp_begin,
-                                                        count,
-                                                        strlen(modname)+1);
-
-                       strncpy(modname, kp->name, name_len);
-                       modname[name_len] = '\0';
-                       count = 0;
-                       kp_begin = kp;
+                       /* This happens for core_param() */
+                       strcpy(modname, "kernel");
+                       name_len = 0;
+               } else {
+                       name_len = dot - kp->name + 1;
+                       strlcpy(modname, kp->name, name_len);
                }
-               count++;
+               kernel_add_sysfs_param(modname, kp, name_len);
        }
-
-       /* last kernel_params need to be registered as well */
-       if (count)
-               kernel_param_sysfs_setup(modname, kp_begin, count,
-                                        strlen(modname)+1);
 }
 
 
 /* module-related sysfs stuff */
 
-#define to_module_attr(n) container_of(n, struct module_attribute, attr);
-#define to_module_kobject(n) container_of(n, struct module_kobject, kobj);
-
 static ssize_t module_attr_show(struct kobject *kobj,
                                struct attribute *attr,
                                char *buf)
index c42a03aef36f07fd326eba959a90aa7bbe45dbd8..153dcb2639c3df614c7862041a9d485b7dbe6614 100644 (file)
@@ -7,6 +7,93 @@
 #include <linux/errno.h>
 #include <linux/math64.h>
 #include <asm/uaccess.h>
+#include <linux/kernel_stat.h>
+
+/*
+ * Allocate the thread_group_cputime structure appropriately and fill in the
+ * current values of the fields.  Called from copy_signal() via
+ * thread_group_cputime_clone_thread() when adding a second or subsequent
+ * thread to a thread group.  Assumes interrupts are enabled when called.
+ */
+int thread_group_cputime_alloc(struct task_struct *tsk)
+{
+       struct signal_struct *sig = tsk->signal;
+       struct task_cputime *cputime;
+
+       /*
+        * If we have multiple threads and we don't already have a
+        * per-CPU task_cputime struct (checked in the caller), allocate
+        * one and fill it in with the times accumulated so far.  We may
+        * race with another thread so recheck after we pick up the sighand
+        * lock.
+        */
+       cputime = alloc_percpu(struct task_cputime);
+       if (cputime == NULL)
+               return -ENOMEM;
+       spin_lock_irq(&tsk->sighand->siglock);
+       if (sig->cputime.totals) {
+               spin_unlock_irq(&tsk->sighand->siglock);
+               free_percpu(cputime);
+               return 0;
+       }
+       sig->cputime.totals = cputime;
+       cputime = per_cpu_ptr(sig->cputime.totals, smp_processor_id());
+       cputime->utime = tsk->utime;
+       cputime->stime = tsk->stime;
+       cputime->sum_exec_runtime = tsk->se.sum_exec_runtime;
+       spin_unlock_irq(&tsk->sighand->siglock);
+       return 0;
+}
+
+/**
+ * thread_group_cputime - Sum the thread group time fields across all CPUs.
+ *
+ * @tsk:       The task we use to identify the thread group.
+ * @times:     task_cputime structure in which we return the summed fields.
+ *
+ * Walk the list of CPUs to sum the per-CPU time fields in the thread group
+ * time structure.
+ */
+void thread_group_cputime(
+       struct task_struct *tsk,
+       struct task_cputime *times)
+{
+       struct signal_struct *sig;
+       int i;
+       struct task_cputime *tot;
+
+       sig = tsk->signal;
+       if (unlikely(!sig) || !sig->cputime.totals) {
+               times->utime = tsk->utime;
+               times->stime = tsk->stime;
+               times->sum_exec_runtime = tsk->se.sum_exec_runtime;
+               return;
+       }
+       times->stime = times->utime = cputime_zero;
+       times->sum_exec_runtime = 0;
+       for_each_possible_cpu(i) {
+               tot = per_cpu_ptr(tsk->signal->cputime.totals, i);
+               times->utime = cputime_add(times->utime, tot->utime);
+               times->stime = cputime_add(times->stime, tot->stime);
+               times->sum_exec_runtime += tot->sum_exec_runtime;
+       }
+}
+
+/*
+ * Called after updating RLIMIT_CPU to set timer expiration if necessary.
+ */
+void update_rlimit_cpu(unsigned long rlim_new)
+{
+       cputime_t cputime;
+
+       cputime = secs_to_cputime(rlim_new);
+       if (cputime_eq(current->signal->it_prof_expires, cputime_zero) ||
+           cputime_lt(current->signal->it_prof_expires, cputime)) {
+               spin_lock_irq(&current->sighand->siglock);
+               set_process_cpu_timer(current, CPUCLOCK_PROF, &cputime, NULL);
+               spin_unlock_irq(&current->sighand->siglock);
+       }
+}
 
 static int check_clock(const clockid_t which_clock)
 {
@@ -158,10 +245,6 @@ static inline cputime_t virt_ticks(struct task_struct *p)
 {
        return p->utime;
 }
-static inline unsigned long long sched_ns(struct task_struct *p)
-{
-       return task_sched_runtime(p);
-}
 
 int posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *tp)
 {
@@ -211,7 +294,7 @@ static int cpu_clock_sample(const clockid_t which_clock, struct task_struct *p,
                cpu->cpu = virt_ticks(p);
                break;
        case CPUCLOCK_SCHED:
-               cpu->sched = sched_ns(p);
+               cpu->sched = p->se.sum_exec_runtime + task_delta_exec(p);
                break;
        }
        return 0;
@@ -220,59 +303,30 @@ static int cpu_clock_sample(const clockid_t which_clock, struct task_struct *p,
 /*
  * Sample a process (thread group) clock for the given group_leader task.
  * Must be called with tasklist_lock held for reading.
- * Must be called with tasklist_lock held for reading, and p->sighand->siglock.
  */
-static int cpu_clock_sample_group_locked(unsigned int clock_idx,
-                                        struct task_struct *p,
-                                        union cpu_time_count *cpu)
+static int cpu_clock_sample_group(const clockid_t which_clock,
+                                 struct task_struct *p,
+                                 union cpu_time_count *cpu)
 {
-       struct task_struct *t = p;
-       switch (clock_idx) {
+       struct task_cputime cputime;
+
+       thread_group_cputime(p, &cputime);
+       switch (which_clock) {
        default:
                return -EINVAL;
        case CPUCLOCK_PROF:
-               cpu->cpu = cputime_add(p->signal->utime, p->signal->stime);
-               do {
-                       cpu->cpu = cputime_add(cpu->cpu, prof_ticks(t));
-                       t = next_thread(t);
-               } while (t != p);
+               cpu->cpu = cputime_add(cputime.utime, cputime.stime);
                break;
        case CPUCLOCK_VIRT:
-               cpu->cpu = p->signal->utime;
-               do {
-                       cpu->cpu = cputime_add(cpu->cpu, virt_ticks(t));
-                       t = next_thread(t);
-               } while (t != p);
+               cpu->cpu = cputime.utime;
                break;
        case CPUCLOCK_SCHED:
-               cpu->sched = p->signal->sum_sched_runtime;
-               /* Add in each other live thread.  */
-               while ((t = next_thread(t)) != p) {
-                       cpu->sched += t->se.sum_exec_runtime;
-               }
-               cpu->sched += sched_ns(p);
+               cpu->sched = cputime.sum_exec_runtime + task_delta_exec(p);
                break;
        }
        return 0;
 }
 
-/*
- * Sample a process (thread group) clock for the given group_leader task.
- * Must be called with tasklist_lock held for reading.
- */
-static int cpu_clock_sample_group(const clockid_t which_clock,
-                                 struct task_struct *p,
-                                 union cpu_time_count *cpu)
-{
-       int ret;
-       unsigned long flags;
-       spin_lock_irqsave(&p->sighand->siglock, flags);
-       ret = cpu_clock_sample_group_locked(CPUCLOCK_WHICH(which_clock), p,
-                                           cpu);
-       spin_unlock_irqrestore(&p->sighand->siglock, flags);
-       return ret;
-}
-
 
 int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp)
 {
@@ -471,80 +525,11 @@ void posix_cpu_timers_exit(struct task_struct *tsk)
 }
 void posix_cpu_timers_exit_group(struct task_struct *tsk)
 {
-       cleanup_timers(tsk->signal->cpu_timers,
-                      cputime_add(tsk->utime, tsk->signal->utime),
-                      cputime_add(tsk->stime, tsk->signal->stime),
-                    tsk->se.sum_exec_runtime + tsk->signal->sum_sched_runtime);
-}
+       struct task_cputime cputime;
 
-
-/*
- * Set the expiry times of all the threads in the process so one of them
- * will go off before the process cumulative expiry total is reached.
- */
-static void process_timer_rebalance(struct task_struct *p,
-                                   unsigned int clock_idx,
-                                   union cpu_time_count expires,
-                                   union cpu_time_count val)
-{
-       cputime_t ticks, left;
-       unsigned long long ns, nsleft;
-       struct task_struct *t = p;
-       unsigned int nthreads = atomic_read(&p->signal->live);
-
-       if (!nthreads)
-               return;
-
-       switch (clock_idx) {
-       default:
-               BUG();
-               break;
-       case CPUCLOCK_PROF:
-               left = cputime_div_non_zero(cputime_sub(expires.cpu, val.cpu),
-                                      nthreads);
-               do {
-                       if (likely(!(t->flags & PF_EXITING))) {
-                               ticks = cputime_add(prof_ticks(t), left);
-                               if (cputime_eq(t->it_prof_expires,
-                                              cputime_zero) ||
-                                   cputime_gt(t->it_prof_expires, ticks)) {
-                                       t->it_prof_expires = ticks;
-                               }
-                       }
-                       t = next_thread(t);
-               } while (t != p);
-               break;
-       case CPUCLOCK_VIRT:
-               left = cputime_div_non_zero(cputime_sub(expires.cpu, val.cpu),
-                                      nthreads);
-               do {
-                       if (likely(!(t->flags & PF_EXITING))) {
-                               ticks = cputime_add(virt_ticks(t), left);
-                               if (cputime_eq(t->it_virt_expires,
-                                              cputime_zero) ||
-                                   cputime_gt(t->it_virt_expires, ticks)) {
-                                       t->it_virt_expires = ticks;
-                               }
-                       }
-                       t = next_thread(t);
-               } while (t != p);
-               break;
-       case CPUCLOCK_SCHED:
-               nsleft = expires.sched - val.sched;
-               do_div(nsleft, nthreads);
-               nsleft = max_t(unsigned long long, nsleft, 1);
-               do {
-                       if (likely(!(t->flags & PF_EXITING))) {
-                               ns = t->se.sum_exec_runtime + nsleft;
-                               if (t->it_sched_expires == 0 ||
-                                   t->it_sched_expires > ns) {
-                                       t->it_sched_expires = ns;
-                               }
-                       }
-                       t = next_thread(t);
-               } while (t != p);
-               break;
-       }
+       thread_group_cputime(tsk, &cputime);
+       cleanup_timers(tsk->signal->cpu_timers,
+                      cputime.utime, cputime.stime, cputime.sum_exec_runtime);
 }
 
 static void clear_dead_task(struct k_itimer *timer, union cpu_time_count now)
@@ -608,29 +593,32 @@ static void arm_timer(struct k_itimer *timer, union cpu_time_count now)
                        default:
                                BUG();
                        case CPUCLOCK_PROF:
-                               if (cputime_eq(p->it_prof_expires,
+                               if (cputime_eq(p->cputime_expires.prof_exp,
                                               cputime_zero) ||
-                                   cputime_gt(p->it_prof_expires,
+                                   cputime_gt(p->cputime_expires.prof_exp,
                                               nt->expires.cpu))
-                                       p->it_prof_expires = nt->expires.cpu;
+                                       p->cputime_expires.prof_exp =
+                                               nt->expires.cpu;
                                break;
                        case CPUCLOCK_VIRT:
-                               if (cputime_eq(p->it_virt_expires,
+                               if (cputime_eq(p->cputime_expires.virt_exp,
                                               cputime_zero) ||
-                                   cputime_gt(p->it_virt_expires,
+                                   cputime_gt(p->cputime_expires.virt_exp,
                                               nt->expires.cpu))
-                                       p->it_virt_expires = nt->expires.cpu;
+                                       p->cputime_expires.virt_exp =
+                                               nt->expires.cpu;
                                break;
                        case CPUCLOCK_SCHED:
-                               if (p->it_sched_expires == 0 ||
-                                   p->it_sched_expires > nt->expires.sched)
-                                       p->it_sched_expires = nt->expires.sched;
+                               if (p->cputime_expires.sched_exp == 0 ||
+                                   p->cputime_expires.sched_exp >
+                                                       nt->expires.sched)
+                                       p->cputime_expires.sched_exp =
+                                               nt->expires.sched;
                                break;
                        }
                } else {
                        /*
-                        * For a process timer, we must balance
-                        * all the live threads' expirations.
+                        * For a process timer, set the cached expiration time.
                         */
                        switch (CPUCLOCK_WHICH(timer->it_clock)) {
                        default:
@@ -641,7 +629,9 @@ static void arm_timer(struct k_itimer *timer, union cpu_time_count now)
                                    cputime_lt(p->signal->it_virt_expires,
                                               timer->it.cpu.expires.cpu))
                                        break;
-                               goto rebalance;
+                               p->signal->cputime_expires.virt_exp =
+                                       timer->it.cpu.expires.cpu;
+                               break;
                        case CPUCLOCK_PROF:
                                if (!cputime_eq(p->signal->it_prof_expires,
                                                cputime_zero) &&
@@ -652,13 +642,12 @@ static void arm_timer(struct k_itimer *timer, union cpu_time_count now)
                                if (i != RLIM_INFINITY &&
                                    i <= cputime_to_secs(timer->it.cpu.expires.cpu))
                                        break;
-                               goto rebalance;
+                               p->signal->cputime_expires.prof_exp =
+                                       timer->it.cpu.expires.cpu;
+                               break;
                        case CPUCLOCK_SCHED:
-                       rebalance:
-                               process_timer_rebalance(
-                                       timer->it.cpu.task,
-                                       CPUCLOCK_WHICH(timer->it_clock),
-                                       timer->it.cpu.expires, now);
+                               p->signal->cputime_expires.sched_exp =
+                                       timer->it.cpu.expires.sched;
                                break;
                        }
                }
@@ -969,13 +958,13 @@ static void check_thread_timers(struct task_struct *tsk,
        struct signal_struct *const sig = tsk->signal;
 
        maxfire = 20;
-       tsk->it_prof_expires = cputime_zero;
+       tsk->cputime_expires.prof_exp = cputime_zero;
        while (!list_empty(timers)) {
                struct cpu_timer_list *t = list_first_entry(timers,
                                                      struct cpu_timer_list,
                                                      entry);
                if (!--maxfire || cputime_lt(prof_ticks(tsk), t->expires.cpu)) {
-                       tsk->it_prof_expires = t->expires.cpu;
+                       tsk->cputime_expires.prof_exp = t->expires.cpu;
                        break;
                }
                t->firing = 1;
@@ -984,13 +973,13 @@ static void check_thread_timers(struct task_struct *tsk,
 
        ++timers;
        maxfire = 20;
-       tsk->it_virt_expires = cputime_zero;
+       tsk->cputime_expires.virt_exp = cputime_zero;
        while (!list_empty(timers)) {
                struct cpu_timer_list *t = list_first_entry(timers,
                                                      struct cpu_timer_list,
                                                      entry);
                if (!--maxfire || cputime_lt(virt_ticks(tsk), t->expires.cpu)) {
-                       tsk->it_virt_expires = t->expires.cpu;
+                       tsk->cputime_expires.virt_exp = t->expires.cpu;
                        break;
                }
                t->firing = 1;
@@ -999,13 +988,13 @@ static void check_thread_timers(struct task_struct *tsk,
 
        ++timers;
        maxfire = 20;
-       tsk->it_sched_expires = 0;
+       tsk->cputime_expires.sched_exp = 0;
        while (!list_empty(timers)) {
                struct cpu_timer_list *t = list_first_entry(timers,
                                                      struct cpu_timer_list,
                                                      entry);
                if (!--maxfire || tsk->se.sum_exec_runtime < t->expires.sched) {
-                       tsk->it_sched_expires = t->expires.sched;
+                       tsk->cputime_expires.sched_exp = t->expires.sched;
                        break;
                }
                t->firing = 1;
@@ -1055,10 +1044,10 @@ static void check_process_timers(struct task_struct *tsk,
 {
        int maxfire;
        struct signal_struct *const sig = tsk->signal;
-       cputime_t utime, stime, ptime, virt_expires, prof_expires;
+       cputime_t utime, ptime, virt_expires, prof_expires;
        unsigned long long sum_sched_runtime, sched_expires;
-       struct task_struct *t;
        struct list_head *timers = sig->cpu_timers;
+       struct task_cputime cputime;
 
        /*
         * Don't sample the current process CPU clocks if there are no timers.
@@ -1074,18 +1063,10 @@ static void check_process_timers(struct task_struct *tsk,
        /*
         * Collect the current process totals.
         */
-       utime = sig->utime;
-       stime = sig->stime;
-       sum_sched_runtime = sig->sum_sched_runtime;
-       t = tsk;
-       do {
-               utime = cputime_add(utime, t->utime);
-               stime = cputime_add(stime, t->stime);
-               sum_sched_runtime += t->se.sum_exec_runtime;
-               t = next_thread(t);
-       } while (t != tsk);
-       ptime = cputime_add(utime, stime);
-
+       thread_group_cputime(tsk, &cputime);
+       utime = cputime.utime;
+       ptime = cputime_add(utime, cputime.stime);
+       sum_sched_runtime = cputime.sum_exec_runtime;
        maxfire = 20;
        prof_expires = cputime_zero;
        while (!list_empty(timers)) {
@@ -1193,60 +1174,18 @@ static void check_process_timers(struct task_struct *tsk,
                }
        }
 
-       if (!cputime_eq(prof_expires, cputime_zero) ||
-           !cputime_eq(virt_expires, cputime_zero) ||
-           sched_expires != 0) {
-               /*
-                * Rebalance the threads' expiry times for the remaining
-                * process CPU timers.
-                */
-
-               cputime_t prof_left, virt_left, ticks;
-               unsigned long long sched_left, sched;
-               const unsigned int nthreads = atomic_read(&sig->live);
-
-               if (!nthreads)
-                       return;
-
-               prof_left = cputime_sub(prof_expires, utime);
-               prof_left = cputime_sub(prof_left, stime);
-               prof_left = cputime_div_non_zero(prof_left, nthreads);
-               virt_left = cputime_sub(virt_expires, utime);
-               virt_left = cputime_div_non_zero(virt_left, nthreads);
-               if (sched_expires) {
-                       sched_left = sched_expires - sum_sched_runtime;
-                       do_div(sched_left, nthreads);
-                       sched_left = max_t(unsigned long long, sched_left, 1);
-               } else {
-                       sched_left = 0;
-               }
-               t = tsk;
-               do {
-                       if (unlikely(t->flags & PF_EXITING))
-                               continue;
-
-                       ticks = cputime_add(cputime_add(t->utime, t->stime),
-                                           prof_left);
-                       if (!cputime_eq(prof_expires, cputime_zero) &&
-                           (cputime_eq(t->it_prof_expires, cputime_zero) ||
-                            cputime_gt(t->it_prof_expires, ticks))) {
-                               t->it_prof_expires = ticks;
-                       }
-
-                       ticks = cputime_add(t->utime, virt_left);
-                       if (!cputime_eq(virt_expires, cputime_zero) &&
-                           (cputime_eq(t->it_virt_expires, cputime_zero) ||
-                            cputime_gt(t->it_virt_expires, ticks))) {
-                               t->it_virt_expires = ticks;
-                       }
-
-                       sched = t->se.sum_exec_runtime + sched_left;
-                       if (sched_expires && (t->it_sched_expires == 0 ||
-                                             t->it_sched_expires > sched)) {
-                               t->it_sched_expires = sched;
-                       }
-               } while ((t = next_thread(t)) != tsk);
-       }
+       if (!cputime_eq(prof_expires, cputime_zero) &&
+           (cputime_eq(sig->cputime_expires.prof_exp, cputime_zero) ||
+            cputime_gt(sig->cputime_expires.prof_exp, prof_expires)))
+               sig->cputime_expires.prof_exp = prof_expires;
+       if (!cputime_eq(virt_expires, cputime_zero) &&
+           (cputime_eq(sig->cputime_expires.virt_exp, cputime_zero) ||
+            cputime_gt(sig->cputime_expires.virt_exp, virt_expires)))
+               sig->cputime_expires.virt_exp = virt_expires;
+       if (sched_expires != 0 &&
+           (sig->cputime_expires.sched_exp == 0 ||
+            sig->cputime_expires.sched_exp > sched_expires))
+               sig->cputime_expires.sched_exp = sched_expires;
 }
 
 /*
@@ -1314,6 +1253,86 @@ out:
        ++timer->it_requeue_pending;
 }
 
+/**
+ * task_cputime_zero - Check a task_cputime struct for all zero fields.
+ *
+ * @cputime:   The struct to compare.
+ *
+ * Checks @cputime to see if all fields are zero.  Returns true if all fields
+ * are zero, false if any field is nonzero.
+ */
+static inline int task_cputime_zero(const struct task_cputime *cputime)
+{
+       if (cputime_eq(cputime->utime, cputime_zero) &&
+           cputime_eq(cputime->stime, cputime_zero) &&
+           cputime->sum_exec_runtime == 0)
+               return 1;
+       return 0;
+}
+
+/**
+ * task_cputime_expired - Compare two task_cputime entities.
+ *
+ * @sample:    The task_cputime structure to be checked for expiration.
+ * @expires:   Expiration times, against which @sample will be checked.
+ *
+ * Checks @sample against @expires to see if any field of @sample has expired.
+ * Returns true if any field of the former is greater than the corresponding
+ * field of the latter if the latter field is set.  Otherwise returns false.
+ */
+static inline int task_cputime_expired(const struct task_cputime *sample,
+                                       const struct task_cputime *expires)
+{
+       if (!cputime_eq(expires->utime, cputime_zero) &&
+           cputime_ge(sample->utime, expires->utime))
+               return 1;
+       if (!cputime_eq(expires->stime, cputime_zero) &&
+           cputime_ge(cputime_add(sample->utime, sample->stime),
+                      expires->stime))
+               return 1;
+       if (expires->sum_exec_runtime != 0 &&
+           sample->sum_exec_runtime >= expires->sum_exec_runtime)
+               return 1;
+       return 0;
+}
+
+/**
+ * fastpath_timer_check - POSIX CPU timers fast path.
+ *
+ * @tsk:       The task (thread) being checked.
+ *
+ * Check the task and thread group timers.  If both are zero (there are no
+ * timers set) return false.  Otherwise snapshot the task and thread group
+ * timers and compare them with the corresponding expiration times.  Return
+ * true if a timer has expired, else return false.
+ */
+static inline int fastpath_timer_check(struct task_struct *tsk)
+{
+       struct signal_struct *sig = tsk->signal;
+
+       if (unlikely(!sig))
+               return 0;
+
+       if (!task_cputime_zero(&tsk->cputime_expires)) {
+               struct task_cputime task_sample = {
+                       .utime = tsk->utime,
+                       .stime = tsk->stime,
+                       .sum_exec_runtime = tsk->se.sum_exec_runtime
+               };
+
+               if (task_cputime_expired(&task_sample, &tsk->cputime_expires))
+                       return 1;
+       }
+       if (!task_cputime_zero(&sig->cputime_expires)) {
+               struct task_cputime group_sample;
+
+               thread_group_cputime(tsk, &group_sample);
+               if (task_cputime_expired(&group_sample, &sig->cputime_expires))
+                       return 1;
+       }
+       return 0;
+}
+
 /*
  * This is called from the timer interrupt handler.  The irq handler has
  * already updated our counts.  We need to check if any timers fire now.
@@ -1326,42 +1345,31 @@ void run_posix_cpu_timers(struct task_struct *tsk)
 
        BUG_ON(!irqs_disabled());
 
-#define UNEXPIRED(clock) \
-               (cputime_eq(tsk->it_##clock##_expires, cputime_zero) || \
-                cputime_lt(clock##_ticks(tsk), tsk->it_##clock##_expires))
-
-       if (UNEXPIRED(prof) && UNEXPIRED(virt) &&
-           (tsk->it_sched_expires == 0 ||
-            tsk->se.sum_exec_runtime < tsk->it_sched_expires))
+       /*
+        * The fast path checks that there are no expired thread or thread
+        * group timers.  If that's so, just return.
+        */
+       if (!fastpath_timer_check(tsk))
                return;
 
-#undef UNEXPIRED
-
+       spin_lock(&tsk->sighand->siglock);
        /*
-        * Double-check with locks held.
+        * Here we take off tsk->signal->cpu_timers[N] and
+        * tsk->cpu_timers[N] all the timers that are firing, and
+        * put them on the firing list.
         */
-       read_lock(&tasklist_lock);
-       if (likely(tsk->signal != NULL)) {
-               spin_lock(&tsk->sighand->siglock);
+       check_thread_timers(tsk, &firing);
+       check_process_timers(tsk, &firing);
 
-               /*
-                * Here we take off tsk->cpu_timers[N] and tsk->signal->cpu_timers[N]
-                * all the timers that are firing, and put them on the firing list.
-                */
-               check_thread_timers(tsk, &firing);
-               check_process_timers(tsk, &firing);
-
-               /*
-                * We must release these locks before taking any timer's lock.
-                * There is a potential race with timer deletion here, as the
-                * siglock now protects our private firing list.  We have set
-                * the firing flag in each timer, so that a deletion attempt
-                * that gets the timer lock before we do will give it up and
-                * spin until we've taken care of that timer below.
-                */
-               spin_unlock(&tsk->sighand->siglock);
-       }
-       read_unlock(&tasklist_lock);
+       /*
+        * We must release these locks before taking any timer's lock.
+        * There is a potential race with timer deletion here, as the
+        * siglock now protects our private firing list.  We have set
+        * the firing flag in each timer, so that a deletion attempt
+        * that gets the timer lock before we do will give it up and
+        * spin until we've taken care of that timer below.
+        */
+       spin_unlock(&tsk->sighand->siglock);
 
        /*
         * Now that all the timers on our list have the firing flag,
@@ -1389,10 +1397,9 @@ void run_posix_cpu_timers(struct task_struct *tsk)
 
 /*
  * Set one of the process-wide special case CPU timers.
- * The tasklist_lock and tsk->sighand->siglock must be held by the caller.
- * The oldval argument is null for the RLIMIT_CPU timer, where *newval is
- * absolute; non-null for ITIMER_*, where *newval is relative and we update
- * it to be absolute, *oldval is absolute and we update it to be relative.
+ * The tsk->sighand->siglock must be held by the caller.
+ * The *newval argument is relative and we update it to be absolute, *oldval
+ * is absolute and we update it to be relative.
  */
 void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
                           cputime_t *newval, cputime_t *oldval)
@@ -1401,7 +1408,7 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
        struct list_head *head;
 
        BUG_ON(clock_idx == CPUCLOCK_SCHED);
-       cpu_clock_sample_group_locked(clock_idx, tsk, &now);
+       cpu_clock_sample_group(clock_idx, tsk, &now);
 
        if (oldval) {
                if (!cputime_eq(*oldval, cputime_zero)) {
@@ -1435,13 +1442,14 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
            cputime_ge(list_first_entry(head,
                                  struct cpu_timer_list, entry)->expires.cpu,
                       *newval)) {
-               /*
-                * Rejigger each thread's expiry time so that one will
-                * notice before we hit the process-cumulative expiry time.
-                */
-               union cpu_time_count expires = { .sched = 0 };
-               expires.cpu = *newval;
-               process_timer_rebalance(tsk, clock_idx, expires, now);
+               switch (clock_idx) {
+               case CPUCLOCK_PROF:
+                       tsk->signal->cputime_expires.prof_exp = *newval;
+                       break;
+               case CPUCLOCK_VIRT:
+                       tsk->signal->cputime_expires.virt_exp = *newval;
+                       break;
+               }
        }
 }
 
index 5131e5471169226ef8db42f20792c8ffdac6d12b..5e79c662294bf542750af232be67a1e92bed858d 100644 (file)
@@ -222,6 +222,15 @@ static int posix_ktime_get_ts(clockid_t which_clock, struct timespec *tp)
        return 0;
 }
 
+/*
+ * Get monotonic time for posix timers
+ */
+static int posix_get_monotonic_raw(clockid_t which_clock, struct timespec *tp)
+{
+       getrawmonotonic(tp);
+       return 0;
+}
+
 /*
  * Initialize everything, well, just everything in Posix clocks/timers ;)
  */
@@ -235,9 +244,15 @@ static __init int init_posix_timers(void)
                .clock_get = posix_ktime_get_ts,
                .clock_set = do_posix_clock_nosettime,
        };
+       struct k_clock clock_monotonic_raw = {
+               .clock_getres = hrtimer_get_res,
+               .clock_get = posix_get_monotonic_raw,
+               .clock_set = do_posix_clock_nosettime,
+       };
 
        register_posix_clock(CLOCK_REALTIME, &clock_realtime);
        register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
+       register_posix_clock(CLOCK_MONOTONIC_RAW, &clock_monotonic_raw);
 
        posix_timers_cache = kmem_cache_create("posix_timers_cache",
                                        sizeof (struct k_itimer), 0, SLAB_PANIC,
@@ -298,6 +313,7 @@ void do_schedule_next_timer(struct siginfo *info)
 
 int posix_timer_event(struct k_itimer *timr, int si_private)
 {
+       int shared, ret;
        /*
         * FIXME: if ->sigq is queued we can race with
         * dequeue_signal()->do_schedule_next_timer().
@@ -311,25 +327,10 @@ int posix_timer_event(struct k_itimer *timr, int si_private)
         */
        timr->sigq->info.si_sys_private = si_private;
 
-       timr->sigq->info.si_signo = timr->it_sigev_signo;
-       timr->sigq->info.si_code = SI_TIMER;
-       timr->sigq->info.si_tid = timr->it_id;
-       timr->sigq->info.si_value = timr->it_sigev_value;
-
-       if (timr->it_sigev_notify & SIGEV_THREAD_ID) {
-               struct task_struct *leader;
-               int ret = send_sigqueue(timr->sigq, timr->it_process, 0);
-
-               if (likely(ret >= 0))
-                       return ret;
-
-               timr->it_sigev_notify = SIGEV_SIGNAL;
-               leader = timr->it_process->group_leader;
-               put_task_struct(timr->it_process);
-               timr->it_process = leader;
-       }
-
-       return send_sigqueue(timr->sigq, timr->it_process, 1);
+       shared = !(timr->it_sigev_notify & SIGEV_THREAD_ID);
+       ret = send_sigqueue(timr->sigq, timr->it_process, shared);
+       /* If we failed to send the signal the timer stops. */
+       return ret > 0;
 }
 EXPORT_SYMBOL_GPL(posix_timer_event);
 
@@ -468,11 +469,9 @@ sys_timer_create(const clockid_t which_clock,
                 struct sigevent __user *timer_event_spec,
                 timer_t __user * created_timer_id)
 {
-       int error = 0;
-       struct k_itimer *new_timer = NULL;
-       int new_timer_id;
-       struct task_struct *process = NULL;
-       unsigned long flags;
+       struct k_itimer *new_timer;
+       int error, new_timer_id;
+       struct task_struct *process;
        sigevent_t event;
        int it_id_set = IT_ID_NOT_SET;
 
@@ -490,12 +489,11 @@ sys_timer_create(const clockid_t which_clock,
                goto out;
        }
        spin_lock_irq(&idr_lock);
-       error = idr_get_new(&posix_timers_id, (void *) new_timer,
-                           &new_timer_id);
+       error = idr_get_new(&posix_timers_id, new_timer, &new_timer_id);
        spin_unlock_irq(&idr_lock);
-       if (error == -EAGAIN)
-               goto retry;
-       else if (error) {
+       if (error) {
+               if (error == -EAGAIN)
+                       goto retry;
                /*
                 * Weird looking, but we return EAGAIN if the IDR is
                 * full (proper POSIX return value for this)
@@ -526,67 +524,43 @@ sys_timer_create(const clockid_t which_clock,
                        error = -EFAULT;
                        goto out;
                }
-               new_timer->it_sigev_notify = event.sigev_notify;
-               new_timer->it_sigev_signo = event.sigev_signo;
-               new_timer->it_sigev_value = event.sigev_value;
-
-               read_lock(&tasklist_lock);
-               if ((process = good_sigevent(&event))) {
-                       /*
-                        * We may be setting up this process for another
-                        * thread.  It may be exiting.  To catch this
-                        * case the we check the PF_EXITING flag.  If
-                        * the flag is not set, the siglock will catch
-                        * him before it is too late (in exit_itimers).
-                        *
-                        * The exec case is a bit more invloved but easy
-                        * to code.  If the process is in our thread
-                        * group (and it must be or we would not allow
-                        * it here) and is doing an exec, it will cause
-                        * us to be killed.  In this case it will wait
-                        * for us to die which means we can finish this
-                        * linkage with our last gasp. I.e. no code :)
-                        */
-                       spin_lock_irqsave(&process->sighand->siglock, flags);
-                       if (!(process->flags & PF_EXITING)) {
-                               new_timer->it_process = process;
-                               list_add(&new_timer->list,
-                                        &process->signal->posix_timers);
-                               if (new_timer->it_sigev_notify == (SIGEV_SIGNAL|SIGEV_THREAD_ID))
-                                       get_task_struct(process);
-                               spin_unlock_irqrestore(&process->sighand->siglock, flags);
-                       } else {
-                               spin_unlock_irqrestore(&process->sighand->siglock, flags);
-                               process = NULL;
-                       }
-               }
-               read_unlock(&tasklist_lock);
+               rcu_read_lock();
+               process = good_sigevent(&event);
+               if (process)
+                       get_task_struct(process);
+               rcu_read_unlock();
                if (!process) {
                        error = -EINVAL;
                        goto out;
                }
        } else {
-               new_timer->it_sigev_notify = SIGEV_SIGNAL;
-               new_timer->it_sigev_signo = SIGALRM;
-               new_timer->it_sigev_value.sival_int = new_timer->it_id;
+               event.sigev_notify = SIGEV_SIGNAL;
+               event.sigev_signo = SIGALRM;
+               event.sigev_value.sival_int = new_timer->it_id;
                process = current->group_leader;
-               spin_lock_irqsave(&process->sighand->siglock, flags);
-               new_timer->it_process = process;
-               list_add(&new_timer->list, &process->signal->posix_timers);
-               spin_unlock_irqrestore(&process->sighand->siglock, flags);
+               get_task_struct(process);
        }
 
+       new_timer->it_sigev_notify     = event.sigev_notify;
+       new_timer->sigq->info.si_signo = event.sigev_signo;
+       new_timer->sigq->info.si_value = event.sigev_value;
+       new_timer->sigq->info.si_tid   = new_timer->it_id;
+       new_timer->sigq->info.si_code  = SI_TIMER;
+
+       spin_lock_irq(&current->sighand->siglock);
+       new_timer->it_process = process;
+       list_add(&new_timer->list, &current->signal->posix_timers);
+       spin_unlock_irq(&current->sighand->siglock);
+
+       return 0;
        /*
         * In the case of the timer belonging to another task, after
         * the task is unlocked, the timer is owned by the other task
         * and may cease to exist at any time.  Don't use or modify
         * new_timer after the unlock call.
         */
-
 out:
-       if (error)
-               release_posix_timer(new_timer, it_id_set);
-
+       release_posix_timer(new_timer, it_id_set);
        return error;
 }
 
@@ -597,7 +571,7 @@ out:
  * the find to the timer lock.  To avoid a dead lock, the timer id MUST
  * be release with out holding the timer lock.
  */
-static struct k_itimer * lock_timer(timer_t timer_id, unsigned long *flags)
+static struct k_itimer *lock_timer(timer_t timer_id, unsigned long *flags)
 {
        struct k_itimer *timr;
        /*
@@ -605,23 +579,20 @@ static struct k_itimer * lock_timer(timer_t timer_id, unsigned long *flags)
         * flags part over to the timer lock.  Must not let interrupts in
         * while we are moving the lock.
         */
-
        spin_lock_irqsave(&idr_lock, *flags);
-       timr = (struct k_itimer *) idr_find(&posix_timers_id, (int) timer_id);
+       timr = idr_find(&posix_timers_id, (int)timer_id);
        if (timr) {
                spin_lock(&timr->it_lock);
-
-               if ((timr->it_id != timer_id) || !(timr->it_process) ||
-                               !same_thread_group(timr->it_process, current)) {
-                       spin_unlock(&timr->it_lock);
-                       spin_unlock_irqrestore(&idr_lock, *flags);
-                       timr = NULL;
-               } else
+               if (timr->it_process &&
+                   same_thread_group(timr->it_process, current)) {
                        spin_unlock(&idr_lock);
-       } else
-               spin_unlock_irqrestore(&idr_lock, *flags);
+                       return timr;
+               }
+               spin_unlock(&timr->it_lock);
+       }
+       spin_unlock_irqrestore(&idr_lock, *flags);
 
-       return timr;
+       return NULL;
 }
 
 /*
@@ -668,7 +639,7 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
            (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE))
                timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv);
 
-       remaining = ktime_sub(timer->expires, now);
+       remaining = ktime_sub(hrtimer_get_expires(timer), now);
        /* Return 0 only, when the timer is expired and not pending */
        if (remaining.tv64 <= 0) {
                /*
@@ -762,7 +733,7 @@ common_timer_set(struct k_itimer *timr, int flags,
        hrtimer_init(&timr->it.real.timer, timr->it_clock, mode);
        timr->it.real.timer.function = posix_timer_fn;
 
-       timer->expires = timespec_to_ktime(new_setting->it_value);
+       hrtimer_set_expires(timer, timespec_to_ktime(new_setting->it_value));
 
        /* Convert interval */
        timr->it.real.interval = timespec_to_ktime(new_setting->it_interval);
@@ -771,14 +742,12 @@ common_timer_set(struct k_itimer *timr, int flags,
        if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) {
                /* Setup correct expiry time for relative timers */
                if (mode == HRTIMER_MODE_REL) {
-                       timer->expires =
-                               ktime_add_safe(timer->expires,
-                                              timer->base->get_time());
+                       hrtimer_add_expires(timer, timer->base->get_time());
                }
                return 0;
        }
 
-       hrtimer_start(timer, timer->expires, mode);
+       hrtimer_start_expires(timer, mode);
        return 0;
 }
 
@@ -862,8 +831,7 @@ retry_delete:
         * This keeps any tasks waiting on the spin lock from thinking
         * they got something (see the lock code above).
         */
-       if (timer->it_sigev_notify == (SIGEV_SIGNAL|SIGEV_THREAD_ID))
-               put_task_struct(timer->it_process);
+       put_task_struct(timer->it_process);
        timer->it_process = NULL;
 
        unlock_timer(timer, flags);
@@ -890,8 +858,7 @@ retry_delete:
         * This keeps any tasks waiting on the spin lock from thinking
         * they got something (see the lock code above).
         */
-       if (timer->it_sigev_notify == (SIGEV_SIGNAL|SIGEV_THREAD_ID))
-               put_task_struct(timer->it_process);
+       put_task_struct(timer->it_process);
        timer->it_process = NULL;
 
        unlock_timer(timer, flags);
index 331f9836383feaba687c89c3e4596edff76fb2fe..c9d74083746f8839f96a5a37888302c41245797e 100644 (file)
@@ -651,7 +651,7 @@ static int software_resume(void)
        pr_debug("PM: Preparing processes for restore.\n");
        error = prepare_processes();
        if (error) {
-               swsusp_close();
+               swsusp_close(FMODE_READ);
                goto Done;
        }
 
index acc0c101dbd54a510049a329260434d56b3c12f9..46b5ec7a3afb243050d04816990780966bab69bc 100644 (file)
@@ -153,7 +153,7 @@ extern int swsusp_shrink_memory(void);
 extern void swsusp_free(void);
 extern int swsusp_read(unsigned int *flags_p);
 extern int swsusp_write(unsigned int flags);
-extern void swsusp_close(void);
+extern void swsusp_close(fmode_t);
 
 struct timeval;
 /* kernel/power/swsusp.c */
index 80ccac849e4639f0b6224dead782aef918fdeec9..b7713b53d07a7a17a97130b81bf9b5946e8f1d29 100644 (file)
@@ -172,13 +172,13 @@ static int swsusp_swap_check(void) /* This is called before saving image */
                return res;
 
        root_swap = res;
-       res = blkdev_get(resume_bdev, FMODE_WRITE, O_RDWR);
+       res = blkdev_get(resume_bdev, FMODE_WRITE);
        if (res)
                return res;
 
        res = set_blocksize(resume_bdev, PAGE_SIZE);
        if (res < 0)
-               blkdev_put(resume_bdev);
+               blkdev_put(resume_bdev, FMODE_WRITE);
 
        return res;
 }
@@ -426,7 +426,7 @@ int swsusp_write(unsigned int flags)
 
        release_swap_writer(&handle);
  out:
-       swsusp_close();
+       swsusp_close(FMODE_WRITE);
        return error;
 }
 
@@ -574,7 +574,7 @@ int swsusp_read(unsigned int *flags_p)
                error = load_image(&handle, &snapshot, header->pages - 1);
        release_swap_reader(&handle);
 
-       blkdev_put(resume_bdev);
+       blkdev_put(resume_bdev, FMODE_READ);
 
        if (!error)
                pr_debug("PM: Image successfully loaded\n");
@@ -609,7 +609,7 @@ int swsusp_check(void)
                        return -EINVAL;
                }
                if (error)
-                       blkdev_put(resume_bdev);
+                       blkdev_put(resume_bdev, FMODE_READ);
                else
                        pr_debug("PM: Signature found, resuming\n");
        } else {
@@ -626,14 +626,14 @@ int swsusp_check(void)
  *     swsusp_close - close swap device.
  */
 
-void swsusp_close(void)
+void swsusp_close(fmode_t mode)
 {
        if (IS_ERR(resume_bdev)) {
                pr_debug("PM: Image device not initialised\n");
                return;
        }
 
-       blkdev_put(resume_bdev);
+       blkdev_put(resume_bdev, mode); /* move up */
 }
 
 static int swsusp_header_init(void)
index 467d5940f62406c35ab64fb7c4c88b1556154fa0..ad63af8b25218f562729d868293285ce3433cff8 100644 (file)
@@ -119,18 +119,19 @@ static void _rcu_barrier(enum rcu_barrier type)
        /* Take cpucontrol mutex to protect against CPU hotplug */
        mutex_lock(&rcu_barrier_mutex);
        init_completion(&rcu_barrier_completion);
-       atomic_set(&rcu_barrier_cpu_count, 0);
        /*
-        * The queueing of callbacks in all CPUs must be atomic with
-        * respect to RCU, otherwise one CPU may queue a callback,
-        * wait for a grace period, decrement barrier count and call
-        * complete(), while other CPUs have not yet queued anything.
-        * So, we need to make sure that grace periods cannot complete
-        * until all the callbacks are queued.
+        * Initialize rcu_barrier_cpu_count to 1, then invoke
+        * rcu_barrier_func() on each CPU, so that each CPU also has
+        * incremented rcu_barrier_cpu_count.  Only then is it safe to
+        * decrement rcu_barrier_cpu_count -- otherwise the first CPU
+        * might complete its grace period before all of the other CPUs
+        * did their increment, causing this function to return too
+        * early.
         */
-       rcu_read_lock();
+       atomic_set(&rcu_barrier_cpu_count, 1);
        on_each_cpu(rcu_barrier_func, (void *)type, 1);
-       rcu_read_unlock();
+       if (atomic_dec_and_test(&rcu_barrier_cpu_count))
+               complete(&rcu_barrier_completion);
        wait_for_completion(&rcu_barrier_completion);
        mutex_unlock(&rcu_barrier_mutex);
 }
index 90b5b123f7a1ee2814686ed791a4d1e45c95935b..85cb90588a55ca54348f00a46cdd9199c6bba2bf 100644 (file)
 #include <linux/freezer.h>
 #include <linux/cpu.h>
 #include <linux/delay.h>
-#include <linux/byteorder/swabb.h>
 #include <linux/stat.h>
 #include <linux/srcu.h>
 #include <linux/slab.h>
+#include <asm/byteorder.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com> and "
index 6522ae5b14a2ad7aca5cde919c3a5f1d305c6fd6..69d9cb921ffa657ef6939be6dcfb053570fb019f 100644 (file)
@@ -631,8 +631,7 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state,
 
        /* Setup the timer, when timeout != NULL */
        if (unlikely(timeout)) {
-               hrtimer_start(&timeout->timer, timeout->timer.expires,
-                             HRTIMER_MODE_ABS);
+               hrtimer_start_expires(&timeout->timer, HRTIMER_MODE_ABS);
                if (!hrtimer_active(&timeout->timer))
                        timeout->task = NULL;
        }
index 6f230596bd0c1d21a2c68ffbff8207e93dcd65b5..6625c3c4b10d06c3f76c371becd615d174244902 100644 (file)
@@ -55,6 +55,7 @@
 #include <linux/cpuset.h>
 #include <linux/percpu.h>
 #include <linux/kthread.h>
+#include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/sysctl.h>
 #include <linux/syscalls.h>
@@ -71,6 +72,7 @@
 #include <linux/debugfs.h>
 #include <linux/ctype.h>
 #include <linux/ftrace.h>
+#include <trace/sched.h>
 
 #include <asm/tlb.h>
 #include <asm/irq_regs.h>
@@ -226,9 +228,8 @@ static void start_rt_bandwidth(struct rt_bandwidth *rt_b)
 
                now = hrtimer_cb_get_time(&rt_b->rt_period_timer);
                hrtimer_forward(&rt_b->rt_period_timer, now, rt_b->rt_period);
-               hrtimer_start(&rt_b->rt_period_timer,
-                             rt_b->rt_period_timer.expires,
-                             HRTIMER_MODE_ABS);
+               hrtimer_start_expires(&rt_b->rt_period_timer,
+                               HRTIMER_MODE_ABS);
        }
        spin_unlock(&rt_b->rt_runtime_lock);
 }
@@ -817,6 +818,13 @@ const_debug unsigned int sysctl_sched_nr_migrate = 32;
  */
 unsigned int sysctl_sched_shares_ratelimit = 250000;
 
+/*
+ * Inject some fuzzyness into changing the per-cpu group shares
+ * this avoids remote rq-locks at the expense of fairness.
+ * default: 4
+ */
+unsigned int sysctl_sched_shares_thresh = 4;
+
 /*
  * period over which we measure -rt task cpu usage in us.
  * default: 1s
@@ -1063,7 +1071,7 @@ static void hrtick_start(struct rq *rq, u64 delay)
        struct hrtimer *timer = &rq->hrtick_timer;
        ktime_t time = ktime_add_ns(timer->base->get_time(), delay);
 
-       timer->expires = time;
+       hrtimer_set_expires(timer, time);
 
        if (rq == this_rq()) {
                hrtimer_restart(timer);
@@ -1453,8 +1461,8 @@ static void __set_se_shares(struct sched_entity *se, unsigned long shares);
  * Calculate and set the cpu's group shares.
  */
 static void
-__update_group_shares_cpu(struct task_group *tg, int cpu,
-                         unsigned long sd_shares, unsigned long sd_rq_weight)
+update_group_shares_cpu(struct task_group *tg, int cpu,
+                       unsigned long sd_shares, unsigned long sd_rq_weight)
 {
        int boost = 0;
        unsigned long shares;
@@ -1485,19 +1493,23 @@ __update_group_shares_cpu(struct task_group *tg, int cpu,
         *
         */
        shares = (sd_shares * rq_weight) / (sd_rq_weight + 1);
+       shares = clamp_t(unsigned long, shares, MIN_SHARES, MAX_SHARES);
 
-       /*
-        * record the actual number of shares, not the boosted amount.
-        */
-       tg->cfs_rq[cpu]->shares = boost ? 0 : shares;
-       tg->cfs_rq[cpu]->rq_weight = rq_weight;
+       if (abs(shares - tg->se[cpu]->load.weight) >
+                       sysctl_sched_shares_thresh) {
+               struct rq *rq = cpu_rq(cpu);
+               unsigned long flags;
 
-       if (shares < MIN_SHARES)
-               shares = MIN_SHARES;
-       else if (shares > MAX_SHARES)
-               shares = MAX_SHARES;
+               spin_lock_irqsave(&rq->lock, flags);
+               /*
+                * record the actual number of shares, not the boosted amount.
+                */
+               tg->cfs_rq[cpu]->shares = boost ? 0 : shares;
+               tg->cfs_rq[cpu]->rq_weight = rq_weight;
 
-       __set_se_shares(tg->se[cpu], shares);
+               __set_se_shares(tg->se[cpu], shares);
+               spin_unlock_irqrestore(&rq->lock, flags);
+       }
 }
 
 /*
@@ -1526,14 +1538,8 @@ static int tg_shares_up(struct task_group *tg, void *data)
        if (!rq_weight)
                rq_weight = cpus_weight(sd->span) * NICE_0_LOAD;
 
-       for_each_cpu_mask(i, sd->span) {
-               struct rq *rq = cpu_rq(i);
-               unsigned long flags;
-
-               spin_lock_irqsave(&rq->lock, flags);
-               __update_group_shares_cpu(tg, i, shares, rq_weight);
-               spin_unlock_irqrestore(&rq->lock, flags);
-       }
+       for_each_cpu_mask(i, sd->span)
+               update_group_shares_cpu(tg, i, shares, rq_weight);
 
        return 0;
 }
@@ -1936,6 +1942,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);
                running = task_running(rq, p);
                on_rq = p->se.on_rq;
                ncsw = 0;
@@ -2297,9 +2304,7 @@ out_activate:
        success = 1;
 
 out_running:
-       trace_mark(kernel_sched_wakeup,
-               "pid %d state %ld ## rq %p task %p rq->curr %p",
-               p->pid, p->state, rq, p, rq->curr);
+       trace_sched_wakeup(rq, p);
        check_preempt_curr(rq, p, sync);
 
        p->state = TASK_RUNNING;
@@ -2432,9 +2437,7 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
                p->sched_class->task_new(rq, p);
                inc_nr_running(rq);
        }
-       trace_mark(kernel_sched_wakeup_new,
-               "pid %d state %ld ## rq %p task %p rq->curr %p",
-               p->pid, p->state, rq, p, rq->curr);
+       trace_sched_wakeup_new(rq, p);
        check_preempt_curr(rq, p, 0);
 #ifdef CONFIG_SMP
        if (p->sched_class->task_wake_up)
@@ -2607,11 +2610,7 @@ context_switch(struct rq *rq, struct task_struct *prev,
        struct mm_struct *mm, *oldmm;
 
        prepare_task_switch(rq, prev, next);
-       trace_mark(kernel_sched_schedule,
-               "prev_pid %d next_pid %d prev_state %ld "
-               "## rq %p prev %p next %p",
-               prev->pid, next->pid, prev->state,
-               rq, prev, next);
+       trace_sched_switch(rq, prev, next);
        mm = next->mm;
        oldmm = prev->active_mm;
        /*
@@ -2851,6 +2850,7 @@ static void sched_migrate_task(struct task_struct *p, int dest_cpu)
            || unlikely(!cpu_active(dest_cpu)))
                goto out;
 
+       trace_sched_migrate_task(rq, 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). */
@@ -4052,23 +4052,26 @@ DEFINE_PER_CPU(struct kernel_stat, kstat);
 EXPORT_PER_CPU_SYMBOL(kstat);
 
 /*
- * Return p->sum_exec_runtime plus any more ns on the sched_clock
- * that have not yet been banked in case the task is currently running.
+ * Return any ns on the sched_clock that have not yet been banked in
+ * @p in case that task is currently running.
  */
-unsigned long long task_sched_runtime(struct task_struct *p)
+unsigned long long task_delta_exec(struct task_struct *p)
 {
        unsigned long flags;
-       u64 ns, delta_exec;
        struct rq *rq;
+       u64 ns = 0;
 
        rq = task_rq_lock(p, &flags);
-       ns = p->se.sum_exec_runtime;
+
        if (task_current(rq, p)) {
+               u64 delta_exec;
+
                update_rq_clock(rq);
                delta_exec = rq->clock - p->se.exec_start;
                if ((s64)delta_exec > 0)
-                       ns += delta_exec;
+                       ns = delta_exec;
        }
+
        task_rq_unlock(rq, &flags);
 
        return ns;
@@ -4085,6 +4088,7 @@ void account_user_time(struct task_struct *p, cputime_t cputime)
        cputime64_t tmp;
 
        p->utime = cputime_add(p->utime, cputime);
+       account_group_user_time(p, cputime);
 
        /* Add user time to cpustat. */
        tmp = cputime_to_cputime64(cputime);
@@ -4109,6 +4113,7 @@ static void account_guest_time(struct task_struct *p, cputime_t cputime)
        tmp = cputime_to_cputime64(cputime);
 
        p->utime = cputime_add(p->utime, cputime);
+       account_group_user_time(p, cputime);
        p->gtime = cputime_add(p->gtime, cputime);
 
        cpustat->user = cputime64_add(cpustat->user, tmp);
@@ -4144,6 +4149,7 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
        }
 
        p->stime = cputime_add(p->stime, cputime);
+       account_group_system_time(p, cputime);
 
        /* Add system time to cpustat. */
        tmp = cputime_to_cputime64(cputime);
@@ -4185,6 +4191,7 @@ void account_steal_time(struct task_struct *p, cputime_t steal)
 
        if (p == rq->idle) {
                p->stime = cputime_add(p->stime, steal);
+               account_group_system_time(p, steal);
                if (atomic_read(&rq->nr_iowait) > 0)
                        cpustat->iowait = cputime64_add(cpustat->iowait, tmp);
                else
@@ -4441,12 +4448,8 @@ need_resched_nonpreemptible:
        if (sched_feat(HRTICK))
                hrtick_clear(rq);
 
-       /*
-        * Do the rq-clock update outside the rq lock:
-        */
-       local_irq_disable();
+       spin_lock_irq(&rq->lock);
        update_rq_clock(rq);
-       spin_lock(&rq->lock);
        clear_tsk_need_resched(prev);
 
        if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
index 18fd17172eb66bb567ca4bcc47ca6c0cea923462..9573c33688b89616d38346ed5a744af4324fc282 100644 (file)
@@ -73,6 +73,8 @@ unsigned int sysctl_sched_wakeup_granularity = 5000000UL;
 
 const_debug unsigned int sysctl_sched_migration_cost = 500000UL;
 
+static const struct sched_class fair_sched_class;
+
 /**************************************************************
  * CFS operations on generic schedulable entities:
  */
@@ -334,7 +336,7 @@ int sched_nr_latency_handler(struct ctl_table *table, int write,
 #endif
 
 /*
- * delta *= w / rw
+ * delta *= P[w / rw]
  */
 static inline unsigned long
 calc_delta_weight(unsigned long delta, struct sched_entity *se)
@@ -348,15 +350,13 @@ calc_delta_weight(unsigned long delta, struct sched_entity *se)
 }
 
 /*
- * delta *= rw / w
+ * delta /= w
  */
 static inline unsigned long
 calc_delta_fair(unsigned long delta, struct sched_entity *se)
 {
-       for_each_sched_entity(se) {
-               delta = calc_delta_mine(delta,
-                               cfs_rq_of(se)->load.weight, &se->load);
-       }
+       if (unlikely(se->load.weight != NICE_0_LOAD))
+               delta = calc_delta_mine(delta, NICE_0_LOAD, &se->load);
 
        return delta;
 }
@@ -386,26 +386,26 @@ static u64 __sched_period(unsigned long nr_running)
  * We calculate the wall-time slice from the period by taking a part
  * proportional to the weight.
  *
- * s = p*w/rw
+ * s = p*P[w/rw]
  */
 static u64 sched_slice(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
-       return calc_delta_weight(__sched_period(cfs_rq->nr_running), se);
+       unsigned long nr_running = cfs_rq->nr_running;
+
+       if (unlikely(!se->on_rq))
+               nr_running++;
+
+       return calc_delta_weight(__sched_period(nr_running), se);
 }
 
 /*
  * We calculate the vruntime slice of a to be inserted task
  *
- * vs = s*rw/w = p
+ * vs = s/w
  */
-static u64 sched_vslice_add(struct cfs_rq *cfs_rq, struct sched_entity *se)
+static u64 sched_vslice(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
-       unsigned long nr_running = cfs_rq->nr_running;
-
-       if (!se->on_rq)
-               nr_running++;
-
-       return __sched_period(nr_running);
+       return calc_delta_fair(sched_slice(cfs_rq, se), se);
 }
 
 /*
@@ -449,6 +449,7 @@ static void update_curr(struct cfs_rq *cfs_rq)
                struct task_struct *curtask = task_of(curr);
 
                cpuacct_charge(curtask, delta_exec);
+               account_group_exec_runtime(curtask, delta_exec);
        }
 }
 
@@ -627,7 +628,7 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
         * stays open at the end.
         */
        if (initial && sched_feat(START_DEBIT))
-               vruntime += sched_vslice_add(cfs_rq, se);
+               vruntime += sched_vslice(cfs_rq, se);
 
        if (!initial) {
                /* sleeps upto a single latency don't count. */
@@ -747,7 +748,7 @@ pick_next(struct cfs_rq *cfs_rq, struct sched_entity *se)
        struct rq *rq = rq_of(cfs_rq);
        u64 pair_slice = rq->clock - cfs_rq->pair_start;
 
-       if (!cfs_rq->next || pair_slice > sched_slice(cfs_rq, cfs_rq->next)) {
+       if (!cfs_rq->next || pair_slice > sysctl_sched_min_granularity) {
                cfs_rq->pair_start = rq->clock;
                return se;
        }
@@ -848,11 +849,31 @@ static void hrtick_start_fair(struct rq *rq, struct task_struct *p)
                hrtick_start(rq, delta);
        }
 }
+
+/*
+ * called from enqueue/dequeue and updates the hrtick when the
+ * current task is from our class and nr_running is low enough
+ * to matter.
+ */
+static void hrtick_update(struct rq *rq)
+{
+       struct task_struct *curr = rq->curr;
+
+       if (curr->sched_class != &fair_sched_class)
+               return;
+
+       if (cfs_rq_of(&curr->se)->nr_running < sched_nr_latency)
+               hrtick_start_fair(rq, curr);
+}
 #else /* !CONFIG_SCHED_HRTICK */
 static inline void
 hrtick_start_fair(struct rq *rq, struct task_struct *p)
 {
 }
+
+static inline void hrtick_update(struct rq *rq)
+{
+}
 #endif
 
 /*
@@ -873,7 +894,7 @@ static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup)
                wakeup = 1;
        }
 
-       hrtick_start_fair(rq, rq->curr);
+       hrtick_update(rq);
 }
 
 /*
@@ -895,7 +916,7 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep)
                sleep = 1;
        }
 
-       hrtick_start_fair(rq, rq->curr);
+       hrtick_update(rq);
 }
 
 /*
@@ -1001,8 +1022,6 @@ static inline int wake_idle(int cpu, struct task_struct *p)
 
 #ifdef CONFIG_SMP
 
-static const struct sched_class fair_sched_class;
-
 #ifdef CONFIG_FAIR_GROUP_SCHED
 /*
  * effective_load() calculates the load change as seen from the root_task_group
index 7c9e8f4a049f6c6ec6fb935de7d766b2135e8782..fda016218296be0d09f54ca7d8d9e2294fb0dbbe 100644 (file)
@@ -5,7 +5,7 @@ SCHED_FEAT(START_DEBIT, 1)
 SCHED_FEAT(AFFINE_WAKEUPS, 1)
 SCHED_FEAT(CACHE_HOT_BUDDY, 1)
 SCHED_FEAT(SYNC_WAKEUPS, 1)
-SCHED_FEAT(HRTICK, 1)
+SCHED_FEAT(HRTICK, 0)
 SCHED_FEAT(DOUBLE_TICK, 0)
 SCHED_FEAT(ASYM_GRAN, 1)
 SCHED_FEAT(LB_BIAS, 1)
index cdf5740ab03e8133c0a2b7713d6c77d2be1f07bf..b446dc87494fd681fd0a7d7e265402ac09936773 100644 (file)
@@ -526,6 +526,8 @@ static void update_curr_rt(struct rq *rq)
        schedstat_set(curr->se.exec_max, max(curr->se.exec_max, delta_exec));
 
        curr->se.sum_exec_runtime += delta_exec;
+       account_group_exec_runtime(curr, delta_exec);
+
        curr->se.exec_start = rq->clock;
        cpuacct_charge(curr, delta_exec);
 
@@ -1458,7 +1460,7 @@ static void watchdog(struct rq *rq, struct task_struct *p)
                p->rt.timeout++;
                next = DIV_ROUND_UP(min(soft, hard), USEC_PER_SEC/HZ);
                if (p->rt.timeout > next)
-                       p->it_sched_expires = p->se.sum_exec_runtime;
+                       p->cputime_expires.sched_exp = p->se.sum_exec_runtime;
        }
 }
 
index 8385d43987e29b3b6a4775947d9a52fd22e8554c..ee71bec1da66a9dcb64d93a0e9934c15a155905b 100644 (file)
@@ -9,7 +9,7 @@
 static int show_schedstat(struct seq_file *seq, void *v)
 {
        int cpu;
-       int mask_len = NR_CPUS/32 * 9;
+       int mask_len = DIV_ROUND_UP(NR_CPUS, 32) * 9;
        char *mask_str = kmalloc(mask_len, GFP_KERNEL);
 
        if (mask_str == NULL)
@@ -90,13 +90,20 @@ static int schedstat_open(struct inode *inode, struct file *file)
        return res;
 }
 
-const struct file_operations proc_schedstat_operations = {
+static const struct file_operations proc_schedstat_operations = {
        .open    = schedstat_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
        .release = single_release,
 };
 
+static int __init proc_schedstat_init(void)
+{
+       proc_create("schedstat", 0, NULL, &proc_schedstat_operations);
+       return 0;
+}
+module_init(proc_schedstat_init);
+
 /*
  * Expects runqueue lock to be held for atomicity of update
  */
@@ -270,3 +277,89 @@ sched_info_switch(struct task_struct *prev, struct task_struct *next)
 #define sched_info_switch(t, next)             do { } while (0)
 #endif /* CONFIG_SCHEDSTATS || CONFIG_TASK_DELAY_ACCT */
 
+/*
+ * The following are functions that support scheduler-internal time accounting.
+ * These functions are generally called at the timer tick.  None of this depends
+ * on CONFIG_SCHEDSTATS.
+ */
+
+/**
+ * account_group_user_time - Maintain utime for a thread group.
+ *
+ * @tsk:       Pointer to task structure.
+ * @cputime:   Time value by which to increment the utime field of the
+ *             thread_group_cputime structure.
+ *
+ * If thread group time is being maintained, get the structure for the
+ * running CPU and update the utime field there.
+ */
+static inline void account_group_user_time(struct task_struct *tsk,
+                                          cputime_t cputime)
+{
+       struct signal_struct *sig;
+
+       sig = tsk->signal;
+       if (unlikely(!sig))
+               return;
+       if (sig->cputime.totals) {
+               struct task_cputime *times;
+
+               times = per_cpu_ptr(sig->cputime.totals, get_cpu());
+               times->utime = cputime_add(times->utime, cputime);
+               put_cpu_no_resched();
+       }
+}
+
+/**
+ * account_group_system_time - Maintain stime for a thread group.
+ *
+ * @tsk:       Pointer to task structure.
+ * @cputime:   Time value by which to increment the stime field of the
+ *             thread_group_cputime structure.
+ *
+ * If thread group time is being maintained, get the structure for the
+ * running CPU and update the stime field there.
+ */
+static inline void account_group_system_time(struct task_struct *tsk,
+                                            cputime_t cputime)
+{
+       struct signal_struct *sig;
+
+       sig = tsk->signal;
+       if (unlikely(!sig))
+               return;
+       if (sig->cputime.totals) {
+               struct task_cputime *times;
+
+               times = per_cpu_ptr(sig->cputime.totals, get_cpu());
+               times->stime = cputime_add(times->stime, cputime);
+               put_cpu_no_resched();
+       }
+}
+
+/**
+ * account_group_exec_runtime - Maintain exec runtime for a thread group.
+ *
+ * @tsk:       Pointer to task structure.
+ * @ns:                Time value by which to increment the sum_exec_runtime field
+ *             of the thread_group_cputime structure.
+ *
+ * If thread group time is being maintained, get the structure for the
+ * running CPU and update the sum_exec_runtime field there.
+ */
+static inline void account_group_exec_runtime(struct task_struct *tsk,
+                                             unsigned long long ns)
+{
+       struct signal_struct *sig;
+
+       sig = tsk->signal;
+       if (unlikely(!sig))
+               return;
+       if (sig->cputime.totals) {
+               struct task_cputime *times;
+
+               times = per_cpu_ptr(sig->cputime.totals, get_cpu());
+               times->sum_exec_runtime += ns;
+               put_cpu_no_resched();
+       }
+}
index e661b01d340f06a17afb6cfef13a712ae0338ff9..105217da5c82eeed7fef7d7c66cf8ec59c6cc2dc 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/freezer.h>
 #include <linux/pid_namespace.h>
 #include <linux/nsproxy.h>
+#include <trace/sched.h>
 
 #include <asm/param.h>
 #include <asm/uaccess.h>
@@ -803,6 +804,8 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
        struct sigpending *pending;
        struct sigqueue *q;
 
+       trace_sched_signal_send(sig, t);
+
        assert_spin_locked(&t->sighand->siglock);
        if (!prepare_signal(sig, t))
                return 0;
@@ -1338,6 +1341,7 @@ int do_notify_parent(struct task_struct *tsk, int sig)
        struct siginfo info;
        unsigned long flags;
        struct sighand_struct *psig;
+       struct task_cputime cputime;
        int ret = sig;
 
        BUG_ON(sig == -1);
@@ -1368,10 +1372,9 @@ int do_notify_parent(struct task_struct *tsk, int sig)
 
        info.si_uid = tsk->uid;
 
-       info.si_utime = cputime_to_clock_t(cputime_add(tsk->utime,
-                                                      tsk->signal->utime));
-       info.si_stime = cputime_to_clock_t(cputime_add(tsk->stime,
-                                                      tsk->signal->stime));
+       thread_group_cputime(tsk, &cputime);
+       info.si_utime = cputime_to_jiffies(cputime.utime);
+       info.si_stime = cputime_to_jiffies(cputime.stime);
 
        info.si_status = tsk->exit_code & 0x7f;
        if (tsk->exit_code & 0x80)
index 83ba21a13bd470cea2815d6792e8ff24af43e727..7110daeb9a90b2b585d97cf0fda94b7eb0b1869f 100644 (file)
@@ -267,16 +267,12 @@ asmlinkage void do_softirq(void)
  */
 void irq_enter(void)
 {
-#ifdef CONFIG_NO_HZ
        int cpu = smp_processor_id();
+
        if (idle_cpu(cpu) && !in_interrupt())
-               tick_nohz_stop_idle(cpu);
-#endif
+               tick_check_idle(cpu);
+
        __irq_enter();
-#ifdef CONFIG_NO_HZ
-       if (idle_cpu(cpu))
-               tick_nohz_update_jiffies();
-#endif
 }
 
 #ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED
index af3c7cea258b00d57762913a8986978495c2a81e..8aff79d90ddccd3647cb884664920e45c609fe72 100644 (file)
@@ -37,9 +37,13 @@ struct stop_machine_data {
 /* Like num_online_cpus(), but hotplug cpu uses us, so we need this. */
 static unsigned int num_threads;
 static atomic_t thread_ack;
-static struct completion finished;
 static DEFINE_MUTEX(lock);
 
+static struct workqueue_struct *stop_machine_wq;
+static struct stop_machine_data active, idle;
+static const cpumask_t *active_cpus;
+static void *stop_machine_work;
+
 static void set_state(enum stopmachine_state newstate)
 {
        /* Reset ack counter. */
@@ -51,21 +55,26 @@ static void set_state(enum stopmachine_state newstate)
 /* Last one to ack a state moves to the next state. */
 static void ack_state(void)
 {
-       if (atomic_dec_and_test(&thread_ack)) {
-               /* If we're the last one to ack the EXIT, we're finished. */
-               if (state == STOPMACHINE_EXIT)
-                       complete(&finished);
-               else
-                       set_state(state + 1);
-       }
+       if (atomic_dec_and_test(&thread_ack))
+               set_state(state + 1);
 }
 
-/* This is the actual thread which stops the CPU.  It exits by itself rather
- * than waiting for kthread_stop(), because it's easier for hotplug CPU. */
-static int stop_cpu(struct stop_machine_data *smdata)
+/* 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)
 {
        enum stopmachine_state curstate = STOPMACHINE_NONE;
-
+       struct stop_machine_data *smdata = &idle;
+       int cpu = smp_processor_id();
+       int err;
+
+       if (!active_cpus) {
+               if (cpu == first_cpu(cpu_online_map))
+                       smdata = &active;
+       } else {
+               if (cpu_isset(cpu, *active_cpus))
+                       smdata = &active;
+       }
        /* Simple state machine */
        do {
                /* Chill out and ensure we re-read stopmachine_state. */
@@ -78,9 +87,11 @@ static int stop_cpu(struct stop_machine_data *smdata)
                                hard_irq_disable();
                                break;
                        case STOPMACHINE_RUN:
-                               /* |= allows error detection if functions on
-                                * multiple CPUs. */
-                               smdata->fnret |= smdata->fn(smdata->data);
+                               /* 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;
                                break;
                        default:
                                break;
@@ -90,7 +101,6 @@ static int stop_cpu(struct stop_machine_data *smdata)
        } while (curstate != STOPMACHINE_EXIT);
 
        local_irq_enable();
-       do_exit(0);
 }
 
 /* Callback for CPUs which aren't supposed to do anything. */
@@ -101,78 +111,34 @@ static int chill(void *unused)
 
 int __stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus)
 {
-       int i, err;
-       struct stop_machine_data active, idle;
-       struct task_struct **threads;
+       struct work_struct *sm_work;
+       int i;
 
+       /* 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;
 
-       /* This could be too big for stack on large machines. */
-       threads = kcalloc(NR_CPUS, sizeof(threads[0]), GFP_KERNEL);
-       if (!threads)
-               return -ENOMEM;
-
-       /* Set up initial state. */
-       mutex_lock(&lock);
-       init_completion(&finished);
-       num_threads = num_online_cpus();
        set_state(STOPMACHINE_PREPARE);
 
-       for_each_online_cpu(i) {
-               struct stop_machine_data *smdata = &idle;
-               struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
-
-               if (!cpus) {
-                       if (i == first_cpu(cpu_online_map))
-                               smdata = &active;
-               } else {
-                       if (cpu_isset(i, *cpus))
-                               smdata = &active;
-               }
-
-               threads[i] = kthread_create((void *)stop_cpu, smdata, "kstop%u",
-                                           i);
-               if (IS_ERR(threads[i])) {
-                       err = PTR_ERR(threads[i]);
-                       threads[i] = NULL;
-                       goto kill_threads;
-               }
-
-               /* Place it onto correct cpu. */
-               kthread_bind(threads[i], i);
-
-               /* Make it highest prio. */
-               if (sched_setscheduler_nocheck(threads[i], SCHED_FIFO, &param))
-                       BUG();
-       }
-
-       /* We've created all the threads.  Wake them all: hold this CPU so one
+       /* 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)
-               wake_up_process(threads[i]);
-
+       for_each_online_cpu(i) {
+               sm_work = percpu_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();
-       wait_for_completion(&finished);
+       flush_workqueue(stop_machine_wq);
        mutex_unlock(&lock);
-
-       kfree(threads);
-
        return active.fnret;
-
-kill_threads:
-       for_each_online_cpu(i)
-               if (threads[i])
-                       kthread_stop(threads[i]);
-       mutex_unlock(&lock);
-
-       kfree(threads);
-       return err;
 }
 
 int stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus)
@@ -187,3 +153,11 @@ int stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus)
        return ret;
 }
 EXPORT_SYMBOL_GPL(stop_machine);
+
+static int __init stop_machine_init(void)
+{
+       stop_machine_wq = create_rt_workqueue("kstop");
+       stop_machine_work = alloc_percpu(struct work_struct);
+       return 0;
+}
+early_initcall(stop_machine_init);
index 0bc8fa3c2288110b49fad4e9eaab2326f52c69f7..31deba8f7d160c19bf262b1be13272e2ede1050d 100644 (file)
@@ -853,38 +853,28 @@ asmlinkage long sys_setfsgid(gid_t gid)
        return old_fsgid;
 }
 
+void do_sys_times(struct tms *tms)
+{
+       struct task_cputime cputime;
+       cputime_t cutime, cstime;
+
+       spin_lock_irq(&current->sighand->siglock);
+       thread_group_cputime(current, &cputime);
+       cutime = current->signal->cutime;
+       cstime = current->signal->cstime;
+       spin_unlock_irq(&current->sighand->siglock);
+       tms->tms_utime = cputime_to_clock_t(cputime.utime);
+       tms->tms_stime = cputime_to_clock_t(cputime.stime);
+       tms->tms_cutime = cputime_to_clock_t(cutime);
+       tms->tms_cstime = cputime_to_clock_t(cstime);
+}
+
 asmlinkage long sys_times(struct tms __user * tbuf)
 {
-       /*
-        *      In the SMP world we might just be unlucky and have one of
-        *      the times increment as we use it. Since the value is an
-        *      atomically safe type this is just fine. Conceptually its
-        *      as if the syscall took an instant longer to occur.
-        */
        if (tbuf) {
                struct tms tmp;
-               struct task_struct *tsk = current;
-               struct task_struct *t;
-               cputime_t utime, stime, cutime, cstime;
-
-               spin_lock_irq(&tsk->sighand->siglock);
-               utime = tsk->signal->utime;
-               stime = tsk->signal->stime;
-               t = tsk;
-               do {
-                       utime = cputime_add(utime, t->utime);
-                       stime = cputime_add(stime, t->stime);
-                       t = next_thread(t);
-               } while (t != tsk);
-
-               cutime = tsk->signal->cutime;
-               cstime = tsk->signal->cstime;
-               spin_unlock_irq(&tsk->sighand->siglock);
-
-               tmp.tms_utime = cputime_to_clock_t(utime);
-               tmp.tms_stime = cputime_to_clock_t(stime);
-               tmp.tms_cutime = cputime_to_clock_t(cutime);
-               tmp.tms_cstime = cputime_to_clock_t(cstime);
+
+               do_sys_times(&tmp);
                if (copy_to_user(tbuf, &tmp, sizeof(struct tms)))
                        return -EFAULT;
        }
@@ -1449,7 +1439,6 @@ asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *r
 asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim)
 {
        struct rlimit new_rlim, *old_rlim;
-       unsigned long it_prof_secs;
        int retval;
 
        if (resource >= RLIM_NLIMITS)
@@ -1503,18 +1492,7 @@ asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim)
        if (new_rlim.rlim_cur == RLIM_INFINITY)
                goto out;
 
-       it_prof_secs = cputime_to_secs(current->signal->it_prof_expires);
-       if (it_prof_secs == 0 || new_rlim.rlim_cur <= it_prof_secs) {
-               unsigned long rlim_cur = new_rlim.rlim_cur;
-               cputime_t cputime;
-
-               cputime = secs_to_cputime(rlim_cur);
-               read_lock(&tasklist_lock);
-               spin_lock_irq(&current->sighand->siglock);
-               set_process_cpu_timer(current, CPUCLOCK_PROF, &cputime, NULL);
-               spin_unlock_irq(&current->sighand->siglock);
-               read_unlock(&tasklist_lock);
-       }
+       update_rlimit_cpu(new_rlim.rlim_cur);
 out:
        return 0;
 }
@@ -1552,11 +1530,8 @@ out:
  *
  */
 
-static void accumulate_thread_rusage(struct task_struct *t, struct rusage *r,
-                                    cputime_t *utimep, cputime_t *stimep)
+static void accumulate_thread_rusage(struct task_struct *t, struct rusage *r)
 {
-       *utimep = cputime_add(*utimep, t->utime);
-       *stimep = cputime_add(*stimep, t->stime);
        r->ru_nvcsw += t->nvcsw;
        r->ru_nivcsw += t->nivcsw;
        r->ru_minflt += t->min_flt;
@@ -1570,12 +1545,13 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
        struct task_struct *t;
        unsigned long flags;
        cputime_t utime, stime;
+       struct task_cputime cputime;
 
        memset((char *) r, 0, sizeof *r);
        utime = stime = cputime_zero;
 
        if (who == RUSAGE_THREAD) {
-               accumulate_thread_rusage(p, r, &utime, &stime);
+               accumulate_thread_rusage(p, r);
                goto out;
        }
 
@@ -1598,8 +1574,9 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
                                break;
 
                case RUSAGE_SELF:
-                       utime = cputime_add(utime, p->signal->utime);
-                       stime = cputime_add(stime, p->signal->stime);
+                       thread_group_cputime(p, &cputime);
+                       utime = cputime_add(utime, cputime.utime);
+                       stime = cputime_add(stime, cputime.stime);
                        r->ru_nvcsw += p->signal->nvcsw;
                        r->ru_nivcsw += p->signal->nivcsw;
                        r->ru_minflt += p->signal->min_flt;
@@ -1608,7 +1585,7 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
                        r->ru_oublock += p->signal->oublock;
                        t = p;
                        do {
-                               accumulate_thread_rusage(t, r, &utime, &stime);
+                               accumulate_thread_rusage(t, r);
                                t = next_thread(t);
                        } while (t != p);
                        break;
@@ -1739,6 +1716,16 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
                case PR_SET_TSC:
                        error = SET_TSC_CTL(arg2);
                        break;
+               case PR_GET_TIMERSLACK:
+                       error = current->timer_slack_ns;
+                       break;
+               case PR_SET_TIMERSLACK:
+                       if (arg2 <= 0)
+                               current->timer_slack_ns =
+                                       current->default_timer_slack_ns;
+                       else
+                               current->timer_slack_ns = arg2;
+                       break;
                default:
                        error = -EINVAL;
                        break;
index b3cc73931d1f6411c6e99faf205124987d4a887e..a13bd4dfaeb1becfff933212893ea1c422ff0a04 100644 (file)
@@ -274,6 +274,16 @@ static struct ctl_table kern_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_dointvec,
        },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "sched_shares_thresh",
+               .data           = &sysctl_sched_shares_thresh,
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec_minmax,
+               .strategy       = &sysctl_intvec,
+               .extra1         = &zero,
+       },
        {
                .ctl_name       = CTL_UNNUMBERED,
                .procname       = "sched_child_runs_first",
index 6a08660b4fac30f97ea573b9cd017941401046ff..d63a4336fad69c85f007788a7932959595f0cb73 100644 (file)
@@ -669,3 +669,21 @@ EXPORT_SYMBOL(get_jiffies_64);
 #endif
 
 EXPORT_SYMBOL(jiffies);
+
+/*
+ * Add two timespec values and do a safety check for overflow.
+ * It's assumed that both values are valid (>= 0)
+ */
+struct timespec timespec_add_safe(const struct timespec lhs,
+                                 const struct timespec rhs)
+{
+       struct timespec res;
+
+       set_normalized_timespec(&res, lhs.tv_sec + rhs.tv_sec,
+                               lhs.tv_nsec + rhs.tv_nsec);
+
+       if (res.tv_sec < lhs.tv_sec || res.tv_sec < rhs.tv_sec)
+               res.tv_sec = TIME_T_MAX;
+
+       return res;
+}
index 093d4acf993b73fde0d575a4e29b06db88935942..9ed2eec97526546e26c4fb640702a8907b3530a9 100644 (file)
@@ -325,6 +325,9 @@ int clocksource_register(struct clocksource *c)
        unsigned long flags;
        int ret;
 
+       /* save mult_orig on registration */
+       c->mult_orig = c->mult;
+
        spin_lock_irqsave(&clocksource_lock, flags);
        ret = clocksource_enqueue(c);
        if (!ret)
index 4c256fdb8875b54f19e1c8062371c4b362cc5773..1ca99557e929261da5825325dafba49edde8be12 100644 (file)
@@ -61,6 +61,7 @@ struct clocksource clocksource_jiffies = {
        .read           = jiffies_read,
        .mask           = 0xffffffff, /*32bits*/
        .mult           = NSEC_PER_JIFFY << JIFFIES_SHIFT, /* details above */
+       .mult_orig      = NSEC_PER_JIFFY << JIFFIES_SHIFT,
        .shift          = JIFFIES_SHIFT,
 };
 
index 1ad46f3df6e76cd8994403b1c1ca72c14ec3553b..8ff15e5d486b137e65f96c64b5a206315bab7ee4 100644 (file)
 
 #include <linux/mm.h>
 #include <linux/time.h>
-#include <linux/timer.h>
 #include <linux/timex.h>
 #include <linux/jiffies.h>
 #include <linux/hrtimer.h>
 #include <linux/capability.h>
 #include <linux/math64.h>
 #include <linux/clocksource.h>
+#include <linux/workqueue.h>
 #include <asm/timex.h>
 
 /*
@@ -142,8 +142,7 @@ static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
                time_state = TIME_OOP;
                printk(KERN_NOTICE "Clock: "
                       "inserting leap second 23:59:60 UTC\n");
-               leap_timer.expires = ktime_add_ns(leap_timer.expires,
-                                                 NSEC_PER_SEC);
+               hrtimer_add_expires_ns(&leap_timer, NSEC_PER_SEC);
                res = HRTIMER_RESTART;
                break;
        case TIME_DEL:
@@ -218,11 +217,11 @@ void second_overflow(void)
 /* Disable the cmos update - used by virtualization and embedded */
 int no_sync_cmos_clock  __read_mostly;
 
-static void sync_cmos_clock(unsigned long dummy);
+static void sync_cmos_clock(struct work_struct *work);
 
-static DEFINE_TIMER(sync_cmos_timer, sync_cmos_clock, 0, 0);
+static DECLARE_DELAYED_WORK(sync_cmos_work, sync_cmos_clock);
 
-static void sync_cmos_clock(unsigned long dummy)
+static void sync_cmos_clock(struct work_struct *work)
 {
        struct timespec now, next;
        int fail = 1;
@@ -258,13 +257,13 @@ static void sync_cmos_clock(unsigned long dummy)
                next.tv_sec++;
                next.tv_nsec -= NSEC_PER_SEC;
        }
-       mod_timer(&sync_cmos_timer, jiffies + timespec_to_jiffies(&next));
+       schedule_delayed_work(&sync_cmos_work, timespec_to_jiffies(&next));
 }
 
 static void notify_cmos_timer(void)
 {
        if (!no_sync_cmos_clock)
-               mod_timer(&sync_cmos_timer, jiffies + 1);
+               schedule_delayed_work(&sync_cmos_work, 0);
 }
 
 #else
@@ -277,38 +276,50 @@ static inline void notify_cmos_timer(void) { }
 int do_adjtimex(struct timex *txc)
 {
        struct timespec ts;
-       long save_adjust, sec;
        int result;
 
-       /* In order to modify anything, you gotta be super-user! */
-       if (txc->modes && !capable(CAP_SYS_TIME))
-               return -EPERM;
-
-       /* Now we validate the data before disabling interrupts */
-
-       if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT) {
+       /* Validate the data before disabling interrupts */
+       if (txc->modes & ADJ_ADJTIME) {
                /* singleshot must not be used with any other mode bits */
-               if (txc->modes & ~ADJ_OFFSET_SS_READ)
+               if (!(txc->modes & ADJ_OFFSET_SINGLESHOT))
                        return -EINVAL;
+               if (!(txc->modes & ADJ_OFFSET_READONLY) &&
+                   !capable(CAP_SYS_TIME))
+                       return -EPERM;
+       } else {
+               /* In order to modify anything, you gotta be super-user! */
+                if (txc->modes && !capable(CAP_SYS_TIME))
+                       return -EPERM;
+
+               /* if the quartz is off by more than 10% something is VERY wrong! */
+               if (txc->modes & ADJ_TICK &&
+                   (txc->tick <  900000/USER_HZ ||
+                    txc->tick > 1100000/USER_HZ))
+                               return -EINVAL;
+
+               if (txc->modes & ADJ_STATUS && time_state != TIME_OK)
+                       hrtimer_cancel(&leap_timer);
        }
 
-       /* if the quartz is off by more than 10% something is VERY wrong ! */
-       if (txc->modes & ADJ_TICK)
-               if (txc->tick <  900000/USER_HZ ||
-                   txc->tick > 1100000/USER_HZ)
-                       return -EINVAL;
-
-       if (time_state != TIME_OK && txc->modes & ADJ_STATUS)
-               hrtimer_cancel(&leap_timer);
        getnstimeofday(&ts);
 
        write_seqlock_irq(&xtime_lock);
 
-       /* Save for later - semantics of adjtime is to return old value */
-       save_adjust = time_adjust;
-
        /* If there are input parameters, then process them */
+       if (txc->modes & ADJ_ADJTIME) {
+               long save_adjust = time_adjust;
+
+               if (!(txc->modes & ADJ_OFFSET_READONLY)) {
+                       /* adjtime() is independent from ntp_adjtime() */
+                       time_adjust = txc->offset;
+                       ntp_update_frequency();
+               }
+               txc->offset = save_adjust;
+               goto adj_done;
+       }
        if (txc->modes) {
+               long sec;
+
                if (txc->modes & ADJ_STATUS) {
                        if ((time_status & STA_PLL) &&
                            !(txc->status & STA_PLL)) {
@@ -375,13 +386,8 @@ int do_adjtimex(struct timex *txc)
                if (txc->modes & ADJ_TAI && txc->constant > 0)
                        time_tai = txc->constant;
 
-               if (txc->modes & ADJ_OFFSET) {
-                       if (txc->modes == ADJ_OFFSET_SINGLESHOT)
-                               /* adjtime() is independent from ntp_adjtime() */
-                               time_adjust = txc->offset;
-                       else
-                               ntp_update_offset(txc->offset);
-               }
+               if (txc->modes & ADJ_OFFSET)
+                       ntp_update_offset(txc->offset);
                if (txc->modes & ADJ_TICK)
                        tick_usec = txc->tick;
 
@@ -389,22 +395,18 @@ int do_adjtimex(struct timex *txc)
                        ntp_update_frequency();
        }
 
+       txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ,
+                                 NTP_SCALE_SHIFT);
+       if (!(time_status & STA_NANO))
+               txc->offset /= NSEC_PER_USEC;
+
+adj_done:
        result = time_state;    /* mostly `TIME_OK' */
        if (time_status & (STA_UNSYNC|STA_CLOCKERR))
                result = TIME_ERROR;
 
-       if ((txc->modes == ADJ_OFFSET_SINGLESHOT) ||
-           (txc->modes == ADJ_OFFSET_SS_READ))
-               txc->offset = save_adjust;
-       else {
-               txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ,
-                                         NTP_SCALE_SHIFT);
-               if (!(time_status & STA_NANO))
-                       txc->offset /= NSEC_PER_USEC;
-       }
-       txc->freq          = shift_right((s32)(time_freq >> PPM_SCALE_INV_SHIFT) *
-                                        (s64)PPM_SCALE_INV,
-                                        NTP_SCALE_SHIFT);
+       txc->freq          = shift_right((time_freq >> PPM_SCALE_INV_SHIFT) *
+                                        (s64)PPM_SCALE_INV, NTP_SCALE_SHIFT);
        txc->maxerror      = time_maxerror;
        txc->esterror      = time_esterror;
        txc->status        = time_status;
index cb01cd8f919b2752cfb7d97b4dc9ea4e87834a97..f98a1b7b16e942018ffe9e5998756405695da9a4 100644 (file)
@@ -383,6 +383,19 @@ int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
        return 0;
 }
 
+/*
+ * Called from irq_enter() when idle was interrupted to reenable the
+ * per cpu device.
+ */
+void tick_check_oneshot_broadcast(int cpu)
+{
+       if (cpu_isset(cpu, tick_broadcast_oneshot_mask)) {
+               struct tick_device *td = &per_cpu(tick_cpu_device, cpu);
+
+               clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_ONESHOT);
+       }
+}
+
 /*
  * Handle oneshot mode broadcasting
  */
index 469248782c2355c0c2d31cf731dc8c692023268e..b1c05bf75ee0ce36e0664d3e2e71d00ac0e09edd 100644 (file)
@@ -36,6 +36,7 @@ extern void tick_broadcast_switch_to_oneshot(void);
 extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup);
 extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc);
 extern int tick_broadcast_oneshot_active(void);
+extern void tick_check_oneshot_broadcast(int cpu);
 # else /* BROADCAST */
 static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
 {
@@ -45,6 +46,7 @@ static inline void tick_broadcast_oneshot_control(unsigned long reason) { }
 static inline void tick_broadcast_switch_to_oneshot(void) { }
 static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
 static inline int tick_broadcast_oneshot_active(void) { return 0; }
+static inline void tick_check_oneshot_broadcast(int cpu) { }
 # endif /* !BROADCAST */
 
 #else /* !ONESHOT */
index b711ffcb106c906be19eab01140ec1e8cafd0063..5bbb1044f8473ff98bd3fdfe2c93a1c0798ed8e7 100644 (file)
@@ -155,7 +155,7 @@ void tick_nohz_update_jiffies(void)
        touch_softlockup_watchdog();
 }
 
-void tick_nohz_stop_idle(int cpu)
+static void tick_nohz_stop_idle(int cpu)
 {
        struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
 
@@ -300,7 +300,7 @@ void tick_nohz_stop_sched_tick(int inidle)
                                goto out;
                        }
 
-                       ts->idle_tick = ts->sched_timer.expires;
+                       ts->idle_tick = hrtimer_get_expires(&ts->sched_timer);
                        ts->tick_stopped = 1;
                        ts->idle_jiffies = last_jiffies;
                        rcu_enter_nohz();
@@ -377,6 +377,32 @@ ktime_t tick_nohz_get_sleep_length(void)
        return ts->sleep_length;
 }
 
+static void tick_nohz_restart(struct tick_sched *ts, ktime_t now)
+{
+       hrtimer_cancel(&ts->sched_timer);
+       hrtimer_set_expires(&ts->sched_timer, ts->idle_tick);
+
+       while (1) {
+               /* Forward the time to expire in the future */
+               hrtimer_forward(&ts->sched_timer, now, tick_period);
+
+               if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
+                       hrtimer_start_expires(&ts->sched_timer,
+                                     HRTIMER_MODE_ABS);
+                       /* Check, if the timer was already in the past */
+                       if (hrtimer_active(&ts->sched_timer))
+                               break;
+               } else {
+                       if (!tick_program_event(
+                               hrtimer_get_expires(&ts->sched_timer), 0))
+                               break;
+               }
+               /* Update jiffies and reread time */
+               tick_do_update_jiffies64(now);
+               now = ktime_get();
+       }
+}
+
 /**
  * tick_nohz_restart_sched_tick - restart the idle tick from the idle task
  *
@@ -430,35 +456,16 @@ void tick_nohz_restart_sched_tick(void)
         */
        ts->tick_stopped  = 0;
        ts->idle_exittime = now;
-       hrtimer_cancel(&ts->sched_timer);
-       ts->sched_timer.expires = ts->idle_tick;
 
-       while (1) {
-               /* Forward the time to expire in the future */
-               hrtimer_forward(&ts->sched_timer, now, tick_period);
+       tick_nohz_restart(ts, now);
 
-               if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
-                       hrtimer_start(&ts->sched_timer,
-                                     ts->sched_timer.expires,
-                                     HRTIMER_MODE_ABS);
-                       /* Check, if the timer was already in the past */
-                       if (hrtimer_active(&ts->sched_timer))
-                               break;
-               } else {
-                       if (!tick_program_event(ts->sched_timer.expires, 0))
-                               break;
-               }
-               /* Update jiffies and reread time */
-               tick_do_update_jiffies64(now);
-               now = ktime_get();
-       }
        local_irq_enable();
 }
 
 static int tick_nohz_reprogram(struct tick_sched *ts, ktime_t now)
 {
        hrtimer_forward(&ts->sched_timer, now, tick_period);
-       return tick_program_event(ts->sched_timer.expires, 0);
+       return tick_program_event(hrtimer_get_expires(&ts->sched_timer), 0);
 }
 
 /*
@@ -503,10 +510,6 @@ static void tick_nohz_handler(struct clock_event_device *dev)
        update_process_times(user_mode(regs));
        profile_tick(CPU_PROFILING);
 
-       /* Do not restart, when we are in the idle loop */
-       if (ts->tick_stopped)
-               return;
-
        while (tick_nohz_reprogram(ts, now)) {
                now = ktime_get();
                tick_do_update_jiffies64(now);
@@ -541,7 +544,7 @@ static void tick_nohz_switch_to_nohz(void)
        next = tick_init_jiffy_update();
 
        for (;;) {
-               ts->sched_timer.expires = next;
+               hrtimer_set_expires(&ts->sched_timer, next);
                if (!tick_program_event(next, 0))
                        break;
                next = ktime_add(next, tick_period);
@@ -552,12 +555,56 @@ static void tick_nohz_switch_to_nohz(void)
               smp_processor_id());
 }
 
+/*
+ * When NOHZ is enabled and the tick is stopped, we need to kick the
+ * tick timer from irq_enter() so that the jiffies update is kept
+ * alive during long running softirqs. That's ugly as hell, but
+ * correctness is key even if we need to fix the offending softirq in
+ * the first place.
+ *
+ * Note, this is different to tick_nohz_restart. We just kick the
+ * timer and do not touch the other magic bits which need to be done
+ * when idle is left.
+ */
+static void tick_nohz_kick_tick(int cpu)
+{
+       struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
+       ktime_t delta, now;
+
+       if (!ts->tick_stopped)
+               return;
+
+       /*
+        * Do not touch the tick device, when the next expiry is either
+        * already reached or less/equal than the tick period.
+        */
+       now = ktime_get();
+       delta = ktime_sub(hrtimer_get_expires(&ts->sched_timer), now);
+       if (delta.tv64 <= tick_period.tv64)
+               return;
+
+       tick_nohz_restart(ts, now);
+}
+
 #else
 
 static inline void tick_nohz_switch_to_nohz(void) { }
 
 #endif /* NO_HZ */
 
+/*
+ * Called from irq_enter to notify about the possible interruption of idle()
+ */
+void tick_check_idle(int cpu)
+{
+       tick_check_oneshot_broadcast(cpu);
+#ifdef CONFIG_NO_HZ
+       tick_nohz_stop_idle(cpu);
+       tick_nohz_update_jiffies();
+       tick_nohz_kick_tick(cpu);
+#endif
+}
+
 /*
  * High resolution timer specific code
  */
@@ -611,10 +658,6 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer)
                profile_tick(CPU_PROFILING);
        }
 
-       /* Do not restart, when we are in the idle loop */
-       if (ts->tick_stopped)
-               return HRTIMER_NORESTART;
-
        hrtimer_forward(timer, now, tick_period);
 
        return HRTIMER_RESTART;
@@ -637,16 +680,15 @@ void tick_setup_sched_timer(void)
        ts->sched_timer.cb_mode = HRTIMER_CB_IRQSAFE_PERCPU;
 
        /* Get the next period (per cpu) */
-       ts->sched_timer.expires = tick_init_jiffy_update();
+       hrtimer_set_expires(&ts->sched_timer, tick_init_jiffy_update());
        offset = ktime_to_ns(tick_period) >> 1;
        do_div(offset, num_possible_cpus());
        offset *= smp_processor_id();
-       ts->sched_timer.expires = ktime_add_ns(ts->sched_timer.expires, offset);
+       hrtimer_add_expires_ns(&ts->sched_timer, offset);
 
        for (;;) {
                hrtimer_forward(&ts->sched_timer, now, tick_period);
-               hrtimer_start(&ts->sched_timer, ts->sched_timer.expires,
-                             HRTIMER_MODE_ABS);
+               hrtimer_start_expires(&ts->sched_timer, HRTIMER_MODE_ABS);
                /* Check, if the timer was already in the past */
                if (hrtimer_active(&ts->sched_timer))
                        break;
index e91c29f961c900d7739c0dc2f27b81c480cdb55c..e7acfb482a680ea248f5268fbb7f158868938e56 100644 (file)
@@ -58,27 +58,26 @@ struct clocksource *clock;
 
 #ifdef CONFIG_GENERIC_TIME
 /**
- * __get_nsec_offset - Returns nanoseconds since last call to periodic_hook
+ * clocksource_forward_now - update clock to the current time
  *
- * private function, must hold xtime_lock lock when being
- * called. Returns the number of nanoseconds since the
- * last call to update_wall_time() (adjusted by NTP scaling)
+ * Forward the current clock to update its state since the last call to
+ * update_wall_time(). This is useful before significant clock changes,
+ * as it avoids having to deal with this time offset explicitly.
  */
-static inline s64 __get_nsec_offset(void)
+static void clocksource_forward_now(void)
 {
        cycle_t cycle_now, cycle_delta;
-       s64 ns_offset;
+       s64 nsec;
 
-       /* read clocksource: */
        cycle_now = clocksource_read(clock);
-
-       /* calculate the delta since the last update_wall_time: */
        cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
+       clock->cycle_last = cycle_now;
 
-       /* convert to nanoseconds: */
-       ns_offset = cyc2ns(clock, cycle_delta);
+       nsec = cyc2ns(clock, cycle_delta);
+       timespec_add_ns(&xtime, nsec);
 
-       return ns_offset;
+       nsec = ((s64)cycle_delta * clock->mult_orig) >> clock->shift;
+       clock->raw_time.tv_nsec += nsec;
 }
 
 /**
@@ -89,6 +88,7 @@ static inline s64 __get_nsec_offset(void)
  */
 void getnstimeofday(struct timespec *ts)
 {
+       cycle_t cycle_now, cycle_delta;
        unsigned long seq;
        s64 nsecs;
 
@@ -96,7 +96,15 @@ void getnstimeofday(struct timespec *ts)
                seq = read_seqbegin(&xtime_lock);
 
                *ts = xtime;
-               nsecs = __get_nsec_offset();
+
+               /* read clocksource: */
+               cycle_now = clocksource_read(clock);
+
+               /* calculate the delta since the last update_wall_time: */
+               cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
+
+               /* convert to nanoseconds: */
+               nsecs = cyc2ns(clock, cycle_delta);
 
        } while (read_seqretry(&xtime_lock, seq));
 
@@ -129,22 +137,22 @@ EXPORT_SYMBOL(do_gettimeofday);
  */
 int do_settimeofday(struct timespec *tv)
 {
+       struct timespec ts_delta;
        unsigned long flags;
-       time_t wtm_sec, sec = tv->tv_sec;
-       long wtm_nsec, nsec = tv->tv_nsec;
 
        if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
                return -EINVAL;
 
        write_seqlock_irqsave(&xtime_lock, flags);
 
-       nsec -= __get_nsec_offset();
+       clocksource_forward_now();
+
+       ts_delta.tv_sec = tv->tv_sec - xtime.tv_sec;
+       ts_delta.tv_nsec = tv->tv_nsec - xtime.tv_nsec;
+       wall_to_monotonic = timespec_sub(wall_to_monotonic, ts_delta);
 
-       wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
-       wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
+       xtime = *tv;
 
-       set_normalized_timespec(&xtime, sec, nsec);
-       set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
        update_xtime_cache(0);
 
        clock->error = 0;
@@ -170,22 +178,19 @@ EXPORT_SYMBOL(do_settimeofday);
 static void change_clocksource(void)
 {
        struct clocksource *new;
-       cycle_t now;
-       u64 nsec;
 
        new = clocksource_get_next();
 
        if (clock == new)
                return;
 
-       new->cycle_last = 0;
-       now = clocksource_read(new);
-       nsec =  __get_nsec_offset();
-       timespec_add_ns(&xtime, nsec);
+       clocksource_forward_now();
 
-       clock = new;
-       clock->cycle_last = now;
+       new->raw_time = clock->raw_time;
 
+       clock = new;
+       clock->cycle_last = 0;
+       clock->cycle_last = clocksource_read(new);
        clock->error = 0;
        clock->xtime_nsec = 0;
        clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH);
@@ -200,10 +205,43 @@ static void change_clocksource(void)
         */
 }
 #else
+static inline void clocksource_forward_now(void) { }
 static inline void change_clocksource(void) { }
-static inline s64 __get_nsec_offset(void) { return 0; }
 #endif
 
+/**
+ * getrawmonotonic - Returns the raw monotonic time in a timespec
+ * @ts:                pointer to the timespec to be set
+ *
+ * Returns the raw monotonic time (completely un-modified by ntp)
+ */
+void getrawmonotonic(struct timespec *ts)
+{
+       unsigned long seq;
+       s64 nsecs;
+       cycle_t cycle_now, cycle_delta;
+
+       do {
+               seq = read_seqbegin(&xtime_lock);
+
+               /* read clocksource: */
+               cycle_now = clocksource_read(clock);
+
+               /* calculate the delta since the last update_wall_time: */
+               cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
+
+               /* convert to nanoseconds: */
+               nsecs = ((s64)cycle_delta * clock->mult_orig) >> clock->shift;
+
+               *ts = clock->raw_time;
+
+       } while (read_seqretry(&xtime_lock, seq));
+
+       timespec_add_ns(ts, nsecs);
+}
+EXPORT_SYMBOL(getrawmonotonic);
+
+
 /**
  * timekeeping_valid_for_hres - Check if timekeeping is suitable for hres
  */
@@ -265,8 +303,6 @@ void __init timekeeping_init(void)
 static int timekeeping_suspended;
 /* time in seconds when suspend began */
 static unsigned long timekeeping_suspend_time;
-/* xtime offset when we went into suspend */
-static s64 timekeeping_suspend_nsecs;
 
 /**
  * timekeeping_resume - Resumes the generic timekeeping subsystem.
@@ -292,8 +328,6 @@ static int timekeeping_resume(struct sys_device *dev)
                wall_to_monotonic.tv_sec -= sleep_length;
                total_sleep_time += sleep_length;
        }
-       /* Make sure that we have the correct xtime reference */
-       timespec_add_ns(&xtime, timekeeping_suspend_nsecs);
        update_xtime_cache(0);
        /* re-base the last cycle value */
        clock->cycle_last = 0;
@@ -319,8 +353,7 @@ static int timekeeping_suspend(struct sys_device *dev, pm_message_t state)
        timekeeping_suspend_time = read_persistent_clock();
 
        write_seqlock_irqsave(&xtime_lock, flags);
-       /* Get the current xtime offset */
-       timekeeping_suspend_nsecs = __get_nsec_offset();
+       clocksource_forward_now();
        timekeeping_suspended = 1;
        write_sequnlock_irqrestore(&xtime_lock, flags);
 
@@ -454,23 +487,29 @@ void update_wall_time(void)
 #else
        offset = clock->cycle_interval;
 #endif
-       clock->xtime_nsec += (s64)xtime.tv_nsec << clock->shift;
+       clock->xtime_nsec = (s64)xtime.tv_nsec << clock->shift;
 
        /* normally this loop will run just once, however in the
         * case of lost or late ticks, it will accumulate correctly.
         */
        while (offset >= clock->cycle_interval) {
                /* accumulate one interval */
-               clock->xtime_nsec += clock->xtime_interval;
-               clock->cycle_last += clock->cycle_interval;
                offset -= clock->cycle_interval;
+               clock->cycle_last += clock->cycle_interval;
 
+               clock->xtime_nsec += clock->xtime_interval;
                if (clock->xtime_nsec >= (u64)NSEC_PER_SEC << clock->shift) {
                        clock->xtime_nsec -= (u64)NSEC_PER_SEC << clock->shift;
                        xtime.tv_sec++;
                        second_overflow();
                }
 
+               clock->raw_time.tv_nsec += clock->raw_interval;
+               if (clock->raw_time.tv_nsec >= NSEC_PER_SEC) {
+                       clock->raw_time.tv_nsec -= NSEC_PER_SEC;
+                       clock->raw_time.tv_sec++;
+               }
+
                /* accumulate error between NTP and clock interval */
                clock->error += tick_length;
                clock->error -= clock->xtime_interval << (NTP_SCALE_SHIFT - clock->shift);
@@ -479,9 +518,12 @@ void update_wall_time(void)
        /* correct the clock when NTP error is too big */
        clocksource_adjust(offset);
 
-       /* store full nanoseconds into xtime */
-       xtime.tv_nsec = (s64)clock->xtime_nsec >> clock->shift;
+       /* store full nanoseconds into xtime after rounding it up and
+        * add the remainder to the error difference.
+        */
+       xtime.tv_nsec = ((s64)clock->xtime_nsec >> clock->shift) + 1;
        clock->xtime_nsec -= (s64)xtime.tv_nsec << clock->shift;
+       clock->error += clock->xtime_nsec << (NTP_SCALE_SHIFT - clock->shift);
 
        update_xtime_cache(cyc2ns(clock, offset));
 
index a40e20fd00010d000a3dfc2406888b2f81146db6..a999b92a12773750daded0c912a822b6f0eebe84 100644 (file)
@@ -47,13 +47,14 @@ static void print_name_offset(struct seq_file *m, void *sym)
 }
 
 static void
-print_timer(struct seq_file *m, struct hrtimer *timer, int idx, u64 now)
+print_timer(struct seq_file *m, struct hrtimer *taddr, struct hrtimer *timer,
+           int idx, u64 now)
 {
 #ifdef CONFIG_TIMER_STATS
        char tmp[TASK_COMM_LEN + 1];
 #endif
        SEQ_printf(m, " #%d: ", idx);
-       print_name_offset(m, timer);
+       print_name_offset(m, taddr);
        SEQ_printf(m, ", ");
        print_name_offset(m, timer->function);
        SEQ_printf(m, ", S:%02lx", timer->state);
@@ -65,9 +66,11 @@ print_timer(struct seq_file *m, struct hrtimer *timer, int idx, u64 now)
        SEQ_printf(m, ", %s/%d", tmp, timer->start_pid);
 #endif
        SEQ_printf(m, "\n");
-       SEQ_printf(m, " # expires at %Lu nsecs [in %Ld nsecs]\n",
-               (unsigned long long)ktime_to_ns(timer->expires),
-               (long long)(ktime_to_ns(timer->expires) - now));
+       SEQ_printf(m, " # expires at %Lu-%Lu nsecs [in %Ld to %Ld nsecs]\n",
+               (unsigned long long)ktime_to_ns(hrtimer_get_softexpires(timer)),
+               (unsigned long long)ktime_to_ns(hrtimer_get_expires(timer)),
+               (long long)(ktime_to_ns(hrtimer_get_softexpires(timer)) - now),
+               (long long)(ktime_to_ns(hrtimer_get_expires(timer)) - now));
 }
 
 static void
@@ -99,7 +102,7 @@ next_one:
                tmp = *timer;
                spin_unlock_irqrestore(&base->cpu_base->lock, flags);
 
-               print_timer(m, &tmp, i, now);
+               print_timer(m, timer, &tmp, i, now);
                next++;
                goto next_one;
        }
@@ -109,6 +112,7 @@ next_one:
 static void
 print_base(struct seq_file *m, struct hrtimer_clock_base *base, u64 now)
 {
+       SEQ_printf(m, "  .base:       %p\n", base);
        SEQ_printf(m, "  .index:      %d\n",
                        base->index);
        SEQ_printf(m, "  .resolution: %Lu nsecs\n",
@@ -183,12 +187,16 @@ static void print_cpu(struct seq_file *m, int cpu, u64 now)
 
 #ifdef CONFIG_GENERIC_CLOCKEVENTS
 static void
-print_tickdevice(struct seq_file *m, struct tick_device *td)
+print_tickdevice(struct seq_file *m, struct tick_device *td, int cpu)
 {
        struct clock_event_device *dev = td->evtdev;
 
        SEQ_printf(m, "\n");
        SEQ_printf(m, "Tick Device: mode:     %d\n", td->mode);
+       if (cpu < 0)
+               SEQ_printf(m, "Broadcast device\n");
+       else
+               SEQ_printf(m, "Per CPU device: %d\n", cpu);
 
        SEQ_printf(m, "Clock Event Device: ");
        if (!dev) {
@@ -222,7 +230,7 @@ static void timer_list_show_tickdevices(struct seq_file *m)
        int cpu;
 
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
-       print_tickdevice(m, tick_get_broadcast_device());
+       print_tickdevice(m, tick_get_broadcast_device(), -1);
        SEQ_printf(m, "tick_broadcast_mask: %08lx\n",
                   tick_get_broadcast_mask()->bits[0]);
 #ifdef CONFIG_TICK_ONESHOT
@@ -232,7 +240,7 @@ static void timer_list_show_tickdevices(struct seq_file *m)
        SEQ_printf(m, "\n");
 #endif
        for_each_online_cpu(cpu)
-                  print_tickdevice(m, tick_get_device(cpu));
+               print_tickdevice(m, tick_get_device(cpu), cpu);
        SEQ_printf(m, "\n");
 }
 #else
@@ -244,7 +252,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.3\n");
+       SEQ_printf(m, "Timer List Version: v0.4\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 510fe69351ca2ec19700802b59ac3dbe9d142019..56becf373c589ba90c36a5b6e23df0527b227663 100644 (file)
@@ -1436,9 +1436,11 @@ static void __cpuinit migrate_timers(int cpu)
        BUG_ON(cpu_online(cpu));
        old_base = per_cpu(tvec_bases, cpu);
        new_base = get_cpu_var(tvec_bases);
-
-       local_irq_disable();
-       spin_lock(&new_base->lock);
+       /*
+        * The caller is globally serialized and nobody else
+        * takes two locks at once, deadlock is not possible.
+        */
+       spin_lock_irq(&new_base->lock);
        spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING);
 
        BUG_ON(old_base->running_timer);
@@ -1453,8 +1455,7 @@ static void __cpuinit migrate_timers(int cpu)
        }
 
        spin_unlock(&old_base->lock);
-       spin_unlock(&new_base->lock);
-       local_irq_enable();
+       spin_unlock_irq(&new_base->lock);
        put_cpu_var(tvec_bases);
 }
 #endif /* CONFIG_HOTPLUG_CPU */
index 263e9e6bbd60912132ba18077c0fa0d66d7e1ffb..1cb3e1f616af5fcd36a6efceebb8892ef26f4324 100644 (file)
@@ -1,23 +1,37 @@
 #
 # Architectures that offer an FTRACE implementation should select HAVE_FTRACE:
 #
+
+config NOP_TRACER
+       bool
+
 config HAVE_FTRACE
        bool
+       select NOP_TRACER
 
 config HAVE_DYNAMIC_FTRACE
        bool
 
+config HAVE_FTRACE_MCOUNT_RECORD
+       bool
+
 config TRACER_MAX_TRACE
        bool
 
+config RING_BUFFER
+       bool
+
 config TRACING
        bool
        select DEBUG_FS
+       select RING_BUFFER
        select STACKTRACE
+       select TRACEPOINTS
 
 config FTRACE
        bool "Kernel Function Tracer"
        depends on HAVE_FTRACE
+       depends on DEBUG_KERNEL
        select FRAME_POINTER
        select TRACING
        select CONTEXT_SWITCH_TRACER
@@ -36,6 +50,7 @@ config IRQSOFF_TRACER
        depends on TRACE_IRQFLAGS_SUPPORT
        depends on GENERIC_TIME
        depends on HAVE_FTRACE
+       depends on DEBUG_KERNEL
        select TRACE_IRQFLAGS
        select TRACING
        select TRACER_MAX_TRACE
@@ -59,6 +74,7 @@ config PREEMPT_TRACER
        depends on GENERIC_TIME
        depends on PREEMPT
        depends on HAVE_FTRACE
+       depends on DEBUG_KERNEL
        select TRACING
        select TRACER_MAX_TRACE
        help
@@ -86,6 +102,7 @@ config SYSPROF_TRACER
 config SCHED_TRACER
        bool "Scheduling Latency Tracer"
        depends on HAVE_FTRACE
+       depends on DEBUG_KERNEL
        select TRACING
        select CONTEXT_SWITCH_TRACER
        select TRACER_MAX_TRACE
@@ -96,16 +113,56 @@ config SCHED_TRACER
 config CONTEXT_SWITCH_TRACER
        bool "Trace process context switches"
        depends on HAVE_FTRACE
+       depends on DEBUG_KERNEL
        select TRACING
        select MARKERS
        help
          This tracer gets called from the context switch and records
          all switching of tasks.
 
+config BOOT_TRACER
+       bool "Trace boot initcalls"
+       depends on HAVE_FTRACE
+       depends on DEBUG_KERNEL
+       select TRACING
+       help
+         This tracer helps developers to optimize boot times: it records
+         the timings of the initcalls and traces key events and the identity
+         of tasks that can cause boot delays, such as context-switches.
+
+         Its aim is to be parsed by the /scripts/bootgraph.pl tool to
+         produce pretty graphics about boot inefficiencies, giving a visual
+         representation of the delays during initcalls - but the raw
+         /debug/tracing/trace text output is readable too.
+
+         ( Note that tracing self tests can't be enabled if this tracer is
+           selected, because the self-tests are an initcall as well and that
+           would invalidate the boot trace. )
+
+config STACK_TRACER
+       bool "Trace max stack"
+       depends on HAVE_FTRACE
+       depends on DEBUG_KERNEL
+       select FTRACE
+       select STACKTRACE
+       help
+         This special tracer records the maximum stack footprint of the
+         kernel and displays it in debugfs/tracing/stack_trace.
+
+         This tracer works by hooking into every function call that the
+         kernel executes, and keeping a maximum stack depth value and
+         stack-trace saved. Because this logic has to execute in every
+         kernel function, all the time, this option can slow down the
+         kernel measurably and is generally intended for kernel
+         developers only.
+
+         Say N if unsure.
+
 config DYNAMIC_FTRACE
        bool "enable/disable ftrace tracepoints dynamically"
        depends on FTRACE
        depends on HAVE_DYNAMIC_FTRACE
+       depends on DEBUG_KERNEL
        default y
        help
          This option will modify all the calls to ftrace dynamically
@@ -121,12 +178,17 @@ config DYNAMIC_FTRACE
         were made. If so, it runs stop_machine (stops all CPUS)
         and modifies the code to jump over the call to ftrace.
 
+config FTRACE_MCOUNT_RECORD
+       def_bool y
+       depends on DYNAMIC_FTRACE
+       depends on HAVE_FTRACE_MCOUNT_RECORD
+
 config FTRACE_SELFTEST
        bool
 
 config FTRACE_STARTUP_TEST
        bool "Perform a startup test on ftrace"
-       depends on TRACING
+       depends on TRACING && DEBUG_KERNEL && !BOOT_TRACER
        select FTRACE_SELFTEST
        help
          This option performs a series of startup tests on ftrace. On bootup
index 71d17de172886b5841a246b2505555cd13d9a981..a85dfba88ba0402d5614d015c5faed60fe4abc55 100644 (file)
@@ -11,6 +11,7 @@ obj-y += trace_selftest_dynamic.o
 endif
 
 obj-$(CONFIG_FTRACE) += libftrace.o
+obj-$(CONFIG_RING_BUFFER) += ring_buffer.o
 
 obj-$(CONFIG_TRACING) += trace.o
 obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o
@@ -19,6 +20,9 @@ obj-$(CONFIG_FTRACE) += trace_functions.o
 obj-$(CONFIG_IRQSOFF_TRACER) += trace_irqsoff.o
 obj-$(CONFIG_PREEMPT_TRACER) += trace_irqsoff.o
 obj-$(CONFIG_SCHED_TRACER) += trace_sched_wakeup.o
+obj-$(CONFIG_NOP_TRACER) += trace_nop.o
+obj-$(CONFIG_STACK_TRACER) += trace_stack.o
 obj-$(CONFIG_MMIOTRACE) += trace_mmiotrace.o
+obj-$(CONFIG_BOOT_TRACER) += trace_boot.o
 
 libftrace-y := ftrace.o
index f6e3af31b403d8eaa77128712fdb594ca48be0c0..4dda4f60a2a9262770e3195b894e48b8178296a3 100644 (file)
@@ -81,7 +81,7 @@ void clear_ftrace_function(void)
 
 static int __register_ftrace_function(struct ftrace_ops *ops)
 {
-       /* Should never be called by interrupts */
+       /* should not be called from interrupt context */
        spin_lock(&ftrace_lock);
 
        ops->next = ftrace_list;
@@ -115,6 +115,7 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops)
        struct ftrace_ops **p;
        int ret = 0;
 
+       /* should not be called from interrupt context */
        spin_lock(&ftrace_lock);
 
        /*
@@ -153,6 +154,30 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops)
 
 #ifdef CONFIG_DYNAMIC_FTRACE
 
+#ifndef CONFIG_FTRACE_MCOUNT_RECORD
+/*
+ * The hash lock is only needed when the recording of the mcount
+ * callers are dynamic. That is, by the caller themselves and
+ * not recorded via the compilation.
+ */
+static DEFINE_SPINLOCK(ftrace_hash_lock);
+#define ftrace_hash_lock(flags)          spin_lock_irqsave(&ftrace_hash_lock, flags)
+#define ftrace_hash_unlock(flags) \
+                       spin_unlock_irqrestore(&ftrace_hash_lock, flags)
+#else
+/* This is protected via the ftrace_lock with MCOUNT_RECORD. */
+#define ftrace_hash_lock(flags)   do { (void)(flags); } while (0)
+#define ftrace_hash_unlock(flags) do { } while(0)
+#endif
+
+/*
+ * Since MCOUNT_ADDR may point to mcount itself, we do not want
+ * to get it confused by reading a reference in the code as we
+ * are parsing on objcopy output of text. Use a variable for
+ * it instead.
+ */
+static unsigned long mcount_addr = MCOUNT_ADDR;
+
 static struct task_struct *ftraced_task;
 
 enum {
@@ -171,7 +196,6 @@ static struct hlist_head ftrace_hash[FTRACE_HASHSIZE];
 
 static DEFINE_PER_CPU(int, ftrace_shutdown_disable_cpu);
 
-static DEFINE_SPINLOCK(ftrace_shutdown_lock);
 static DEFINE_MUTEX(ftraced_lock);
 static DEFINE_MUTEX(ftrace_regex_lock);
 
@@ -294,13 +318,37 @@ static inline void ftrace_del_hash(struct dyn_ftrace *node)
 
 static void ftrace_free_rec(struct dyn_ftrace *rec)
 {
-       /* no locking, only called from kstop_machine */
-
        rec->ip = (unsigned long)ftrace_free_records;
        ftrace_free_records = rec;
        rec->flags |= FTRACE_FL_FREE;
 }
 
+void ftrace_release(void *start, unsigned long size)
+{
+       struct dyn_ftrace *rec;
+       struct ftrace_page *pg;
+       unsigned long s = (unsigned long)start;
+       unsigned long e = s + size;
+       int i;
+
+       if (ftrace_disabled || !start)
+               return;
+
+       /* should not be called from interrupt context */
+       spin_lock(&ftrace_lock);
+
+       for (pg = ftrace_pages_start; pg; pg = pg->next) {
+               for (i = 0; i < pg->index; i++) {
+                       rec = &pg->records[i];
+
+                       if ((rec->ip >= s) && (rec->ip < e))
+                               ftrace_free_rec(rec);
+               }
+       }
+       spin_unlock(&ftrace_lock);
+
+}
+
 static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip)
 {
        struct dyn_ftrace *rec;
@@ -338,7 +386,6 @@ ftrace_record_ip(unsigned long ip)
        unsigned long flags;
        unsigned long key;
        int resched;
-       int atomic;
        int cpu;
 
        if (!ftrace_enabled || ftrace_disabled)
@@ -368,9 +415,7 @@ ftrace_record_ip(unsigned long ip)
        if (ftrace_ip_in_hash(ip, key))
                goto out;
 
-       atomic = irqs_disabled();
-
-       spin_lock_irqsave(&ftrace_shutdown_lock, flags);
+       ftrace_hash_lock(flags);
 
        /* This ip may have hit the hash before the lock */
        if (ftrace_ip_in_hash(ip, key))
@@ -387,7 +432,7 @@ ftrace_record_ip(unsigned long ip)
        ftraced_trigger = 1;
 
  out_unlock:
-       spin_unlock_irqrestore(&ftrace_shutdown_lock, flags);
+       ftrace_hash_unlock(flags);
  out:
        per_cpu(ftrace_shutdown_disable_cpu, cpu)--;
 
@@ -531,6 +576,16 @@ static void ftrace_shutdown_replenish(void)
        ftrace_pages->next = (void *)get_zeroed_page(GFP_KERNEL);
 }
 
+static void print_ip_ins(const char *fmt, unsigned char *p)
+{
+       int i;
+
+       printk(KERN_CONT "%s", fmt);
+
+       for (i = 0; i < MCOUNT_INSN_SIZE; i++)
+               printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]);
+}
+
 static int
 ftrace_code_disable(struct dyn_ftrace *rec)
 {
@@ -541,10 +596,27 @@ ftrace_code_disable(struct dyn_ftrace *rec)
        ip = rec->ip;
 
        nop = ftrace_nop_replace();
-       call = ftrace_call_replace(ip, MCOUNT_ADDR);
+       call = ftrace_call_replace(ip, mcount_addr);
 
        failed = ftrace_modify_code(ip, call, nop);
        if (failed) {
+               switch (failed) {
+               case 1:
+                       WARN_ON_ONCE(1);
+                       pr_info("ftrace faulted on modifying ");
+                       print_ip_sym(ip);
+                       break;
+               case 2:
+                       WARN_ON_ONCE(1);
+                       pr_info("ftrace failed to modify ");
+                       print_ip_sym(ip);
+                       print_ip_ins(" expected: ", call);
+                       print_ip_ins(" actual: ", (unsigned char *)ip);
+                       print_ip_ins(" replace: ", nop);
+                       printk(KERN_CONT "\n");
+                       break;
+               }
+
                rec->flags |= FTRACE_FL_FAILED;
                return 0;
        }
@@ -792,47 +864,7 @@ static int ftrace_update_code(void)
        return 1;
 }
 
-static int ftraced(void *ignore)
-{
-       unsigned long usecs;
-
-       while (!kthread_should_stop()) {
-
-               set_current_state(TASK_INTERRUPTIBLE);
-
-               /* check once a second */
-               schedule_timeout(HZ);
-
-               if (unlikely(ftrace_disabled))
-                       continue;
-
-               mutex_lock(&ftrace_sysctl_lock);
-               mutex_lock(&ftraced_lock);
-               if (!ftraced_suspend && !ftraced_stop &&
-                   ftrace_update_code()) {
-                       usecs = nsecs_to_usecs(ftrace_update_time);
-                       if (ftrace_update_tot_cnt > 100000) {
-                               ftrace_update_tot_cnt = 0;
-                               pr_info("hm, dftrace overflow: %lu change%s"
-                                       " (%lu total) in %lu usec%s\n",
-                                       ftrace_update_cnt,
-                                       ftrace_update_cnt != 1 ? "s" : "",
-                                       ftrace_update_tot_cnt,
-                                       usecs, usecs != 1 ? "s" : "");
-                               ftrace_disabled = 1;
-                               WARN_ON_ONCE(1);
-                       }
-               }
-               mutex_unlock(&ftraced_lock);
-               mutex_unlock(&ftrace_sysctl_lock);
-
-               ftrace_shutdown_replenish();
-       }
-       __set_current_state(TASK_RUNNING);
-       return 0;
-}
-
-static int __init ftrace_dyn_table_alloc(void)
+static int __init ftrace_dyn_table_alloc(unsigned long num_to_init)
 {
        struct ftrace_page *pg;
        int cnt;
@@ -859,7 +891,9 @@ static int __init ftrace_dyn_table_alloc(void)
 
        pg = ftrace_pages = ftrace_pages_start;
 
-       cnt = NR_TO_INIT / ENTRIES_PER_PAGE;
+       cnt = num_to_init / ENTRIES_PER_PAGE;
+       pr_info("ftrace: allocating %ld hash entries in %d pages\n",
+               num_to_init, cnt);
 
        for (i = 0; i < cnt; i++) {
                pg->next = (void *)get_zeroed_page(GFP_KERNEL);
@@ -901,6 +935,8 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
 
        (*pos)++;
 
+       /* should not be called from interrupt context */
+       spin_lock(&ftrace_lock);
  retry:
        if (iter->idx >= iter->pg->index) {
                if (iter->pg->next) {
@@ -910,15 +946,13 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
                }
        } else {
                rec = &iter->pg->records[iter->idx++];
-               if ((!(iter->flags & FTRACE_ITER_FAILURES) &&
+               if ((rec->flags & FTRACE_FL_FREE) ||
+
+                   (!(iter->flags & FTRACE_ITER_FAILURES) &&
                     (rec->flags & FTRACE_FL_FAILED)) ||
 
                    ((iter->flags & FTRACE_ITER_FAILURES) &&
-                    (!(rec->flags & FTRACE_FL_FAILED) ||
-                     (rec->flags & FTRACE_FL_FREE))) ||
-
-                   ((iter->flags & FTRACE_ITER_FILTER) &&
-                    !(rec->flags & FTRACE_FL_FILTER)) ||
+                    !(rec->flags & FTRACE_FL_FAILED)) ||
 
                    ((iter->flags & FTRACE_ITER_NOTRACE) &&
                     !(rec->flags & FTRACE_FL_NOTRACE))) {
@@ -926,6 +960,7 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
                        goto retry;
                }
        }
+       spin_unlock(&ftrace_lock);
 
        iter->pos = *pos;
 
@@ -1039,8 +1074,8 @@ static void ftrace_filter_reset(int enable)
        unsigned long type = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
        unsigned i;
 
-       /* keep kstop machine from running */
-       preempt_disable();
+       /* should not be called from interrupt context */
+       spin_lock(&ftrace_lock);
        if (enable)
                ftrace_filtered = 0;
        pg = ftrace_pages_start;
@@ -1053,7 +1088,7 @@ static void ftrace_filter_reset(int enable)
                }
                pg = pg->next;
        }
-       preempt_enable();
+       spin_unlock(&ftrace_lock);
 }
 
 static int
@@ -1165,8 +1200,8 @@ ftrace_match(unsigned char *buff, int len, int enable)
                }
        }
 
-       /* keep kstop machine from running */
-       preempt_disable();
+       /* should not be called from interrupt context */
+       spin_lock(&ftrace_lock);
        if (enable)
                ftrace_filtered = 1;
        pg = ftrace_pages_start;
@@ -1203,7 +1238,7 @@ ftrace_match(unsigned char *buff, int len, int enable)
                }
                pg = pg->next;
        }
-       preempt_enable();
+       spin_unlock(&ftrace_lock);
 }
 
 static ssize_t
@@ -1556,6 +1591,114 @@ static __init int ftrace_init_debugfs(void)
 
 fs_initcall(ftrace_init_debugfs);
 
+#ifdef CONFIG_FTRACE_MCOUNT_RECORD
+static int ftrace_convert_nops(unsigned long *start,
+                              unsigned long *end)
+{
+       unsigned long *p;
+       unsigned long addr;
+       unsigned long flags;
+
+       p = start;
+       while (p < end) {
+               addr = ftrace_call_adjust(*p++);
+               /* should not be called from interrupt context */
+               spin_lock(&ftrace_lock);
+               ftrace_record_ip(addr);
+               spin_unlock(&ftrace_lock);
+               ftrace_shutdown_replenish();
+       }
+
+       /* p is ignored */
+       local_irq_save(flags);
+       __ftrace_update_code(p);
+       local_irq_restore(flags);
+
+       return 0;
+}
+
+void ftrace_init_module(unsigned long *start, unsigned long *end)
+{
+       if (ftrace_disabled || start == end)
+               return;
+       ftrace_convert_nops(start, end);
+}
+
+extern unsigned long __start_mcount_loc[];
+extern unsigned long __stop_mcount_loc[];
+
+void __init ftrace_init(void)
+{
+       unsigned long count, addr, flags;
+       int ret;
+
+       /* Keep the ftrace pointer to the stub */
+       addr = (unsigned long)ftrace_stub;
+
+       local_irq_save(flags);
+       ftrace_dyn_arch_init(&addr);
+       local_irq_restore(flags);
+
+       /* ftrace_dyn_arch_init places the return code in addr */
+       if (addr)
+               goto failed;
+
+       count = __stop_mcount_loc - __start_mcount_loc;
+
+       ret = ftrace_dyn_table_alloc(count);
+       if (ret)
+               goto failed;
+
+       last_ftrace_enabled = ftrace_enabled = 1;
+
+       ret = ftrace_convert_nops(__start_mcount_loc,
+                                 __stop_mcount_loc);
+
+       return;
+ failed:
+       ftrace_disabled = 1;
+}
+#else /* CONFIG_FTRACE_MCOUNT_RECORD */
+static int ftraced(void *ignore)
+{
+       unsigned long usecs;
+
+       while (!kthread_should_stop()) {
+
+               set_current_state(TASK_INTERRUPTIBLE);
+
+               /* check once a second */
+               schedule_timeout(HZ);
+
+               if (unlikely(ftrace_disabled))
+                       continue;
+
+               mutex_lock(&ftrace_sysctl_lock);
+               mutex_lock(&ftraced_lock);
+               if (!ftraced_suspend && !ftraced_stop &&
+                   ftrace_update_code()) {
+                       usecs = nsecs_to_usecs(ftrace_update_time);
+                       if (ftrace_update_tot_cnt > 100000) {
+                               ftrace_update_tot_cnt = 0;
+                               pr_info("hm, dftrace overflow: %lu change%s"
+                                       " (%lu total) in %lu usec%s\n",
+                                       ftrace_update_cnt,
+                                       ftrace_update_cnt != 1 ? "s" : "",
+                                       ftrace_update_tot_cnt,
+                                       usecs, usecs != 1 ? "s" : "");
+                               ftrace_disabled = 1;
+                               WARN_ON_ONCE(1);
+                       }
+               }
+               mutex_unlock(&ftraced_lock);
+               mutex_unlock(&ftrace_sysctl_lock);
+
+               ftrace_shutdown_replenish();
+       }
+       __set_current_state(TASK_RUNNING);
+       return 0;
+}
+
 static int __init ftrace_dynamic_init(void)
 {
        struct task_struct *p;
@@ -1572,7 +1715,7 @@ static int __init ftrace_dynamic_init(void)
                goto failed;
        }
 
-       ret = ftrace_dyn_table_alloc();
+       ret = ftrace_dyn_table_alloc(NR_TO_INIT);
        if (ret)
                goto failed;
 
@@ -1593,6 +1736,8 @@ static int __init ftrace_dynamic_init(void)
 }
 
 core_initcall(ftrace_dynamic_init);
+#endif /* CONFIG_FTRACE_MCOUNT_RECORD */
+
 #else
 # define ftrace_startup()              do { } while (0)
 # define ftrace_shutdown()             do { } while (0)
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
new file mode 100644 (file)
index 0000000..94af1fe
--- /dev/null
@@ -0,0 +1,2014 @@
+/*
+ * Generic ring buffer
+ *
+ * Copyright (C) 2008 Steven Rostedt <srostedt@redhat.com>
+ */
+#include <linux/ring_buffer.h>
+#include <linux/spinlock.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/module.h>
+#include <linux/percpu.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>       /* used for sched_clock() (for now) */
+#include <linux/init.h>
+#include <linux/hash.h>
+#include <linux/list.h>
+#include <linux/fs.h>
+
+/* Up this if you want to test the TIME_EXTENTS and normalization */
+#define DEBUG_SHIFT 0
+
+/* FIXME!!! */
+u64 ring_buffer_time_stamp(int cpu)
+{
+       /* shift to debug/test normalization and TIME_EXTENTS */
+       return sched_clock() << DEBUG_SHIFT;
+}
+
+void ring_buffer_normalize_time_stamp(int cpu, u64 *ts)
+{
+       /* Just stupid testing the normalize function and deltas */
+       *ts >>= DEBUG_SHIFT;
+}
+
+#define RB_EVNT_HDR_SIZE (sizeof(struct ring_buffer_event))
+#define RB_ALIGNMENT_SHIFT     2
+#define RB_ALIGNMENT           (1 << RB_ALIGNMENT_SHIFT)
+#define RB_MAX_SMALL_DATA      28
+
+enum {
+       RB_LEN_TIME_EXTEND = 8,
+       RB_LEN_TIME_STAMP = 16,
+};
+
+/* inline for ring buffer fast paths */
+static inline unsigned
+rb_event_length(struct ring_buffer_event *event)
+{
+       unsigned length;
+
+       switch (event->type) {
+       case RINGBUF_TYPE_PADDING:
+               /* undefined */
+               return -1;
+
+       case RINGBUF_TYPE_TIME_EXTEND:
+               return RB_LEN_TIME_EXTEND;
+
+       case RINGBUF_TYPE_TIME_STAMP:
+               return RB_LEN_TIME_STAMP;
+
+       case RINGBUF_TYPE_DATA:
+               if (event->len)
+                       length = event->len << RB_ALIGNMENT_SHIFT;
+               else
+                       length = event->array[0];
+               return length + RB_EVNT_HDR_SIZE;
+       default:
+               BUG();
+       }
+       /* not hit */
+       return 0;
+}
+
+/**
+ * ring_buffer_event_length - return the length of the event
+ * @event: the event to get the length of
+ */
+unsigned ring_buffer_event_length(struct ring_buffer_event *event)
+{
+       return rb_event_length(event);
+}
+
+/* inline for ring buffer fast paths */
+static inline void *
+rb_event_data(struct ring_buffer_event *event)
+{
+       BUG_ON(event->type != RINGBUF_TYPE_DATA);
+       /* If length is in len field, then array[0] has the data */
+       if (event->len)
+               return (void *)&event->array[0];
+       /* Otherwise length is in array[0] and array[1] has the data */
+       return (void *)&event->array[1];
+}
+
+/**
+ * ring_buffer_event_data - return the data of the event
+ * @event: the event to get the data from
+ */
+void *ring_buffer_event_data(struct ring_buffer_event *event)
+{
+       return rb_event_data(event);
+}
+
+#define for_each_buffer_cpu(buffer, cpu)               \
+       for_each_cpu_mask(cpu, buffer->cpumask)
+
+#define TS_SHIFT       27
+#define TS_MASK                ((1ULL << TS_SHIFT) - 1)
+#define TS_DELTA_TEST  (~TS_MASK)
+
+/*
+ * This hack stolen from mm/slob.c.
+ * We can store per page timing information in the page frame of the page.
+ * Thanks to Peter Zijlstra for suggesting this idea.
+ */
+struct buffer_page {
+       u64              time_stamp;    /* page time stamp */
+       local_t          write;         /* index for next write */
+       local_t          commit;        /* write commited index */
+       unsigned         read;          /* index for next read */
+       struct list_head list;          /* list of free pages */
+       void *page;                     /* Actual data page */
+};
+
+/*
+ * Also stolen from mm/slob.c. Thanks to Mathieu Desnoyers for pointing
+ * this issue out.
+ */
+static inline void free_buffer_page(struct buffer_page *bpage)
+{
+       if (bpage->page)
+               __free_page(bpage->page);
+       kfree(bpage);
+}
+
+/*
+ * We need to fit the time_stamp delta into 27 bits.
+ */
+static inline int test_time_stamp(u64 delta)
+{
+       if (delta & TS_DELTA_TEST)
+               return 1;
+       return 0;
+}
+
+#define BUF_PAGE_SIZE PAGE_SIZE
+
+/*
+ * head_page == tail_page && head == tail then buffer is empty.
+ */
+struct ring_buffer_per_cpu {
+       int                             cpu;
+       struct ring_buffer              *buffer;
+       spinlock_t                      lock;
+       struct lock_class_key           lock_key;
+       struct list_head                pages;
+       struct buffer_page              *head_page;     /* read from head */
+       struct buffer_page              *tail_page;     /* write to tail */
+       struct buffer_page              *commit_page;   /* commited pages */
+       struct buffer_page              *reader_page;
+       unsigned long                   overrun;
+       unsigned long                   entries;
+       u64                             write_stamp;
+       u64                             read_stamp;
+       atomic_t                        record_disabled;
+};
+
+struct ring_buffer {
+       unsigned long                   size;
+       unsigned                        pages;
+       unsigned                        flags;
+       int                             cpus;
+       cpumask_t                       cpumask;
+       atomic_t                        record_disabled;
+
+       struct mutex                    mutex;
+
+       struct ring_buffer_per_cpu      **buffers;
+};
+
+struct ring_buffer_iter {
+       struct ring_buffer_per_cpu      *cpu_buffer;
+       unsigned long                   head;
+       struct buffer_page              *head_page;
+       u64                             read_stamp;
+};
+
+#define RB_WARN_ON(buffer, cond)                               \
+       do {                                                    \
+               if (unlikely(cond)) {                           \
+                       atomic_inc(&buffer->record_disabled);   \
+                       WARN_ON(1);                             \
+               }                                               \
+       } while (0)
+
+#define RB_WARN_ON_RET(buffer, cond)                           \
+       do {                                                    \
+               if (unlikely(cond)) {                           \
+                       atomic_inc(&buffer->record_disabled);   \
+                       WARN_ON(1);                             \
+                       return -1;                              \
+               }                                               \
+       } while (0)
+
+#define RB_WARN_ON_ONCE(buffer, cond)                          \
+       do {                                                    \
+               static int once;                                \
+               if (unlikely(cond) && !once) {                  \
+                       once++;                                 \
+                       atomic_inc(&buffer->record_disabled);   \
+                       WARN_ON(1);                             \
+               }                                               \
+       } while (0)
+
+/**
+ * check_pages - integrity check of buffer pages
+ * @cpu_buffer: CPU buffer with pages to test
+ *
+ * As a safty measure we check to make sure the data pages have not
+ * been corrupted.
+ */
+static int rb_check_pages(struct ring_buffer_per_cpu *cpu_buffer)
+{
+       struct list_head *head = &cpu_buffer->pages;
+       struct buffer_page *page, *tmp;
+
+       RB_WARN_ON_RET(cpu_buffer, head->next->prev != head);
+       RB_WARN_ON_RET(cpu_buffer, head->prev->next != head);
+
+       list_for_each_entry_safe(page, tmp, head, list) {
+               RB_WARN_ON_RET(cpu_buffer,
+                              page->list.next->prev != &page->list);
+               RB_WARN_ON_RET(cpu_buffer,
+                              page->list.prev->next != &page->list);
+       }
+
+       return 0;
+}
+
+static int rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer,
+                            unsigned nr_pages)
+{
+       struct list_head *head = &cpu_buffer->pages;
+       struct buffer_page *page, *tmp;
+       unsigned long addr;
+       LIST_HEAD(pages);
+       unsigned i;
+
+       for (i = 0; i < nr_pages; i++) {
+               page = kzalloc_node(ALIGN(sizeof(*page), cache_line_size()),
+                                   GFP_KERNEL, cpu_to_node(cpu_buffer->cpu));
+               if (!page)
+                       goto free_pages;
+               list_add(&page->list, &pages);
+
+               addr = __get_free_page(GFP_KERNEL);
+               if (!addr)
+                       goto free_pages;
+               page->page = (void *)addr;
+       }
+
+       list_splice(&pages, head);
+
+       rb_check_pages(cpu_buffer);
+
+       return 0;
+
+ free_pages:
+       list_for_each_entry_safe(page, tmp, &pages, list) {
+               list_del_init(&page->list);
+               free_buffer_page(page);
+       }
+       return -ENOMEM;
+}
+
+static struct ring_buffer_per_cpu *
+rb_allocate_cpu_buffer(struct ring_buffer *buffer, int cpu)
+{
+       struct ring_buffer_per_cpu *cpu_buffer;
+       struct buffer_page *page;
+       unsigned long addr;
+       int ret;
+
+       cpu_buffer = kzalloc_node(ALIGN(sizeof(*cpu_buffer), cache_line_size()),
+                                 GFP_KERNEL, cpu_to_node(cpu));
+       if (!cpu_buffer)
+               return NULL;
+
+       cpu_buffer->cpu = cpu;
+       cpu_buffer->buffer = buffer;
+       spin_lock_init(&cpu_buffer->lock);
+       INIT_LIST_HEAD(&cpu_buffer->pages);
+
+       page = kzalloc_node(ALIGN(sizeof(*page), cache_line_size()),
+                           GFP_KERNEL, cpu_to_node(cpu));
+       if (!page)
+               goto fail_free_buffer;
+
+       cpu_buffer->reader_page = page;
+       addr = __get_free_page(GFP_KERNEL);
+       if (!addr)
+               goto fail_free_reader;
+       page->page = (void *)addr;
+
+       INIT_LIST_HEAD(&cpu_buffer->reader_page->list);
+
+       ret = rb_allocate_pages(cpu_buffer, buffer->pages);
+       if (ret < 0)
+               goto fail_free_reader;
+
+       cpu_buffer->head_page
+               = list_entry(cpu_buffer->pages.next, struct buffer_page, list);
+       cpu_buffer->tail_page = cpu_buffer->commit_page = cpu_buffer->head_page;
+
+       return cpu_buffer;
+
+ fail_free_reader:
+       free_buffer_page(cpu_buffer->reader_page);
+
+ fail_free_buffer:
+       kfree(cpu_buffer);
+       return NULL;
+}
+
+static void rb_free_cpu_buffer(struct ring_buffer_per_cpu *cpu_buffer)
+{
+       struct list_head *head = &cpu_buffer->pages;
+       struct buffer_page *page, *tmp;
+
+       list_del_init(&cpu_buffer->reader_page->list);
+       free_buffer_page(cpu_buffer->reader_page);
+
+       list_for_each_entry_safe(page, tmp, head, list) {
+               list_del_init(&page->list);
+               free_buffer_page(page);
+       }
+       kfree(cpu_buffer);
+}
+
+/*
+ * Causes compile errors if the struct buffer_page gets bigger
+ * than the struct page.
+ */
+extern int ring_buffer_page_too_big(void);
+
+/**
+ * ring_buffer_alloc - allocate a new ring_buffer
+ * @size: the size in bytes that is needed.
+ * @flags: attributes to set for the ring buffer.
+ *
+ * Currently the only flag that is available is the RB_FL_OVERWRITE
+ * flag. This flag means that the buffer will overwrite old data
+ * when the buffer wraps. If this flag is not set, the buffer will
+ * drop data when the tail hits the head.
+ */
+struct ring_buffer *ring_buffer_alloc(unsigned long size, unsigned flags)
+{
+       struct ring_buffer *buffer;
+       int bsize;
+       int cpu;
+
+       /* Paranoid! Optimizes out when all is well */
+       if (sizeof(struct buffer_page) > sizeof(struct page))
+               ring_buffer_page_too_big();
+
+
+       /* keep it in its own cache line */
+       buffer = kzalloc(ALIGN(sizeof(*buffer), cache_line_size()),
+                        GFP_KERNEL);
+       if (!buffer)
+               return NULL;
+
+       buffer->pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
+       buffer->flags = flags;
+
+       /* need at least two pages */
+       if (buffer->pages == 1)
+               buffer->pages++;
+
+       buffer->cpumask = cpu_possible_map;
+       buffer->cpus = nr_cpu_ids;
+
+       bsize = sizeof(void *) * nr_cpu_ids;
+       buffer->buffers = kzalloc(ALIGN(bsize, cache_line_size()),
+                                 GFP_KERNEL);
+       if (!buffer->buffers)
+               goto fail_free_buffer;
+
+       for_each_buffer_cpu(buffer, cpu) {
+               buffer->buffers[cpu] =
+                       rb_allocate_cpu_buffer(buffer, cpu);
+               if (!buffer->buffers[cpu])
+                       goto fail_free_buffers;
+       }
+
+       mutex_init(&buffer->mutex);
+
+       return buffer;
+
+ fail_free_buffers:
+       for_each_buffer_cpu(buffer, cpu) {
+               if (buffer->buffers[cpu])
+                       rb_free_cpu_buffer(buffer->buffers[cpu]);
+       }
+       kfree(buffer->buffers);
+
+ fail_free_buffer:
+       kfree(buffer);
+       return NULL;
+}
+
+/**
+ * ring_buffer_free - free a ring buffer.
+ * @buffer: the buffer to free.
+ */
+void
+ring_buffer_free(struct ring_buffer *buffer)
+{
+       int cpu;
+
+       for_each_buffer_cpu(buffer, cpu)
+               rb_free_cpu_buffer(buffer->buffers[cpu]);
+
+       kfree(buffer);
+}
+
+static void rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer);
+
+static void
+rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned nr_pages)
+{
+       struct buffer_page *page;
+       struct list_head *p;
+       unsigned i;
+
+       atomic_inc(&cpu_buffer->record_disabled);
+       synchronize_sched();
+
+       for (i = 0; i < nr_pages; i++) {
+               BUG_ON(list_empty(&cpu_buffer->pages));
+               p = cpu_buffer->pages.next;
+               page = list_entry(p, struct buffer_page, list);
+               list_del_init(&page->list);
+               free_buffer_page(page);
+       }
+       BUG_ON(list_empty(&cpu_buffer->pages));
+
+       rb_reset_cpu(cpu_buffer);
+
+       rb_check_pages(cpu_buffer);
+
+       atomic_dec(&cpu_buffer->record_disabled);
+
+}
+
+static void
+rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer,
+               struct list_head *pages, unsigned nr_pages)
+{
+       struct buffer_page *page;
+       struct list_head *p;
+       unsigned i;
+
+       atomic_inc(&cpu_buffer->record_disabled);
+       synchronize_sched();
+
+       for (i = 0; i < nr_pages; i++) {
+               BUG_ON(list_empty(pages));
+               p = pages->next;
+               page = list_entry(p, struct buffer_page, list);
+               list_del_init(&page->list);
+               list_add_tail(&page->list, &cpu_buffer->pages);
+       }
+       rb_reset_cpu(cpu_buffer);
+
+       rb_check_pages(cpu_buffer);
+
+       atomic_dec(&cpu_buffer->record_disabled);
+}
+
+/**
+ * ring_buffer_resize - resize the ring buffer
+ * @buffer: the buffer to resize.
+ * @size: the new size.
+ *
+ * The tracer is responsible for making sure that the buffer is
+ * not being used while changing the size.
+ * Note: We may be able to change the above requirement by using
+ *  RCU synchronizations.
+ *
+ * Minimum size is 2 * BUF_PAGE_SIZE.
+ *
+ * Returns -1 on failure.
+ */
+int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size)
+{
+       struct ring_buffer_per_cpu *cpu_buffer;
+       unsigned nr_pages, rm_pages, new_pages;
+       struct buffer_page *page, *tmp;
+       unsigned long buffer_size;
+       unsigned long addr;
+       LIST_HEAD(pages);
+       int i, cpu;
+
+       size = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
+       size *= BUF_PAGE_SIZE;
+       buffer_size = buffer->pages * BUF_PAGE_SIZE;
+
+       /* we need a minimum of two pages */
+       if (size < BUF_PAGE_SIZE * 2)
+               size = BUF_PAGE_SIZE * 2;
+
+       if (size == buffer_size)
+               return size;
+
+       mutex_lock(&buffer->mutex);
+
+       nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
+
+       if (size < buffer_size) {
+
+               /* easy case, just free pages */
+               BUG_ON(nr_pages >= buffer->pages);
+
+               rm_pages = buffer->pages - nr_pages;
+
+               for_each_buffer_cpu(buffer, cpu) {
+                       cpu_buffer = buffer->buffers[cpu];
+                       rb_remove_pages(cpu_buffer, rm_pages);
+               }
+               goto out;
+       }
+
+       /*
+        * This is a bit more difficult. We only want to add pages
+        * when we can allocate enough for all CPUs. We do this
+        * by allocating all the pages and storing them on a local
+        * link list. If we succeed in our allocation, then we
+        * add these pages to the cpu_buffers. Otherwise we just free
+        * them all and return -ENOMEM;
+        */
+       BUG_ON(nr_pages <= buffer->pages);
+       new_pages = nr_pages - buffer->pages;
+
+       for_each_buffer_cpu(buffer, cpu) {
+               for (i = 0; i < new_pages; i++) {
+                       page = kzalloc_node(ALIGN(sizeof(*page),
+                                                 cache_line_size()),
+                                           GFP_KERNEL, cpu_to_node(cpu));
+                       if (!page)
+                               goto free_pages;
+                       list_add(&page->list, &pages);
+                       addr = __get_free_page(GFP_KERNEL);
+                       if (!addr)
+                               goto free_pages;
+                       page->page = (void *)addr;
+               }
+       }
+
+       for_each_buffer_cpu(buffer, cpu) {
+               cpu_buffer = buffer->buffers[cpu];
+               rb_insert_pages(cpu_buffer, &pages, new_pages);
+       }
+
+       BUG_ON(!list_empty(&pages));
+
+ out:
+       buffer->pages = nr_pages;
+       mutex_unlock(&buffer->mutex);
+
+       return size;
+
+ free_pages:
+       list_for_each_entry_safe(page, tmp, &pages, list) {
+               list_del_init(&page->list);
+               free_buffer_page(page);
+       }
+       return -ENOMEM;
+}
+
+static inline int rb_null_event(struct ring_buffer_event *event)
+{
+       return event->type == RINGBUF_TYPE_PADDING;
+}
+
+static inline void *__rb_page_index(struct buffer_page *page, unsigned index)
+{
+       return page->page + index;
+}
+
+static inline struct ring_buffer_event *
+rb_reader_event(struct ring_buffer_per_cpu *cpu_buffer)
+{
+       return __rb_page_index(cpu_buffer->reader_page,
+                              cpu_buffer->reader_page->read);
+}
+
+static inline struct ring_buffer_event *
+rb_head_event(struct ring_buffer_per_cpu *cpu_buffer)
+{
+       return __rb_page_index(cpu_buffer->head_page,
+                              cpu_buffer->head_page->read);
+}
+
+static inline struct ring_buffer_event *
+rb_iter_head_event(struct ring_buffer_iter *iter)
+{
+       return __rb_page_index(iter->head_page, iter->head);
+}
+
+static inline unsigned rb_page_write(struct buffer_page *bpage)
+{
+       return local_read(&bpage->write);
+}
+
+static inline unsigned rb_page_commit(struct buffer_page *bpage)
+{
+       return local_read(&bpage->commit);
+}
+
+/* Size is determined by what has been commited */
+static inline unsigned rb_page_size(struct buffer_page *bpage)
+{
+       return rb_page_commit(bpage);
+}
+
+static inline unsigned
+rb_commit_index(struct ring_buffer_per_cpu *cpu_buffer)
+{
+       return rb_page_commit(cpu_buffer->commit_page);
+}
+
+static inline unsigned rb_head_size(struct ring_buffer_per_cpu *cpu_buffer)
+{
+       return rb_page_commit(cpu_buffer->head_page);
+}
+
+/*
+ * When the tail hits the head and the buffer is in overwrite mode,
+ * the head jumps to the next page and all content on the previous
+ * page is discarded. But before doing so, we update the overrun
+ * variable of the buffer.
+ */
+static void rb_update_overflow(struct ring_buffer_per_cpu *cpu_buffer)
+{
+       struct ring_buffer_event *event;
+       unsigned long head;
+
+       for (head = 0; head < rb_head_size(cpu_buffer);
+            head += rb_event_length(event)) {
+
+               event = __rb_page_index(cpu_buffer->head_page, head);
+               BUG_ON(rb_null_event(event));
+               /* Only count data entries */
+               if (event->type != RINGBUF_TYPE_DATA)
+                       continue;
+               cpu_buffer->overrun++;
+               cpu_buffer->entries--;
+       }
+}
+
+static inline void rb_inc_page(struct ring_buffer_per_cpu *cpu_buffer,
+                              struct buffer_page **page)
+{
+       struct list_head *p = (*page)->list.next;
+
+       if (p == &cpu_buffer->pages)
+               p = p->next;
+
+       *page = list_entry(p, struct buffer_page, list);
+}
+
+static inline unsigned
+rb_event_index(struct ring_buffer_event *event)
+{
+       unsigned long addr = (unsigned long)event;
+
+       return (addr & ~PAGE_MASK) - (PAGE_SIZE - BUF_PAGE_SIZE);
+}
+
+static inline int
+rb_is_commit(struct ring_buffer_per_cpu *cpu_buffer,
+            struct ring_buffer_event *event)
+{
+       unsigned long addr = (unsigned long)event;
+       unsigned long index;
+
+       index = rb_event_index(event);
+       addr &= PAGE_MASK;
+
+       return cpu_buffer->commit_page->page == (void *)addr &&
+               rb_commit_index(cpu_buffer) == index;
+}
+
+static inline void
+rb_set_commit_event(struct ring_buffer_per_cpu *cpu_buffer,
+                   struct ring_buffer_event *event)
+{
+       unsigned long addr = (unsigned long)event;
+       unsigned long index;
+
+       index = rb_event_index(event);
+       addr &= PAGE_MASK;
+
+       while (cpu_buffer->commit_page->page != (void *)addr) {
+               RB_WARN_ON(cpu_buffer,
+                          cpu_buffer->commit_page == cpu_buffer->tail_page);
+               cpu_buffer->commit_page->commit =
+                       cpu_buffer->commit_page->write;
+               rb_inc_page(cpu_buffer, &cpu_buffer->commit_page);
+               cpu_buffer->write_stamp = cpu_buffer->commit_page->time_stamp;
+       }
+
+       /* Now set the commit to the event's index */
+       local_set(&cpu_buffer->commit_page->commit, index);
+}
+
+static inline void
+rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer)
+{
+       /*
+        * We only race with interrupts and NMIs on this CPU.
+        * If we own the commit event, then we can commit
+        * all others that interrupted us, since the interruptions
+        * are in stack format (they finish before they come
+        * back to us). This allows us to do a simple loop to
+        * assign the commit to the tail.
+        */
+       while (cpu_buffer->commit_page != cpu_buffer->tail_page) {
+               cpu_buffer->commit_page->commit =
+                       cpu_buffer->commit_page->write;
+               rb_inc_page(cpu_buffer, &cpu_buffer->commit_page);
+               cpu_buffer->write_stamp = cpu_buffer->commit_page->time_stamp;
+               /* add barrier to keep gcc from optimizing too much */
+               barrier();
+       }
+       while (rb_commit_index(cpu_buffer) !=
+              rb_page_write(cpu_buffer->commit_page)) {
+               cpu_buffer->commit_page->commit =
+                       cpu_buffer->commit_page->write;
+               barrier();
+       }
+}
+
+static void rb_reset_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
+{
+       cpu_buffer->read_stamp = cpu_buffer->reader_page->time_stamp;
+       cpu_buffer->reader_page->read = 0;
+}
+
+static inline void rb_inc_iter(struct ring_buffer_iter *iter)
+{
+       struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer;
+
+       /*
+        * The iterator could be on the reader page (it starts there).
+        * But the head could have moved, since the reader was
+        * found. Check for this case and assign the iterator
+        * to the head page instead of next.
+        */
+       if (iter->head_page == cpu_buffer->reader_page)
+               iter->head_page = cpu_buffer->head_page;
+       else
+               rb_inc_page(cpu_buffer, &iter->head_page);
+
+       iter->read_stamp = iter->head_page->time_stamp;
+       iter->head = 0;
+}
+
+/**
+ * ring_buffer_update_event - update event type and data
+ * @event: the even to update
+ * @type: the type of event
+ * @length: the size of the event field in the ring buffer
+ *
+ * Update the type and data fields of the event. The length
+ * is the actual size that is written to the ring buffer,
+ * and with this, we can determine what to place into the
+ * data field.
+ */
+static inline void
+rb_update_event(struct ring_buffer_event *event,
+                        unsigned type, unsigned length)
+{
+       event->type = type;
+
+       switch (type) {
+
+       case RINGBUF_TYPE_PADDING:
+               break;
+
+       case RINGBUF_TYPE_TIME_EXTEND:
+               event->len =
+                       (RB_LEN_TIME_EXTEND + (RB_ALIGNMENT-1))
+                       >> RB_ALIGNMENT_SHIFT;
+               break;
+
+       case RINGBUF_TYPE_TIME_STAMP:
+               event->len =
+                       (RB_LEN_TIME_STAMP + (RB_ALIGNMENT-1))
+                       >> RB_ALIGNMENT_SHIFT;
+               break;
+
+       case RINGBUF_TYPE_DATA:
+               length -= RB_EVNT_HDR_SIZE;
+               if (length > RB_MAX_SMALL_DATA) {
+                       event->len = 0;
+                       event->array[0] = length;
+               } else
+                       event->len =
+                               (length + (RB_ALIGNMENT-1))
+                               >> RB_ALIGNMENT_SHIFT;
+               break;
+       default:
+               BUG();
+       }
+}
+
+static inline unsigned rb_calculate_event_length(unsigned length)
+{
+       struct ring_buffer_event event; /* Used only for sizeof array */
+
+       /* zero length can cause confusions */
+       if (!length)
+               length = 1;
+
+       if (length > RB_MAX_SMALL_DATA)
+               length += sizeof(event.array[0]);
+
+       length += RB_EVNT_HDR_SIZE;
+       length = ALIGN(length, RB_ALIGNMENT);
+
+       return length;
+}
+
+static struct ring_buffer_event *
+__rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
+                 unsigned type, unsigned long length, u64 *ts)
+{
+       struct buffer_page *tail_page, *head_page, *reader_page;
+       unsigned long tail, write;
+       struct ring_buffer *buffer = cpu_buffer->buffer;
+       struct ring_buffer_event *event;
+       unsigned long flags;
+
+       tail_page = cpu_buffer->tail_page;
+       write = local_add_return(length, &tail_page->write);
+       tail = write - length;
+
+       /* See if we shot pass the end of this buffer page */
+       if (write > BUF_PAGE_SIZE) {
+               struct buffer_page *next_page = tail_page;
+
+               spin_lock_irqsave(&cpu_buffer->lock, flags);
+
+               rb_inc_page(cpu_buffer, &next_page);
+
+               head_page = cpu_buffer->head_page;
+               reader_page = cpu_buffer->reader_page;
+
+               /* we grabbed the lock before incrementing */
+               RB_WARN_ON(cpu_buffer, next_page == reader_page);
+
+               /*
+                * If for some reason, we had an interrupt storm that made
+                * it all the way around the buffer, bail, and warn
+                * about it.
+                */
+               if (unlikely(next_page == cpu_buffer->commit_page)) {
+                       WARN_ON_ONCE(1);
+                       goto out_unlock;
+               }
+
+               if (next_page == head_page) {
+                       if (!(buffer->flags & RB_FL_OVERWRITE)) {
+                               /* reset write */
+                               if (tail <= BUF_PAGE_SIZE)
+                                       local_set(&tail_page->write, tail);
+                               goto out_unlock;
+                       }
+
+                       /* tail_page has not moved yet? */
+                       if (tail_page == cpu_buffer->tail_page) {
+                               /* count overflows */
+                               rb_update_overflow(cpu_buffer);
+
+                               rb_inc_page(cpu_buffer, &head_page);
+                               cpu_buffer->head_page = head_page;
+                               cpu_buffer->head_page->read = 0;
+                       }
+               }
+
+               /*
+                * If the tail page is still the same as what we think
+                * it is, then it is up to us to update the tail
+                * pointer.
+                */
+               if (tail_page == cpu_buffer->tail_page) {
+                       local_set(&next_page->write, 0);
+                       local_set(&next_page->commit, 0);
+                       cpu_buffer->tail_page = next_page;
+
+                       /* reread the time stamp */
+                       *ts = ring_buffer_time_stamp(cpu_buffer->cpu);
+                       cpu_buffer->tail_page->time_stamp = *ts;
+               }
+
+               /*
+                * The actual tail page has moved forward.
+                */
+               if (tail < BUF_PAGE_SIZE) {
+                       /* Mark the rest of the page with padding */
+                       event = __rb_page_index(tail_page, tail);
+                       event->type = RINGBUF_TYPE_PADDING;
+               }
+
+               if (tail <= BUF_PAGE_SIZE)
+                       /* Set the write back to the previous setting */
+                       local_set(&tail_page->write, tail);
+
+               /*
+                * If this was a commit entry that failed,
+                * increment that too
+                */
+               if (tail_page == cpu_buffer->commit_page &&
+                   tail == rb_commit_index(cpu_buffer)) {
+                       rb_set_commit_to_write(cpu_buffer);
+               }
+
+               spin_unlock_irqrestore(&cpu_buffer->lock, flags);
+
+               /* fail and let the caller try again */
+               return ERR_PTR(-EAGAIN);
+       }
+
+       /* We reserved something on the buffer */
+
+       BUG_ON(write > BUF_PAGE_SIZE);
+
+       event = __rb_page_index(tail_page, tail);
+       rb_update_event(event, type, length);
+
+       /*
+        * If this is a commit and the tail is zero, then update
+        * this page's time stamp.
+        */
+       if (!tail && rb_is_commit(cpu_buffer, event))
+               cpu_buffer->commit_page->time_stamp = *ts;
+
+       return event;
+
+ out_unlock:
+       spin_unlock_irqrestore(&cpu_buffer->lock, flags);
+       return NULL;
+}
+
+static int
+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",
+                      *delta, *ts, cpu_buffer->write_stamp);
+               WARN_ON(1);
+       }
+
+       /*
+        * The delta is too big, we to add a
+        * new timestamp.
+        */
+       event = __rb_reserve_next(cpu_buffer,
+                                 RINGBUF_TYPE_TIME_EXTEND,
+                                 RB_LEN_TIME_EXTEND,
+                                 ts);
+       if (!event)
+               return -EBUSY;
+
+       if (PTR_ERR(event) == -EAGAIN)
+               return -EAGAIN;
+
+       /* Only a commited time event can update the write stamp */
+       if (rb_is_commit(cpu_buffer, event)) {
+               /*
+                * If this is the first on the page, then we need to
+                * update the page itself, and just put in a zero.
+                */
+               if (rb_event_index(event)) {
+                       event->time_delta = *delta & TS_MASK;
+                       event->array[0] = *delta >> TS_SHIFT;
+               } else {
+                       cpu_buffer->commit_page->time_stamp = *ts;
+                       event->time_delta = 0;
+                       event->array[0] = 0;
+               }
+               cpu_buffer->write_stamp = *ts;
+               /* let the caller know this was the commit */
+               ret = 1;
+       } else {
+               /* Darn, this is just wasted space */
+               event->time_delta = 0;
+               event->array[0] = 0;
+               ret = 0;
+       }
+
+       *delta = 0;
+
+       return ret;
+}
+
+static struct ring_buffer_event *
+rb_reserve_next_event(struct ring_buffer_per_cpu *cpu_buffer,
+                     unsigned type, unsigned long length)
+{
+       struct ring_buffer_event *event;
+       u64 ts, delta;
+       int commit = 0;
+
+ again:
+       ts = ring_buffer_time_stamp(cpu_buffer->cpu);
+
+       /*
+        * Only the first commit can update the timestamp.
+        * Yes there is a race here. If an interrupt comes in
+        * just after the conditional and it traces too, then it
+        * will also check the deltas. More than one timestamp may
+        * also be made. But only the entry that did the actual
+        * commit will be something other than zero.
+        */
+       if (cpu_buffer->tail_page == cpu_buffer->commit_page &&
+           rb_page_write(cpu_buffer->tail_page) ==
+           rb_commit_index(cpu_buffer)) {
+
+               delta = ts - cpu_buffer->write_stamp;
+
+               /* make sure this delta is calculated here */
+               barrier();
+
+               /* Did the write stamp get updated already? */
+               if (unlikely(ts < cpu_buffer->write_stamp))
+                       goto again;
+
+               if (test_time_stamp(delta)) {
+
+                       commit = rb_add_time_stamp(cpu_buffer, &ts, &delta);
+
+                       if (commit == -EBUSY)
+                               return NULL;
+
+                       if (commit == -EAGAIN)
+                               goto again;
+
+                       RB_WARN_ON(cpu_buffer, commit < 0);
+               }
+       } else
+               /* Non commits have zero deltas */
+               delta = 0;
+
+       event = __rb_reserve_next(cpu_buffer, type, length, &ts);
+       if (PTR_ERR(event) == -EAGAIN)
+               goto again;
+
+       if (!event) {
+               if (unlikely(commit))
+                       /*
+                        * Ouch! We needed a timestamp and it was commited. But
+                        * we didn't get our event reserved.
+                        */
+                       rb_set_commit_to_write(cpu_buffer);
+               return NULL;
+       }
+
+       /*
+        * If the timestamp was commited, make the commit our entry
+        * now so that we will update it when needed.
+        */
+       if (commit)
+               rb_set_commit_event(cpu_buffer, event);
+       else if (!rb_is_commit(cpu_buffer, event))
+               delta = 0;
+
+       event->time_delta = delta;
+
+       return event;
+}
+
+static DEFINE_PER_CPU(int, rb_need_resched);
+
+/**
+ * ring_buffer_lock_reserve - reserve a part of the buffer
+ * @buffer: the ring buffer to reserve from
+ * @length: the length of the data to reserve (excluding event header)
+ * @flags: a pointer to save the interrupt flags
+ *
+ * Returns a reseverd event on the ring buffer to copy directly to.
+ * The user of this interface will need to get the body to write into
+ * and can use the ring_buffer_event_data() interface.
+ *
+ * The length is the length of the data needed, not the event length
+ * which also includes the event header.
+ *
+ * Must be paired with ring_buffer_unlock_commit, unless NULL is returned.
+ * If NULL is returned, then nothing has been allocated or locked.
+ */
+struct ring_buffer_event *
+ring_buffer_lock_reserve(struct ring_buffer *buffer,
+                        unsigned long length,
+                        unsigned long *flags)
+{
+       struct ring_buffer_per_cpu *cpu_buffer;
+       struct ring_buffer_event *event;
+       int cpu, resched;
+
+       if (atomic_read(&buffer->record_disabled))
+               return NULL;
+
+       /* If we are tracing schedule, we don't want to recurse */
+       resched = need_resched();
+       preempt_disable_notrace();
+
+       cpu = raw_smp_processor_id();
+
+       if (!cpu_isset(cpu, buffer->cpumask))
+               goto out;
+
+       cpu_buffer = buffer->buffers[cpu];
+
+       if (atomic_read(&cpu_buffer->record_disabled))
+               goto out;
+
+       length = rb_calculate_event_length(length);
+       if (length > BUF_PAGE_SIZE)
+               goto out;
+
+       event = rb_reserve_next_event(cpu_buffer, RINGBUF_TYPE_DATA, length);
+       if (!event)
+               goto out;
+
+       /*
+        * Need to store resched state on this cpu.
+        * Only the first needs to.
+        */
+
+       if (preempt_count() == 1)
+               per_cpu(rb_need_resched, cpu) = resched;
+
+       return event;
+
+ out:
+       if (resched)
+               preempt_enable_notrace();
+       else
+               preempt_enable_notrace();
+       return NULL;
+}
+
+static void rb_commit(struct ring_buffer_per_cpu *cpu_buffer,
+                     struct ring_buffer_event *event)
+{
+       cpu_buffer->entries++;
+
+       /* Only process further if we own the commit */
+       if (!rb_is_commit(cpu_buffer, event))
+               return;
+
+       cpu_buffer->write_stamp += event->time_delta;
+
+       rb_set_commit_to_write(cpu_buffer);
+}
+
+/**
+ * ring_buffer_unlock_commit - commit a reserved
+ * @buffer: The buffer to commit to
+ * @event: The event pointer to commit.
+ * @flags: the interrupt flags received from ring_buffer_lock_reserve.
+ *
+ * This commits the data to the ring buffer, and releases any locks held.
+ *
+ * Must be paired with ring_buffer_lock_reserve.
+ */
+int ring_buffer_unlock_commit(struct ring_buffer *buffer,
+                             struct ring_buffer_event *event,
+                             unsigned long flags)
+{
+       struct ring_buffer_per_cpu *cpu_buffer;
+       int cpu = raw_smp_processor_id();
+
+       cpu_buffer = buffer->buffers[cpu];
+
+       rb_commit(cpu_buffer, event);
+
+       /*
+        * Only the last preempt count needs to restore preemption.
+        */
+       if (preempt_count() == 1) {
+               if (per_cpu(rb_need_resched, cpu))
+                       preempt_enable_no_resched_notrace();
+               else
+                       preempt_enable_notrace();
+       } else
+               preempt_enable_no_resched_notrace();
+
+       return 0;
+}
+
+/**
+ * ring_buffer_write - write data to the buffer without reserving
+ * @buffer: The ring buffer to write to.
+ * @length: The length of the data being written (excluding the event header)
+ * @data: The data to write to the buffer.
+ *
+ * This is like ring_buffer_lock_reserve and ring_buffer_unlock_commit as
+ * one function. If you already have the data to write to the buffer, it
+ * may be easier to simply call this function.
+ *
+ * Note, like ring_buffer_lock_reserve, the length is the length of the data
+ * and not the length of the event which would hold the header.
+ */
+int ring_buffer_write(struct ring_buffer *buffer,
+                       unsigned long length,
+                       void *data)
+{
+       struct ring_buffer_per_cpu *cpu_buffer;
+       struct ring_buffer_event *event;
+       unsigned long event_length;
+       void *body;
+       int ret = -EBUSY;
+       int cpu, resched;
+
+       if (atomic_read(&buffer->record_disabled))
+               return -EBUSY;
+
+       resched = need_resched();
+       preempt_disable_notrace();
+
+       cpu = raw_smp_processor_id();
+
+       if (!cpu_isset(cpu, buffer->cpumask))
+               goto out;
+
+       cpu_buffer = buffer->buffers[cpu];
+
+       if (atomic_read(&cpu_buffer->record_disabled))
+               goto out;
+
+       event_length = rb_calculate_event_length(length);
+       event = rb_reserve_next_event(cpu_buffer,
+                                     RINGBUF_TYPE_DATA, event_length);
+       if (!event)
+               goto out;
+
+       body = rb_event_data(event);
+
+       memcpy(body, data, length);
+
+       rb_commit(cpu_buffer, event);
+
+       ret = 0;
+ out:
+       if (resched)
+               preempt_enable_no_resched_notrace();
+       else
+               preempt_enable_notrace();
+
+       return ret;
+}
+
+static inline int rb_per_cpu_empty(struct ring_buffer_per_cpu *cpu_buffer)
+{
+       struct buffer_page *reader = cpu_buffer->reader_page;
+       struct buffer_page *head = cpu_buffer->head_page;
+       struct buffer_page *commit = cpu_buffer->commit_page;
+
+       return reader->read == rb_page_commit(reader) &&
+               (commit == reader ||
+                (commit == head &&
+                 head->read == rb_page_commit(commit)));
+}
+
+/**
+ * ring_buffer_record_disable - stop all writes into the buffer
+ * @buffer: The ring buffer to stop writes to.
+ *
+ * This prevents all writes to the buffer. Any attempt to write
+ * to the buffer after this will fail and return NULL.
+ *
+ * The caller should call synchronize_sched() after this.
+ */
+void ring_buffer_record_disable(struct ring_buffer *buffer)
+{
+       atomic_inc(&buffer->record_disabled);
+}
+
+/**
+ * ring_buffer_record_enable - enable writes to the buffer
+ * @buffer: The ring buffer to enable writes
+ *
+ * Note, multiple disables will need the same number of enables
+ * to truely enable the writing (much like preempt_disable).
+ */
+void ring_buffer_record_enable(struct ring_buffer *buffer)
+{
+       atomic_dec(&buffer->record_disabled);
+}
+
+/**
+ * ring_buffer_record_disable_cpu - stop all writes into the cpu_buffer
+ * @buffer: The ring buffer to stop writes to.
+ * @cpu: The CPU buffer to stop
+ *
+ * This prevents all writes to the buffer. Any attempt to write
+ * to the buffer after this will fail and return NULL.
+ *
+ * The caller should call synchronize_sched() after this.
+ */
+void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu)
+{
+       struct ring_buffer_per_cpu *cpu_buffer;
+
+       if (!cpu_isset(cpu, buffer->cpumask))
+               return;
+
+       cpu_buffer = buffer->buffers[cpu];
+       atomic_inc(&cpu_buffer->record_disabled);
+}
+
+/**
+ * ring_buffer_record_enable_cpu - enable writes to the buffer
+ * @buffer: The ring buffer to enable writes
+ * @cpu: The CPU to enable.
+ *
+ * Note, multiple disables will need the same number of enables
+ * to truely enable the writing (much like preempt_disable).
+ */
+void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu)
+{
+       struct ring_buffer_per_cpu *cpu_buffer;
+
+       if (!cpu_isset(cpu, buffer->cpumask))
+               return;
+
+       cpu_buffer = buffer->buffers[cpu];
+       atomic_dec(&cpu_buffer->record_disabled);
+}
+
+/**
+ * ring_buffer_entries_cpu - get the number of entries in a cpu buffer
+ * @buffer: The ring buffer
+ * @cpu: The per CPU buffer to get the entries from.
+ */
+unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu)
+{
+       struct ring_buffer_per_cpu *cpu_buffer;
+
+       if (!cpu_isset(cpu, buffer->cpumask))
+               return 0;
+
+       cpu_buffer = buffer->buffers[cpu];
+       return cpu_buffer->entries;
+}
+
+/**
+ * ring_buffer_overrun_cpu - get the number of overruns in a cpu_buffer
+ * @buffer: The ring buffer
+ * @cpu: The per CPU buffer to get the number of overruns from
+ */
+unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu)
+{
+       struct ring_buffer_per_cpu *cpu_buffer;
+
+       if (!cpu_isset(cpu, buffer->cpumask))
+               return 0;
+
+       cpu_buffer = buffer->buffers[cpu];
+       return cpu_buffer->overrun;
+}
+
+/**
+ * ring_buffer_entries - get the number of entries in a buffer
+ * @buffer: The ring buffer
+ *
+ * Returns the total number of entries in the ring buffer
+ * (all CPU entries)
+ */
+unsigned long ring_buffer_entries(struct ring_buffer *buffer)
+{
+       struct ring_buffer_per_cpu *cpu_buffer;
+       unsigned long entries = 0;
+       int cpu;
+
+       /* if you care about this being correct, lock the buffer */
+       for_each_buffer_cpu(buffer, cpu) {
+               cpu_buffer = buffer->buffers[cpu];
+               entries += cpu_buffer->entries;
+       }
+
+       return entries;
+}
+
+/**
+ * ring_buffer_overrun_cpu - get the number of overruns in buffer
+ * @buffer: The ring buffer
+ *
+ * Returns the total number of overruns in the ring buffer
+ * (all CPU entries)
+ */
+unsigned long ring_buffer_overruns(struct ring_buffer *buffer)
+{
+       struct ring_buffer_per_cpu *cpu_buffer;
+       unsigned long overruns = 0;
+       int cpu;
+
+       /* if you care about this being correct, lock the buffer */
+       for_each_buffer_cpu(buffer, cpu) {
+               cpu_buffer = buffer->buffers[cpu];
+               overruns += cpu_buffer->overrun;
+       }
+
+       return overruns;
+}
+
+/**
+ * ring_buffer_iter_reset - reset an iterator
+ * @iter: The iterator to reset
+ *
+ * Resets the iterator, so that it will start from the beginning
+ * again.
+ */
+void ring_buffer_iter_reset(struct ring_buffer_iter *iter)
+{
+       struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer;
+
+       /* Iterator usage is expected to have record disabled */
+       if (list_empty(&cpu_buffer->reader_page->list)) {
+               iter->head_page = cpu_buffer->head_page;
+               iter->head = cpu_buffer->head_page->read;
+       } else {
+               iter->head_page = cpu_buffer->reader_page;
+               iter->head = cpu_buffer->reader_page->read;
+       }
+       if (iter->head)
+               iter->read_stamp = cpu_buffer->read_stamp;
+       else
+               iter->read_stamp = iter->head_page->time_stamp;
+}
+
+/**
+ * ring_buffer_iter_empty - check if an iterator has no more to read
+ * @iter: The iterator to check
+ */
+int ring_buffer_iter_empty(struct ring_buffer_iter *iter)
+{
+       struct ring_buffer_per_cpu *cpu_buffer;
+
+       cpu_buffer = iter->cpu_buffer;
+
+       return iter->head_page == cpu_buffer->commit_page &&
+               iter->head == rb_commit_index(cpu_buffer);
+}
+
+static void
+rb_update_read_stamp(struct ring_buffer_per_cpu *cpu_buffer,
+                    struct ring_buffer_event *event)
+{
+       u64 delta;
+
+       switch (event->type) {
+       case RINGBUF_TYPE_PADDING:
+               return;
+
+       case RINGBUF_TYPE_TIME_EXTEND:
+               delta = event->array[0];
+               delta <<= TS_SHIFT;
+               delta += event->time_delta;
+               cpu_buffer->read_stamp += delta;
+               return;
+
+       case RINGBUF_TYPE_TIME_STAMP:
+               /* FIXME: not implemented */
+               return;
+
+       case RINGBUF_TYPE_DATA:
+               cpu_buffer->read_stamp += event->time_delta;
+               return;
+
+       default:
+               BUG();
+       }
+       return;
+}
+
+static void
+rb_update_iter_read_stamp(struct ring_buffer_iter *iter,
+                         struct ring_buffer_event *event)
+{
+       u64 delta;
+
+       switch (event->type) {
+       case RINGBUF_TYPE_PADDING:
+               return;
+
+       case RINGBUF_TYPE_TIME_EXTEND:
+               delta = event->array[0];
+               delta <<= TS_SHIFT;
+               delta += event->time_delta;
+               iter->read_stamp += delta;
+               return;
+
+       case RINGBUF_TYPE_TIME_STAMP:
+               /* FIXME: not implemented */
+               return;
+
+       case RINGBUF_TYPE_DATA:
+               iter->read_stamp += event->time_delta;
+               return;
+
+       default:
+               BUG();
+       }
+       return;
+}
+
+static struct buffer_page *
+rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
+{
+       struct buffer_page *reader = NULL;
+       unsigned long flags;
+
+       spin_lock_irqsave(&cpu_buffer->lock, flags);
+
+ again:
+       reader = cpu_buffer->reader_page;
+
+       /* If there's more to read, return this page */
+       if (cpu_buffer->reader_page->read < rb_page_size(reader))
+               goto out;
+
+       /* Never should we have an index greater than the size */
+       RB_WARN_ON(cpu_buffer,
+                  cpu_buffer->reader_page->read > rb_page_size(reader));
+
+       /* check if we caught up to the tail */
+       reader = NULL;
+       if (cpu_buffer->commit_page == cpu_buffer->reader_page)
+               goto out;
+
+       /*
+        * Splice the empty reader page into the list around the head.
+        * Reset the reader page to size zero.
+        */
+
+       reader = cpu_buffer->head_page;
+       cpu_buffer->reader_page->list.next = reader->list.next;
+       cpu_buffer->reader_page->list.prev = reader->list.prev;
+
+       local_set(&cpu_buffer->reader_page->write, 0);
+       local_set(&cpu_buffer->reader_page->commit, 0);
+
+       /* Make the reader page now replace the head */
+       reader->list.prev->next = &cpu_buffer->reader_page->list;
+       reader->list.next->prev = &cpu_buffer->reader_page->list;
+
+       /*
+        * If the tail is on the reader, then we must set the head
+        * to the inserted page, otherwise we set it one before.
+        */
+       cpu_buffer->head_page = cpu_buffer->reader_page;
+
+       if (cpu_buffer->commit_page != reader)
+               rb_inc_page(cpu_buffer, &cpu_buffer->head_page);
+
+       /* Finally update the reader page to the new head */
+       cpu_buffer->reader_page = reader;
+       rb_reset_reader_page(cpu_buffer);
+
+       goto again;
+
+ out:
+       spin_unlock_irqrestore(&cpu_buffer->lock, flags);
+
+       return reader;
+}
+
+static void rb_advance_reader(struct ring_buffer_per_cpu *cpu_buffer)
+{
+       struct ring_buffer_event *event;
+       struct buffer_page *reader;
+       unsigned length;
+
+       reader = rb_get_reader_page(cpu_buffer);
+
+       /* This function should not be called when buffer is empty */
+       BUG_ON(!reader);
+
+       event = rb_reader_event(cpu_buffer);
+
+       if (event->type == RINGBUF_TYPE_DATA)
+               cpu_buffer->entries--;
+
+       rb_update_read_stamp(cpu_buffer, event);
+
+       length = rb_event_length(event);
+       cpu_buffer->reader_page->read += length;
+}
+
+static void rb_advance_iter(struct ring_buffer_iter *iter)
+{
+       struct ring_buffer *buffer;
+       struct ring_buffer_per_cpu *cpu_buffer;
+       struct ring_buffer_event *event;
+       unsigned length;
+
+       cpu_buffer = iter->cpu_buffer;
+       buffer = cpu_buffer->buffer;
+
+       /*
+        * Check if we are at the end of the buffer.
+        */
+       if (iter->head >= rb_page_size(iter->head_page)) {
+               BUG_ON(iter->head_page == cpu_buffer->commit_page);
+               rb_inc_iter(iter);
+               return;
+       }
+
+       event = rb_iter_head_event(iter);
+
+       length = rb_event_length(event);
+
+       /*
+        * This should not be called to advance the header if we are
+        * at the tail of the buffer.
+        */
+       BUG_ON((iter->head_page == cpu_buffer->commit_page) &&
+              (iter->head + length > rb_commit_index(cpu_buffer)));
+
+       rb_update_iter_read_stamp(iter, event);
+
+       iter->head += length;
+
+       /* check for end of page padding */
+       if ((iter->head >= rb_page_size(iter->head_page)) &&
+           (iter->head_page != cpu_buffer->commit_page))
+               rb_advance_iter(iter);
+}
+
+/**
+ * ring_buffer_peek - peek at the next event to be read
+ * @buffer: The ring buffer to read
+ * @cpu: The cpu to peak at
+ * @ts: The timestamp counter of this event.
+ *
+ * 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)
+{
+       struct ring_buffer_per_cpu *cpu_buffer;
+       struct ring_buffer_event *event;
+       struct buffer_page *reader;
+
+       if (!cpu_isset(cpu, buffer->cpumask))
+               return NULL;
+
+       cpu_buffer = buffer->buffers[cpu];
+
+ again:
+       reader = rb_get_reader_page(cpu_buffer);
+       if (!reader)
+               return NULL;
+
+       event = rb_reader_event(cpu_buffer);
+
+       switch (event->type) {
+       case RINGBUF_TYPE_PADDING:
+               RB_WARN_ON(cpu_buffer, 1);
+               rb_advance_reader(cpu_buffer);
+               return NULL;
+
+       case RINGBUF_TYPE_TIME_EXTEND:
+               /* Internal data, OK to advance */
+               rb_advance_reader(cpu_buffer);
+               goto again;
+
+       case RINGBUF_TYPE_TIME_STAMP:
+               /* FIXME: not implemented */
+               rb_advance_reader(cpu_buffer);
+               goto again;
+
+       case RINGBUF_TYPE_DATA:
+               if (ts) {
+                       *ts = cpu_buffer->read_stamp + event->time_delta;
+                       ring_buffer_normalize_time_stamp(cpu_buffer->cpu, ts);
+               }
+               return event;
+
+       default:
+               BUG();
+       }
+
+       return NULL;
+}
+
+/**
+ * ring_buffer_iter_peek - peek at the next event to be read
+ * @iter: The ring buffer iterator
+ * @ts: The timestamp counter of this event.
+ *
+ * This will return the event that will be read next, but does
+ * not increment the iterator.
+ */
+struct ring_buffer_event *
+ring_buffer_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
+{
+       struct ring_buffer *buffer;
+       struct ring_buffer_per_cpu *cpu_buffer;
+       struct ring_buffer_event *event;
+
+       if (ring_buffer_iter_empty(iter))
+               return NULL;
+
+       cpu_buffer = iter->cpu_buffer;
+       buffer = cpu_buffer->buffer;
+
+ again:
+       if (rb_per_cpu_empty(cpu_buffer))
+               return NULL;
+
+       event = rb_iter_head_event(iter);
+
+       switch (event->type) {
+       case RINGBUF_TYPE_PADDING:
+               rb_inc_iter(iter);
+               goto again;
+
+       case RINGBUF_TYPE_TIME_EXTEND:
+               /* Internal data, OK to advance */
+               rb_advance_iter(iter);
+               goto again;
+
+       case RINGBUF_TYPE_TIME_STAMP:
+               /* FIXME: not implemented */
+               rb_advance_iter(iter);
+               goto again;
+
+       case RINGBUF_TYPE_DATA:
+               if (ts) {
+                       *ts = iter->read_stamp + event->time_delta;
+                       ring_buffer_normalize_time_stamp(cpu_buffer->cpu, ts);
+               }
+               return event;
+
+       default:
+               BUG();
+       }
+
+       return NULL;
+}
+
+/**
+ * ring_buffer_consume - return an event and consume it
+ * @buffer: The ring buffer to get the next event from
+ *
+ * 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)
+{
+       struct ring_buffer_per_cpu *cpu_buffer;
+       struct ring_buffer_event *event;
+
+       if (!cpu_isset(cpu, buffer->cpumask))
+               return NULL;
+
+       event = ring_buffer_peek(buffer, cpu, ts);
+       if (!event)
+               return NULL;
+
+       cpu_buffer = buffer->buffers[cpu];
+       rb_advance_reader(cpu_buffer);
+
+       return event;
+}
+
+/**
+ * ring_buffer_read_start - start 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.
+ *
+ * Must be paired with ring_buffer_finish.
+ */
+struct ring_buffer_iter *
+ring_buffer_read_start(struct ring_buffer *buffer, int cpu)
+{
+       struct ring_buffer_per_cpu *cpu_buffer;
+       struct ring_buffer_iter *iter;
+       unsigned long flags;
+
+       if (!cpu_isset(cpu, buffer->cpumask))
+               return NULL;
+
+       iter = kmalloc(sizeof(*iter), GFP_KERNEL);
+       if (!iter)
+               return NULL;
+
+       cpu_buffer = buffer->buffers[cpu];
+
+       iter->cpu_buffer = cpu_buffer;
+
+       atomic_inc(&cpu_buffer->record_disabled);
+       synchronize_sched();
+
+       spin_lock_irqsave(&cpu_buffer->lock, flags);
+       ring_buffer_iter_reset(iter);
+       spin_unlock_irqrestore(&cpu_buffer->lock, flags);
+
+       return iter;
+}
+
+/**
+ * ring_buffer_finish - finish reading the iterator of the buffer
+ * @iter: The iterator retrieved by ring_buffer_start
+ *
+ * This re-enables the recording to the buffer, and frees the
+ * iterator.
+ */
+void
+ring_buffer_read_finish(struct ring_buffer_iter *iter)
+{
+       struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer;
+
+       atomic_dec(&cpu_buffer->record_disabled);
+       kfree(iter);
+}
+
+/**
+ * ring_buffer_read - read the next item in the ring buffer by the iterator
+ * @iter: The ring buffer iterator
+ * @ts: The time stamp of the event read.
+ *
+ * This reads the next event in the ring buffer and increments the iterator.
+ */
+struct ring_buffer_event *
+ring_buffer_read(struct ring_buffer_iter *iter, u64 *ts)
+{
+       struct ring_buffer_event *event;
+
+       event = ring_buffer_iter_peek(iter, ts);
+       if (!event)
+               return NULL;
+
+       rb_advance_iter(iter);
+
+       return event;
+}
+
+/**
+ * ring_buffer_size - return the size of the ring buffer (in bytes)
+ * @buffer: The ring buffer.
+ */
+unsigned long ring_buffer_size(struct ring_buffer *buffer)
+{
+       return BUF_PAGE_SIZE * buffer->pages;
+}
+
+static void
+rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
+{
+       cpu_buffer->head_page
+               = list_entry(cpu_buffer->pages.next, struct buffer_page, list);
+       local_set(&cpu_buffer->head_page->write, 0);
+       local_set(&cpu_buffer->head_page->commit, 0);
+
+       cpu_buffer->head_page->read = 0;
+
+       cpu_buffer->tail_page = cpu_buffer->head_page;
+       cpu_buffer->commit_page = cpu_buffer->head_page;
+
+       INIT_LIST_HEAD(&cpu_buffer->reader_page->list);
+       local_set(&cpu_buffer->reader_page->write, 0);
+       local_set(&cpu_buffer->reader_page->commit, 0);
+       cpu_buffer->reader_page->read = 0;
+
+       cpu_buffer->overrun = 0;
+       cpu_buffer->entries = 0;
+}
+
+/**
+ * ring_buffer_reset_cpu - reset a ring buffer per CPU buffer
+ * @buffer: The ring buffer to reset a per cpu buffer of
+ * @cpu: The CPU buffer to be reset
+ */
+void ring_buffer_reset_cpu(struct ring_buffer *buffer, int cpu)
+{
+       struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
+       unsigned long flags;
+
+       if (!cpu_isset(cpu, buffer->cpumask))
+               return;
+
+       spin_lock_irqsave(&cpu_buffer->lock, flags);
+
+       rb_reset_cpu(cpu_buffer);
+
+       spin_unlock_irqrestore(&cpu_buffer->lock, flags);
+}
+
+/**
+ * ring_buffer_reset - reset a ring buffer
+ * @buffer: The ring buffer to reset all cpu buffers
+ */
+void ring_buffer_reset(struct ring_buffer *buffer)
+{
+       int cpu;
+
+       for_each_buffer_cpu(buffer, cpu)
+               ring_buffer_reset_cpu(buffer, cpu);
+}
+
+/**
+ * rind_buffer_empty - is the ring buffer empty?
+ * @buffer: The ring buffer to test
+ */
+int ring_buffer_empty(struct ring_buffer *buffer)
+{
+       struct ring_buffer_per_cpu *cpu_buffer;
+       int cpu;
+
+       /* yes this is racy, but if you don't like the race, lock the buffer */
+       for_each_buffer_cpu(buffer, cpu) {
+               cpu_buffer = buffer->buffers[cpu];
+               if (!rb_per_cpu_empty(cpu_buffer))
+                       return 0;
+       }
+       return 1;
+}
+
+/**
+ * ring_buffer_empty_cpu - is a cpu buffer of a ring buffer empty?
+ * @buffer: The ring buffer
+ * @cpu: The CPU buffer to test
+ */
+int ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu)
+{
+       struct ring_buffer_per_cpu *cpu_buffer;
+
+       if (!cpu_isset(cpu, buffer->cpumask))
+               return 1;
+
+       cpu_buffer = buffer->buffers[cpu];
+       return rb_per_cpu_empty(cpu_buffer);
+}
+
+/**
+ * ring_buffer_swap_cpu - swap a CPU buffer between two ring buffers
+ * @buffer_a: One buffer to swap with
+ * @buffer_b: The other buffer to swap with
+ *
+ * This function is useful for tracers that want to take a "snapshot"
+ * of a CPU buffer and has another back up buffer lying around.
+ * it is expected that the tracer handles the cpu buffer not being
+ * used at the moment.
+ */
+int ring_buffer_swap_cpu(struct ring_buffer *buffer_a,
+                        struct ring_buffer *buffer_b, int cpu)
+{
+       struct ring_buffer_per_cpu *cpu_buffer_a;
+       struct ring_buffer_per_cpu *cpu_buffer_b;
+
+       if (!cpu_isset(cpu, buffer_a->cpumask) ||
+           !cpu_isset(cpu, buffer_b->cpumask))
+               return -EINVAL;
+
+       /* At least make sure the two buffers are somewhat the same */
+       if (buffer_a->size != buffer_b->size ||
+           buffer_a->pages != buffer_b->pages)
+               return -EINVAL;
+
+       cpu_buffer_a = buffer_a->buffers[cpu];
+       cpu_buffer_b = buffer_b->buffers[cpu];
+
+       /*
+        * We can't do a synchronize_sched here because this
+        * function can be called in atomic context.
+        * Normally this will be called from the same CPU as cpu.
+        * If not it's up to the caller to protect this.
+        */
+       atomic_inc(&cpu_buffer_a->record_disabled);
+       atomic_inc(&cpu_buffer_b->record_disabled);
+
+       buffer_a->buffers[cpu] = cpu_buffer_b;
+       buffer_b->buffers[cpu] = cpu_buffer_a;
+
+       cpu_buffer_b->buffer = buffer_a;
+       cpu_buffer_a->buffer = buffer_b;
+
+       atomic_dec(&cpu_buffer_a->record_disabled);
+       atomic_dec(&cpu_buffer_b->record_disabled);
+
+       return 0;
+}
+
index 8f3fb3db61c39306bdbffd36303cfed7dab02420..d345d649d073a39d6e572b88047e726754e8da1f 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/utsrelease.h>
 #include <linux/kallsyms.h>
 #include <linux/seq_file.h>
+#include <linux/notifier.h>
 #include <linux/debugfs.h>
 #include <linux/pagemap.h>
 #include <linux/hardirq.h>
@@ -22,6 +23,7 @@
 #include <linux/ftrace.h>
 #include <linux/module.h>
 #include <linux/percpu.h>
+#include <linux/kdebug.h>
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/poll.h>
 #include <linux/writeback.h>
 
 #include <linux/stacktrace.h>
+#include <linux/ring_buffer.h>
 
 #include "trace.h"
 
+#define TRACE_BUFFER_FLAGS     (RB_FL_OVERWRITE)
+
 unsigned long __read_mostly    tracing_max_latency = (cycle_t)ULONG_MAX;
 unsigned long __read_mostly    tracing_thresh;
 
-static unsigned long __read_mostly     tracing_nr_buffers;
+static DEFINE_PER_CPU(local_t, ftrace_cpu_disabled);
+
+static inline void ftrace_disable_cpu(void)
+{
+       preempt_disable();
+       local_inc(&__get_cpu_var(ftrace_cpu_disabled));
+}
+
+static inline void ftrace_enable_cpu(void)
+{
+       local_dec(&__get_cpu_var(ftrace_cpu_disabled));
+       preempt_enable();
+}
+
 static cpumask_t __read_mostly         tracing_buffer_mask;
 
 #define for_each_tracing_cpu(cpu)      \
        for_each_cpu_mask(cpu, tracing_buffer_mask)
 
-static int trace_alloc_page(void);
-static int trace_free_page(void);
-
 static int tracing_disabled = 1;
 
-static unsigned long tracing_pages_allocated;
-
 long
 ns2usecs(cycle_t nsec)
 {
@@ -60,7 +73,9 @@ ns2usecs(cycle_t nsec)
 
 cycle_t ftrace_now(int cpu)
 {
-       return cpu_clock(cpu);
+       u64 ts = ring_buffer_time_stamp(cpu);
+       ring_buffer_normalize_time_stamp(cpu, &ts);
+       return ts;
 }
 
 /*
@@ -100,11 +115,18 @@ static int                        tracer_enabled = 1;
 int                            ftrace_function_enabled;
 
 /*
- * trace_nr_entries is the number of entries that is allocated
- * for a buffer. Note, the number of entries is always rounded
- * to ENTRIES_PER_PAGE.
+ * trace_buf_size is the size in bytes that is allocated
+ * for a buffer. Note, the number of bytes is always rounded
+ * to page size.
+ *
+ * This number is purposely set to a low number of 16384.
+ * If the dump on oops happens, it will be much appreciated
+ * to not have to wait for all that output. Anyway this can be
+ * boot time and run time configurable.
  */
-static unsigned long           trace_nr_entries = 65536UL;
+#define TRACE_BUF_SIZE_DEFAULT 1441792UL /* 16384 * 88 (sizeof(entry)) */
+
+static unsigned long           trace_buf_size = TRACE_BUF_SIZE_DEFAULT;
 
 /* trace_types holds a link list of available tracers. */
 static struct tracer           *trace_types __read_mostly;
@@ -133,24 +155,6 @@ static DECLARE_WAIT_QUEUE_HEAD(trace_wait);
 /* trace_flags holds iter_ctrl options */
 unsigned long trace_flags = TRACE_ITER_PRINT_PARENT;
 
-static notrace void no_trace_init(struct trace_array *tr)
-{
-       int cpu;
-
-       ftrace_function_enabled = 0;
-       if(tr->ctrl)
-               for_each_online_cpu(cpu)
-                       tracing_reset(tr->data[cpu]);
-       tracer_enabled = 0;
-}
-
-/* dummy trace to disable tracing */
-static struct tracer no_tracer __read_mostly = {
-       .name           = "none",
-       .init           = no_trace_init
-};
-
-
 /**
  * trace_wake_up - wake up tasks waiting for trace input
  *
@@ -167,44 +171,27 @@ void trace_wake_up(void)
                wake_up(&trace_wait);
 }
 
-#define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(struct trace_entry))
-
-static int __init set_nr_entries(char *str)
+static int __init set_buf_size(char *str)
 {
-       unsigned long nr_entries;
+       unsigned long buf_size;
        int ret;
 
        if (!str)
                return 0;
-       ret = strict_strtoul(str, 0, &nr_entries);
+       ret = strict_strtoul(str, 0, &buf_size);
        /* nr_entries can not be zero */
-       if (ret < 0 || nr_entries == 0)
+       if (ret < 0 || buf_size == 0)
                return 0;
-       trace_nr_entries = nr_entries;
+       trace_buf_size = buf_size;
        return 1;
 }
-__setup("trace_entries=", set_nr_entries);
+__setup("trace_buf_size=", set_buf_size);
 
 unsigned long nsecs_to_usecs(unsigned long nsecs)
 {
        return nsecs / 1000;
 }
 
-/*
- * trace_flag_type is an enumeration that holds different
- * states when a trace occurs. These are:
- *  IRQS_OFF   - interrupts were disabled
- *  NEED_RESCED - reschedule is requested
- *  HARDIRQ    - inside an interrupt handler
- *  SOFTIRQ    - inside a softirq handler
- */
-enum trace_flag_type {
-       TRACE_FLAG_IRQS_OFF             = 0x01,
-       TRACE_FLAG_NEED_RESCHED         = 0x02,
-       TRACE_FLAG_HARDIRQ              = 0x04,
-       TRACE_FLAG_SOFTIRQ              = 0x08,
-};
-
 /*
  * TRACE_ITER_SYM_MASK masks the options in trace_flags that
  * control the output of kernel symbols.
@@ -224,6 +211,7 @@ static const char *trace_options[] = {
        "block",
        "stacktrace",
        "sched-tree",
+       "ftrace_printk",
        NULL
 };
 
@@ -266,54 +254,6 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
        tracing_record_cmdline(current);
 }
 
-#define CHECK_COND(cond)                       \
-       if (unlikely(cond)) {                   \
-               tracing_disabled = 1;           \
-               WARN_ON(1);                     \
-               return -1;                      \
-       }
-
-/**
- * check_pages - integrity check of trace buffers
- *
- * As a safty measure we check to make sure the data pages have not
- * been corrupted.
- */
-int check_pages(struct trace_array_cpu *data)
-{
-       struct page *page, *tmp;
-
-       CHECK_COND(data->trace_pages.next->prev != &data->trace_pages);
-       CHECK_COND(data->trace_pages.prev->next != &data->trace_pages);
-
-       list_for_each_entry_safe(page, tmp, &data->trace_pages, lru) {
-               CHECK_COND(page->lru.next->prev != &page->lru);
-               CHECK_COND(page->lru.prev->next != &page->lru);
-       }
-
-       return 0;
-}
-
-/**
- * head_page - page address of the first page in per_cpu buffer.
- *
- * head_page returns the page address of the first page in
- * a per_cpu buffer. This also preforms various consistency
- * checks to make sure the buffer has not been corrupted.
- */
-void *head_page(struct trace_array_cpu *data)
-{
-       struct page *page;
-
-       if (list_empty(&data->trace_pages))
-               return NULL;
-
-       page = list_entry(data->trace_pages.next, struct page, lru);
-       BUG_ON(&page->lru == &data->trace_pages);
-
-       return page_address(page);
-}
-
 /**
  * trace_seq_printf - sequence printing of trace information
  * @s: trace sequence descriptor
@@ -395,28 +335,23 @@ trace_seq_putmem(struct trace_seq *s, void *mem, size_t len)
        return len;
 }
 
-#define HEX_CHARS 17
-static const char hex2asc[] = "0123456789abcdef";
+#define MAX_MEMHEX_BYTES       8
+#define HEX_CHARS              (MAX_MEMHEX_BYTES*2 + 1)
 
 static int
 trace_seq_putmem_hex(struct trace_seq *s, void *mem, size_t len)
 {
        unsigned char hex[HEX_CHARS];
        unsigned char *data = mem;
-       unsigned char byte;
        int i, j;
 
-       BUG_ON(len >= HEX_CHARS);
-
 #ifdef __BIG_ENDIAN
        for (i = 0, j = 0; i < len; i++) {
 #else
        for (i = len-1, j = 0; i >= 0; i--) {
 #endif
-               byte = data[i];
-
-               hex[j++] = hex2asc[byte & 0x0f];
-               hex[j++] = hex2asc[byte >> 4];
+               hex[j++] = hex_asc_hi(data[i]);
+               hex[j++] = hex_asc_lo(data[i]);
        }
        hex[j++] = ' ';
 
@@ -460,34 +395,6 @@ trace_print_seq(struct seq_file *m, struct trace_seq *s)
        trace_seq_reset(s);
 }
 
-/*
- * flip the trace buffers between two trace descriptors.
- * This usually is the buffers between the global_trace and
- * the max_tr to record a snapshot of a current trace.
- *
- * The ftrace_max_lock must be held.
- */
-static void
-flip_trace(struct trace_array_cpu *tr1, struct trace_array_cpu *tr2)
-{
-       struct list_head flip_pages;
-
-       INIT_LIST_HEAD(&flip_pages);
-
-       memcpy(&tr1->trace_head_idx, &tr2->trace_head_idx,
-               sizeof(struct trace_array_cpu) -
-               offsetof(struct trace_array_cpu, trace_head_idx));
-
-       check_pages(tr1);
-       check_pages(tr2);
-       list_splice_init(&tr1->trace_pages, &flip_pages);
-       list_splice_init(&tr2->trace_pages, &tr1->trace_pages);
-       list_splice_init(&flip_pages, &tr2->trace_pages);
-       BUG_ON(!list_empty(&flip_pages));
-       check_pages(tr1);
-       check_pages(tr2);
-}
-
 /**
  * update_max_tr - snapshot all trace buffers from global_trace to max_tr
  * @tr: tracer
@@ -500,17 +407,17 @@ flip_trace(struct trace_array_cpu *tr1, struct trace_array_cpu *tr2)
 void
 update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
 {
-       struct trace_array_cpu *data;
-       int i;
+       struct ring_buffer *buf = tr->buffer;
 
        WARN_ON_ONCE(!irqs_disabled());
        __raw_spin_lock(&ftrace_max_lock);
-       /* clear out all the previous traces */
-       for_each_tracing_cpu(i) {
-               data = tr->data[i];
-               flip_trace(max_tr.data[i], data);
-               tracing_reset(data);
-       }
+
+       tr->buffer = max_tr.buffer;
+       max_tr.buffer = buf;
+
+       ftrace_disable_cpu();
+       ring_buffer_reset(tr->buffer);
+       ftrace_enable_cpu();
 
        __update_max_tr(tr, tsk, cpu);
        __raw_spin_unlock(&ftrace_max_lock);
@@ -527,16 +434,19 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
 void
 update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu)
 {
-       struct trace_array_cpu *data = tr->data[cpu];
-       int i;
+       int ret;
 
        WARN_ON_ONCE(!irqs_disabled());
        __raw_spin_lock(&ftrace_max_lock);
-       for_each_tracing_cpu(i)
-               tracing_reset(max_tr.data[i]);
 
-       flip_trace(max_tr.data[cpu], data);
-       tracing_reset(data);
+       ftrace_disable_cpu();
+
+       ring_buffer_reset(max_tr.buffer);
+       ret = ring_buffer_swap_cpu(max_tr.buffer, tr->buffer, cpu);
+
+       ftrace_enable_cpu();
+
+       WARN_ON_ONCE(ret);
 
        __update_max_tr(tr, tsk, cpu);
        __raw_spin_unlock(&ftrace_max_lock);
@@ -573,7 +483,6 @@ int register_tracer(struct tracer *type)
 #ifdef CONFIG_FTRACE_STARTUP_TEST
        if (type->selftest) {
                struct tracer *saved_tracer = current_trace;
-               struct trace_array_cpu *data;
                struct trace_array *tr = &global_trace;
                int saved_ctrl = tr->ctrl;
                int i;
@@ -585,10 +494,7 @@ int register_tracer(struct tracer *type)
                 * If we fail, we do not register this tracer.
                 */
                for_each_tracing_cpu(i) {
-                       data = tr->data[i];
-                       if (!head_page(data))
-                               continue;
-                       tracing_reset(data);
+                       tracing_reset(tr, i);
                }
                current_trace = type;
                tr->ctrl = 0;
@@ -604,10 +510,7 @@ int register_tracer(struct tracer *type)
                }
                /* Only reset on passing, to avoid touching corrupted buffers */
                for_each_tracing_cpu(i) {
-                       data = tr->data[i];
-                       if (!head_page(data))
-                               continue;
-                       tracing_reset(data);
+                       tracing_reset(tr, i);
                }
                printk(KERN_CONT "PASSED\n");
        }
@@ -653,13 +556,11 @@ void unregister_tracer(struct tracer *type)
        mutex_unlock(&trace_types_lock);
 }
 
-void tracing_reset(struct trace_array_cpu *data)
+void tracing_reset(struct trace_array *tr, int cpu)
 {
-       data->trace_idx = 0;
-       data->overrun = 0;
-       data->trace_head = data->trace_tail = head_page(data);
-       data->trace_head_idx = 0;
-       data->trace_tail_idx = 0;
+       ftrace_disable_cpu();
+       ring_buffer_reset_cpu(tr->buffer, cpu);
+       ftrace_enable_cpu();
 }
 
 #define SAVED_CMDLINES 128
@@ -745,82 +646,16 @@ void tracing_record_cmdline(struct task_struct *tsk)
        trace_save_cmdline(tsk);
 }
 
-static inline struct list_head *
-trace_next_list(struct trace_array_cpu *data, struct list_head *next)
-{
-       /*
-        * Roundrobin - but skip the head (which is not a real page):
-        */
-       next = next->next;
-       if (unlikely(next == &data->trace_pages))
-               next = next->next;
-       BUG_ON(next == &data->trace_pages);
-
-       return next;
-}
-
-static inline void *
-trace_next_page(struct trace_array_cpu *data, void *addr)
-{
-       struct list_head *next;
-       struct page *page;
-
-       page = virt_to_page(addr);
-
-       next = trace_next_list(data, &page->lru);
-       page = list_entry(next, struct page, lru);
-
-       return page_address(page);
-}
-
-static inline struct trace_entry *
-tracing_get_trace_entry(struct trace_array *tr, struct trace_array_cpu *data)
-{
-       unsigned long idx, idx_next;
-       struct trace_entry *entry;
-
-       data->trace_idx++;
-       idx = data->trace_head_idx;
-       idx_next = idx + 1;
-
-       BUG_ON(idx * TRACE_ENTRY_SIZE >= PAGE_SIZE);
-
-       entry = data->trace_head + idx * TRACE_ENTRY_SIZE;
-
-       if (unlikely(idx_next >= ENTRIES_PER_PAGE)) {
-               data->trace_head = trace_next_page(data, data->trace_head);
-               idx_next = 0;
-       }
-
-       if (data->trace_head == data->trace_tail &&
-           idx_next == data->trace_tail_idx) {
-               /* overrun */
-               data->overrun++;
-               data->trace_tail_idx++;
-               if (data->trace_tail_idx >= ENTRIES_PER_PAGE) {
-                       data->trace_tail =
-                               trace_next_page(data, data->trace_tail);
-                       data->trace_tail_idx = 0;
-               }
-       }
-
-       data->trace_head_idx = idx_next;
-
-       return entry;
-}
-
-static inline void
-tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags)
+void
+tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags,
+                            int pc)
 {
        struct task_struct *tsk = current;
-       unsigned long pc;
-
-       pc = preempt_count();
 
-       entry->preempt_count    = pc & 0xff;
-       entry->pid              = (tsk) ? tsk->pid : 0;
-       entry->t                = ftrace_now(raw_smp_processor_id());
-       entry->flags = (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) |
+       entry->preempt_count            = pc & 0xff;
+       entry->pid                      = (tsk) ? tsk->pid : 0;
+       entry->flags =
+               (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) |
                ((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) |
                ((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) |
                (need_resched() ? TRACE_FLAG_NEED_RESCHED : 0);
@@ -828,145 +663,139 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags)
 
 void
 trace_function(struct trace_array *tr, struct trace_array_cpu *data,
-              unsigned long ip, unsigned long parent_ip, unsigned long flags)
+              unsigned long ip, unsigned long parent_ip, unsigned long flags,
+              int pc)
 {
-       struct trace_entry *entry;
+       struct ring_buffer_event *event;
+       struct ftrace_entry *entry;
        unsigned long irq_flags;
 
-       raw_local_irq_save(irq_flags);
-       __raw_spin_lock(&data->lock);
-       entry                   = tracing_get_trace_entry(tr, data);
-       tracing_generic_entry_update(entry, flags);
-       entry->type             = TRACE_FN;
-       entry->fn.ip            = ip;
-       entry->fn.parent_ip     = parent_ip;
-       __raw_spin_unlock(&data->lock);
-       raw_local_irq_restore(irq_flags);
+       /* If we are reading the ring buffer, don't trace */
+       if (unlikely(local_read(&__get_cpu_var(ftrace_cpu_disabled))))
+               return;
+
+       event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
+                                        &irq_flags);
+       if (!event)
+               return;
+       entry   = ring_buffer_event_data(event);
+       tracing_generic_entry_update(&entry->ent, flags, pc);
+       entry->ent.type                 = TRACE_FN;
+       entry->ip                       = ip;
+       entry->parent_ip                = parent_ip;
+       ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
 }
 
 void
 ftrace(struct trace_array *tr, struct trace_array_cpu *data,
-       unsigned long ip, unsigned long parent_ip, unsigned long flags)
+       unsigned long ip, unsigned long parent_ip, unsigned long flags,
+       int pc)
 {
        if (likely(!atomic_read(&data->disabled)))
-               trace_function(tr, data, ip, parent_ip, flags);
+               trace_function(tr, data, ip, parent_ip, flags, pc);
 }
 
-#ifdef CONFIG_MMIOTRACE
-void __trace_mmiotrace_rw(struct trace_array *tr, struct trace_array_cpu *data,
-                                               struct mmiotrace_rw *rw)
+static void ftrace_trace_stack(struct trace_array *tr,
+                              struct trace_array_cpu *data,
+                              unsigned long flags,
+                              int skip, int pc)
 {
-       struct trace_entry *entry;
+       struct ring_buffer_event *event;
+       struct stack_entry *entry;
+       struct stack_trace trace;
        unsigned long irq_flags;
 
-       raw_local_irq_save(irq_flags);
-       __raw_spin_lock(&data->lock);
-
-       entry                   = tracing_get_trace_entry(tr, data);
-       tracing_generic_entry_update(entry, 0);
-       entry->type             = TRACE_MMIO_RW;
-       entry->mmiorw           = *rw;
-
-       __raw_spin_unlock(&data->lock);
-       raw_local_irq_restore(irq_flags);
-
-       trace_wake_up();
-}
-
-void __trace_mmiotrace_map(struct trace_array *tr, struct trace_array_cpu *data,
-                                               struct mmiotrace_map *map)
-{
-       struct trace_entry *entry;
-       unsigned long irq_flags;
+       if (!(trace_flags & TRACE_ITER_STACKTRACE))
+               return;
 
-       raw_local_irq_save(irq_flags);
-       __raw_spin_lock(&data->lock);
+       event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
+                                        &irq_flags);
+       if (!event)
+               return;
+       entry   = ring_buffer_event_data(event);
+       tracing_generic_entry_update(&entry->ent, flags, pc);
+       entry->ent.type         = TRACE_STACK;
 
-       entry                   = tracing_get_trace_entry(tr, data);
-       tracing_generic_entry_update(entry, 0);
-       entry->type             = TRACE_MMIO_MAP;
-       entry->mmiomap          = *map;
+       memset(&entry->caller, 0, sizeof(entry->caller));
 
-       __raw_spin_unlock(&data->lock);
-       raw_local_irq_restore(irq_flags);
+       trace.nr_entries        = 0;
+       trace.max_entries       = FTRACE_STACK_ENTRIES;
+       trace.skip              = skip;
+       trace.entries           = entry->caller;
 
-       trace_wake_up();
+       save_stack_trace(&trace);
+       ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
 }
-#endif
 
 void __trace_stack(struct trace_array *tr,
                   struct trace_array_cpu *data,
                   unsigned long flags,
                   int skip)
 {
-       struct trace_entry *entry;
-       struct stack_trace trace;
-
-       if (!(trace_flags & TRACE_ITER_STACKTRACE))
-               return;
-
-       entry                   = tracing_get_trace_entry(tr, data);
-       tracing_generic_entry_update(entry, flags);
-       entry->type             = TRACE_STACK;
-
-       memset(&entry->stack, 0, sizeof(entry->stack));
-
-       trace.nr_entries        = 0;
-       trace.max_entries       = FTRACE_STACK_ENTRIES;
-       trace.skip              = skip;
-       trace.entries           = entry->stack.caller;
-
-       save_stack_trace(&trace);
+       ftrace_trace_stack(tr, data, flags, skip, preempt_count());
 }
 
-void
-__trace_special(void *__tr, void *__data,
-               unsigned long arg1, unsigned long arg2, unsigned long arg3)
+static void
+ftrace_trace_special(void *__tr, void *__data,
+                    unsigned long arg1, unsigned long arg2, unsigned long arg3,
+                    int pc)
 {
+       struct ring_buffer_event *event;
        struct trace_array_cpu *data = __data;
        struct trace_array *tr = __tr;
-       struct trace_entry *entry;
+       struct special_entry *entry;
        unsigned long irq_flags;
 
-       raw_local_irq_save(irq_flags);
-       __raw_spin_lock(&data->lock);
-       entry                   = tracing_get_trace_entry(tr, data);
-       tracing_generic_entry_update(entry, 0);
-       entry->type             = TRACE_SPECIAL;
-       entry->special.arg1     = arg1;
-       entry->special.arg2     = arg2;
-       entry->special.arg3     = arg3;
-       __trace_stack(tr, data, irq_flags, 4);
-       __raw_spin_unlock(&data->lock);
-       raw_local_irq_restore(irq_flags);
+       event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
+                                        &irq_flags);
+       if (!event)
+               return;
+       entry   = ring_buffer_event_data(event);
+       tracing_generic_entry_update(&entry->ent, 0, pc);
+       entry->ent.type                 = TRACE_SPECIAL;
+       entry->arg1                     = arg1;
+       entry->arg2                     = arg2;
+       entry->arg3                     = arg3;
+       ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+       ftrace_trace_stack(tr, data, irq_flags, 4, pc);
 
        trace_wake_up();
 }
 
+void
+__trace_special(void *__tr, void *__data,
+               unsigned long arg1, unsigned long arg2, unsigned long arg3)
+{
+       ftrace_trace_special(__tr, __data, arg1, arg2, arg3, preempt_count());
+}
+
 void
 tracing_sched_switch_trace(struct trace_array *tr,
                           struct trace_array_cpu *data,
                           struct task_struct *prev,
                           struct task_struct *next,
-                          unsigned long flags)
+                          unsigned long flags, int pc)
 {
-       struct trace_entry *entry;
+       struct ring_buffer_event *event;
+       struct ctx_switch_entry *entry;
        unsigned long irq_flags;
 
-       raw_local_irq_save(irq_flags);
-       __raw_spin_lock(&data->lock);
-       entry                   = tracing_get_trace_entry(tr, data);
-       tracing_generic_entry_update(entry, flags);
-       entry->type             = TRACE_CTX;
-       entry->ctx.prev_pid     = prev->pid;
-       entry->ctx.prev_prio    = prev->prio;
-       entry->ctx.prev_state   = prev->state;
-       entry->ctx.next_pid     = next->pid;
-       entry->ctx.next_prio    = next->prio;
-       entry->ctx.next_state   = next->state;
-       __trace_stack(tr, data, flags, 5);
-       __raw_spin_unlock(&data->lock);
-       raw_local_irq_restore(irq_flags);
+       event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
+                                          &irq_flags);
+       if (!event)
+               return;
+       entry   = ring_buffer_event_data(event);
+       tracing_generic_entry_update(&entry->ent, flags, pc);
+       entry->ent.type                 = TRACE_CTX;
+       entry->prev_pid                 = prev->pid;
+       entry->prev_prio                = prev->prio;
+       entry->prev_state               = prev->state;
+       entry->next_pid                 = next->pid;
+       entry->next_prio                = next->prio;
+       entry->next_state               = next->state;
+       entry->next_cpu = task_cpu(next);
+       ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+       ftrace_trace_stack(tr, data, flags, 5, pc);
 }
 
 void
@@ -974,25 +803,28 @@ tracing_sched_wakeup_trace(struct trace_array *tr,
                           struct trace_array_cpu *data,
                           struct task_struct *wakee,
                           struct task_struct *curr,
-                          unsigned long flags)
+                          unsigned long flags, int pc)
 {
-       struct trace_entry *entry;
+       struct ring_buffer_event *event;
+       struct ctx_switch_entry *entry;
        unsigned long irq_flags;
 
-       raw_local_irq_save(irq_flags);
-       __raw_spin_lock(&data->lock);
-       entry                   = tracing_get_trace_entry(tr, data);
-       tracing_generic_entry_update(entry, flags);
-       entry->type             = TRACE_WAKE;
-       entry->ctx.prev_pid     = curr->pid;
-       entry->ctx.prev_prio    = curr->prio;
-       entry->ctx.prev_state   = curr->state;
-       entry->ctx.next_pid     = wakee->pid;
-       entry->ctx.next_prio    = wakee->prio;
-       entry->ctx.next_state   = wakee->state;
-       __trace_stack(tr, data, flags, 6);
-       __raw_spin_unlock(&data->lock);
-       raw_local_irq_restore(irq_flags);
+       event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
+                                          &irq_flags);
+       if (!event)
+               return;
+       entry   = ring_buffer_event_data(event);
+       tracing_generic_entry_update(&entry->ent, flags, pc);
+       entry->ent.type                 = TRACE_WAKE;
+       entry->prev_pid                 = curr->pid;
+       entry->prev_prio                = curr->prio;
+       entry->prev_state               = curr->state;
+       entry->next_pid                 = wakee->pid;
+       entry->next_prio                = wakee->prio;
+       entry->next_state               = wakee->state;
+       entry->next_cpu                 = task_cpu(wakee);
+       ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+       ftrace_trace_stack(tr, data, flags, 6, pc);
 
        trace_wake_up();
 }
@@ -1002,23 +834,21 @@ ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3)
 {
        struct trace_array *tr = &global_trace;
        struct trace_array_cpu *data;
-       unsigned long flags;
-       long disabled;
        int cpu;
+       int pc;
 
-       if (tracing_disabled || current_trace == &no_tracer || !tr->ctrl)
+       if (tracing_disabled || !tr->ctrl)
                return;
 
-       local_irq_save(flags);
+       pc = preempt_count();
+       preempt_disable_notrace();
        cpu = raw_smp_processor_id();
        data = tr->data[cpu];
-       disabled = atomic_inc_return(&data->disabled);
 
-       if (likely(disabled == 1))
-               __trace_special(tr, data, arg1, arg2, arg3);
+       if (likely(!atomic_read(&data->disabled)))
+               ftrace_trace_special(tr, data, arg1, arg2, arg3, pc);
 
-       atomic_dec(&data->disabled);
-       local_irq_restore(flags);
+       preempt_enable_notrace();
 }
 
 #ifdef CONFIG_FTRACE
@@ -1029,7 +859,8 @@ function_trace_call(unsigned long ip, unsigned long parent_ip)
        struct trace_array_cpu *data;
        unsigned long flags;
        long disabled;
-       int cpu;
+       int cpu, resched;
+       int pc;
 
        if (unlikely(!ftrace_function_enabled))
                return;
@@ -1037,16 +868,22 @@ function_trace_call(unsigned long ip, unsigned long parent_ip)
        if (skip_trace(ip))
                return;
 
-       local_irq_save(flags);
+       pc = preempt_count();
+       resched = need_resched();
+       preempt_disable_notrace();
+       local_save_flags(flags);
        cpu = raw_smp_processor_id();
        data = tr->data[cpu];
        disabled = atomic_inc_return(&data->disabled);
 
        if (likely(disabled == 1))
-               trace_function(tr, data, ip, parent_ip, flags);
+               trace_function(tr, data, ip, parent_ip, flags, pc);
 
        atomic_dec(&data->disabled);
-       local_irq_restore(flags);
+       if (resched)
+               preempt_enable_no_resched_notrace();
+       else
+               preempt_enable_notrace();
 }
 
 static struct ftrace_ops trace_ops __read_mostly =
@@ -1073,111 +910,96 @@ enum trace_file_type {
        TRACE_FILE_LAT_FMT      = 1,
 };
 
-static struct trace_entry *
-trace_entry_idx(struct trace_array *tr, struct trace_array_cpu *data,
-               struct trace_iterator *iter, int cpu)
+static void trace_iterator_increment(struct trace_iterator *iter, int cpu)
 {
-       struct page *page;
-       struct trace_entry *array;
+       /* Don't allow ftrace to trace into the ring buffers */
+       ftrace_disable_cpu();
 
-       if (iter->next_idx[cpu] >= tr->entries ||
-           iter->next_idx[cpu] >= data->trace_idx ||
-           (data->trace_head == data->trace_tail &&
-            data->trace_head_idx == data->trace_tail_idx))
-               return NULL;
+       iter->idx++;
+       if (iter->buffer_iter[iter->cpu])
+               ring_buffer_read(iter->buffer_iter[iter->cpu], NULL);
 
-       if (!iter->next_page[cpu]) {
-               /* Initialize the iterator for this cpu trace buffer */
-               WARN_ON(!data->trace_tail);
-               page = virt_to_page(data->trace_tail);
-               iter->next_page[cpu] = &page->lru;
-               iter->next_page_idx[cpu] = data->trace_tail_idx;
-       }
+       ftrace_enable_cpu();
+}
+
+static struct trace_entry *
+peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts)
+{
+       struct ring_buffer_event *event;
+       struct ring_buffer_iter *buf_iter = iter->buffer_iter[cpu];
 
-       page = list_entry(iter->next_page[cpu], struct page, lru);
-       BUG_ON(&data->trace_pages == &page->lru);
+       /* Don't allow ftrace to trace into the ring buffers */
+       ftrace_disable_cpu();
+
+       if (buf_iter)
+               event = ring_buffer_iter_peek(buf_iter, ts);
+       else
+               event = ring_buffer_peek(iter->tr->buffer, cpu, ts);
 
-       array = page_address(page);
+       ftrace_enable_cpu();
 
-       WARN_ON(iter->next_page_idx[cpu] >= ENTRIES_PER_PAGE);
-       return &array[iter->next_page_idx[cpu]];
+       return event ? ring_buffer_event_data(event) : NULL;
 }
 
 static struct trace_entry *
-find_next_entry(struct trace_iterator *iter, int *ent_cpu)
+__find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
 {
-       struct trace_array *tr = iter->tr;
+       struct ring_buffer *buffer = iter->tr->buffer;
        struct trace_entry *ent, *next = NULL;
+       u64 next_ts = 0, ts;
        int next_cpu = -1;
        int cpu;
 
        for_each_tracing_cpu(cpu) {
-               if (!head_page(tr->data[cpu]))
+
+               if (ring_buffer_empty_cpu(buffer, cpu))
                        continue;
-               ent = trace_entry_idx(tr, tr->data[cpu], iter, cpu);
+
+               ent = peek_next_entry(iter, cpu, &ts);
+
                /*
                 * Pick the entry with the smallest timestamp:
                 */
-               if (ent && (!next || ent->t < next->t)) {
+               if (ent && (!next || ts < next_ts)) {
                        next = ent;
                        next_cpu = cpu;
+                       next_ts = ts;
                }
        }
 
        if (ent_cpu)
                *ent_cpu = next_cpu;
 
+       if (ent_ts)
+               *ent_ts = next_ts;
+
        return next;
 }
 
-static void trace_iterator_increment(struct trace_iterator *iter)
+/* Find the next real entry, without updating the iterator itself */
+static struct trace_entry *
+find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
 {
-       iter->idx++;
-       iter->next_idx[iter->cpu]++;
-       iter->next_page_idx[iter->cpu]++;
-
-       if (iter->next_page_idx[iter->cpu] >= ENTRIES_PER_PAGE) {
-               struct trace_array_cpu *data = iter->tr->data[iter->cpu];
-
-               iter->next_page_idx[iter->cpu] = 0;
-               iter->next_page[iter->cpu] =
-                       trace_next_list(data, iter->next_page[iter->cpu]);
-       }
+       return __find_next_entry(iter, ent_cpu, ent_ts);
 }
 
-static void trace_consume(struct trace_iterator *iter)
+/* Find the next real entry, and increment the iterator to the next entry */
+static void *find_next_entry_inc(struct trace_iterator *iter)
 {
-       struct trace_array_cpu *data = iter->tr->data[iter->cpu];
+       iter->ent = __find_next_entry(iter, &iter->cpu, &iter->ts);
 
-       data->trace_tail_idx++;
-       if (data->trace_tail_idx >= ENTRIES_PER_PAGE) {
-               data->trace_tail = trace_next_page(data, data->trace_tail);
-               data->trace_tail_idx = 0;
-       }
+       if (iter->ent)
+               trace_iterator_increment(iter, iter->cpu);
 
-       /* Check if we empty it, then reset the index */
-       if (data->trace_head == data->trace_tail &&
-           data->trace_head_idx == data->trace_tail_idx)
-               data->trace_idx = 0;
+       return iter->ent ? iter : NULL;
 }
 
-static void *find_next_entry_inc(struct trace_iterator *iter)
+static void trace_consume(struct trace_iterator *iter)
 {
-       struct trace_entry *next;
-       int next_cpu = -1;
-
-       next = find_next_entry(iter, &next_cpu);
-
-       iter->prev_ent = iter->ent;
-       iter->prev_cpu = iter->cpu;
-
-       iter->ent = next;
-       iter->cpu = next_cpu;
-
-       if (next)
-               trace_iterator_increment(iter);
-
-       return next ? iter : NULL;
+       /* Don't allow ftrace to trace into the ring buffers */
+       ftrace_disable_cpu();
+       ring_buffer_consume(iter->tr->buffer, iter->cpu, &iter->ts);
+       ftrace_enable_cpu();
 }
 
 static void *s_next(struct seq_file *m, void *v, loff_t *pos)
@@ -1210,7 +1032,7 @@ static void *s_start(struct seq_file *m, loff_t *pos)
        struct trace_iterator *iter = m->private;
        void *p = NULL;
        loff_t l = 0;
-       int i;
+       int cpu;
 
        mutex_lock(&trace_types_lock);
 
@@ -1229,14 +1051,15 @@ static void *s_start(struct seq_file *m, loff_t *pos)
                iter->ent = NULL;
                iter->cpu = 0;
                iter->idx = -1;
-               iter->prev_ent = NULL;
-               iter->prev_cpu = -1;
 
-               for_each_tracing_cpu(i) {
-                       iter->next_idx[i] = 0;
-                       iter->next_page[i] = NULL;
+               ftrace_disable_cpu();
+
+               for_each_tracing_cpu(cpu) {
+                       ring_buffer_iter_reset(iter->buffer_iter[cpu]);
                }
 
+               ftrace_enable_cpu();
+
                for (p = iter; p && l < *pos; p = s_next(m, p, &l))
                        ;
 
@@ -1330,21 +1153,21 @@ seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
 
 static void print_lat_help_header(struct seq_file *m)
 {
-       seq_puts(m, "#                _------=> CPU#            \n");
-       seq_puts(m, "#               / _-----=> irqs-off        \n");
-       seq_puts(m, "#              | / _----=> need-resched    \n");
-       seq_puts(m, "#              || / _---=> hardirq/softirq \n");
-       seq_puts(m, "#              ||| / _--=> preempt-depth   \n");
-       seq_puts(m, "#              |||| /                      \n");
-       seq_puts(m, "#              |||||     delay             \n");
-       seq_puts(m, "#  cmd     pid ||||| time  |   caller      \n");
-       seq_puts(m, "#     \\   /    |||||   \\   |   /           \n");
+       seq_puts(m, "#                  _------=> CPU#            \n");
+       seq_puts(m, "#                 / _-----=> irqs-off        \n");
+       seq_puts(m, "#                | / _----=> need-resched    \n");
+       seq_puts(m, "#                || / _---=> hardirq/softirq \n");
+       seq_puts(m, "#                ||| / _--=> preempt-depth   \n");
+       seq_puts(m, "#                |||| /                      \n");
+       seq_puts(m, "#                |||||     delay             \n");
+       seq_puts(m, "#  cmd     pid   ||||| time  |   caller      \n");
+       seq_puts(m, "#     \\   /      |||||   \\   |   /           \n");
 }
 
 static void print_func_help_header(struct seq_file *m)
 {
-       seq_puts(m, "#           TASK-PID   CPU#    TIMESTAMP  FUNCTION\n");
-       seq_puts(m, "#              | |      |          |         |\n");
+       seq_puts(m, "#           TASK-PID    CPU#    TIMESTAMP  FUNCTION\n");
+       seq_puts(m, "#              | |       |          |         |\n");
 }
 
 
@@ -1355,23 +1178,16 @@ print_trace_header(struct seq_file *m, struct trace_iterator *iter)
        struct trace_array *tr = iter->tr;
        struct trace_array_cpu *data = tr->data[tr->cpu];
        struct tracer *type = current_trace;
-       unsigned long total   = 0;
-       unsigned long entries = 0;
-       int cpu;
+       unsigned long total;
+       unsigned long entries;
        const char *name = "preemption";
 
        if (type)
                name = type->name;
 
-       for_each_tracing_cpu(cpu) {
-               if (head_page(tr->data[cpu])) {
-                       total += tr->data[cpu]->trace_idx;
-                       if (tr->data[cpu]->trace_idx > tr->entries)
-                               entries += tr->entries;
-                       else
-                               entries += tr->data[cpu]->trace_idx;
-               }
-       }
+       entries = ring_buffer_entries(iter->tr->buffer);
+       total = entries +
+               ring_buffer_overruns(iter->tr->buffer);
 
        seq_printf(m, "%s latency trace v1.1.5 on %s\n",
                   name, UTS_RELEASE);
@@ -1428,7 +1244,7 @@ lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
        comm = trace_find_cmdline(entry->pid);
 
        trace_seq_printf(s, "%8.8s-%-5d ", comm, entry->pid);
-       trace_seq_printf(s, "%d", cpu);
+       trace_seq_printf(s, "%3d", cpu);
        trace_seq_printf(s, "%c%c",
                        (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' : '.',
                        ((entry->flags & TRACE_FLAG_NEED_RESCHED) ? 'N' : '.'));
@@ -1457,7 +1273,7 @@ lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
 unsigned long preempt_mark_thresh = 100;
 
 static void
-lat_print_timestamp(struct trace_seq *s, unsigned long long abs_usecs,
+lat_print_timestamp(struct trace_seq *s, u64 abs_usecs,
                    unsigned long rel_usecs)
 {
        trace_seq_printf(s, " %4lldus", abs_usecs);
@@ -1471,34 +1287,76 @@ lat_print_timestamp(struct trace_seq *s, unsigned long long abs_usecs,
 
 static const char state_to_char[] = TASK_STATE_TO_CHAR_STR;
 
-static int
+/*
+ * The message is supposed to contain an ending newline.
+ * If the printing stops prematurely, try to add a newline of our own.
+ */
+void trace_seq_print_cont(struct trace_seq *s, struct trace_iterator *iter)
+{
+       struct trace_entry *ent;
+       struct trace_field_cont *cont;
+       bool ok = true;
+
+       ent = peek_next_entry(iter, iter->cpu, NULL);
+       if (!ent || ent->type != TRACE_CONT) {
+               trace_seq_putc(s, '\n');
+               return;
+       }
+
+       do {
+               cont = (struct trace_field_cont *)ent;
+               if (ok)
+                       ok = (trace_seq_printf(s, "%s", cont->buf) > 0);
+
+               ftrace_disable_cpu();
+
+               if (iter->buffer_iter[iter->cpu])
+                       ring_buffer_read(iter->buffer_iter[iter->cpu], NULL);
+               else
+                       ring_buffer_consume(iter->tr->buffer, iter->cpu, NULL);
+
+               ftrace_enable_cpu();
+
+               ent = peek_next_entry(iter, iter->cpu, NULL);
+       } while (ent && ent->type == TRACE_CONT);
+
+       if (!ok)
+               trace_seq_putc(s, '\n');
+}
+
+static enum print_line_t
 print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu)
 {
        struct trace_seq *s = &iter->seq;
        unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
-       struct trace_entry *next_entry = find_next_entry(iter, NULL);
+       struct trace_entry *next_entry;
        unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE);
        struct trace_entry *entry = iter->ent;
        unsigned long abs_usecs;
        unsigned long rel_usecs;
+       u64 next_ts;
        char *comm;
        int S, T;
        int i;
        unsigned state;
 
+       if (entry->type == TRACE_CONT)
+               return TRACE_TYPE_HANDLED;
+
+       next_entry = find_next_entry(iter, NULL, &next_ts);
        if (!next_entry)
-               next_entry = entry;
-       rel_usecs = ns2usecs(next_entry->t - entry->t);
-       abs_usecs = ns2usecs(entry->t - iter->tr->time_start);
+               next_ts = iter->ts;
+       rel_usecs = ns2usecs(next_ts - iter->ts);
+       abs_usecs = ns2usecs(iter->ts - iter->tr->time_start);
 
        if (verbose) {
                comm = trace_find_cmdline(entry->pid);
-               trace_seq_printf(s, "%16s %5d %d %d %08x %08x [%08lx]"
+               trace_seq_printf(s, "%16s %5d %3d %d %08x %08x [%08lx]"
                                 " %ld.%03ldms (+%ld.%03ldms): ",
                                 comm,
                                 entry->pid, cpu, entry->flags,
                                 entry->preempt_count, trace_idx,
-                                ns2usecs(entry->t),
+                                ns2usecs(iter->ts),
                                 abs_usecs/1000,
                                 abs_usecs % 1000, rel_usecs/1000,
                                 rel_usecs % 1000);
@@ -1507,52 +1365,85 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu)
                lat_print_timestamp(s, abs_usecs, rel_usecs);
        }
        switch (entry->type) {
-       case TRACE_FN:
-               seq_print_ip_sym(s, entry->fn.ip, sym_flags);
+       case TRACE_FN: {
+               struct ftrace_entry *field;
+
+               trace_assign_type(field, entry);
+
+               seq_print_ip_sym(s, field->ip, sym_flags);
                trace_seq_puts(s, " (");
-               if (kretprobed(entry->fn.parent_ip))
+               if (kretprobed(field->parent_ip))
                        trace_seq_puts(s, KRETPROBE_MSG);
                else
-                       seq_print_ip_sym(s, entry->fn.parent_ip, sym_flags);
+                       seq_print_ip_sym(s, field->parent_ip, sym_flags);
                trace_seq_puts(s, ")\n");
                break;
+       }
        case TRACE_CTX:
-       case TRACE_WAKE:
-               T = entry->ctx.next_state < sizeof(state_to_char) ?
-                       state_to_char[entry->ctx.next_state] : 'X';
+       case TRACE_WAKE: {
+               struct ctx_switch_entry *field;
+
+               trace_assign_type(field, entry);
 
-               state = entry->ctx.prev_state ? __ffs(entry->ctx.prev_state) + 1 : 0;
+               T = field->next_state < sizeof(state_to_char) ?
+                       state_to_char[field->next_state] : 'X';
+
+               state = field->prev_state ?
+                       __ffs(field->prev_state) + 1 : 0;
                S = state < sizeof(state_to_char) - 1 ? state_to_char[state] : 'X';
-               comm = trace_find_cmdline(entry->ctx.next_pid);
-               trace_seq_printf(s, " %5d:%3d:%c %s %5d:%3d:%c %s\n",
-                                entry->ctx.prev_pid,
-                                entry->ctx.prev_prio,
+               comm = trace_find_cmdline(field->next_pid);
+               trace_seq_printf(s, " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n",
+                                field->prev_pid,
+                                field->prev_prio,
                                 S, entry->type == TRACE_CTX ? "==>" : "  +",
-                                entry->ctx.next_pid,
-                                entry->ctx.next_prio,
+                                field->next_cpu,
+                                field->next_pid,
+                                field->next_prio,
                                 T, comm);
                break;
-       case TRACE_SPECIAL:
+       }
+       case TRACE_SPECIAL: {
+               struct special_entry *field;
+
+               trace_assign_type(field, entry);
+
                trace_seq_printf(s, "# %ld %ld %ld\n",
-                                entry->special.arg1,
-                                entry->special.arg2,
-                                entry->special.arg3);
+                                field->arg1,
+                                field->arg2,
+                                field->arg3);
                break;
-       case TRACE_STACK:
+       }
+       case TRACE_STACK: {
+               struct stack_entry *field;
+
+               trace_assign_type(field, entry);
+
                for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
                        if (i)
                                trace_seq_puts(s, " <= ");
-                       seq_print_ip_sym(s, entry->stack.caller[i], sym_flags);
+                       seq_print_ip_sym(s, field->caller[i], sym_flags);
                }
                trace_seq_puts(s, "\n");
                break;
+       }
+       case TRACE_PRINT: {
+               struct print_entry *field;
+
+               trace_assign_type(field, entry);
+
+               seq_print_ip_sym(s, field->ip, sym_flags);
+               trace_seq_printf(s, ": %s", field->buf);
+               if (entry->flags & TRACE_FLAG_CONT)
+                       trace_seq_print_cont(s, iter);
+               break;
+       }
        default:
                trace_seq_printf(s, "Unknown type %d\n", entry->type);
        }
-       return 1;
+       return TRACE_TYPE_HANDLED;
 }
 
-static int print_trace_fmt(struct trace_iterator *iter)
+static enum print_line_t print_trace_fmt(struct trace_iterator *iter)
 {
        struct trace_seq *s = &iter->seq;
        unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
@@ -1567,90 +1458,126 @@ static int print_trace_fmt(struct trace_iterator *iter)
 
        entry = iter->ent;
 
+       if (entry->type == TRACE_CONT)
+               return TRACE_TYPE_HANDLED;
+
        comm = trace_find_cmdline(iter->ent->pid);
 
-       t = ns2usecs(entry->t);
+       t = ns2usecs(iter->ts);
        usec_rem = do_div(t, 1000000ULL);
        secs = (unsigned long)t;
 
        ret = trace_seq_printf(s, "%16s-%-5d ", comm, entry->pid);
        if (!ret)
-               return 0;
-       ret = trace_seq_printf(s, "[%02d] ", iter->cpu);
+               return TRACE_TYPE_PARTIAL_LINE;
+       ret = trace_seq_printf(s, "[%03d] ", iter->cpu);
        if (!ret)
-               return 0;
+               return TRACE_TYPE_PARTIAL_LINE;
        ret = trace_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem);
        if (!ret)
-               return 0;
+               return TRACE_TYPE_PARTIAL_LINE;
 
        switch (entry->type) {
-       case TRACE_FN:
-               ret = seq_print_ip_sym(s, entry->fn.ip, sym_flags);
+       case TRACE_FN: {
+               struct ftrace_entry *field;
+
+               trace_assign_type(field, entry);
+
+               ret = seq_print_ip_sym(s, field->ip, sym_flags);
                if (!ret)
-                       return 0;
+                       return TRACE_TYPE_PARTIAL_LINE;
                if ((sym_flags & TRACE_ITER_PRINT_PARENT) &&
-                                               entry->fn.parent_ip) {
+                                               field->parent_ip) {
                        ret = trace_seq_printf(s, " <-");
                        if (!ret)
-                               return 0;
-                       if (kretprobed(entry->fn.parent_ip))
+                               return TRACE_TYPE_PARTIAL_LINE;
+                       if (kretprobed(field->parent_ip))
                                ret = trace_seq_puts(s, KRETPROBE_MSG);
                        else
-                               ret = seq_print_ip_sym(s, entry->fn.parent_ip,
+                               ret = seq_print_ip_sym(s,
+                                                      field->parent_ip,
                                                       sym_flags);
                        if (!ret)
-                               return 0;
+                               return TRACE_TYPE_PARTIAL_LINE;
                }
                ret = trace_seq_printf(s, "\n");
                if (!ret)
-                       return 0;
+                       return TRACE_TYPE_PARTIAL_LINE;
                break;
+       }
        case TRACE_CTX:
-       case TRACE_WAKE:
-               S = entry->ctx.prev_state < sizeof(state_to_char) ?
-                       state_to_char[entry->ctx.prev_state] : 'X';
-               T = entry->ctx.next_state < sizeof(state_to_char) ?
-                       state_to_char[entry->ctx.next_state] : 'X';
-               ret = trace_seq_printf(s, " %5d:%3d:%c %s %5d:%3d:%c\n",
-                                      entry->ctx.prev_pid,
-                                      entry->ctx.prev_prio,
+       case TRACE_WAKE: {
+               struct ctx_switch_entry *field;
+
+               trace_assign_type(field, entry);
+
+               S = field->prev_state < sizeof(state_to_char) ?
+                       state_to_char[field->prev_state] : 'X';
+               T = field->next_state < sizeof(state_to_char) ?
+                       state_to_char[field->next_state] : 'X';
+               ret = trace_seq_printf(s, " %5d:%3d:%c %s [%03d] %5d:%3d:%c\n",
+                                      field->prev_pid,
+                                      field->prev_prio,
                                       S,
                                       entry->type == TRACE_CTX ? "==>" : "  +",
-                                      entry->ctx.next_pid,
-                                      entry->ctx.next_prio,
+                                      field->next_cpu,
+                                      field->next_pid,
+                                      field->next_prio,
                                       T);
                if (!ret)
-                       return 0;
+                       return TRACE_TYPE_PARTIAL_LINE;
                break;
-       case TRACE_SPECIAL:
+       }
+       case TRACE_SPECIAL: {
+               struct special_entry *field;
+
+               trace_assign_type(field, entry);
+
                ret = trace_seq_printf(s, "# %ld %ld %ld\n",
-                                entry->special.arg1,
-                                entry->special.arg2,
-                                entry->special.arg3);
+                                field->arg1,
+                                field->arg2,
+                                field->arg3);
                if (!ret)
-                       return 0;
+                       return TRACE_TYPE_PARTIAL_LINE;
                break;
-       case TRACE_STACK:
-               for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
+       }
+       case TRACE_STACK: {
+               struct stack_entry *field;
+
+               trace_assign_type(field, entry);
+
+               for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
                        if (i) {
                                ret = trace_seq_puts(s, " <= ");
                                if (!ret)
-                                       return 0;
+                                       return TRACE_TYPE_PARTIAL_LINE;
                        }
-                       ret = seq_print_ip_sym(s, entry->stack.caller[i],
+                       ret = seq_print_ip_sym(s, field->caller[i],
                                               sym_flags);
                        if (!ret)
-                               return 0;
+                               return TRACE_TYPE_PARTIAL_LINE;
                }
                ret = trace_seq_puts(s, "\n");
                if (!ret)
-                       return 0;
+                       return TRACE_TYPE_PARTIAL_LINE;
                break;
        }
-       return 1;
+       case TRACE_PRINT: {
+               struct print_entry *field;
+
+               trace_assign_type(field, entry);
+
+               seq_print_ip_sym(s, field->ip, sym_flags);
+               trace_seq_printf(s, ": %s", field->buf);
+               if (entry->flags & TRACE_FLAG_CONT)
+                       trace_seq_print_cont(s, iter);
+               break;
+       }
+       }
+       return TRACE_TYPE_HANDLED;
 }
 
-static int print_raw_fmt(struct trace_iterator *iter)
+static enum print_line_t print_raw_fmt(struct trace_iterator *iter)
 {
        struct trace_seq *s = &iter->seq;
        struct trace_entry *entry;
@@ -1659,47 +1586,77 @@ static int print_raw_fmt(struct trace_iterator *iter)
 
        entry = iter->ent;
 
+       if (entry->type == TRACE_CONT)
+               return TRACE_TYPE_HANDLED;
+
        ret = trace_seq_printf(s, "%d %d %llu ",
-               entry->pid, iter->cpu, entry->t);
+               entry->pid, iter->cpu, iter->ts);
        if (!ret)
-               return 0;
+               return TRACE_TYPE_PARTIAL_LINE;
 
        switch (entry->type) {
-       case TRACE_FN:
+       case TRACE_FN: {
+               struct ftrace_entry *field;
+
+               trace_assign_type(field, entry);
+
                ret = trace_seq_printf(s, "%x %x\n",
-                                       entry->fn.ip, entry->fn.parent_ip);
+                                       field->ip,
+                                       field->parent_ip);
                if (!ret)
-                       return 0;
+                       return TRACE_TYPE_PARTIAL_LINE;
                break;
+       }
        case TRACE_CTX:
-       case TRACE_WAKE:
-               S = entry->ctx.prev_state < sizeof(state_to_char) ?
-                       state_to_char[entry->ctx.prev_state] : 'X';
-               T = entry->ctx.next_state < sizeof(state_to_char) ?
-                       state_to_char[entry->ctx.next_state] : 'X';
+       case TRACE_WAKE: {
+               struct ctx_switch_entry *field;
+
+               trace_assign_type(field, entry);
+
+               S = field->prev_state < sizeof(state_to_char) ?
+                       state_to_char[field->prev_state] : 'X';
+               T = field->next_state < sizeof(state_to_char) ?
+                       state_to_char[field->next_state] : 'X';
                if (entry->type == TRACE_WAKE)
                        S = '+';
-               ret = trace_seq_printf(s, "%d %d %c %d %d %c\n",
-                                      entry->ctx.prev_pid,
-                                      entry->ctx.prev_prio,
+               ret = trace_seq_printf(s, "%d %d %c %d %d %d %c\n",
+                                      field->prev_pid,
+                                      field->prev_prio,
                                       S,
-                                      entry->ctx.next_pid,
-                                      entry->ctx.next_prio,
+                                      field->next_cpu,
+                                      field->next_pid,
+                                      field->next_prio,
                                       T);
                if (!ret)
-                       return 0;
+                       return TRACE_TYPE_PARTIAL_LINE;
                break;
+       }
        case TRACE_SPECIAL:
-       case TRACE_STACK:
+       case TRACE_STACK: {
+               struct special_entry *field;
+
+               trace_assign_type(field, entry);
+
                ret = trace_seq_printf(s, "# %ld %ld %ld\n",
-                                entry->special.arg1,
-                                entry->special.arg2,
-                                entry->special.arg3);
+                                field->arg1,
+                                field->arg2,
+                                field->arg3);
                if (!ret)
-                       return 0;
+                       return TRACE_TYPE_PARTIAL_LINE;
                break;
        }
-       return 1;
+       case TRACE_PRINT: {
+               struct print_entry *field;
+
+               trace_assign_type(field, entry);
+
+               trace_seq_printf(s, "# %lx %s", field->ip, field->buf);
+               if (entry->flags & TRACE_FLAG_CONT)
+                       trace_seq_print_cont(s, iter);
+               break;
+       }
+       }
+       return TRACE_TYPE_HANDLED;
 }
 
 #define SEQ_PUT_FIELD_RET(s, x)                                \
@@ -1710,11 +1667,12 @@ do {                                                    \
 
 #define SEQ_PUT_HEX_FIELD_RET(s, x)                    \
 do {                                                   \
+       BUILD_BUG_ON(sizeof(x) > MAX_MEMHEX_BYTES);     \
        if (!trace_seq_putmem_hex(s, &(x), sizeof(x)))  \
                return 0;                               \
 } while (0)
 
-static int print_hex_fmt(struct trace_iterator *iter)
+static enum print_line_t print_hex_fmt(struct trace_iterator *iter)
 {
        struct trace_seq *s = &iter->seq;
        unsigned char newline = '\n';
@@ -1723,97 +1681,139 @@ static int print_hex_fmt(struct trace_iterator *iter)
 
        entry = iter->ent;
 
+       if (entry->type == TRACE_CONT)
+               return TRACE_TYPE_HANDLED;
+
        SEQ_PUT_HEX_FIELD_RET(s, entry->pid);
        SEQ_PUT_HEX_FIELD_RET(s, iter->cpu);
-       SEQ_PUT_HEX_FIELD_RET(s, entry->t);
+       SEQ_PUT_HEX_FIELD_RET(s, iter->ts);
 
        switch (entry->type) {
-       case TRACE_FN:
-               SEQ_PUT_HEX_FIELD_RET(s, entry->fn.ip);
-               SEQ_PUT_HEX_FIELD_RET(s, entry->fn.parent_ip);
+       case TRACE_FN: {
+               struct ftrace_entry *field;
+
+               trace_assign_type(field, entry);
+
+               SEQ_PUT_HEX_FIELD_RET(s, field->ip);
+               SEQ_PUT_HEX_FIELD_RET(s, field->parent_ip);
                break;
+       }
        case TRACE_CTX:
-       case TRACE_WAKE:
-               S = entry->ctx.prev_state < sizeof(state_to_char) ?
-                       state_to_char[entry->ctx.prev_state] : 'X';
-               T = entry->ctx.next_state < sizeof(state_to_char) ?
-                       state_to_char[entry->ctx.next_state] : 'X';
+       case TRACE_WAKE: {
+               struct ctx_switch_entry *field;
+
+               trace_assign_type(field, entry);
+
+               S = field->prev_state < sizeof(state_to_char) ?
+                       state_to_char[field->prev_state] : 'X';
+               T = field->next_state < sizeof(state_to_char) ?
+                       state_to_char[field->next_state] : 'X';
                if (entry->type == TRACE_WAKE)
                        S = '+';
-               SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.prev_pid);
-               SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.prev_prio);
+               SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid);
+               SEQ_PUT_HEX_FIELD_RET(s, field->prev_prio);
                SEQ_PUT_HEX_FIELD_RET(s, S);
-               SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.next_pid);
-               SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.next_prio);
-               SEQ_PUT_HEX_FIELD_RET(s, entry->fn.parent_ip);
+               SEQ_PUT_HEX_FIELD_RET(s, field->next_cpu);
+               SEQ_PUT_HEX_FIELD_RET(s, field->next_pid);
+               SEQ_PUT_HEX_FIELD_RET(s, field->next_prio);
                SEQ_PUT_HEX_FIELD_RET(s, T);
                break;
+       }
        case TRACE_SPECIAL:
-       case TRACE_STACK:
-               SEQ_PUT_HEX_FIELD_RET(s, entry->special.arg1);
-               SEQ_PUT_HEX_FIELD_RET(s, entry->special.arg2);
-               SEQ_PUT_HEX_FIELD_RET(s, entry->special.arg3);
+       case TRACE_STACK: {
+               struct special_entry *field;
+
+               trace_assign_type(field, entry);
+
+               SEQ_PUT_HEX_FIELD_RET(s, field->arg1);
+               SEQ_PUT_HEX_FIELD_RET(s, field->arg2);
+               SEQ_PUT_HEX_FIELD_RET(s, field->arg3);
                break;
        }
+       }
        SEQ_PUT_FIELD_RET(s, newline);
 
-       return 1;
+       return TRACE_TYPE_HANDLED;
 }
 
-static int print_bin_fmt(struct trace_iterator *iter)
+static enum print_line_t print_bin_fmt(struct trace_iterator *iter)
 {
        struct trace_seq *s = &iter->seq;
        struct trace_entry *entry;
 
        entry = iter->ent;
 
+       if (entry->type == TRACE_CONT)
+               return TRACE_TYPE_HANDLED;
+
        SEQ_PUT_FIELD_RET(s, entry->pid);
-       SEQ_PUT_FIELD_RET(s, entry->cpu);
-       SEQ_PUT_FIELD_RET(s, entry->t);
+       SEQ_PUT_FIELD_RET(s, iter->cpu);
+       SEQ_PUT_FIELD_RET(s, iter->ts);
 
        switch (entry->type) {
-       case TRACE_FN:
-               SEQ_PUT_FIELD_RET(s, entry->fn.ip);
-               SEQ_PUT_FIELD_RET(s, entry->fn.parent_ip);
+       case TRACE_FN: {
+               struct ftrace_entry *field;
+
+               trace_assign_type(field, entry);
+
+               SEQ_PUT_FIELD_RET(s, field->ip);
+               SEQ_PUT_FIELD_RET(s, field->parent_ip);
                break;
-       case TRACE_CTX:
-               SEQ_PUT_FIELD_RET(s, entry->ctx.prev_pid);
-               SEQ_PUT_FIELD_RET(s, entry->ctx.prev_prio);
-               SEQ_PUT_FIELD_RET(s, entry->ctx.prev_state);
-               SEQ_PUT_FIELD_RET(s, entry->ctx.next_pid);
-               SEQ_PUT_FIELD_RET(s, entry->ctx.next_prio);
-               SEQ_PUT_FIELD_RET(s, entry->ctx.next_state);
+       }
+       case TRACE_CTX: {
+               struct ctx_switch_entry *field;
+
+               trace_assign_type(field, entry);
+
+               SEQ_PUT_FIELD_RET(s, field->prev_pid);
+               SEQ_PUT_FIELD_RET(s, field->prev_prio);
+               SEQ_PUT_FIELD_RET(s, field->prev_state);
+               SEQ_PUT_FIELD_RET(s, field->next_pid);
+               SEQ_PUT_FIELD_RET(s, field->next_prio);
+               SEQ_PUT_FIELD_RET(s, field->next_state);
                break;
+       }
        case TRACE_SPECIAL:
-       case TRACE_STACK:
-               SEQ_PUT_FIELD_RET(s, entry->special.arg1);
-               SEQ_PUT_FIELD_RET(s, entry->special.arg2);
-               SEQ_PUT_FIELD_RET(s, entry->special.arg3);
+       case TRACE_STACK: {
+               struct special_entry *field;
+
+               trace_assign_type(field, entry);
+
+               SEQ_PUT_FIELD_RET(s, field->arg1);
+               SEQ_PUT_FIELD_RET(s, field->arg2);
+               SEQ_PUT_FIELD_RET(s, field->arg3);
                break;
        }
+       }
        return 1;
 }
 
 static int trace_empty(struct trace_iterator *iter)
 {
-       struct trace_array_cpu *data;
        int cpu;
 
        for_each_tracing_cpu(cpu) {
-               data = iter->tr->data[cpu];
-
-               if (head_page(data) && data->trace_idx &&
-                   (data->trace_tail != data->trace_head ||
-                    data->trace_tail_idx != data->trace_head_idx))
-                       return 0;
+               if (iter->buffer_iter[cpu]) {
+                       if (!ring_buffer_iter_empty(iter->buffer_iter[cpu]))
+                               return 0;
+               } else {
+                       if (!ring_buffer_empty_cpu(iter->tr->buffer, cpu))
+                               return 0;
+               }
        }
+
        return 1;
 }
 
-static int print_trace_line(struct trace_iterator *iter)
+static enum print_line_t print_trace_line(struct trace_iterator *iter)
 {
-       if (iter->trace && iter->trace->print_line)
-               return iter->trace->print_line(iter);
+       enum print_line_t ret;
+
+       if (iter->trace && iter->trace->print_line) {
+               ret = iter->trace->print_line(iter);
+               if (ret != TRACE_TYPE_UNHANDLED)
+                       return ret;
+       }
 
        if (trace_flags & TRACE_ITER_BIN)
                return print_bin_fmt(iter);
@@ -1869,6 +1869,8 @@ static struct trace_iterator *
 __tracing_open(struct inode *inode, struct file *file, int *ret)
 {
        struct trace_iterator *iter;
+       struct seq_file *m;
+       int cpu;
 
        if (tracing_disabled) {
                *ret = -ENODEV;
@@ -1889,28 +1891,45 @@ __tracing_open(struct inode *inode, struct file *file, int *ret)
        iter->trace = current_trace;
        iter->pos = -1;
 
+       for_each_tracing_cpu(cpu) {
+
+               iter->buffer_iter[cpu] =
+                       ring_buffer_read_start(iter->tr->buffer, cpu);
+
+               if (!iter->buffer_iter[cpu])
+                       goto fail_buffer;
+       }
+
        /* TODO stop tracer */
        *ret = seq_open(file, &tracer_seq_ops);
-       if (!*ret) {
-               struct seq_file *m = file->private_data;
-               m->private = iter;
+       if (*ret)
+               goto fail_buffer;
 
-               /* stop the trace while dumping */
-               if (iter->tr->ctrl) {
-                       tracer_enabled = 0;
-                       ftrace_function_enabled = 0;
-               }
+       m = file->private_data;
+       m->private = iter;
 
-               if (iter->trace && iter->trace->open)
-                       iter->trace->open(iter);
-       } else {
-               kfree(iter);
-               iter = NULL;
+       /* stop the trace while dumping */
+       if (iter->tr->ctrl) {
+               tracer_enabled = 0;
+               ftrace_function_enabled = 0;
        }
+
+       if (iter->trace && iter->trace->open)
+                       iter->trace->open(iter);
+
        mutex_unlock(&trace_types_lock);
 
  out:
        return iter;
+
+ fail_buffer:
+       for_each_tracing_cpu(cpu) {
+               if (iter->buffer_iter[cpu])
+                       ring_buffer_read_finish(iter->buffer_iter[cpu]);
+       }
+       mutex_unlock(&trace_types_lock);
+
+       return ERR_PTR(-ENOMEM);
 }
 
 int tracing_open_generic(struct inode *inode, struct file *filp)
@@ -1926,8 +1945,14 @@ int tracing_release(struct inode *inode, struct file *file)
 {
        struct seq_file *m = (struct seq_file *)file->private_data;
        struct trace_iterator *iter = m->private;
+       int cpu;
 
        mutex_lock(&trace_types_lock);
+       for_each_tracing_cpu(cpu) {
+               if (iter->buffer_iter[cpu])
+                       ring_buffer_read_finish(iter->buffer_iter[cpu]);
+       }
+
        if (iter->trace && iter->trace->close)
                iter->trace->close(iter);
 
@@ -2352,9 +2377,11 @@ tracing_set_trace_write(struct file *filp, const char __user *ubuf,
        struct tracer *t;
        char buf[max_tracer_type_len+1];
        int i;
+       size_t ret;
 
        if (cnt > max_tracer_type_len)
                cnt = max_tracer_type_len;
+       ret = cnt;
 
        if (copy_from_user(&buf, ubuf, cnt))
                return -EFAULT;
@@ -2370,7 +2397,11 @@ tracing_set_trace_write(struct file *filp, const char __user *ubuf,
                if (strcmp(t->name, buf) == 0)
                        break;
        }
-       if (!t || t == current_trace)
+       if (!t) {
+               ret = -EINVAL;
+               goto out;
+       }
+       if (t == current_trace)
                goto out;
 
        if (current_trace && current_trace->reset)
@@ -2383,9 +2414,10 @@ tracing_set_trace_write(struct file *filp, const char __user *ubuf,
  out:
        mutex_unlock(&trace_types_lock);
 
-       filp->f_pos += cnt;
+       if (ret == cnt)
+               filp->f_pos += cnt;
 
-       return cnt;
+       return ret;
 }
 
 static ssize_t
@@ -2500,20 +2532,12 @@ tracing_read_pipe(struct file *filp, char __user *ubuf,
                  size_t cnt, loff_t *ppos)
 {
        struct trace_iterator *iter = filp->private_data;
-       struct trace_array_cpu *data;
-       static cpumask_t mask;
-       unsigned long flags;
-#ifdef CONFIG_FTRACE
-       int ftrace_save;
-#endif
-       int cpu;
        ssize_t sret;
 
        /* return any leftover data */
        sret = trace_seq_to_user(&iter->seq, ubuf, cnt);
        if (sret != -EBUSY)
                return sret;
-       sret = 0;
 
        trace_seq_reset(&iter->seq);
 
@@ -2524,6 +2548,8 @@ tracing_read_pipe(struct file *filp, char __user *ubuf,
                        goto out;
        }
 
+waitagain:
+       sret = 0;
        while (trace_empty(iter)) {
 
                if ((filp->f_flags & O_NONBLOCK)) {
@@ -2588,46 +2614,12 @@ tracing_read_pipe(struct file *filp, char __user *ubuf,
               offsetof(struct trace_iterator, seq));
        iter->pos = -1;
 
-       /*
-        * We need to stop all tracing on all CPUS to read the
-        * the next buffer. This is a bit expensive, but is
-        * not done often. We fill all what we can read,
-        * and then release the locks again.
-        */
-
-       cpus_clear(mask);
-       local_irq_save(flags);
-#ifdef CONFIG_FTRACE
-       ftrace_save = ftrace_enabled;
-       ftrace_enabled = 0;
-#endif
-       smp_wmb();
-       for_each_tracing_cpu(cpu) {
-               data = iter->tr->data[cpu];
-
-               if (!head_page(data) || !data->trace_idx)
-                       continue;
-
-               atomic_inc(&data->disabled);
-               cpu_set(cpu, mask);
-       }
-
-       for_each_cpu_mask(cpu, mask) {
-               data = iter->tr->data[cpu];
-               __raw_spin_lock(&data->lock);
-
-               if (data->overrun > iter->last_overrun[cpu])
-                       iter->overrun[cpu] +=
-                               data->overrun - iter->last_overrun[cpu];
-               iter->last_overrun[cpu] = data->overrun;
-       }
-
        while (find_next_entry_inc(iter) != NULL) {
-               int ret;
+               enum print_line_t ret;
                int len = iter->seq.len;
 
                ret = print_trace_line(iter);
-               if (!ret) {
+               if (ret == TRACE_TYPE_PARTIAL_LINE) {
                        /* don't print partial lines */
                        iter->seq.len = len;
                        break;
@@ -2639,26 +2631,17 @@ tracing_read_pipe(struct file *filp, char __user *ubuf,
                        break;
        }
 
-       for_each_cpu_mask(cpu, mask) {
-               data = iter->tr->data[cpu];
-               __raw_spin_unlock(&data->lock);
-       }
-
-       for_each_cpu_mask(cpu, mask) {
-               data = iter->tr->data[cpu];
-               atomic_dec(&data->disabled);
-       }
-#ifdef CONFIG_FTRACE
-       ftrace_enabled = ftrace_save;
-#endif
-       local_irq_restore(flags);
-
        /* Now copy what we have to the user */
        sret = trace_seq_to_user(&iter->seq, ubuf, cnt);
        if (iter->seq.readpos >= iter->seq.len)
                trace_seq_reset(&iter->seq);
+
+       /*
+        * If there was nothing to send to user, inspite of consuming trace
+        * entries, go back to wait for more entries.
+        */
        if (sret == -EBUSY)
-               sret = 0;
+               goto waitagain;
 
 out:
        mutex_unlock(&trace_types_lock);
@@ -2684,7 +2667,8 @@ tracing_entries_write(struct file *filp, const char __user *ubuf,
 {
        unsigned long val;
        char buf[64];
-       int i, ret;
+       int ret;
+       struct trace_array *tr = filp->private_data;
 
        if (cnt >= sizeof(buf))
                return -EINVAL;
@@ -2704,59 +2688,38 @@ tracing_entries_write(struct file *filp, const char __user *ubuf,
 
        mutex_lock(&trace_types_lock);
 
-       if (current_trace != &no_tracer) {
+       if (tr->ctrl) {
                cnt = -EBUSY;
-               pr_info("ftrace: set current_tracer to none"
+               pr_info("ftrace: please disable tracing"
                        " before modifying buffer size\n");
                goto out;
        }
 
-       if (val > global_trace.entries) {
-               long pages_requested;
-               unsigned long freeable_pages;
-
-               /* make sure we have enough memory before mapping */
-               pages_requested =
-                       (val + (ENTRIES_PER_PAGE-1)) / ENTRIES_PER_PAGE;
-
-               /* account for each buffer (and max_tr) */
-               pages_requested *= tracing_nr_buffers * 2;
-
-               /* Check for overflow */
-               if (pages_requested < 0) {
-                       cnt = -ENOMEM;
+       if (val != global_trace.entries) {
+               ret = ring_buffer_resize(global_trace.buffer, val);
+               if (ret < 0) {
+                       cnt = ret;
                        goto out;
                }
 
-               freeable_pages = determine_dirtyable_memory();
-
-               /* we only allow to request 1/4 of useable memory */
-               if (pages_requested >
-                   ((freeable_pages + tracing_pages_allocated) / 4)) {
-                       cnt = -ENOMEM;
-                       goto out;
-               }
-
-               while (global_trace.entries < val) {
-                       if (trace_alloc_page()) {
-                               cnt = -ENOMEM;
-                               goto out;
+               ret = ring_buffer_resize(max_tr.buffer, val);
+               if (ret < 0) {
+                       int r;
+                       cnt = ret;
+                       r = ring_buffer_resize(global_trace.buffer,
+                                              global_trace.entries);
+                       if (r < 0) {
+                               /* AARGH! We are left with different
+                                * size max buffer!!!! */
+                               WARN_ON(1);
+                               tracing_disabled = 1;
                        }
-                       /* double check that we don't go over the known pages */
-                       if (tracing_pages_allocated > pages_requested)
-                               break;
+                       goto out;
                }
 
-       } else {
-               /* include the number of entries in val (inc of page entries) */
-               while (global_trace.entries > val + (ENTRIES_PER_PAGE - 1))
-                       trace_free_page();
+               global_trace.entries = val;
        }
 
-       /* check integrity */
-       for_each_tracing_cpu(i)
-               check_pages(global_trace.data[i]);
-
        filp->f_pos += cnt;
 
        /* If check pages failed, return ENOMEM */
@@ -2769,6 +2732,52 @@ tracing_entries_write(struct file *filp, const char __user *ubuf,
        return cnt;
 }
 
+static int mark_printk(const char *fmt, ...)
+{
+       int ret;
+       va_list args;
+       va_start(args, fmt);
+       ret = trace_vprintk(0, fmt, args);
+       va_end(args);
+       return ret;
+}
+
+static ssize_t
+tracing_mark_write(struct file *filp, const char __user *ubuf,
+                                       size_t cnt, loff_t *fpos)
+{
+       char *buf;
+       char *end;
+       struct trace_array *tr = &global_trace;
+
+       if (!tr->ctrl || tracing_disabled)
+               return -EINVAL;
+
+       if (cnt > TRACE_BUF_SIZE)
+               cnt = TRACE_BUF_SIZE;
+
+       buf = kmalloc(cnt + 1, GFP_KERNEL);
+       if (buf == NULL)
+               return -ENOMEM;
+
+       if (copy_from_user(buf, ubuf, cnt)) {
+               kfree(buf);
+               return -EFAULT;
+       }
+
+       /* Cut from the first nil or newline. */
+       buf[cnt] = '\0';
+       end = strchr(buf, '\n');
+       if (end)
+               *end = '\0';
+
+       cnt = mark_printk("%s\n", buf);
+       kfree(buf);
+       *fpos += cnt;
+
+       return cnt;
+}
+
 static struct file_operations tracing_max_lat_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_max_lat_read,
@@ -2800,6 +2809,11 @@ static struct file_operations tracing_entries_fops = {
        .write          = tracing_entries_write,
 };
 
+static struct file_operations tracing_mark_fops = {
+       .open           = tracing_open_generic,
+       .write          = tracing_mark_write,
+};
+
 #ifdef CONFIG_DYNAMIC_FTRACE
 
 static ssize_t
@@ -2846,7 +2860,7 @@ struct dentry *tracing_init_dentry(void)
 #include "trace_selftest.c"
 #endif
 
-static __init void tracer_init_debugfs(void)
+static __init int tracer_init_debugfs(void)
 {
        struct dentry *d_tracer;
        struct dentry *entry;
@@ -2881,12 +2895,12 @@ static __init void tracer_init_debugfs(void)
        entry = debugfs_create_file("available_tracers", 0444, d_tracer,
                                    &global_trace, &show_traces_fops);
        if (!entry)
-               pr_warning("Could not create debugfs 'trace' entry\n");
+               pr_warning("Could not create debugfs 'available_tracers' entry\n");
 
        entry = debugfs_create_file("current_tracer", 0444, d_tracer,
                                    &global_trace, &set_tracer_fops);
        if (!entry)
-               pr_warning("Could not create debugfs 'trace' entry\n");
+               pr_warning("Could not create debugfs 'current_tracer' entry\n");
 
        entry = debugfs_create_file("tracing_max_latency", 0644, d_tracer,
                                    &tracing_max_latency,
@@ -2899,7 +2913,7 @@ static __init void tracer_init_debugfs(void)
                                    &tracing_thresh, &tracing_max_lat_fops);
        if (!entry)
                pr_warning("Could not create debugfs "
-                          "'tracing_threash' entry\n");
+                          "'tracing_thresh' entry\n");
        entry = debugfs_create_file("README", 0644, d_tracer,
                                    NULL, &tracing_readme_fops);
        if (!entry)
@@ -2909,13 +2923,19 @@ static __init void tracer_init_debugfs(void)
                                    NULL, &tracing_pipe_fops);
        if (!entry)
                pr_warning("Could not create debugfs "
-                          "'tracing_threash' entry\n");
+                          "'trace_pipe' entry\n");
 
        entry = debugfs_create_file("trace_entries", 0644, d_tracer,
                                    &global_trace, &tracing_entries_fops);
        if (!entry)
                pr_warning("Could not create debugfs "
-                          "'tracing_threash' entry\n");
+                          "'trace_entries' entry\n");
+
+       entry = debugfs_create_file("trace_marker", 0220, d_tracer,
+                                   NULL, &tracing_mark_fops);
+       if (!entry)
+               pr_warning("Could not create debugfs "
+                          "'trace_marker' entry\n");
 
 #ifdef CONFIG_DYNAMIC_FTRACE
        entry = debugfs_create_file("dyn_ftrace_total_info", 0444, d_tracer,
@@ -2928,230 +2948,263 @@ static __init void tracer_init_debugfs(void)
 #ifdef CONFIG_SYSPROF_TRACER
        init_tracer_sysprof_debugfs(d_tracer);
 #endif
+       return 0;
 }
 
-static int trace_alloc_page(void)
+int trace_vprintk(unsigned long ip, const char *fmt, va_list args)
 {
+       static DEFINE_SPINLOCK(trace_buf_lock);
+       static char trace_buf[TRACE_BUF_SIZE];
+
+       struct ring_buffer_event *event;
+       struct trace_array *tr = &global_trace;
        struct trace_array_cpu *data;
-       struct page *page, *tmp;
-       LIST_HEAD(pages);
-       void *array;
-       unsigned pages_allocated = 0;
-       int i;
+       struct print_entry *entry;
+       unsigned long flags, irq_flags;
+       int cpu, len = 0, size, pc;
 
-       /* first allocate a page for each CPU */
-       for_each_tracing_cpu(i) {
-               array = (void *)__get_free_page(GFP_KERNEL);
-               if (array == NULL) {
-                       printk(KERN_ERR "tracer: failed to allocate page"
-                              "for trace buffer!\n");
-                       goto free_pages;
-               }
+       if (!tr->ctrl || tracing_disabled)
+               return 0;
 
-               pages_allocated++;
-               page = virt_to_page(array);
-               list_add(&page->lru, &pages);
+       pc = preempt_count();
+       preempt_disable_notrace();
+       cpu = raw_smp_processor_id();
+       data = tr->data[cpu];
 
-/* Only allocate if we are actually using the max trace */
-#ifdef CONFIG_TRACER_MAX_TRACE
-               array = (void *)__get_free_page(GFP_KERNEL);
-               if (array == NULL) {
-                       printk(KERN_ERR "tracer: failed to allocate page"
-                              "for trace buffer!\n");
-                       goto free_pages;
-               }
-               pages_allocated++;
-               page = virt_to_page(array);
-               list_add(&page->lru, &pages);
-#endif
-       }
+       if (unlikely(atomic_read(&data->disabled)))
+               goto out;
 
-       /* Now that we successfully allocate a page per CPU, add them */
-       for_each_tracing_cpu(i) {
-               data = global_trace.data[i];
-               page = list_entry(pages.next, struct page, lru);
-               list_del_init(&page->lru);
-               list_add_tail(&page->lru, &data->trace_pages);
-               ClearPageLRU(page);
+       spin_lock_irqsave(&trace_buf_lock, flags);
+       len = vsnprintf(trace_buf, TRACE_BUF_SIZE, fmt, args);
 
-#ifdef CONFIG_TRACER_MAX_TRACE
-               data = max_tr.data[i];
-               page = list_entry(pages.next, struct page, lru);
-               list_del_init(&page->lru);
-               list_add_tail(&page->lru, &data->trace_pages);
-               SetPageLRU(page);
-#endif
-       }
-       tracing_pages_allocated += pages_allocated;
-       global_trace.entries += ENTRIES_PER_PAGE;
+       len = min(len, TRACE_BUF_SIZE-1);
+       trace_buf[len] = 0;
 
-       return 0;
+       size = sizeof(*entry) + len + 1;
+       event = ring_buffer_lock_reserve(tr->buffer, size, &irq_flags);
+       if (!event)
+               goto out_unlock;
+       entry = ring_buffer_event_data(event);
+       tracing_generic_entry_update(&entry->ent, flags, pc);
+       entry->ent.type                 = TRACE_PRINT;
+       entry->ip                       = ip;
 
- free_pages:
-       list_for_each_entry_safe(page, tmp, &pages, lru) {
-               list_del_init(&page->lru);
-               __free_page(page);
-       }
-       return -ENOMEM;
+       memcpy(&entry->buf, trace_buf, len);
+       entry->buf[len] = 0;
+       ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+
+ out_unlock:
+       spin_unlock_irqrestore(&trace_buf_lock, flags);
+
+ out:
+       preempt_enable_notrace();
+
+       return len;
 }
+EXPORT_SYMBOL_GPL(trace_vprintk);
 
-static int trace_free_page(void)
+int __ftrace_printk(unsigned long ip, const char *fmt, ...)
 {
-       struct trace_array_cpu *data;
-       struct page *page;
-       struct list_head *p;
-       int i;
-       int ret = 0;
+       int ret;
+       va_list ap;
 
-       /* free one page from each buffer */
-       for_each_tracing_cpu(i) {
-               data = global_trace.data[i];
-               p = data->trace_pages.next;
-               if (p == &data->trace_pages) {
-                       /* should never happen */
-                       WARN_ON(1);
-                       tracing_disabled = 1;
-                       ret = -1;
-                       break;
-               }
-               page = list_entry(p, struct page, lru);
-               ClearPageLRU(page);
-               list_del(&page->lru);
-               tracing_pages_allocated--;
-               tracing_pages_allocated--;
-               __free_page(page);
+       if (!(trace_flags & TRACE_ITER_PRINTK))
+               return 0;
 
-               tracing_reset(data);
+       va_start(ap, fmt);
+       ret = trace_vprintk(ip, fmt, ap);
+       va_end(ap);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(__ftrace_printk);
 
-#ifdef CONFIG_TRACER_MAX_TRACE
-               data = max_tr.data[i];
-               p = data->trace_pages.next;
-               if (p == &data->trace_pages) {
-                       /* should never happen */
-                       WARN_ON(1);
-                       tracing_disabled = 1;
-                       ret = -1;
-                       break;
-               }
-               page = list_entry(p, struct page, lru);
-               ClearPageLRU(page);
-               list_del(&page->lru);
-               __free_page(page);
+static int trace_panic_handler(struct notifier_block *this,
+                              unsigned long event, void *unused)
+{
+       ftrace_dump();
+       return NOTIFY_OK;
+}
 
-               tracing_reset(data);
-#endif
-       }
-       global_trace.entries -= ENTRIES_PER_PAGE;
+static struct notifier_block trace_panic_notifier = {
+       .notifier_call  = trace_panic_handler,
+       .next           = NULL,
+       .priority       = 150   /* priority: INT_MAX >= x >= 0 */
+};
 
-       return ret;
+static int trace_die_handler(struct notifier_block *self,
+                            unsigned long val,
+                            void *data)
+{
+       switch (val) {
+       case DIE_OOPS:
+               ftrace_dump();
+               break;
+       default:
+               break;
+       }
+       return NOTIFY_OK;
 }
 
-__init static int tracer_alloc_buffers(void)
+static struct notifier_block trace_die_notifier = {
+       .notifier_call = trace_die_handler,
+       .priority = 200
+};
+
+/*
+ * printk is set to max of 1024, we really don't need it that big.
+ * Nothing should be printing 1000 characters anyway.
+ */
+#define TRACE_MAX_PRINT                1000
+
+/*
+ * Define here KERN_TRACE so that we have one place to modify
+ * it if we decide to change what log level the ftrace dump
+ * should be at.
+ */
+#define KERN_TRACE             KERN_INFO
+
+static void
+trace_printk_seq(struct trace_seq *s)
 {
-       struct trace_array_cpu *data;
-       void *array;
-       struct page *page;
-       int pages = 0;
-       int ret = -ENOMEM;
-       int i;
+       /* Probably should print a warning here. */
+       if (s->len >= 1000)
+               s->len = 1000;
 
-       /* TODO: make the number of buffers hot pluggable with CPUS */
-       tracing_nr_buffers = num_possible_cpus();
-       tracing_buffer_mask = cpu_possible_map;
+       /* should be zero ended, but we are paranoid. */
+       s->buffer[s->len] = 0;
 
-       /* Allocate the first page for all buffers */
-       for_each_tracing_cpu(i) {
-               data = global_trace.data[i] = &per_cpu(global_trace_cpu, i);
-               max_tr.data[i] = &per_cpu(max_data, i);
+       printk(KERN_TRACE "%s", s->buffer);
 
-               array = (void *)__get_free_page(GFP_KERNEL);
-               if (array == NULL) {
-                       printk(KERN_ERR "tracer: failed to allocate page"
-                              "for trace buffer!\n");
-                       goto free_buffers;
-               }
+       trace_seq_reset(s);
+}
 
-               /* set the array to the list */
-               INIT_LIST_HEAD(&data->trace_pages);
-               page = virt_to_page(array);
-               list_add(&page->lru, &data->trace_pages);
-               /* use the LRU flag to differentiate the two buffers */
-               ClearPageLRU(page);
 
-               data->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
-               max_tr.data[i]->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
+void ftrace_dump(void)
+{
+       static DEFINE_SPINLOCK(ftrace_dump_lock);
+       /* use static because iter can be a bit big for the stack */
+       static struct trace_iterator iter;
+       static cpumask_t mask;
+       static int dump_ran;
+       unsigned long flags;
+       int cnt = 0, cpu;
 
-/* Only allocate if we are actually using the max trace */
-#ifdef CONFIG_TRACER_MAX_TRACE
-               array = (void *)__get_free_page(GFP_KERNEL);
-               if (array == NULL) {
-                       printk(KERN_ERR "tracer: failed to allocate page"
-                              "for trace buffer!\n");
-                       goto free_buffers;
-               }
+       /* only one dump */
+       spin_lock_irqsave(&ftrace_dump_lock, flags);
+       if (dump_ran)
+               goto out;
 
-               INIT_LIST_HEAD(&max_tr.data[i]->trace_pages);
-               page = virt_to_page(array);
-               list_add(&page->lru, &max_tr.data[i]->trace_pages);
-               SetPageLRU(page);
-#endif
+       dump_ran = 1;
+
+       /* No turning back! */
+       ftrace_kill_atomic();
+
+       for_each_tracing_cpu(cpu) {
+               atomic_inc(&global_trace.data[cpu]->disabled);
        }
 
+       printk(KERN_TRACE "Dumping ftrace buffer:\n");
+
+       iter.tr = &global_trace;
+       iter.trace = current_trace;
+
        /*
-        * Since we allocate by orders of pages, we may be able to
-        * round up a bit.
+        * We need to stop all tracing on all CPUS to read the
+        * the next buffer. This is a bit expensive, but is
+        * not done often. We fill all what we can read,
+        * and then release the locks again.
         */
-       global_trace.entries = ENTRIES_PER_PAGE;
-       pages++;
 
-       while (global_trace.entries < trace_nr_entries) {
-               if (trace_alloc_page())
-                       break;
-               pages++;
+       cpus_clear(mask);
+
+       while (!trace_empty(&iter)) {
+
+               if (!cnt)
+                       printk(KERN_TRACE "---------------------------------\n");
+
+               cnt++;
+
+               /* reset all but tr, trace, and overruns */
+               memset(&iter.seq, 0,
+                      sizeof(struct trace_iterator) -
+                      offsetof(struct trace_iterator, seq));
+               iter.iter_flags |= TRACE_FILE_LAT_FMT;
+               iter.pos = -1;
+
+               if (find_next_entry_inc(&iter) != NULL) {
+                       print_trace_line(&iter);
+                       trace_consume(&iter);
+               }
+
+               trace_printk_seq(&iter.seq);
        }
-       max_tr.entries = global_trace.entries;
 
-       pr_info("tracer: %d pages allocated for %ld entries of %ld bytes\n",
-               pages, trace_nr_entries, (long)TRACE_ENTRY_SIZE);
-       pr_info("   actual entries %ld\n", global_trace.entries);
+       if (!cnt)
+               printk(KERN_TRACE "   (ftrace buffer empty)\n");
+       else
+               printk(KERN_TRACE "---------------------------------\n");
+
+ out:
+       spin_unlock_irqrestore(&ftrace_dump_lock, flags);
+}
+
+__init static int tracer_alloc_buffers(void)
+{
+       struct trace_array_cpu *data;
+       int i;
+
+       /* TODO: make the number of buffers hot pluggable with CPUS */
+       tracing_buffer_mask = cpu_possible_map;
+
+       global_trace.buffer = ring_buffer_alloc(trace_buf_size,
+                                                  TRACE_BUFFER_FLAGS);
+       if (!global_trace.buffer) {
+               printk(KERN_ERR "tracer: failed to allocate ring buffer!\n");
+               WARN_ON(1);
+               return 0;
+       }
+       global_trace.entries = ring_buffer_size(global_trace.buffer);
+
+#ifdef CONFIG_TRACER_MAX_TRACE
+       max_tr.buffer = ring_buffer_alloc(trace_buf_size,
+                                            TRACE_BUFFER_FLAGS);
+       if (!max_tr.buffer) {
+               printk(KERN_ERR "tracer: failed to allocate max ring buffer!\n");
+               WARN_ON(1);
+               ring_buffer_free(global_trace.buffer);
+               return 0;
+       }
+       max_tr.entries = ring_buffer_size(max_tr.buffer);
+       WARN_ON(max_tr.entries != global_trace.entries);
+#endif
 
-       tracer_init_debugfs();
+       /* Allocate the first page for all buffers */
+       for_each_tracing_cpu(i) {
+               data = global_trace.data[i] = &per_cpu(global_trace_cpu, i);
+               max_tr.data[i] = &per_cpu(max_data, i);
+       }
 
        trace_init_cmdlines();
 
-       register_tracer(&no_tracer);
-       current_trace = &no_tracer;
+       register_tracer(&nop_trace);
+#ifdef CONFIG_BOOT_TRACER
+       register_tracer(&boot_tracer);
+       current_trace = &boot_tracer;
+       current_trace->init(&global_trace);
+#else
+       current_trace = &nop_trace;
+#endif
 
        /* All seems OK, enable tracing */
        global_trace.ctrl = tracer_enabled;
        tracing_disabled = 0;
 
-       return 0;
+       atomic_notifier_chain_register(&panic_notifier_list,
+                                      &trace_panic_notifier);
 
- free_buffers:
-       for (i-- ; i >= 0; i--) {
-               struct page *page, *tmp;
-               struct trace_array_cpu *data = global_trace.data[i];
+       register_die_notifier(&trace_die_notifier);
 
-               if (data) {
-                       list_for_each_entry_safe(page, tmp,
-                                                &data->trace_pages, lru) {
-                               list_del_init(&page->lru);
-                               __free_page(page);
-                       }
-               }
-
-#ifdef CONFIG_TRACER_MAX_TRACE
-               data = max_tr.data[i];
-               if (data) {
-                       list_for_each_entry_safe(page, tmp,
-                                                &data->trace_pages, lru) {
-                               list_del_init(&page->lru);
-                               __free_page(page);
-                       }
-               }
-#endif
-       }
-       return ret;
+       return 0;
 }
-fs_initcall(tracer_alloc_buffers);
+early_initcall(tracer_alloc_buffers);
+fs_initcall(tracer_init_debugfs);
index f69f86788c2bd12a2df18e4dabe9e66046a2e71f..f1f99572cde7dee758217125925e2690a45b38d1 100644 (file)
@@ -5,7 +5,9 @@
 #include <asm/atomic.h>
 #include <linux/sched.h>
 #include <linux/clocksource.h>
+#include <linux/ring_buffer.h>
 #include <linux/mmiotrace.h>
+#include <linux/ftrace.h>
 
 enum trace_type {
        __TRACE_FIRST_TYPE = 0,
@@ -13,38 +15,60 @@ enum trace_type {
        TRACE_FN,
        TRACE_CTX,
        TRACE_WAKE,
+       TRACE_CONT,
        TRACE_STACK,
+       TRACE_PRINT,
        TRACE_SPECIAL,
        TRACE_MMIO_RW,
        TRACE_MMIO_MAP,
+       TRACE_BOOT,
 
        __TRACE_LAST_TYPE
 };
 
+/*
+ * The trace entry - the most basic unit of tracing. This is what
+ * is printed in the end as a single line in the trace output, such as:
+ *
+ *     bash-15816 [01]   235.197585: idle_cpu <- irq_enter
+ */
+struct trace_entry {
+       unsigned char           type;
+       unsigned char           cpu;
+       unsigned char           flags;
+       unsigned char           preempt_count;
+       int                     pid;
+};
+
 /*
  * Function trace entry - function address and parent function addres:
  */
 struct ftrace_entry {
+       struct trace_entry      ent;
        unsigned long           ip;
        unsigned long           parent_ip;
 };
+extern struct tracer boot_tracer;
 
 /*
  * Context switch trace entry - which task (and prio) we switched from/to:
  */
 struct ctx_switch_entry {
+       struct trace_entry      ent;
        unsigned int            prev_pid;
        unsigned char           prev_prio;
        unsigned char           prev_state;
        unsigned int            next_pid;
        unsigned char           next_prio;
        unsigned char           next_state;
+       unsigned int            next_cpu;
 };
 
 /*
  * Special (free-form) trace entry:
  */
 struct special_entry {
+       struct trace_entry      ent;
        unsigned long           arg1;
        unsigned long           arg2;
        unsigned long           arg3;
@@ -57,33 +81,60 @@ struct special_entry {
 #define FTRACE_STACK_ENTRIES   8
 
 struct stack_entry {
+       struct trace_entry      ent;
        unsigned long           caller[FTRACE_STACK_ENTRIES];
 };
 
 /*
- * The trace entry - the most basic unit of tracing. This is what
- * is printed in the end as a single line in the trace output, such as:
- *
- *     bash-15816 [01]   235.197585: idle_cpu <- irq_enter
+ * ftrace_printk entry:
  */
-struct trace_entry {
-       char                    type;
-       char                    cpu;
-       char                    flags;
-       char                    preempt_count;
-       int                     pid;
-       cycle_t                 t;
-       union {
-               struct ftrace_entry             fn;
-               struct ctx_switch_entry         ctx;
-               struct special_entry            special;
-               struct stack_entry              stack;
-               struct mmiotrace_rw             mmiorw;
-               struct mmiotrace_map            mmiomap;
-       };
+struct print_entry {
+       struct trace_entry      ent;
+       unsigned long           ip;
+       char                    buf[];
+};
+
+#define TRACE_OLD_SIZE         88
+
+struct trace_field_cont {
+       unsigned char           type;
+       /* Temporary till we get rid of this completely */
+       char                    buf[TRACE_OLD_SIZE - 1];
+};
+
+struct trace_mmiotrace_rw {
+       struct trace_entry      ent;
+       struct mmiotrace_rw     rw;
 };
 
-#define TRACE_ENTRY_SIZE       sizeof(struct trace_entry)
+struct trace_mmiotrace_map {
+       struct trace_entry      ent;
+       struct mmiotrace_map    map;
+};
+
+struct trace_boot {
+       struct trace_entry      ent;
+       struct boot_trace       initcall;
+};
+
+/*
+ * trace_flag_type is an enumeration that holds different
+ * states when a trace occurs. These are:
+ *  IRQS_OFF   - interrupts were disabled
+ *  NEED_RESCED - reschedule is requested
+ *  HARDIRQ    - inside an interrupt handler
+ *  SOFTIRQ    - inside a softirq handler
+ *  CONT       - multiple entries hold the trace item
+ */
+enum trace_flag_type {
+       TRACE_FLAG_IRQS_OFF             = 0x01,
+       TRACE_FLAG_NEED_RESCHED         = 0x02,
+       TRACE_FLAG_HARDIRQ              = 0x04,
+       TRACE_FLAG_SOFTIRQ              = 0x08,
+       TRACE_FLAG_CONT                 = 0x10,
+};
+
+#define TRACE_BUF_SIZE         1024
 
 /*
  * The CPU trace array - it consists of thousands of trace entries
@@ -91,16 +142,9 @@ struct trace_entry {
  * the trace, etc.)
  */
 struct trace_array_cpu {
-       struct list_head        trace_pages;
        atomic_t                disabled;
-       raw_spinlock_t          lock;
-       struct lock_class_key   lock_key;
 
        /* these fields get copied into max-trace: */
-       unsigned                trace_head_idx;
-       unsigned                trace_tail_idx;
-       void                    *trace_head; /* producer */
-       void                    *trace_tail; /* consumer */
        unsigned long           trace_idx;
        unsigned long           overrun;
        unsigned long           saved_latency;
@@ -124,6 +168,7 @@ struct trace_iterator;
  * They have on/off state as well:
  */
 struct trace_array {
+       struct ring_buffer      *buffer;
        unsigned long           entries;
        long                    ctrl;
        int                     cpu;
@@ -132,6 +177,56 @@ struct trace_array {
        struct trace_array_cpu  *data[NR_CPUS];
 };
 
+#define FTRACE_CMP_TYPE(var, type) \
+       __builtin_types_compatible_p(typeof(var), type *)
+
+#undef IF_ASSIGN
+#define IF_ASSIGN(var, entry, etype, id)               \
+       if (FTRACE_CMP_TYPE(var, etype)) {              \
+               var = (typeof(var))(entry);             \
+               WARN_ON(id && (entry)->type != id);     \
+               break;                                  \
+       }
+
+/* Will cause compile errors if type is not found. */
+extern void __ftrace_bad_type(void);
+
+/*
+ * The trace_assign_type is a verifier that the entry type is
+ * the same as the type being assigned. To add new types simply
+ * add a line with the following format:
+ *
+ * IF_ASSIGN(var, ent, type, id);
+ *
+ *  Where "type" is the trace type that includes the trace_entry
+ *  as the "ent" item. And "id" is the trace identifier that is
+ *  used in the trace_type enum.
+ *
+ *  If the type can have more than one id, then use zero.
+ */
+#define trace_assign_type(var, ent)                                    \
+       do {                                                            \
+               IF_ASSIGN(var, ent, struct ftrace_entry, TRACE_FN);     \
+               IF_ASSIGN(var, ent, struct ctx_switch_entry, 0);        \
+               IF_ASSIGN(var, ent, struct trace_field_cont, TRACE_CONT); \
+               IF_ASSIGN(var, ent, struct stack_entry, TRACE_STACK);   \
+               IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT);   \
+               IF_ASSIGN(var, ent, struct special_entry, 0);           \
+               IF_ASSIGN(var, ent, struct trace_mmiotrace_rw,          \
+                         TRACE_MMIO_RW);                               \
+               IF_ASSIGN(var, ent, struct trace_mmiotrace_map,         \
+                         TRACE_MMIO_MAP);                              \
+               IF_ASSIGN(var, ent, struct trace_boot, TRACE_BOOT);     \
+               __ftrace_bad_type();                                    \
+       } while (0)
+
+/* Return values for print_line callback */
+enum print_line_t {
+       TRACE_TYPE_PARTIAL_LINE = 0,    /* Retry after flushing the seq */
+       TRACE_TYPE_HANDLED      = 1,
+       TRACE_TYPE_UNHANDLED    = 2     /* Relay to other output functions */
+};
+
 /*
  * A specific tracer, represented by methods that operate on a trace array:
  */
@@ -152,7 +247,7 @@ struct tracer {
        int                     (*selftest)(struct tracer *trace,
                                            struct trace_array *tr);
 #endif
-       int                     (*print_line)(struct trace_iterator *iter);
+       enum print_line_t       (*print_line)(struct trace_iterator *iter);
        struct tracer           *next;
        int                     print_max;
 };
@@ -171,57 +266,58 @@ struct trace_iterator {
        struct trace_array      *tr;
        struct tracer           *trace;
        void                    *private;
-       long                    last_overrun[NR_CPUS];
-       long                    overrun[NR_CPUS];
+       struct ring_buffer_iter *buffer_iter[NR_CPUS];
 
        /* The below is zeroed out in pipe_read */
        struct trace_seq        seq;
        struct trace_entry      *ent;
        int                     cpu;
-
-       struct trace_entry      *prev_ent;
-       int                     prev_cpu;
+       u64                     ts;
 
        unsigned long           iter_flags;
        loff_t                  pos;
-       unsigned long           next_idx[NR_CPUS];
-       struct list_head        *next_page[NR_CPUS];
-       unsigned                next_page_idx[NR_CPUS];
        long                    idx;
 };
 
-void tracing_reset(struct trace_array_cpu *data);
+void trace_wake_up(void);
+void tracing_reset(struct trace_array *tr, int cpu);
 int tracing_open_generic(struct inode *inode, struct file *filp);
 struct dentry *tracing_init_dentry(void);
 void init_tracer_sysprof_debugfs(struct dentry *d_tracer);
 
+struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,
+                                               struct trace_array_cpu *data);
+void tracing_generic_entry_update(struct trace_entry *entry,
+                                 unsigned long flags,
+                                 int pc);
+
 void ftrace(struct trace_array *tr,
                            struct trace_array_cpu *data,
                            unsigned long ip,
                            unsigned long parent_ip,
-                           unsigned long flags);
+                           unsigned long flags, int pc);
 void tracing_sched_switch_trace(struct trace_array *tr,
                                struct trace_array_cpu *data,
                                struct task_struct *prev,
                                struct task_struct *next,
-                               unsigned long flags);
+                               unsigned long flags, int pc);
 void tracing_record_cmdline(struct task_struct *tsk);
 
 void tracing_sched_wakeup_trace(struct trace_array *tr,
                                struct trace_array_cpu *data,
                                struct task_struct *wakee,
                                struct task_struct *cur,
-                               unsigned long flags);
+                               unsigned long flags, int pc);
 void trace_special(struct trace_array *tr,
                   struct trace_array_cpu *data,
                   unsigned long arg1,
                   unsigned long arg2,
-                  unsigned long arg3);
+                  unsigned long arg3, int pc);
 void trace_function(struct trace_array *tr,
                    struct trace_array_cpu *data,
                    unsigned long ip,
                    unsigned long parent_ip,
-                   unsigned long flags);
+                   unsigned long flags, int pc);
 
 void tracing_start_cmdline_record(void);
 void tracing_stop_cmdline_record(void);
@@ -268,51 +364,33 @@ extern unsigned long ftrace_update_tot_cnt;
 extern int DYN_FTRACE_TEST_NAME(void);
 #endif
 
-#ifdef CONFIG_MMIOTRACE
-extern void __trace_mmiotrace_rw(struct trace_array *tr,
-                               struct trace_array_cpu *data,
-                               struct mmiotrace_rw *rw);
-extern void __trace_mmiotrace_map(struct trace_array *tr,
-                               struct trace_array_cpu *data,
-                               struct mmiotrace_map *map);
-#endif
-
 #ifdef CONFIG_FTRACE_STARTUP_TEST
-#ifdef CONFIG_FTRACE
 extern int trace_selftest_startup_function(struct tracer *trace,
                                           struct trace_array *tr);
-#endif
-#ifdef CONFIG_IRQSOFF_TRACER
 extern int trace_selftest_startup_irqsoff(struct tracer *trace,
                                          struct trace_array *tr);
-#endif
-#ifdef CONFIG_PREEMPT_TRACER
 extern int trace_selftest_startup_preemptoff(struct tracer *trace,
                                             struct trace_array *tr);
-#endif
-#if defined(CONFIG_IRQSOFF_TRACER) && defined(CONFIG_PREEMPT_TRACER)
 extern int trace_selftest_startup_preemptirqsoff(struct tracer *trace,
                                                 struct trace_array *tr);
-#endif
-#ifdef CONFIG_SCHED_TRACER
 extern int trace_selftest_startup_wakeup(struct tracer *trace,
                                         struct trace_array *tr);
-#endif
-#ifdef CONFIG_CONTEXT_SWITCH_TRACER
+extern int trace_selftest_startup_nop(struct tracer *trace,
+                                        struct trace_array *tr);
 extern int trace_selftest_startup_sched_switch(struct tracer *trace,
                                               struct trace_array *tr);
-#endif
-#ifdef CONFIG_SYSPROF_TRACER
 extern int trace_selftest_startup_sysprof(struct tracer *trace,
                                               struct trace_array *tr);
-#endif
 #endif /* CONFIG_FTRACE_STARTUP_TEST */
 
 extern void *head_page(struct trace_array_cpu *data);
 extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...);
+extern void trace_seq_print_cont(struct trace_seq *s,
+                                struct trace_iterator *iter);
 extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
                                 size_t cnt);
 extern long ns2usecs(cycle_t nsec);
+extern int trace_vprintk(unsigned long ip, const char *fmt, va_list args);
 
 extern unsigned long trace_flags;
 
@@ -334,6 +412,9 @@ enum trace_iterator_flags {
        TRACE_ITER_BLOCK                = 0x80,
        TRACE_ITER_STACKTRACE           = 0x100,
        TRACE_ITER_SCHED_TREE           = 0x200,
+       TRACE_ITER_PRINTK               = 0x400,
 };
 
+extern struct tracer nop_trace;
+
 #endif /* _LINUX_KERNEL_TRACE_H */
diff --git a/kernel/trace/trace_boot.c b/kernel/trace/trace_boot.c
new file mode 100644 (file)
index 0000000..d0a5e50
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * ring buffer based initcalls tracer
+ *
+ * Copyright (C) 2008 Frederic Weisbecker <fweisbec@gmail.com>
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/debugfs.h>
+#include <linux/ftrace.h>
+#include <linux/kallsyms.h>
+
+#include "trace.h"
+
+static struct trace_array *boot_trace;
+static int trace_boot_enabled;
+
+
+/* Should be started after do_pre_smp_initcalls() in init/main.c */
+void start_boot_trace(void)
+{
+       trace_boot_enabled = 1;
+}
+
+void stop_boot_trace(void)
+{
+       trace_boot_enabled = 0;
+}
+
+void reset_boot_trace(struct trace_array *tr)
+{
+       stop_boot_trace();
+}
+
+static void boot_trace_init(struct trace_array *tr)
+{
+       int cpu;
+       boot_trace = tr;
+
+       trace_boot_enabled = 0;
+
+       for_each_cpu_mask(cpu, cpu_possible_map)
+               tracing_reset(tr, cpu);
+}
+
+static void boot_trace_ctrl_update(struct trace_array *tr)
+{
+       if (tr->ctrl)
+               start_boot_trace();
+       else
+               stop_boot_trace();
+}
+
+static enum print_line_t initcall_print_line(struct trace_iterator *iter)
+{
+       int ret;
+       struct trace_entry *entry = iter->ent;
+       struct trace_boot *field = (struct trace_boot *)entry;
+       struct boot_trace *it = &field->initcall;
+       struct trace_seq *s = &iter->seq;
+       struct timespec calltime = ktime_to_timespec(it->calltime);
+       struct timespec rettime = ktime_to_timespec(it->rettime);
+
+       if (entry->type == TRACE_BOOT) {
+               ret = trace_seq_printf(s, "[%5ld.%09ld] calling  %s @ %i\n",
+                                         calltime.tv_sec,
+                                         calltime.tv_nsec,
+                                         it->func, it->caller);
+               if (!ret)
+                       return TRACE_TYPE_PARTIAL_LINE;
+
+               ret = trace_seq_printf(s, "[%5ld.%09ld] initcall %s "
+                                         "returned %d after %lld msecs\n",
+                                         rettime.tv_sec,
+                                         rettime.tv_nsec,
+                                         it->func, it->result, it->duration);
+
+               if (!ret)
+                       return TRACE_TYPE_PARTIAL_LINE;
+               return TRACE_TYPE_HANDLED;
+       }
+       return TRACE_TYPE_UNHANDLED;
+}
+
+struct tracer boot_tracer __read_mostly =
+{
+       .name           = "initcall",
+       .init           = boot_trace_init,
+       .reset          = reset_boot_trace,
+       .ctrl_update    = boot_trace_ctrl_update,
+       .print_line     = initcall_print_line,
+};
+
+void trace_boot(struct boot_trace *it, initcall_t fn)
+{
+       struct ring_buffer_event *event;
+       struct trace_boot *entry;
+       struct trace_array_cpu *data;
+       unsigned long irq_flags;
+       struct trace_array *tr = boot_trace;
+
+       if (!trace_boot_enabled)
+               return;
+
+       /* Get its name now since this function could
+        * disappear because it is in the .init section.
+        */
+       sprint_symbol(it->func, (unsigned long)fn);
+       preempt_disable();
+       data = tr->data[smp_processor_id()];
+
+       event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
+                                        &irq_flags);
+       if (!event)
+               goto out;
+       entry   = ring_buffer_event_data(event);
+       tracing_generic_entry_update(&entry->ent, 0, 0);
+       entry->ent.type = TRACE_BOOT;
+       entry->initcall = *it;
+       ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+
+       trace_wake_up();
+
+ out:
+       preempt_enable();
+}
index 312144897970b18c7d9fd596bbf033182f68822b..e90eb0c2c56ca78d917f4e353dd099fd51c29172 100644 (file)
@@ -23,7 +23,7 @@ static void function_reset(struct trace_array *tr)
        tr->time_start = ftrace_now(tr->cpu);
 
        for_each_online_cpu(cpu)
-               tracing_reset(tr->data[cpu]);
+               tracing_reset(tr, cpu);
 }
 
 static void start_function_trace(struct trace_array *tr)
index ece6cfb649fa52823f33988fd6792dad2d0d1fae..a7db7f040ae03bc3b3556b3f77e47f032be62c1d 100644 (file)
@@ -95,7 +95,7 @@ irqsoff_tracer_call(unsigned long ip, unsigned long parent_ip)
        disabled = atomic_inc_return(&data->disabled);
 
        if (likely(disabled == 1))
-               trace_function(tr, data, ip, parent_ip, flags);
+               trace_function(tr, data, ip, parent_ip, flags, preempt_count());
 
        atomic_dec(&data->disabled);
 }
@@ -130,6 +130,7 @@ check_critical_timing(struct trace_array *tr,
        unsigned long latency, t0, t1;
        cycle_t T0, T1, delta;
        unsigned long flags;
+       int pc;
 
        /*
         * usecs conversion is slow so we try to delay the conversion
@@ -141,6 +142,8 @@ check_critical_timing(struct trace_array *tr,
 
        local_save_flags(flags);
 
+       pc = preempt_count();
+
        if (!report_latency(delta))
                goto out;
 
@@ -150,7 +153,7 @@ check_critical_timing(struct trace_array *tr,
        if (!report_latency(delta))
                goto out_unlock;
 
-       trace_function(tr, data, CALLER_ADDR0, parent_ip, flags);
+       trace_function(tr, data, CALLER_ADDR0, parent_ip, flags, pc);
 
        latency = nsecs_to_usecs(delta);
 
@@ -173,8 +176,8 @@ out_unlock:
 out:
        data->critical_sequence = max_sequence;
        data->preempt_timestamp = ftrace_now(cpu);
-       tracing_reset(data);
-       trace_function(tr, data, CALLER_ADDR0, parent_ip, flags);
+       tracing_reset(tr, cpu);
+       trace_function(tr, data, CALLER_ADDR0, parent_ip, flags, pc);
 }
 
 static inline void
@@ -203,11 +206,11 @@ start_critical_timing(unsigned long ip, unsigned long parent_ip)
        data->critical_sequence = max_sequence;
        data->preempt_timestamp = ftrace_now(cpu);
        data->critical_start = parent_ip ? : ip;
-       tracing_reset(data);
+       tracing_reset(tr, cpu);
 
        local_save_flags(flags);
 
-       trace_function(tr, data, ip, parent_ip, flags);
+       trace_function(tr, data, ip, parent_ip, flags, preempt_count());
 
        per_cpu(tracing_cpu, cpu) = 1;
 
@@ -234,14 +237,14 @@ stop_critical_timing(unsigned long ip, unsigned long parent_ip)
 
        data = tr->data[cpu];
 
-       if (unlikely(!data) || unlikely(!head_page(data)) ||
+       if (unlikely(!data) ||
            !data->critical_start || atomic_read(&data->disabled))
                return;
 
        atomic_inc(&data->disabled);
 
        local_save_flags(flags);
-       trace_function(tr, data, ip, parent_ip, flags);
+       trace_function(tr, data, ip, parent_ip, flags, preempt_count());
        check_critical_timing(tr, data, parent_ip ? : ip, cpu);
        data->critical_start = 0;
        atomic_dec(&data->disabled);
index b13dc19dcbb4691e51bd802238cfbbda15782a73..f28484618ff0de99b0c9d5062f23fe8eec25070a 100644 (file)
@@ -27,7 +27,7 @@ static void mmio_reset_data(struct trace_array *tr)
        tr->time_start = ftrace_now(tr->cpu);
 
        for_each_online_cpu(cpu)
-               tracing_reset(tr->data[cpu]);
+               tracing_reset(tr, cpu);
 }
 
 static void mmio_trace_init(struct trace_array *tr)
@@ -130,10 +130,14 @@ static unsigned long count_overruns(struct trace_iterator *iter)
 {
        int cpu;
        unsigned long cnt = 0;
+/* FIXME: */
+#if 0
        for_each_online_cpu(cpu) {
                cnt += iter->overrun[cpu];
                iter->overrun[cpu] = 0;
        }
+#endif
+       (void)cpu;
        return cnt;
 }
 
@@ -171,17 +175,21 @@ print_out:
        return (ret == -EBUSY) ? 0 : ret;
 }
 
-static int mmio_print_rw(struct trace_iterator *iter)
+static enum print_line_t mmio_print_rw(struct trace_iterator *iter)
 {
        struct trace_entry *entry = iter->ent;
-       struct mmiotrace_rw *rw = &entry->mmiorw;
+       struct trace_mmiotrace_rw *field;
+       struct mmiotrace_rw *rw;
        struct trace_seq *s     = &iter->seq;
-       unsigned long long t    = ns2usecs(entry->t);
+       unsigned long long t    = ns2usecs(iter->ts);
        unsigned long usec_rem  = do_div(t, 1000000ULL);
        unsigned secs           = (unsigned long)t;
        int ret = 1;
 
-       switch (entry->mmiorw.opcode) {
+       trace_assign_type(field, entry);
+       rw = &field->rw;
+
+       switch (rw->opcode) {
        case MMIO_READ:
                ret = trace_seq_printf(s,
                        "R %d %lu.%06lu %d 0x%llx 0x%lx 0x%lx %d\n",
@@ -209,21 +217,25 @@ static int mmio_print_rw(struct trace_iterator *iter)
                break;
        }
        if (ret)
-               return 1;
-       return 0;
+               return TRACE_TYPE_HANDLED;
+       return TRACE_TYPE_PARTIAL_LINE;
 }
 
-static int mmio_print_map(struct trace_iterator *iter)
+static enum print_line_t mmio_print_map(struct trace_iterator *iter)
 {
        struct trace_entry *entry = iter->ent;
-       struct mmiotrace_map *m = &entry->mmiomap;
+       struct trace_mmiotrace_map *field;
+       struct mmiotrace_map *m;
        struct trace_seq *s     = &iter->seq;
-       unsigned long long t    = ns2usecs(entry->t);
+       unsigned long long t    = ns2usecs(iter->ts);
        unsigned long usec_rem  = do_div(t, 1000000ULL);
        unsigned secs           = (unsigned long)t;
-       int ret = 1;
+       int ret;
 
-       switch (entry->mmiorw.opcode) {
+       trace_assign_type(field, entry);
+       m = &field->map;
+
+       switch (m->opcode) {
        case MMIO_PROBE:
                ret = trace_seq_printf(s,
                        "MAP %lu.%06lu %d 0x%llx 0x%lx 0x%lx 0x%lx %d\n",
@@ -241,20 +253,43 @@ static int mmio_print_map(struct trace_iterator *iter)
                break;
        }
        if (ret)
-               return 1;
-       return 0;
+               return TRACE_TYPE_HANDLED;
+       return TRACE_TYPE_PARTIAL_LINE;
+}
+
+static enum print_line_t mmio_print_mark(struct trace_iterator *iter)
+{
+       struct trace_entry *entry = iter->ent;
+       struct print_entry *print = (struct print_entry *)entry;
+       const char *msg         = print->buf;
+       struct trace_seq *s     = &iter->seq;
+       unsigned long long t    = ns2usecs(iter->ts);
+       unsigned long usec_rem  = do_div(t, 1000000ULL);
+       unsigned secs           = (unsigned long)t;
+       int ret;
+
+       /* The trailing newline must be in the message. */
+       ret = trace_seq_printf(s, "MARK %lu.%06lu %s", secs, usec_rem, msg);
+       if (!ret)
+               return TRACE_TYPE_PARTIAL_LINE;
+
+       if (entry->flags & TRACE_FLAG_CONT)
+               trace_seq_print_cont(s, iter);
+
+       return TRACE_TYPE_HANDLED;
 }
 
-/* return 0 to abort printing without consuming current entry in pipe mode */
-static int mmio_print_line(struct trace_iterator *iter)
+static enum print_line_t mmio_print_line(struct trace_iterator *iter)
 {
        switch (iter->ent->type) {
        case TRACE_MMIO_RW:
                return mmio_print_rw(iter);
        case TRACE_MMIO_MAP:
                return mmio_print_map(iter);
+       case TRACE_PRINT:
+               return mmio_print_mark(iter);
        default:
-               return 1; /* ignore unknown entries */
+               return TRACE_TYPE_HANDLED; /* ignore unknown entries */
        }
 }
 
@@ -276,6 +311,27 @@ __init static int init_mmio_trace(void)
 }
 device_initcall(init_mmio_trace);
 
+static void __trace_mmiotrace_rw(struct trace_array *tr,
+                               struct trace_array_cpu *data,
+                               struct mmiotrace_rw *rw)
+{
+       struct ring_buffer_event *event;
+       struct trace_mmiotrace_rw *entry;
+       unsigned long irq_flags;
+
+       event   = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
+                                          &irq_flags);
+       if (!event)
+               return;
+       entry   = ring_buffer_event_data(event);
+       tracing_generic_entry_update(&entry->ent, 0, preempt_count());
+       entry->ent.type                 = TRACE_MMIO_RW;
+       entry->rw                       = *rw;
+       ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+
+       trace_wake_up();
+}
+
 void mmio_trace_rw(struct mmiotrace_rw *rw)
 {
        struct trace_array *tr = mmio_trace_array;
@@ -283,6 +339,27 @@ void mmio_trace_rw(struct mmiotrace_rw *rw)
        __trace_mmiotrace_rw(tr, data, rw);
 }
 
+static void __trace_mmiotrace_map(struct trace_array *tr,
+                               struct trace_array_cpu *data,
+                               struct mmiotrace_map *map)
+{
+       struct ring_buffer_event *event;
+       struct trace_mmiotrace_map *entry;
+       unsigned long irq_flags;
+
+       event   = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
+                                          &irq_flags);
+       if (!event)
+               return;
+       entry   = ring_buffer_event_data(event);
+       tracing_generic_entry_update(&entry->ent, 0, preempt_count());
+       entry->ent.type                 = TRACE_MMIO_MAP;
+       entry->map                      = *map;
+       ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+
+       trace_wake_up();
+}
+
 void mmio_trace_mapping(struct mmiotrace_map *map)
 {
        struct trace_array *tr = mmio_trace_array;
@@ -293,3 +370,8 @@ void mmio_trace_mapping(struct mmiotrace_map *map)
        __trace_mmiotrace_map(tr, data, map);
        preempt_enable();
 }
+
+int mmio_trace_printk(const char *fmt, va_list args)
+{
+       return trace_vprintk(0, fmt, args);
+}
diff --git a/kernel/trace/trace_nop.c b/kernel/trace/trace_nop.c
new file mode 100644 (file)
index 0000000..4592b48
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * nop tracer
+ *
+ * Copyright (C) 2008 Steven Noonan <steven@uplinklabs.net>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <linux/ftrace.h>
+
+#include "trace.h"
+
+static struct trace_array      *ctx_trace;
+
+static void start_nop_trace(struct trace_array *tr)
+{
+       /* Nothing to do! */
+}
+
+static void stop_nop_trace(struct trace_array *tr)
+{
+       /* Nothing to do! */
+}
+
+static void nop_trace_init(struct trace_array *tr)
+{
+       int cpu;
+       ctx_trace = tr;
+
+       for_each_online_cpu(cpu)
+               tracing_reset(tr, cpu);
+
+       if (tr->ctrl)
+               start_nop_trace(tr);
+}
+
+static void nop_trace_reset(struct trace_array *tr)
+{
+       if (tr->ctrl)
+               stop_nop_trace(tr);
+}
+
+static void nop_trace_ctrl_update(struct trace_array *tr)
+{
+       /* When starting a new trace, reset the buffers */
+       if (tr->ctrl)
+               start_nop_trace(tr);
+       else
+               stop_nop_trace(tr);
+}
+
+struct tracer nop_trace __read_mostly =
+{
+       .name           = "nop",
+       .init           = nop_trace_init,
+       .reset          = nop_trace_reset,
+       .ctrl_update    = nop_trace_ctrl_update,
+#ifdef CONFIG_FTRACE_SELFTEST
+       .selftest       = trace_selftest_startup_nop,
+#endif
+};
+
index cb817a209aa005d9b151b79e2ef52b48178dffd4..b8f56beb1a621d5ff527a93aee383f0e02fd30dd 100644 (file)
@@ -9,8 +9,8 @@
 #include <linux/debugfs.h>
 #include <linux/kallsyms.h>
 #include <linux/uaccess.h>
-#include <linux/marker.h>
 #include <linux/ftrace.h>
+#include <trace/sched.h>
 
 #include "trace.h"
 
@@ -19,15 +19,16 @@ static int __read_mostly    tracer_enabled;
 static atomic_t                        sched_ref;
 
 static void
-sched_switch_func(void *private, void *__rq, struct task_struct *prev,
+probe_sched_switch(struct rq *__rq, struct task_struct *prev,
                        struct task_struct *next)
 {
-       struct trace_array **ptr = private;
-       struct trace_array *tr = *ptr;
        struct trace_array_cpu *data;
        unsigned long flags;
-       long disabled;
        int cpu;
+       int pc;
+
+       if (!atomic_read(&sched_ref))
+               return;
 
        tracing_record_cmdline(prev);
        tracing_record_cmdline(next);
@@ -35,97 +36,41 @@ sched_switch_func(void *private, void *__rq, struct task_struct *prev,
        if (!tracer_enabled)
                return;
 
+       pc = preempt_count();
        local_irq_save(flags);
        cpu = raw_smp_processor_id();
-       data = tr->data[cpu];
-       disabled = atomic_inc_return(&data->disabled);
+       data = ctx_trace->data[cpu];
 
-       if (likely(disabled == 1))
-               tracing_sched_switch_trace(tr, data, prev, next, flags);
+       if (likely(!atomic_read(&data->disabled)))
+               tracing_sched_switch_trace(ctx_trace, data, prev, next, flags, pc);
 
-       atomic_dec(&data->disabled);
        local_irq_restore(flags);
 }
 
-static notrace void
-sched_switch_callback(void *probe_data, void *call_data,
-                     const char *format, va_list *args)
-{
-       struct task_struct *prev;
-       struct task_struct *next;
-       struct rq *__rq;
-
-       if (!atomic_read(&sched_ref))
-               return;
-
-       /* skip prev_pid %d next_pid %d prev_state %ld */
-       (void)va_arg(*args, int);
-       (void)va_arg(*args, int);
-       (void)va_arg(*args, long);
-       __rq = va_arg(*args, typeof(__rq));
-       prev = va_arg(*args, typeof(prev));
-       next = va_arg(*args, typeof(next));
-
-       /*
-        * If tracer_switch_func only points to the local
-        * switch func, it still needs the ptr passed to it.
-        */
-       sched_switch_func(probe_data, __rq, prev, next);
-}
-
 static void
-wakeup_func(void *private, void *__rq, struct task_struct *wakee, struct
-                       task_struct *curr)
+probe_sched_wakeup(struct rq *__rq, struct task_struct *wakee)
 {
-       struct trace_array **ptr = private;
-       struct trace_array *tr = *ptr;
        struct trace_array_cpu *data;
        unsigned long flags;
-       long disabled;
-       int cpu;
+       int cpu, pc;
 
-       if (!tracer_enabled)
+       if (!likely(tracer_enabled))
                return;
 
-       tracing_record_cmdline(curr);
+       pc = preempt_count();
+       tracing_record_cmdline(current);
 
        local_irq_save(flags);
        cpu = raw_smp_processor_id();
-       data = tr->data[cpu];
-       disabled = atomic_inc_return(&data->disabled);
+       data = ctx_trace->data[cpu];
 
-       if (likely(disabled == 1))
-               tracing_sched_wakeup_trace(tr, data, wakee, curr, flags);
+       if (likely(!atomic_read(&data->disabled)))
+               tracing_sched_wakeup_trace(ctx_trace, data, wakee, current,
+                                          flags, pc);
 
-       atomic_dec(&data->disabled);
        local_irq_restore(flags);
 }
 
-static notrace void
-wake_up_callback(void *probe_data, void *call_data,
-                const char *format, va_list *args)
-{
-       struct task_struct *curr;
-       struct task_struct *task;
-       struct rq *__rq;
-
-       if (likely(!tracer_enabled))
-               return;
-
-       /* Skip pid %d state %ld */
-       (void)va_arg(*args, int);
-       (void)va_arg(*args, long);
-       /* now get the meat: "rq %p task %p rq->curr %p" */
-       __rq = va_arg(*args, typeof(__rq));
-       task = va_arg(*args, typeof(task));
-       curr = va_arg(*args, typeof(curr));
-
-       tracing_record_cmdline(task);
-       tracing_record_cmdline(curr);
-
-       wakeup_func(probe_data, __rq, task, curr);
-}
-
 static void sched_switch_reset(struct trace_array *tr)
 {
        int cpu;
@@ -133,67 +78,47 @@ static void sched_switch_reset(struct trace_array *tr)
        tr->time_start = ftrace_now(tr->cpu);
 
        for_each_online_cpu(cpu)
-               tracing_reset(tr->data[cpu]);
+               tracing_reset(tr, cpu);
 }
 
 static int tracing_sched_register(void)
 {
        int ret;
 
-       ret = marker_probe_register("kernel_sched_wakeup",
-                       "pid %d state %ld ## rq %p task %p rq->curr %p",
-                       wake_up_callback,
-                       &ctx_trace);
+       ret = register_trace_sched_wakeup(probe_sched_wakeup);
        if (ret) {
-               pr_info("wakeup trace: Couldn't add marker"
+               pr_info("wakeup trace: Couldn't activate tracepoint"
                        " probe to kernel_sched_wakeup\n");
                return ret;
        }
 
-       ret = marker_probe_register("kernel_sched_wakeup_new",
-                       "pid %d state %ld ## rq %p task %p rq->curr %p",
-                       wake_up_callback,
-                       &ctx_trace);
+       ret = register_trace_sched_wakeup_new(probe_sched_wakeup);
        if (ret) {
-               pr_info("wakeup trace: Couldn't add marker"
+               pr_info("wakeup trace: Couldn't activate tracepoint"
                        " probe to kernel_sched_wakeup_new\n");
                goto fail_deprobe;
        }
 
-       ret = marker_probe_register("kernel_sched_schedule",
-               "prev_pid %d next_pid %d prev_state %ld "
-               "## rq %p prev %p next %p",
-               sched_switch_callback,
-               &ctx_trace);
+       ret = register_trace_sched_switch(probe_sched_switch);
        if (ret) {
-               pr_info("sched trace: Couldn't add marker"
+               pr_info("sched trace: Couldn't activate tracepoint"
                        " probe to kernel_sched_schedule\n");
                goto fail_deprobe_wake_new;
        }
 
        return ret;
 fail_deprobe_wake_new:
-       marker_probe_unregister("kernel_sched_wakeup_new",
-                               wake_up_callback,
-                               &ctx_trace);
+       unregister_trace_sched_wakeup_new(probe_sched_wakeup);
 fail_deprobe:
-       marker_probe_unregister("kernel_sched_wakeup",
-                               wake_up_callback,
-                               &ctx_trace);
+       unregister_trace_sched_wakeup(probe_sched_wakeup);
        return ret;
 }
 
 static void tracing_sched_unregister(void)
 {
-       marker_probe_unregister("kernel_sched_schedule",
-                               sched_switch_callback,
-                               &ctx_trace);
-       marker_probe_unregister("kernel_sched_wakeup_new",
-                               wake_up_callback,
-                               &ctx_trace);
-       marker_probe_unregister("kernel_sched_wakeup",
-                               wake_up_callback,
-                               &ctx_trace);
+       unregister_trace_sched_switch(probe_sched_switch);
+       unregister_trace_sched_wakeup_new(probe_sched_wakeup);
+       unregister_trace_sched_wakeup(probe_sched_wakeup);
 }
 
 static void tracing_start_sched_switch(void)
index e303ccb62cdfb1284847864821d63a72694ca6af..fe4a252c236384bb1ac5eff3ac441522d90ce0d4 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/kallsyms.h>
 #include <linux/uaccess.h>
 #include <linux/ftrace.h>
-#include <linux/marker.h>
+#include <trace/sched.h>
 
 #include "trace.h"
 
@@ -44,10 +44,12 @@ wakeup_tracer_call(unsigned long ip, unsigned long parent_ip)
        long disabled;
        int resched;
        int cpu;
+       int pc;
 
        if (likely(!wakeup_task))
                return;
 
+       pc = preempt_count();
        resched = need_resched();
        preempt_disable_notrace();
 
@@ -70,7 +72,7 @@ wakeup_tracer_call(unsigned long ip, unsigned long parent_ip)
        if (task_cpu(wakeup_task) != cpu)
                goto unlock;
 
-       trace_function(tr, data, ip, parent_ip, flags);
+       trace_function(tr, data, ip, parent_ip, flags, pc);
 
  unlock:
        __raw_spin_unlock(&wakeup_lock);
@@ -112,17 +114,18 @@ static int report_latency(cycle_t delta)
 }
 
 static void notrace
-wakeup_sched_switch(void *private, void *rq, struct task_struct *prev,
+probe_wakeup_sched_switch(struct rq *rq, struct task_struct *prev,
        struct task_struct *next)
 {
        unsigned long latency = 0, t0 = 0, t1 = 0;
-       struct trace_array **ptr = private;
-       struct trace_array *tr = *ptr;
        struct trace_array_cpu *data;
        cycle_t T0, T1, delta;
        unsigned long flags;
        long disabled;
        int cpu;
+       int pc;
+
+       tracing_record_cmdline(prev);
 
        if (unlikely(!tracer_enabled))
                return;
@@ -139,12 +142,14 @@ wakeup_sched_switch(void *private, void *rq, struct task_struct *prev,
        if (next != wakeup_task)
                return;
 
+       pc = preempt_count();
+
        /* The task we are waiting for is waking up */
-       data = tr->data[wakeup_cpu];
+       data = wakeup_trace->data[wakeup_cpu];
 
        /* disable local data, not wakeup_cpu data */
        cpu = raw_smp_processor_id();
-       disabled = atomic_inc_return(&tr->data[cpu]->disabled);
+       disabled = atomic_inc_return(&wakeup_trace->data[cpu]->disabled);
        if (likely(disabled != 1))
                goto out;
 
@@ -155,7 +160,7 @@ wakeup_sched_switch(void *private, void *rq, struct task_struct *prev,
        if (unlikely(!tracer_enabled || next != wakeup_task))
                goto out_unlock;
 
-       trace_function(tr, data, CALLER_ADDR1, CALLER_ADDR2, flags);
+       trace_function(wakeup_trace, data, CALLER_ADDR1, CALLER_ADDR2, flags, pc);
 
        /*
         * usecs conversion is slow so we try to delay the conversion
@@ -174,39 +179,14 @@ wakeup_sched_switch(void *private, void *rq, struct task_struct *prev,
        t0 = nsecs_to_usecs(T0);
        t1 = nsecs_to_usecs(T1);
 
-       update_max_tr(tr, wakeup_task, wakeup_cpu);
+       update_max_tr(wakeup_trace, wakeup_task, wakeup_cpu);
 
 out_unlock:
-       __wakeup_reset(tr);
+       __wakeup_reset(wakeup_trace);
        __raw_spin_unlock(&wakeup_lock);
        local_irq_restore(flags);
 out:
-       atomic_dec(&tr->data[cpu]->disabled);
-}
-
-static notrace void
-sched_switch_callback(void *probe_data, void *call_data,
-                     const char *format, va_list *args)
-{
-       struct task_struct *prev;
-       struct task_struct *next;
-       struct rq *__rq;
-
-       /* skip prev_pid %d next_pid %d prev_state %ld */
-       (void)va_arg(*args, int);
-       (void)va_arg(*args, int);
-       (void)va_arg(*args, long);
-       __rq = va_arg(*args, typeof(__rq));
-       prev = va_arg(*args, typeof(prev));
-       next = va_arg(*args, typeof(next));
-
-       tracing_record_cmdline(prev);
-
-       /*
-        * If tracer_switch_func only points to the local
-        * switch func, it still needs the ptr passed to it.
-        */
-       wakeup_sched_switch(probe_data, __rq, prev, next);
+       atomic_dec(&wakeup_trace->data[cpu]->disabled);
 }
 
 static void __wakeup_reset(struct trace_array *tr)
@@ -216,7 +196,7 @@ static void __wakeup_reset(struct trace_array *tr)
 
        for_each_possible_cpu(cpu) {
                data = tr->data[cpu];
-               tracing_reset(data);
+               tracing_reset(tr, cpu);
        }
 
        wakeup_cpu = -1;
@@ -240,19 +220,26 @@ static void wakeup_reset(struct trace_array *tr)
 }
 
 static void
-wakeup_check_start(struct trace_array *tr, struct task_struct *p,
-                  struct task_struct *curr)
+probe_wakeup(struct rq *rq, struct task_struct *p)
 {
        int cpu = smp_processor_id();
        unsigned long flags;
        long disabled;
+       int pc;
+
+       if (likely(!tracer_enabled))
+               return;
+
+       tracing_record_cmdline(p);
+       tracing_record_cmdline(current);
 
        if (likely(!rt_task(p)) ||
                        p->prio >= wakeup_prio ||
-                       p->prio >= curr->prio)
+                       p->prio >= current->prio)
                return;
 
-       disabled = atomic_inc_return(&tr->data[cpu]->disabled);
+       pc = preempt_count();
+       disabled = atomic_inc_return(&wakeup_trace->data[cpu]->disabled);
        if (unlikely(disabled != 1))
                goto out;
 
@@ -264,7 +251,7 @@ wakeup_check_start(struct trace_array *tr, struct task_struct *p,
                goto out_locked;
 
        /* reset the trace */
-       __wakeup_reset(tr);
+       __wakeup_reset(wakeup_trace);
 
        wakeup_cpu = task_cpu(p);
        wakeup_prio = p->prio;
@@ -274,74 +261,37 @@ wakeup_check_start(struct trace_array *tr, struct task_struct *p,
 
        local_save_flags(flags);
 
-       tr->data[wakeup_cpu]->preempt_timestamp = ftrace_now(cpu);
-       trace_function(tr, tr->data[wakeup_cpu],
-                      CALLER_ADDR1, CALLER_ADDR2, flags);
+       wakeup_trace->data[wakeup_cpu]->preempt_timestamp = ftrace_now(cpu);
+       trace_function(wakeup_trace, wakeup_trace->data[wakeup_cpu],
+                      CALLER_ADDR1, CALLER_ADDR2, flags, pc);
 
 out_locked:
        __raw_spin_unlock(&wakeup_lock);
 out:
-       atomic_dec(&tr->data[cpu]->disabled);
-}
-
-static notrace void
-wake_up_callback(void *probe_data, void *call_data,
-                const char *format, va_list *args)
-{
-       struct trace_array **ptr = probe_data;
-       struct trace_array *tr = *ptr;
-       struct task_struct *curr;
-       struct task_struct *task;
-       struct rq *__rq;
-
-       if (likely(!tracer_enabled))
-               return;
-
-       /* Skip pid %d state %ld */
-       (void)va_arg(*args, int);
-       (void)va_arg(*args, long);
-       /* now get the meat: "rq %p task %p rq->curr %p" */
-       __rq = va_arg(*args, typeof(__rq));
-       task = va_arg(*args, typeof(task));
-       curr = va_arg(*args, typeof(curr));
-
-       tracing_record_cmdline(task);
-       tracing_record_cmdline(curr);
-
-       wakeup_check_start(tr, task, curr);
+       atomic_dec(&wakeup_trace->data[cpu]->disabled);
 }
 
 static void start_wakeup_tracer(struct trace_array *tr)
 {
        int ret;
 
-       ret = marker_probe_register("kernel_sched_wakeup",
-                       "pid %d state %ld ## rq %p task %p rq->curr %p",
-                       wake_up_callback,
-                       &wakeup_trace);
+       ret = register_trace_sched_wakeup(probe_wakeup);
        if (ret) {
-               pr_info("wakeup trace: Couldn't add marker"
+               pr_info("wakeup trace: Couldn't activate tracepoint"
                        " probe to kernel_sched_wakeup\n");
                return;
        }
 
-       ret = marker_probe_register("kernel_sched_wakeup_new",
-                       "pid %d state %ld ## rq %p task %p rq->curr %p",
-                       wake_up_callback,
-                       &wakeup_trace);
+       ret = register_trace_sched_wakeup_new(probe_wakeup);
        if (ret) {
-               pr_info("wakeup trace: Couldn't add marker"
+               pr_info("wakeup trace: Couldn't activate tracepoint"
                        " probe to kernel_sched_wakeup_new\n");
                goto fail_deprobe;
        }
 
-       ret = marker_probe_register("kernel_sched_schedule",
-               "prev_pid %d next_pid %d prev_state %ld "
-               "## rq %p prev %p next %p",
-               sched_switch_callback,
-               &wakeup_trace);
+       ret = register_trace_sched_switch(probe_wakeup_sched_switch);
        if (ret) {
-               pr_info("sched trace: Couldn't add marker"
+               pr_info("sched trace: Couldn't activate tracepoint"
                        " probe to kernel_sched_schedule\n");
                goto fail_deprobe_wake_new;
        }
@@ -363,28 +313,18 @@ static void start_wakeup_tracer(struct trace_array *tr)
 
        return;
 fail_deprobe_wake_new:
-       marker_probe_unregister("kernel_sched_wakeup_new",
-                               wake_up_callback,
-                               &wakeup_trace);
+       unregister_trace_sched_wakeup_new(probe_wakeup);
 fail_deprobe:
-       marker_probe_unregister("kernel_sched_wakeup",
-                               wake_up_callback,
-                               &wakeup_trace);
+       unregister_trace_sched_wakeup(probe_wakeup);
 }
 
 static void stop_wakeup_tracer(struct trace_array *tr)
 {
        tracer_enabled = 0;
        unregister_ftrace_function(&trace_ops);
-       marker_probe_unregister("kernel_sched_schedule",
-                               sched_switch_callback,
-                               &wakeup_trace);
-       marker_probe_unregister("kernel_sched_wakeup_new",
-                               wake_up_callback,
-                               &wakeup_trace);
-       marker_probe_unregister("kernel_sched_wakeup",
-                               wake_up_callback,
-                               &wakeup_trace);
+       unregister_trace_sched_switch(probe_wakeup_sched_switch);
+       unregister_trace_sched_wakeup_new(probe_wakeup);
+       unregister_trace_sched_wakeup(probe_wakeup);
 }
 
 static void wakeup_tracer_init(struct trace_array *tr)
index 0911b7e073bf197b021ba77c75f6777a03910aa7..09cf230d7ecae8ecd25d5f24dee21c4e2fd7b41d 100644 (file)
@@ -9,65 +9,29 @@ static inline int trace_valid_entry(struct trace_entry *entry)
        case TRACE_FN:
        case TRACE_CTX:
        case TRACE_WAKE:
+       case TRACE_CONT:
        case TRACE_STACK:
+       case TRACE_PRINT:
        case TRACE_SPECIAL:
                return 1;
        }
        return 0;
 }
 
-static int
-trace_test_buffer_cpu(struct trace_array *tr, struct trace_array_cpu *data)
+static int trace_test_buffer_cpu(struct trace_array *tr, int cpu)
 {
-       struct trace_entry *entries;
-       struct page *page;
-       int idx = 0;
-       int i;
+       struct ring_buffer_event *event;
+       struct trace_entry *entry;
 
-       BUG_ON(list_empty(&data->trace_pages));
-       page = list_entry(data->trace_pages.next, struct page, lru);
-       entries = page_address(page);
+       while ((event = ring_buffer_consume(tr->buffer, cpu, NULL))) {
+               entry = ring_buffer_event_data(event);
 
-       check_pages(data);
-       if (head_page(data) != entries)
-               goto failed;
-
-       /*
-        * The starting trace buffer always has valid elements,
-        * if any element exists.
-        */
-       entries = head_page(data);
-
-       for (i = 0; i < tr->entries; i++) {
-
-               if (i < data->trace_idx && !trace_valid_entry(&entries[idx])) {
+               if (!trace_valid_entry(entry)) {
                        printk(KERN_CONT ".. invalid entry %d ",
-                               entries[idx].type);
+                               entry->type);
                        goto failed;
                }
-
-               idx++;
-               if (idx >= ENTRIES_PER_PAGE) {
-                       page = virt_to_page(entries);
-                       if (page->lru.next == &data->trace_pages) {
-                               if (i != tr->entries - 1) {
-                                       printk(KERN_CONT ".. entries buffer mismatch");
-                                       goto failed;
-                               }
-                       } else {
-                               page = list_entry(page->lru.next, struct page, lru);
-                               entries = page_address(page);
-                       }
-                       idx = 0;
-               }
        }
-
-       page = virt_to_page(entries);
-       if (page->lru.next != &data->trace_pages) {
-               printk(KERN_CONT ".. too many entries");
-               goto failed;
-       }
-
        return 0;
 
  failed:
@@ -89,13 +53,11 @@ static int trace_test_buffer(struct trace_array *tr, unsigned long *count)
        /* Don't allow flipping of max traces now */
        raw_local_irq_save(flags);
        __raw_spin_lock(&ftrace_max_lock);
-       for_each_possible_cpu(cpu) {
-               if (!head_page(tr->data[cpu]))
-                       continue;
 
-               cnt += tr->data[cpu]->trace_idx;
+       cnt = ring_buffer_entries(tr->buffer);
 
-               ret = trace_test_buffer_cpu(tr, tr->data[cpu]);
+       for_each_possible_cpu(cpu) {
+               ret = trace_test_buffer_cpu(tr, cpu);
                if (ret)
                        break;
        }
@@ -120,11 +82,11 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
                                           struct trace_array *tr,
                                           int (*func)(void))
 {
-       unsigned long count;
-       int ret;
        int save_ftrace_enabled = ftrace_enabled;
        int save_tracer_enabled = tracer_enabled;
+       unsigned long count;
        char *func_name;
+       int ret;
 
        /* The ftrace test PASSED */
        printk(KERN_CONT "PASSED\n");
@@ -157,6 +119,7 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
        /* enable tracing */
        tr->ctrl = 1;
        trace->init(tr);
+
        /* Sleep for a 1/10 of a second */
        msleep(100);
 
@@ -212,10 +175,10 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
 int
 trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr)
 {
-       unsigned long count;
-       int ret;
        int save_ftrace_enabled = ftrace_enabled;
        int save_tracer_enabled = tracer_enabled;
+       unsigned long count;
+       int ret;
 
        /* make sure msleep has been recorded */
        msleep(1);
@@ -415,6 +378,15 @@ trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array *
 }
 #endif /* CONFIG_IRQSOFF_TRACER && CONFIG_PREEMPT_TRACER */
 
+#ifdef CONFIG_NOP_TRACER
+int
+trace_selftest_startup_nop(struct tracer *trace, struct trace_array *tr)
+{
+       /* What could possibly go wrong? */
+       return 0;
+}
+#endif
+
 #ifdef CONFIG_SCHED_TRACER
 static int trace_wakeup_test_thread(void *data)
 {
@@ -486,6 +458,9 @@ trace_selftest_startup_wakeup(struct tracer *trace, struct trace_array *tr)
 
        wake_up_process(p);
 
+       /* give a little time to let the thread wake up */
+       msleep(100);
+
        /* stop the tracing. */
        tr->ctrl = 0;
        trace->ctrl_update(tr);
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
new file mode 100644 (file)
index 0000000..74c5d9a
--- /dev/null
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2008 Steven Rostedt <srostedt@redhat.com>
+ *
+ */
+#include <linux/stacktrace.h>
+#include <linux/kallsyms.h>
+#include <linux/seq_file.h>
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
+#include <linux/debugfs.h>
+#include <linux/ftrace.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include "trace.h"
+
+#define STACK_TRACE_ENTRIES 500
+
+static unsigned long stack_dump_trace[STACK_TRACE_ENTRIES+1] =
+        { [0 ... (STACK_TRACE_ENTRIES)] = ULONG_MAX };
+static unsigned stack_dump_index[STACK_TRACE_ENTRIES];
+
+static struct stack_trace max_stack_trace = {
+       .max_entries            = STACK_TRACE_ENTRIES,
+       .entries                = stack_dump_trace,
+};
+
+static unsigned long max_stack_size;
+static raw_spinlock_t max_stack_lock =
+       (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
+
+static int stack_trace_disabled __read_mostly;
+static DEFINE_PER_CPU(int, trace_active);
+
+static inline void check_stack(void)
+{
+       unsigned long this_size, flags;
+       unsigned long *p, *top, *start;
+       int i;
+
+       this_size = ((unsigned long)&this_size) & (THREAD_SIZE-1);
+       this_size = THREAD_SIZE - this_size;
+
+       if (this_size <= max_stack_size)
+               return;
+
+       raw_local_irq_save(flags);
+       __raw_spin_lock(&max_stack_lock);
+
+       /* a race could have already updated it */
+       if (this_size <= max_stack_size)
+               goto out;
+
+       max_stack_size = this_size;
+
+       max_stack_trace.nr_entries      = 0;
+       max_stack_trace.skip            = 3;
+
+       save_stack_trace(&max_stack_trace);
+
+       /*
+        * Now find where in the stack these are.
+        */
+       i = 0;
+       start = &this_size;
+       top = (unsigned long *)
+               (((unsigned long)start & ~(THREAD_SIZE-1)) + THREAD_SIZE);
+
+       /*
+        * Loop through all the entries. One of the entries may
+        * for some reason be missed on the stack, so we may
+        * have to account for them. If they are all there, this
+        * loop will only happen once. This code only takes place
+        * on a new max, so it is far from a fast path.
+        */
+       while (i < max_stack_trace.nr_entries) {
+
+               stack_dump_index[i] = this_size;
+               p = start;
+
+               for (; p < top && i < max_stack_trace.nr_entries; p++) {
+                       if (*p == stack_dump_trace[i]) {
+                               this_size = stack_dump_index[i++] =
+                                       (top - p) * sizeof(unsigned long);
+                               /* Start the search from here */
+                               start = p + 1;
+                       }
+               }
+
+               i++;
+       }
+
+ out:
+       __raw_spin_unlock(&max_stack_lock);
+       raw_local_irq_restore(flags);
+}
+
+static void
+stack_trace_call(unsigned long ip, unsigned long parent_ip)
+{
+       int cpu, resched;
+
+       if (unlikely(!ftrace_enabled || stack_trace_disabled))
+               return;
+
+       resched = need_resched();
+       preempt_disable_notrace();
+
+       cpu = raw_smp_processor_id();
+       /* no atomic needed, we only modify this variable by this cpu */
+       if (per_cpu(trace_active, cpu)++ != 0)
+               goto out;
+
+       check_stack();
+
+ out:
+       per_cpu(trace_active, cpu)--;
+       /* prevent recursion in schedule */
+       if (resched)
+               preempt_enable_no_resched_notrace();
+       else
+               preempt_enable_notrace();
+}
+
+static struct ftrace_ops trace_ops __read_mostly =
+{
+       .func = stack_trace_call,
+};
+
+static ssize_t
+stack_max_size_read(struct file *filp, char __user *ubuf,
+                   size_t count, loff_t *ppos)
+{
+       unsigned long *ptr = filp->private_data;
+       char buf[64];
+       int r;
+
+       r = snprintf(buf, sizeof(buf), "%ld\n", *ptr);
+       if (r > sizeof(buf))
+               r = sizeof(buf);
+       return simple_read_from_buffer(ubuf, count, ppos, buf, r);
+}
+
+static ssize_t
+stack_max_size_write(struct file *filp, const char __user *ubuf,
+                    size_t count, loff_t *ppos)
+{
+       long *ptr = filp->private_data;
+       unsigned long val, flags;
+       char buf[64];
+       int ret;
+
+       if (count >= sizeof(buf))
+               return -EINVAL;
+
+       if (copy_from_user(&buf, ubuf, count))
+               return -EFAULT;
+
+       buf[count] = 0;
+
+       ret = strict_strtoul(buf, 10, &val);
+       if (ret < 0)
+               return ret;
+
+       raw_local_irq_save(flags);
+       __raw_spin_lock(&max_stack_lock);
+       *ptr = val;
+       __raw_spin_unlock(&max_stack_lock);
+       raw_local_irq_restore(flags);
+
+       return count;
+}
+
+static struct file_operations stack_max_size_fops = {
+       .open           = tracing_open_generic,
+       .read           = stack_max_size_read,
+       .write          = stack_max_size_write,
+};
+
+static void *
+t_next(struct seq_file *m, void *v, loff_t *pos)
+{
+       long i = (long)m->private;
+
+       (*pos)++;
+
+       i++;
+
+       if (i >= max_stack_trace.nr_entries ||
+           stack_dump_trace[i] == ULONG_MAX)
+               return NULL;
+
+       m->private = (void *)i;
+
+       return &m->private;
+}
+
+static void *t_start(struct seq_file *m, loff_t *pos)
+{
+       void *t = &m->private;
+       loff_t l = 0;
+
+       local_irq_disable();
+       __raw_spin_lock(&max_stack_lock);
+
+       for (; t && l < *pos; t = t_next(m, t, &l))
+               ;
+
+       return t;
+}
+
+static void t_stop(struct seq_file *m, void *p)
+{
+       __raw_spin_unlock(&max_stack_lock);
+       local_irq_enable();
+}
+
+static int trace_lookup_stack(struct seq_file *m, long i)
+{
+       unsigned long addr = stack_dump_trace[i];
+#ifdef CONFIG_KALLSYMS
+       char str[KSYM_SYMBOL_LEN];
+
+       sprint_symbol(str, addr);
+
+       return seq_printf(m, "%s\n", str);
+#else
+       return seq_printf(m, "%p\n", (void*)addr);
+#endif
+}
+
+static int t_show(struct seq_file *m, void *v)
+{
+       long i = *(long *)v;
+       int size;
+
+       if (i < 0) {
+               seq_printf(m, "        Depth   Size      Location"
+                          "    (%d entries)\n"
+                          "        -----   ----      --------\n",
+                          max_stack_trace.nr_entries);
+               return 0;
+       }
+
+       if (i >= max_stack_trace.nr_entries ||
+           stack_dump_trace[i] == ULONG_MAX)
+               return 0;
+
+       if (i+1 == max_stack_trace.nr_entries ||
+           stack_dump_trace[i+1] == ULONG_MAX)
+               size = stack_dump_index[i];
+       else
+               size = stack_dump_index[i] - stack_dump_index[i+1];
+
+       seq_printf(m, "%3ld) %8d   %5d   ", i, stack_dump_index[i], size);
+
+       trace_lookup_stack(m, i);
+
+       return 0;
+}
+
+static struct seq_operations stack_trace_seq_ops = {
+       .start          = t_start,
+       .next           = t_next,
+       .stop           = t_stop,
+       .show           = t_show,
+};
+
+static int stack_trace_open(struct inode *inode, struct file *file)
+{
+       int ret;
+
+       ret = seq_open(file, &stack_trace_seq_ops);
+       if (!ret) {
+               struct seq_file *m = file->private_data;
+               m->private = (void *)-1;
+       }
+
+       return ret;
+}
+
+static struct file_operations stack_trace_fops = {
+       .open           = stack_trace_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+};
+
+static __init int stack_trace_init(void)
+{
+       struct dentry *d_tracer;
+       struct dentry *entry;
+
+       d_tracer = tracing_init_dentry();
+
+       entry = debugfs_create_file("stack_max_size", 0644, d_tracer,
+                                   &max_stack_size, &stack_max_size_fops);
+       if (!entry)
+               pr_warning("Could not create debugfs 'stack_max_size' entry\n");
+
+       entry = debugfs_create_file("stack_trace", 0444, d_tracer,
+                                   NULL, &stack_trace_fops);
+       if (!entry)
+               pr_warning("Could not create debugfs 'stack_trace' entry\n");
+
+       register_ftrace_function(&trace_ops);
+
+       return 0;
+}
+
+device_initcall(stack_trace_init);
index db58fb66a135bbbbc71b16f949bcbf47300fbb4c..9587d3bcba556761de49854c95676a03a6dcecbf 100644 (file)
@@ -241,7 +241,7 @@ static void stack_reset(struct trace_array *tr)
        tr->time_start = ftrace_now(tr->cpu);
 
        for_each_online_cpu(cpu)
-               tracing_reset(tr->data[cpu]);
+               tracing_reset(tr, cpu);
 }
 
 static void start_stack_trace(struct trace_array *tr)
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
new file mode 100644 (file)
index 0000000..f2b7c28
--- /dev/null
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) 2008 Mathieu Desnoyers
+ *
+ * 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/mutex.h>
+#include <linux/types.h>
+#include <linux/jhash.h>
+#include <linux/list.h>
+#include <linux/rcupdate.h>
+#include <linux/tracepoint.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+extern struct tracepoint __start___tracepoints[];
+extern struct tracepoint __stop___tracepoints[];
+
+/* Set to 1 to enable tracepoint debug output */
+static const int tracepoint_debug;
+
+/*
+ * tracepoints_mutex nests inside module_mutex. Tracepoints mutex protects the
+ * builtin and module tracepoints and the hash table.
+ */
+static DEFINE_MUTEX(tracepoints_mutex);
+
+/*
+ * Tracepoint hash table, containing the active tracepoints.
+ * Protected by tracepoints_mutex.
+ */
+#define TRACEPOINT_HASH_BITS 6
+#define TRACEPOINT_TABLE_SIZE (1 << TRACEPOINT_HASH_BITS)
+
+/*
+ * Note about RCU :
+ * It is used to to delay the free of multiple probes array until a quiescent
+ * state is reached.
+ * Tracepoint entries modifications are protected by the tracepoints_mutex.
+ */
+struct tracepoint_entry {
+       struct hlist_node hlist;
+       void **funcs;
+       int refcount;   /* Number of times armed. 0 if disarmed. */
+       struct rcu_head rcu;
+       void *oldptr;
+       unsigned char rcu_pending:1;
+       char name[0];
+};
+
+static struct hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE];
+
+static void free_old_closure(struct rcu_head *head)
+{
+       struct tracepoint_entry *entry = container_of(head,
+               struct tracepoint_entry, rcu);
+       kfree(entry->oldptr);
+       /* Make sure we free the data before setting the pending flag to 0 */
+       smp_wmb();
+       entry->rcu_pending = 0;
+}
+
+static void tracepoint_entry_free_old(struct tracepoint_entry *entry, void *old)
+{
+       if (!old)
+               return;
+       entry->oldptr = old;
+       entry->rcu_pending = 1;
+       /* write rcu_pending before calling the RCU callback */
+       smp_wmb();
+       call_rcu_sched(&entry->rcu, free_old_closure);
+}
+
+static void debug_print_probes(struct tracepoint_entry *entry)
+{
+       int i;
+
+       if (!tracepoint_debug)
+               return;
+
+       for (i = 0; entry->funcs[i]; i++)
+               printk(KERN_DEBUG "Probe %d : %p\n", i, entry->funcs[i]);
+}
+
+static void *
+tracepoint_entry_add_probe(struct tracepoint_entry *entry, void *probe)
+{
+       int nr_probes = 0;
+       void **old, **new;
+
+       WARN_ON(!probe);
+
+       debug_print_probes(entry);
+       old = entry->funcs;
+       if (old) {
+               /* (N -> N+1), (N != 0, 1) probes */
+               for (nr_probes = 0; old[nr_probes]; nr_probes++)
+                       if (old[nr_probes] == probe)
+                               return ERR_PTR(-EEXIST);
+       }
+       /* + 2 : one for new probe, one for NULL func */
+       new = kzalloc((nr_probes + 2) * sizeof(void *), GFP_KERNEL);
+       if (new == NULL)
+               return ERR_PTR(-ENOMEM);
+       if (old)
+               memcpy(new, old, nr_probes * sizeof(void *));
+       new[nr_probes] = probe;
+       entry->refcount = nr_probes + 1;
+       entry->funcs = new;
+       debug_print_probes(entry);
+       return old;
+}
+
+static void *
+tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe)
+{
+       int nr_probes = 0, nr_del = 0, i;
+       void **old, **new;
+
+       old = entry->funcs;
+
+       debug_print_probes(entry);
+       /* (N -> M), (N > 1, M >= 0) probes */
+       for (nr_probes = 0; old[nr_probes]; nr_probes++) {
+               if ((!probe || old[nr_probes] == probe))
+                       nr_del++;
+       }
+
+       if (nr_probes - nr_del == 0) {
+               /* N -> 0, (N > 1) */
+               entry->funcs = NULL;
+               entry->refcount = 0;
+               debug_print_probes(entry);
+               return old;
+       } else {
+               int j = 0;
+               /* N -> M, (N > 1, M > 0) */
+               /* + 1 for NULL */
+               new = kzalloc((nr_probes - nr_del + 1)
+                       * sizeof(void *), GFP_KERNEL);
+               if (new == NULL)
+                       return ERR_PTR(-ENOMEM);
+               for (i = 0; old[i]; i++)
+                       if ((probe && old[i] != probe))
+                               new[j++] = old[i];
+               entry->refcount = nr_probes - nr_del;
+               entry->funcs = new;
+       }
+       debug_print_probes(entry);
+       return old;
+}
+
+/*
+ * Get tracepoint if the tracepoint is present in the tracepoint hash table.
+ * Must be called with tracepoints_mutex held.
+ * Returns NULL if not present.
+ */
+static struct tracepoint_entry *get_tracepoint(const char *name)
+{
+       struct hlist_head *head;
+       struct hlist_node *node;
+       struct tracepoint_entry *e;
+       u32 hash = jhash(name, strlen(name), 0);
+
+       head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
+       hlist_for_each_entry(e, node, head, hlist) {
+               if (!strcmp(name, e->name))
+                       return e;
+       }
+       return NULL;
+}
+
+/*
+ * Add the tracepoint to the tracepoint hash table. Must be called with
+ * tracepoints_mutex held.
+ */
+static struct tracepoint_entry *add_tracepoint(const char *name)
+{
+       struct hlist_head *head;
+       struct hlist_node *node;
+       struct tracepoint_entry *e;
+       size_t name_len = strlen(name) + 1;
+       u32 hash = jhash(name, name_len-1, 0);
+
+       head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
+       hlist_for_each_entry(e, node, head, hlist) {
+               if (!strcmp(name, e->name)) {
+                       printk(KERN_NOTICE
+                               "tracepoint %s busy\n", name);
+                       return ERR_PTR(-EEXIST);        /* Already there */
+               }
+       }
+       /*
+        * Using kmalloc here to allocate a variable length element. Could
+        * cause some memory fragmentation if overused.
+        */
+       e = kmalloc(sizeof(struct tracepoint_entry) + name_len, GFP_KERNEL);
+       if (!e)
+               return ERR_PTR(-ENOMEM);
+       memcpy(&e->name[0], name, name_len);
+       e->funcs = NULL;
+       e->refcount = 0;
+       e->rcu_pending = 0;
+       hlist_add_head(&e->hlist, head);
+       return e;
+}
+
+/*
+ * Remove the tracepoint from the tracepoint hash table. Must be called with
+ * mutex_lock held.
+ */
+static int remove_tracepoint(const char *name)
+{
+       struct hlist_head *head;
+       struct hlist_node *node;
+       struct tracepoint_entry *e;
+       int found = 0;
+       size_t len = strlen(name) + 1;
+       u32 hash = jhash(name, len-1, 0);
+
+       head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
+       hlist_for_each_entry(e, node, head, hlist) {
+               if (!strcmp(name, e->name)) {
+                       found = 1;
+                       break;
+               }
+       }
+       if (!found)
+               return -ENOENT;
+       if (e->refcount)
+               return -EBUSY;
+       hlist_del(&e->hlist);
+       /* Make sure the call_rcu_sched has been executed */
+       if (e->rcu_pending)
+               rcu_barrier_sched();
+       kfree(e);
+       return 0;
+}
+
+/*
+ * Sets the probe callback corresponding to one tracepoint.
+ */
+static void set_tracepoint(struct tracepoint_entry **entry,
+       struct tracepoint *elem, int active)
+{
+       WARN_ON(strcmp((*entry)->name, elem->name) != 0);
+
+       /*
+        * rcu_assign_pointer has a smp_wmb() which makes sure that the new
+        * probe callbacks array is consistent before setting a pointer to it.
+        * This array is referenced by __DO_TRACE from
+        * include/linux/tracepoints.h. A matching smp_read_barrier_depends()
+        * is used.
+        */
+       rcu_assign_pointer(elem->funcs, (*entry)->funcs);
+       elem->state = active;
+}
+
+/*
+ * Disable a tracepoint and its probe callback.
+ * Note: only waiting an RCU period after setting elem->call to the empty
+ * function insures that the original callback is not used anymore. This insured
+ * by preempt_disable around the call site.
+ */
+static void disable_tracepoint(struct tracepoint *elem)
+{
+       elem->state = 0;
+}
+
+/**
+ * tracepoint_update_probe_range - Update a probe range
+ * @begin: beginning of the range
+ * @end: end of the range
+ *
+ * Updates the probe callback corresponding to a range of tracepoints.
+ */
+void tracepoint_update_probe_range(struct tracepoint *begin,
+       struct tracepoint *end)
+{
+       struct tracepoint *iter;
+       struct tracepoint_entry *mark_entry;
+
+       mutex_lock(&tracepoints_mutex);
+       for (iter = begin; iter < end; iter++) {
+               mark_entry = get_tracepoint(iter->name);
+               if (mark_entry) {
+                       set_tracepoint(&mark_entry, iter,
+                                       !!mark_entry->refcount);
+               } else {
+                       disable_tracepoint(iter);
+               }
+       }
+       mutex_unlock(&tracepoints_mutex);
+}
+
+/*
+ * Update probes, removing the faulty probes.
+ */
+static void tracepoint_update_probes(void)
+{
+       /* Core kernel tracepoints */
+       tracepoint_update_probe_range(__start___tracepoints,
+               __stop___tracepoints);
+       /* tracepoints in modules. */
+       module_update_tracepoints();
+}
+
+/**
+ * tracepoint_probe_register -  Connect a probe to a tracepoint
+ * @name: tracepoint name
+ * @probe: probe handler
+ *
+ * Returns 0 if ok, error value on error.
+ * The probe address must at least be aligned on the architecture pointer size.
+ */
+int tracepoint_probe_register(const char *name, void *probe)
+{
+       struct tracepoint_entry *entry;
+       int ret = 0;
+       void *old;
+
+       mutex_lock(&tracepoints_mutex);
+       entry = get_tracepoint(name);
+       if (!entry) {
+               entry = add_tracepoint(name);
+               if (IS_ERR(entry)) {
+                       ret = PTR_ERR(entry);
+                       goto end;
+               }
+       }
+       /*
+        * If we detect that a call_rcu_sched is pending for this tracepoint,
+        * make sure it's executed now.
+        */
+       if (entry->rcu_pending)
+               rcu_barrier_sched();
+       old = tracepoint_entry_add_probe(entry, probe);
+       if (IS_ERR(old)) {
+               ret = PTR_ERR(old);
+               goto end;
+       }
+       mutex_unlock(&tracepoints_mutex);
+       tracepoint_update_probes();             /* may update entry */
+       mutex_lock(&tracepoints_mutex);
+       entry = get_tracepoint(name);
+       WARN_ON(!entry);
+       if (entry->rcu_pending)
+               rcu_barrier_sched();
+       tracepoint_entry_free_old(entry, old);
+end:
+       mutex_unlock(&tracepoints_mutex);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(tracepoint_probe_register);
+
+/**
+ * tracepoint_probe_unregister -  Disconnect a probe from a tracepoint
+ * @name: tracepoint name
+ * @probe: probe function pointer
+ *
+ * We do not need to call a synchronize_sched to make sure the probes have
+ * finished running before doing a module unload, because the module unload
+ * itself uses stop_machine(), which insures that every preempt disabled section
+ * have finished.
+ */
+int tracepoint_probe_unregister(const char *name, void *probe)
+{
+       struct tracepoint_entry *entry;
+       void *old;
+       int ret = -ENOENT;
+
+       mutex_lock(&tracepoints_mutex);
+       entry = get_tracepoint(name);
+       if (!entry)
+               goto end;
+       if (entry->rcu_pending)
+               rcu_barrier_sched();
+       old = tracepoint_entry_remove_probe(entry, probe);
+       mutex_unlock(&tracepoints_mutex);
+       tracepoint_update_probes();             /* may update entry */
+       mutex_lock(&tracepoints_mutex);
+       entry = get_tracepoint(name);
+       if (!entry)
+               goto end;
+       if (entry->rcu_pending)
+               rcu_barrier_sched();
+       tracepoint_entry_free_old(entry, old);
+       remove_tracepoint(name);        /* Ignore busy error message */
+       ret = 0;
+end:
+       mutex_unlock(&tracepoints_mutex);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(tracepoint_probe_unregister);
+
+/**
+ * tracepoint_get_iter_range - Get a next tracepoint iterator given a range.
+ * @tracepoint: current tracepoints (in), next tracepoint (out)
+ * @begin: beginning of the range
+ * @end: end of the range
+ *
+ * Returns whether a next tracepoint has been found (1) or not (0).
+ * Will return the first tracepoint in the range if the input tracepoint is
+ * NULL.
+ */
+int tracepoint_get_iter_range(struct tracepoint **tracepoint,
+       struct tracepoint *begin, struct tracepoint *end)
+{
+       if (!*tracepoint && begin != end) {
+               *tracepoint = begin;
+               return 1;
+       }
+       if (*tracepoint >= begin && *tracepoint < end)
+               return 1;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(tracepoint_get_iter_range);
+
+static void tracepoint_get_iter(struct tracepoint_iter *iter)
+{
+       int found = 0;
+
+       /* Core kernel tracepoints */
+       if (!iter->module) {
+               found = tracepoint_get_iter_range(&iter->tracepoint,
+                               __start___tracepoints, __stop___tracepoints);
+               if (found)
+                       goto end;
+       }
+       /* tracepoints in modules. */
+       found = module_get_iter_tracepoints(iter);
+end:
+       if (!found)
+               tracepoint_iter_reset(iter);
+}
+
+void tracepoint_iter_start(struct tracepoint_iter *iter)
+{
+       tracepoint_get_iter(iter);
+}
+EXPORT_SYMBOL_GPL(tracepoint_iter_start);
+
+void tracepoint_iter_next(struct tracepoint_iter *iter)
+{
+       iter->tracepoint++;
+       /*
+        * iter->tracepoint may be invalid because we blindly incremented it.
+        * Make sure it is valid by marshalling on the tracepoints, getting the
+        * tracepoints from following modules if necessary.
+        */
+       tracepoint_get_iter(iter);
+}
+EXPORT_SYMBOL_GPL(tracepoint_iter_next);
+
+void tracepoint_iter_stop(struct tracepoint_iter *iter)
+{
+}
+EXPORT_SYMBOL_GPL(tracepoint_iter_stop);
+
+void tracepoint_iter_reset(struct tracepoint_iter *iter)
+{
+       iter->module = NULL;
+       iter->tracepoint = NULL;
+}
+EXPORT_SYMBOL_GPL(tracepoint_iter_reset);
index 714afad46539616e4bbcab15240160ca4d188226..f928f2a87b9b365a8e1d8684902a3ad6f917d6b0 100644 (file)
@@ -62,6 +62,7 @@ struct workqueue_struct {
        const char *name;
        int singlethread;
        int freezeable;         /* Freeze threads during suspend */
+       int rt;
 #ifdef CONFIG_LOCKDEP
        struct lockdep_map lockdep_map;
 #endif
@@ -766,6 +767,7 @@ init_cpu_workqueue(struct workqueue_struct *wq, int cpu)
 
 static int create_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
 {
+       struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
        struct workqueue_struct *wq = cwq->wq;
        const char *fmt = is_single_threaded(wq) ? "%s" : "%s/%d";
        struct task_struct *p;
@@ -781,7 +783,8 @@ static int create_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
         */
        if (IS_ERR(p))
                return PTR_ERR(p);
-
+       if (cwq->wq->rt)
+               sched_setscheduler_nocheck(p, SCHED_FIFO, &param);
        cwq->thread = p;
 
        return 0;
@@ -801,6 +804,7 @@ static void start_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
 struct workqueue_struct *__create_workqueue_key(const char *name,
                                                int singlethread,
                                                int freezeable,
+                                               int rt,
                                                struct lock_class_key *key,
                                                const char *lock_name)
 {
@@ -822,6 +826,7 @@ struct workqueue_struct *__create_workqueue_key(const char *name,
        lockdep_init_map(&wq->lockdep_map, lock_name, key, 0);
        wq->singlethread = singlethread;
        wq->freezeable = freezeable;
+       wq->rt = rt;
        INIT_LIST_HEAD(&wq->list);
 
        if (singlethread) {
index 482df94ea21eb3e9ab7b2ef4efe88643147c3d80..1338469ac849cb230fc8f1e74441ece4a6cfd58c 100644 (file)
@@ -996,3 +996,25 @@ int bitmap_allocate_region(unsigned long *bitmap, int pos, int order)
        return 0;
 }
 EXPORT_SYMBOL(bitmap_allocate_region);
+
+/**
+ * bitmap_copy_le - copy a bitmap, putting the bits into little-endian order.
+ * @dst:   destination buffer
+ * @src:   bitmap to copy
+ * @nbits: number of bits in the bitmap
+ *
+ * Require nbits % BITS_PER_LONG == 0.
+ */
+void bitmap_copy_le(void *dst, const unsigned long *src, int nbits)
+{
+       unsigned long *d = dst;
+       int i;
+
+       for (i = 0; i < nbits/BITS_PER_LONG; i++) {
+               if (BITS_PER_LONG == 64)
+                       d[i] = cpu_to_le64(src[i]);
+               else
+                       d[i] = cpu_to_le32(src[i]);
+       }
+}
+EXPORT_SYMBOL(bitmap_copy_le);
index 8347925030ff51a0a98d1a81cb5ae9c0b06413fa..ab431d4cc970d50f4b90b8f0639fcdea417e78a0 100644 (file)
@@ -23,7 +23,7 @@
 int string_get_size(u64 size, const enum string_size_units units,
                    char *buf, int len)
 {
-       const char *units_10[] = { "B", "KB", "MB", "GB", "TB", "PB",
+       const char *units_10[] = { "B", "kB", "MB", "GB", "TB", "PB",
                                   "EB", "ZB", "YB", NULL};
        const char *units_2[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB",
                                 "EiB", "ZiB", "YiB", NULL };
@@ -31,7 +31,7 @@ int string_get_size(u64 size, const enum string_size_units units,
                [STRING_UNITS_10] =  units_10,
                [STRING_UNITS_2] = units_2,
        };
-       const int divisor[] = {
+       const unsigned int divisor[] = {
                [STRING_UNITS_10] = 1000,
                [STRING_UNITS_2] = 1024,
        };
@@ -40,23 +40,27 @@ int string_get_size(u64 size, const enum string_size_units units,
        char tmp[8];
 
        tmp[0] = '\0';
+       i = 0;
+       if (size >= divisor[units]) {
+               while (size >= divisor[units] && units_str[units][i]) {
+                       remainder = do_div(size, divisor[units]);
+                       i++;
+               }
 
-       for (i = 0; size > divisor[units] && units_str[units][i]; i++)
-               remainder = do_div(size, divisor[units]);
+               sf_cap = size;
+               for (j = 0; sf_cap*10 < 1000; j++)
+                       sf_cap *= 10;
 
-       sf_cap = size;
-       for (j = 0; sf_cap*10 < 1000; j++)
-               sf_cap *= 10;
-
-       if (j) {
-               remainder *= 1000;
-               do_div(remainder, divisor[units]);
-               snprintf(tmp, sizeof(tmp), ".%03lld",
-                        (unsigned long long)remainder);
-               tmp[j+1] = '\0';
+               if (j) {
+                       remainder *= 1000;
+                       do_div(remainder, divisor[units]);
+                       snprintf(tmp, sizeof(tmp), ".%03lld",
+                                (unsigned long long)remainder);
+                       tmp[j+1] = '\0';
+               }
        }
 
-       snprintf(buf, len, "%lld%s%s", (unsigned long long)size,
+       snprintf(buf, len, "%lld%s %s", (unsigned long long)size,
                 tmp, units_str[units][i]);
 
        return 0;
index ce8cbb29860bd1b867454014195fe497332e2f61..421aee99b84a4da8120de8eaf1d9518fa57199c9 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mm.h>
+#include <linux/seq_file.h>
 #include <linux/sysctl.h>
 #include <linux/highmem.h>
 #include <linux/mmu_notifier.h>
@@ -1455,10 +1456,10 @@ int hugetlb_overcommit_handler(struct ctl_table *table, int write,
 
 #endif /* CONFIG_SYSCTL */
 
-int hugetlb_report_meminfo(char *buf)
+void hugetlb_report_meminfo(struct seq_file *m)
 {
        struct hstate *h = &default_hstate;
-       return sprintf(buf,
+       seq_printf(m,
                        "HugePages_Total:   %5lu\n"
                        "HugePages_Free:    %5lu\n"
                        "HugePages_Rsvd:    %5lu\n"
index d4a92b63e98e1da2fa619a7272cd0db3d15f18f1..866dcc7eeb0c3da1e4c6d822ece39a3ea65dc6f9 100644 (file)
@@ -1088,7 +1088,6 @@ mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont)
        int node;
 
        if (unlikely((cont->parent) == NULL)) {
-               page_cgroup_init();
                mem = &init_mem_cgroup;
        } else {
                mem = mem_cgroup_alloc();
index 3a6c4a6583256584303c4ac7c8813938abc49ed0..164951c473058a25c081d5e47260d872068cdbb7 100644 (file)
@@ -64,8 +64,6 @@
 
 #include "internal.h"
 
-#include "internal.h"
-
 #ifndef CONFIG_NEED_MULTIPLE_NODES
 /* use the per-pgdat data instead for discontigmem - mbligh */
 unsigned long max_mapnr;
index 5d86550701f2fb40f60c649b4aa91c56824a9e3b..f59d797dc5a9b28ddcb3eae0f0aeeb4bc6e6daad 100644 (file)
@@ -4,7 +4,10 @@
 #include <linux/bit_spinlock.h>
 #include <linux/page_cgroup.h>
 #include <linux/hash.h>
+#include <linux/slab.h>
 #include <linux/memory.h>
+#include <linux/vmalloc.h>
+#include <linux/cgroup.h>
 
 static void __meminit
 __init_page_cgroup(struct page_cgroup *pc, unsigned long pfn)
@@ -66,6 +69,9 @@ void __init page_cgroup_init(void)
 
        int nid, fail;
 
+       if (mem_cgroup_subsys.disabled)
+               return;
+
        for_each_online_node(nid)  {
                fail = alloc_node_page_cgroup(nid);
                if (fail)
@@ -106,9 +112,14 @@ int __meminit init_section_page_cgroup(unsigned long pfn)
        nid = page_to_nid(pfn_to_page(pfn));
 
        table_size = sizeof(struct page_cgroup) * PAGES_PER_SECTION;
-       base = kmalloc_node(table_size, GFP_KERNEL, nid);
-       if (!base)
-               base = vmalloc_node(table_size, nid);
+       if (slab_is_available()) {
+               base = kmalloc_node(table_size, GFP_KERNEL, nid);
+               if (!base)
+                       base = vmalloc_node(table_size, nid);
+       } else {
+               base = __alloc_bootmem_node_nopanic(NODE_DATA(nid), table_size,
+                               PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
+       }
 
        if (!base) {
                printk(KERN_ERR "page cgroup allocation failure\n");
@@ -135,11 +146,16 @@ void __free_page_cgroup(unsigned long pfn)
        if (!ms || !ms->page_cgroup)
                return;
        base = ms->page_cgroup + pfn;
-       ms->page_cgroup = NULL;
-       if (is_vmalloc_addr(base))
+       if (is_vmalloc_addr(base)) {
                vfree(base);
-       else
-               kfree(base);
+               ms->page_cgroup = NULL;
+       } else {
+               struct page *page = virt_to_page(base);
+               if (!PageReserved(page)) { /* Is bootmem ? */
+                       kfree(base);
+                       ms->page_cgroup = NULL;
+               }
+       }
 }
 
 int online_page_cgroup(unsigned long start_pfn,
@@ -213,6 +229,9 @@ void __init page_cgroup_init(void)
        unsigned long pfn;
        int fail = 0;
 
+       if (mem_cgroup_subsys.disabled)
+               return;
+
        for (pfn = 0; !fail && pfn < max_pfn; pfn += PAGES_PER_SECTION) {
                if (!pfn_present(pfn))
                        continue;
index e76eee46688619bd65c110f934cab134dd698e27..09187517f9dc64804cc80453db0be0a72bcbf922 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -95,6 +95,7 @@
 #include       <linux/init.h>
 #include       <linux/compiler.h>
 #include       <linux/cpuset.h>
+#include       <linux/proc_fs.h>
 #include       <linux/seq_file.h>
 #include       <linux/notifier.h>
 #include       <linux/kallsyms.h>
@@ -4258,7 +4259,7 @@ static int s_show(struct seq_file *m, void *p)
  * + further values on SMP and with statistics enabled
  */
 
-const struct seq_operations slabinfo_op = {
+static const struct seq_operations slabinfo_op = {
        .start = s_start,
        .next = s_next,
        .stop = s_stop,
@@ -4315,6 +4316,19 @@ ssize_t slabinfo_write(struct file *file, const char __user * buffer,
        return res;
 }
 
+static int slabinfo_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &slabinfo_op);
+}
+
+static const struct file_operations proc_slabinfo_operations = {
+       .open           = slabinfo_open,
+       .read           = seq_read,
+       .write          = slabinfo_write,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 #ifdef CONFIG_DEBUG_SLAB_LEAK
 
 static void *leaks_start(struct seq_file *m, loff_t *pos)
@@ -4443,13 +4457,47 @@ static int leaks_show(struct seq_file *m, void *p)
        return 0;
 }
 
-const struct seq_operations slabstats_op = {
+static const struct seq_operations slabstats_op = {
        .start = leaks_start,
        .next = s_next,
        .stop = s_stop,
        .show = leaks_show,
 };
+
+static int slabstats_open(struct inode *inode, struct file *file)
+{
+       unsigned long *n = kzalloc(PAGE_SIZE, GFP_KERNEL);
+       int ret = -ENOMEM;
+       if (n) {
+               ret = seq_open(file, &slabstats_op);
+               if (!ret) {
+                       struct seq_file *m = file->private_data;
+                       *n = PAGE_SIZE / (2 * sizeof(unsigned long));
+                       m->private = n;
+                       n = NULL;
+               }
+               kfree(n);
+       }
+       return ret;
+}
+
+static const struct file_operations proc_slabstats_operations = {
+       .open           = slabstats_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release_private,
+};
+#endif
+
+static int __init slab_proc_init(void)
+{
+       proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
+#ifdef CONFIG_DEBUG_SLAB_LEAK
+       proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
 #endif
+       return 0;
+}
+module_init(slab_proc_init);
 #endif
 
 /**
index 0c83e6afe7b223757f1608268436c59648c3633d..7ad489af95614602a2f5fec8756460108a1f6be1 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -14,6 +14,7 @@
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
 #include <linux/slab.h>
+#include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/cpu.h>
 #include <linux/cpuset.h>
@@ -4417,14 +4418,6 @@ __initcall(slab_sysfs_init);
  * The /proc/slabinfo ABI
  */
 #ifdef CONFIG_SLABINFO
-
-ssize_t slabinfo_write(struct file *file, const char __user *buffer,
-                      size_t count, loff_t *ppos)
-{
-       return -EINVAL;
-}
-
-
 static void print_slabinfo_header(struct seq_file *m)
 {
        seq_puts(m, "slabinfo - version: 2.1\n");
@@ -4492,11 +4485,29 @@ static int s_show(struct seq_file *m, void *p)
        return 0;
 }
 
-const struct seq_operations slabinfo_op = {
+static const struct seq_operations slabinfo_op = {
        .start = s_start,
        .next = s_next,
        .stop = s_stop,
        .show = s_show,
 };
 
+static int slabinfo_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &slabinfo_op);
+}
+
+static const struct file_operations proc_slabinfo_operations = {
+       .open           = slabinfo_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+static int __init slab_proc_init(void)
+{
+       proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
+       return 0;
+}
+module_init(slab_proc_init);
 #endif /* CONFIG_SLABINFO */
index 8d7a27a6335c4c6076b38fc2ab990a82081ada5d..3e67d575ee6e64821c43ea2b7d181a3d36d9805d 100644 (file)
@@ -95,6 +95,7 @@ put_dentry:
 put_memory:
        return ERR_PTR(error);
 }
+EXPORT_SYMBOL_GPL(shmem_file_setup);
 
 /**
  * shmem_zero_setup - setup a shared anonymous mapping
index 712ae47af0bf5f23a4b32ea0497dd2f6e8272085..036536945dd9e06f53adf21c165f087a4700c3cc 100644 (file)
@@ -15,9 +15,9 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
+#include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/debugobjects.h>
-#include <linux/vmalloc.h>
 #include <linux/kallsyms.h>
 #include <linux/list.h>
 #include <linux/rbtree.h>
@@ -175,6 +175,21 @@ static int vmap_page_range(unsigned long addr, unsigned long end,
        return nr;
 }
 
+static inline int is_vmalloc_or_module_addr(const void *x)
+{
+       /*
+        * x86-64 and sparc64 put modules in a special place,
+        * and fall back on vmalloc() if that fails. Others
+        * just put it in the vmalloc space.
+        */
+#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
+       unsigned long addr = (unsigned long)x;
+       if (addr >= MODULES_VADDR && addr < MODULES_END)
+               return 1;
+#endif
+       return is_vmalloc_addr(x);
+}
+
 /*
  * Walk a vmap address to the struct page it maps.
  */
@@ -188,8 +203,7 @@ struct page *vmalloc_to_page(const void *vmalloc_addr)
         * XXX we might need to change this if we add VIRTUAL_BUG_ON for
         * architectures that do not vmalloc module space
         */
-       VIRTUAL_BUG_ON(!is_vmalloc_addr(vmalloc_addr) &&
-                       !is_module_address(addr));
+       VIRTUAL_BUG_ON(!is_vmalloc_or_module_addr(vmalloc_addr));
 
        if (!pgd_none(*pgd)) {
                pud_t *pud = pud_offset(pgd, addr);
@@ -1705,11 +1719,41 @@ static int s_show(struct seq_file *m, void *p)
        return 0;
 }
 
-const struct seq_operations vmalloc_op = {
+static const struct seq_operations vmalloc_op = {
        .start = s_start,
        .next = s_next,
        .stop = s_stop,
        .show = s_show,
 };
+
+static int vmalloc_open(struct inode *inode, struct file *file)
+{
+       unsigned int *ptr = NULL;
+       int ret;
+
+       if (NUMA_BUILD)
+               ptr = kmalloc(nr_node_ids * sizeof(unsigned int), GFP_KERNEL);
+       ret = seq_open(file, &vmalloc_op);
+       if (!ret) {
+               struct seq_file *m = file->private_data;
+               m->private = ptr;
+       } else
+               kfree(ptr);
+       return ret;
+}
+
+static const struct file_operations proc_vmalloc_operations = {
+       .open           = vmalloc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release_private,
+};
+
+static int __init proc_vmalloc_init(void)
+{
+       proc_create("vmallocinfo", S_IRUSR, NULL, &proc_vmalloc_operations);
+       return 0;
+}
+module_init(proc_vmalloc_init);
 #endif
 
index 9343227c5c60b6dc3a1b7e09c64143a53a407003..c3ccfda23adc56abafb58abbcc31b33c5588ce4d 100644 (file)
@@ -8,7 +8,7 @@
  *  Copyright (C) 2006 Silicon Graphics, Inc.,
  *             Christoph Lameter <christoph@lameter.com>
  */
-
+#include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/err.h>
 #include <linux/module.h>
@@ -384,7 +384,7 @@ void zone_statistics(struct zone *preferred_zone, struct zone *z)
 #endif
 
 #ifdef CONFIG_PROC_FS
-
+#include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 
 static char * const migratetype_names[MIGRATE_TYPES] = {
@@ -581,20 +581,44 @@ static int pagetypeinfo_show(struct seq_file *m, void *arg)
        return 0;
 }
 
-const struct seq_operations fragmentation_op = {
+static const struct seq_operations fragmentation_op = {
        .start  = frag_start,
        .next   = frag_next,
        .stop   = frag_stop,
        .show   = frag_show,
 };
 
-const struct seq_operations pagetypeinfo_op = {
+static int fragmentation_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &fragmentation_op);
+}
+
+static const struct file_operations fragmentation_file_operations = {
+       .open           = fragmentation_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+static const struct seq_operations pagetypeinfo_op = {
        .start  = frag_start,
        .next   = frag_next,
        .stop   = frag_stop,
        .show   = pagetypeinfo_show,
 };
 
+static int pagetypeinfo_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &pagetypeinfo_op);
+}
+
+static const struct file_operations pagetypeinfo_file_ops = {
+       .open           = pagetypeinfo_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 #ifdef CONFIG_ZONE_DMA
 #define TEXT_FOR_DMA(xx) xx "_dma",
 #else
@@ -771,7 +795,7 @@ static int zoneinfo_show(struct seq_file *m, void *arg)
        return 0;
 }
 
-const struct seq_operations zoneinfo_op = {
+static const struct seq_operations zoneinfo_op = {
        .start  = frag_start, /* iterate over all zones. The same as in
                               * fragmentation. */
        .next   = frag_next,
@@ -779,6 +803,18 @@ const struct seq_operations zoneinfo_op = {
        .show   = zoneinfo_show,
 };
 
+static int zoneinfo_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &zoneinfo_op);
+}
+
+static const struct file_operations proc_zoneinfo_file_operations = {
+       .open           = zoneinfo_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 static void *vmstat_start(struct seq_file *m, loff_t *pos)
 {
        unsigned long *v;
@@ -834,13 +870,24 @@ static void vmstat_stop(struct seq_file *m, void *arg)
        m->private = NULL;
 }
 
-const struct seq_operations vmstat_op = {
+static const struct seq_operations vmstat_op = {
        .start  = vmstat_start,
        .next   = vmstat_next,
        .stop   = vmstat_stop,
        .show   = vmstat_show,
 };
 
+static int vmstat_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &vmstat_op);
+}
+
+static const struct file_operations proc_vmstat_file_operations = {
+       .open           = vmstat_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
 #endif /* CONFIG_PROC_FS */
 
 #ifdef CONFIG_SMP
@@ -898,9 +945,11 @@ static int __cpuinit vmstat_cpuup_callback(struct notifier_block *nfb,
 
 static struct notifier_block __cpuinitdata vmstat_notifier =
        { &vmstat_cpuup_callback, NULL, 0 };
+#endif
 
 static int __init setup_vmstat(void)
 {
+#ifdef CONFIG_SMP
        int cpu;
 
        refresh_zone_stat_thresholds();
@@ -908,7 +957,13 @@ static int __init setup_vmstat(void)
 
        for_each_online_cpu(cpu)
                start_cpu_timer(cpu);
+#endif
+#ifdef CONFIG_PROC_FS
+       proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations);
+       proc_create("pagetypeinfo", S_IRUGO, NULL, &pagetypeinfo_file_ops);
+       proc_create("vmstat", S_IRUGO, NULL, &proc_vmstat_file_operations);
+       proc_create("zoneinfo", S_IRUGO, NULL, &proc_zoneinfo_file_operations);
+#endif
        return 0;
 }
 module_init(setup_vmstat)
-#endif
index ff34c5acc1309ea7cdb2c8e60e73740cd23264a6..c42c0c400bf9a36176ceedcac6a94083016e5b8d 100644 (file)
@@ -20,6 +20,12 @@ config NET_9P_VIRTIO
          This builds support for a transports between
          guest partitions and a host partition.
 
+config NET_9P_RDMA
+       depends on NET_9P && INFINIBAND && EXPERIMENTAL
+       tristate "9P RDMA Transport (Experimental)"
+       help
+         This builds support for a RDMA transport.
+
 config NET_9P_DEBUG
        bool "Debug information"
        depends on NET_9P
index 1041b7bd12e29af0e3be78ff364d8fd7aa2bcec4..198a640d53a64b681e89f4032f8ed133158fa96a 100644 (file)
@@ -1,5 +1,6 @@
 obj-$(CONFIG_NET_9P) := 9pnet.o
 obj-$(CONFIG_NET_9P_VIRTIO) += 9pnet_virtio.o
+obj-$(CONFIG_NET_9P_RDMA) += 9pnet_rdma.o
 
 9pnet-objs := \
        mod.o \
@@ -11,3 +12,6 @@ obj-$(CONFIG_NET_9P_VIRTIO) += 9pnet_virtio.o
 
 9pnet_virtio-objs := \
        trans_virtio.o \
+
+9pnet_rdma-objs := \
+       trans_rdma.o \
index bbac2f72b4d27c00e8692ee10760b3f5fa56d9b8..67717f69412e47c182f34715291ec83c979d6f73 100644 (file)
@@ -159,6 +159,7 @@ static struct p9_req_t *p9_tag_alloc(struct p9_client *c, u16 tag)
 
                        if (!c->reqs[row]) {
                                printk(KERN_ERR "Couldn't grow tag array\n");
+                               spin_unlock_irqrestore(&c->lock, flags);
                                return ERR_PTR(-ENOMEM);
                        }
                        for (col = 0; col < P9_ROW_MAXTAG; col++) {
index 29be5243908674e7bc00d6063adbfc925449bcc0..dcd7666824ba57708df3fa9e9f4a8d6893539712 100644 (file)
@@ -53,6 +53,7 @@
 static int
 p9pdu_writef(struct p9_fcall *pdu, int optional, const char *fmt, ...);
 
+#ifdef CONFIG_NET_9P_DEBUG
 void
 p9pdu_dump(int way, struct p9_fcall *pdu)
 {
@@ -81,6 +82,12 @@ p9pdu_dump(int way, struct p9_fcall *pdu)
        else
                P9_DPRINTK(P9_DEBUG_PKT, "]]](%d) %s\n", datalen, buf);
 }
+#else
+void
+p9pdu_dump(int way, struct p9_fcall *pdu)
+{
+}
+#endif
 EXPORT_SYMBOL(p9pdu_dump);
 
 void p9stat_free(struct p9_wstat *stbuf)
@@ -179,7 +186,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
                        }
                        break;
                case 's':{
-                               char **ptr = va_arg(ap, char **);
+                               char **sptr = va_arg(ap, char **);
                                int16_t len;
                                int size;
 
@@ -189,17 +196,17 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
 
                                size = MAX(len, 0);
 
-                               *ptr = kmalloc(size + 1, GFP_KERNEL);
-                               if (*ptr == NULL) {
+                               *sptr = kmalloc(size + 1, GFP_KERNEL);
+                               if (*sptr == NULL) {
                                        errcode = -EFAULT;
                                        break;
                                }
-                               if (pdu_read(pdu, *ptr, size)) {
+                               if (pdu_read(pdu, *sptr, size)) {
                                        errcode = -EFAULT;
-                                       kfree(*ptr);
-                                       *ptr = NULL;
+                                       kfree(*sptr);
+                                       *sptr = NULL;
                                } else
-                                       (*ptr)[size] = 0;
+                                       (*sptr)[size] = 0;
                        }
                        break;
                case 'Q':{
@@ -373,13 +380,13 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
                        }
                        break;
                case 's':{
-                               const char *ptr = va_arg(ap, const char *);
+                               const char *sptr = va_arg(ap, const char *);
                                int16_t len = 0;
-                               if (ptr)
-                                       len = MIN(strlen(ptr), USHORT_MAX);
+                               if (sptr)
+                                       len = MIN(strlen(sptr), USHORT_MAX);
 
                                errcode = p9pdu_writef(pdu, optional, "w", len);
-                               if (!errcode && pdu_write(pdu, ptr, len))
+                               if (!errcode && pdu_write(pdu, sptr, len))
                                        errcode = -EFAULT;
                        }
                        break;
@@ -419,7 +426,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
                case 'U':{
                                int32_t count = va_arg(ap, int32_t);
                                const char __user *udata =
-                                               va_arg(ap, const void *);
+                                               va_arg(ap, const void __user *);
                                errcode =
                                    p9pdu_writef(pdu, optional, "d", count);
                                if (!errcode && pdu_write_u(pdu, udata, count))
@@ -542,8 +549,10 @@ int p9pdu_finalize(struct p9_fcall *pdu)
        err = p9pdu_writef(pdu, 0, "d", size);
        pdu->size = size;
 
+#ifdef CONFIG_NET_9P_DEBUG
        if ((p9_debug_level & P9_DEBUG_PKT) == P9_DEBUG_PKT)
                p9pdu_dump(0, pdu);
+#endif
 
        P9_DPRINTK(P9_DEBUG_9P, ">>> size=%d type: %d tag: %d\n", pdu->size,
                                                        pdu->id, pdu->tag);
index be65d8242fd253ce0d9201cedfa448cfe36d6bed..1df0356f242b651ddedaa937394a4cd9944e8c27 100644 (file)
@@ -678,11 +678,9 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
 
 static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
 {
-       struct p9_trans_fd *ts = client->trans;
-       struct p9_conn *m = ts->conn;
        int ret = 1;
 
-       P9_DPRINTK(P9_DEBUG_TRANS, "mux %p req %p\n", m, req);
+       P9_DPRINTK(P9_DEBUG_TRANS, "client %p req %p\n", client, req);
 
        spin_lock(&client->lock);
        list_del(&req->req_list);
diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c
new file mode 100644 (file)
index 0000000..8d6cc47
--- /dev/null
@@ -0,0 +1,712 @@
+/*
+ * linux/fs/9p/trans_rdma.c
+ *
+ * RDMA transport layer based on the trans_fd.c implementation.
+ *
+ *  Copyright (C) 2008 by Tom Tucker <tom@opengridcomputing.com>
+ *  Copyright (C) 2006 by Russ Cox <rsc@swtch.com>
+ *  Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net>
+ *  Copyright (C) 2004-2008 by Eric Van Hensbergen <ericvh@gmail.com>
+ *  Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.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:
+ *  Free Software Foundation
+ *  51 Franklin Street, Fifth Floor
+ *  Boston, MA  02111-1301  USA
+ *
+ */
+
+#include <linux/in.h>
+#include <linux/module.h>
+#include <linux/net.h>
+#include <linux/ipv6.h>
+#include <linux/kthread.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/un.h>
+#include <linux/uaccess.h>
+#include <linux/inet.h>
+#include <linux/idr.h>
+#include <linux/file.h>
+#include <linux/parser.h>
+#include <linux/semaphore.h>
+#include <net/9p/9p.h>
+#include <net/9p/client.h>
+#include <net/9p/transport.h>
+#include <rdma/ib_verbs.h>
+#include <rdma/rdma_cm.h>
+#include <rdma/ib_verbs.h>
+
+#define P9_PORT                        5640
+#define P9_RDMA_SQ_DEPTH       32
+#define P9_RDMA_RQ_DEPTH       32
+#define P9_RDMA_SEND_SGE       4
+#define P9_RDMA_RECV_SGE       4
+#define P9_RDMA_IRD            0
+#define P9_RDMA_ORD            0
+#define P9_RDMA_TIMEOUT                30000           /* 30 seconds */
+#define P9_RDMA_MAXSIZE                (4*4096)        /* Min SGE is 4, so we can
+                                                * safely advertise a maxsize
+                                                * of 64k */
+
+#define P9_RDMA_MAX_SGE (P9_RDMA_MAXSIZE >> PAGE_SHIFT)
+/**
+ * struct p9_trans_rdma - RDMA transport instance
+ *
+ * @state: tracks the transport state machine for connection setup and tear down
+ * @cm_id: The RDMA CM ID
+ * @pd: Protection Domain pointer
+ * @qp: Queue Pair pointer
+ * @cq: Completion Queue pointer
+ * @lkey: The local access only memory region key
+ * @timeout: Number of uSecs to wait for connection management events
+ * @sq_depth: The depth of the Send Queue
+ * @sq_sem: Semaphore for the SQ
+ * @rq_depth: The depth of the Receive Queue.
+ * @addr: The remote peer's address
+ * @req_lock: Protects the active request list
+ * @send_wait: Wait list when the SQ fills up
+ * @cm_done: Completion event for connection management tracking
+ */
+struct p9_trans_rdma {
+       enum {
+               P9_RDMA_INIT,
+               P9_RDMA_ADDR_RESOLVED,
+               P9_RDMA_ROUTE_RESOLVED,
+               P9_RDMA_CONNECTED,
+               P9_RDMA_FLUSHING,
+               P9_RDMA_CLOSING,
+               P9_RDMA_CLOSED,
+       } state;
+       struct rdma_cm_id *cm_id;
+       struct ib_pd *pd;
+       struct ib_qp *qp;
+       struct ib_cq *cq;
+       struct ib_mr *dma_mr;
+       u32 lkey;
+       long timeout;
+       int sq_depth;
+       struct semaphore sq_sem;
+       int rq_depth;
+       atomic_t rq_count;
+       struct sockaddr_in addr;
+       spinlock_t req_lock;
+
+       struct completion cm_done;
+};
+
+/**
+ * p9_rdma_context - Keeps track of in-process WR
+ *
+ * @wc_op: The original WR op for when the CQE completes in error.
+ * @busa: Bus address to unmap when the WR completes
+ * @req: Keeps track of requests (send)
+ * @rc: Keepts track of replies (receive)
+ */
+struct p9_rdma_req;
+struct p9_rdma_context {
+       enum ib_wc_opcode wc_op;
+       dma_addr_t busa;
+       union {
+               struct p9_req_t *req;
+               struct p9_fcall *rc;
+       };
+};
+
+/**
+ * p9_rdma_opts - Collection of mount options
+ * @port: port of connection
+ * @sq_depth: The requested depth of the SQ. This really doesn't need
+ * to be any deeper than the number of threads used in the client
+ * @rq_depth: The depth of the RQ. Should be greater than or equal to SQ depth
+ * @timeout: Time to wait in msecs for CM events
+ */
+struct p9_rdma_opts {
+       short port;
+       int sq_depth;
+       int rq_depth;
+       long timeout;
+};
+
+/*
+ * Option Parsing (code inspired by NFS code)
+ */
+enum {
+       /* Options that take integer arguments */
+       Opt_port, Opt_rq_depth, Opt_sq_depth, Opt_timeout, Opt_err,
+};
+
+static match_table_t tokens = {
+       {Opt_port, "port=%u"},
+       {Opt_sq_depth, "sq=%u"},
+       {Opt_rq_depth, "rq=%u"},
+       {Opt_timeout, "timeout=%u"},
+       {Opt_err, NULL},
+};
+
+/**
+ * parse_options - parse mount options into session structure
+ * @options: options string passed from mount
+ * @opts: transport-specific structure to parse options into
+ *
+ * Returns 0 upon success, -ERRNO upon failure
+ */
+static int parse_opts(char *params, struct p9_rdma_opts *opts)
+{
+       char *p;
+       substring_t args[MAX_OPT_ARGS];
+       int option;
+       char *options;
+       int ret;
+
+       opts->port = P9_PORT;
+       opts->sq_depth = P9_RDMA_SQ_DEPTH;
+       opts->rq_depth = P9_RDMA_RQ_DEPTH;
+       opts->timeout = P9_RDMA_TIMEOUT;
+
+       if (!params)
+               return 0;
+
+       options = kstrdup(params, GFP_KERNEL);
+       if (!options) {
+               P9_DPRINTK(P9_DEBUG_ERROR,
+                          "failed to allocate copy of option string\n");
+               return -ENOMEM;
+       }
+
+       while ((p = strsep(&options, ",")) != NULL) {
+               int token;
+               int r;
+               if (!*p)
+                       continue;
+               token = match_token(p, tokens, args);
+               r = match_int(&args[0], &option);
+               if (r < 0) {
+                       P9_DPRINTK(P9_DEBUG_ERROR,
+                                  "integer field, but no integer?\n");
+                       ret = r;
+                       continue;
+               }
+               switch (token) {
+               case Opt_port:
+                       opts->port = option;
+                       break;
+               case Opt_sq_depth:
+                       opts->sq_depth = option;
+                       break;
+               case Opt_rq_depth:
+                       opts->rq_depth = option;
+                       break;
+               case Opt_timeout:
+                       opts->timeout = option;
+                       break;
+               default:
+                       continue;
+               }
+       }
+       /* RQ must be at least as large as the SQ */
+       opts->rq_depth = max(opts->rq_depth, opts->sq_depth);
+       kfree(options);
+       return 0;
+}
+
+static int
+p9_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event)
+{
+       struct p9_client *c = id->context;
+       struct p9_trans_rdma *rdma = c->trans;
+       switch (event->event) {
+       case RDMA_CM_EVENT_ADDR_RESOLVED:
+               BUG_ON(rdma->state != P9_RDMA_INIT);
+               rdma->state = P9_RDMA_ADDR_RESOLVED;
+               break;
+
+       case RDMA_CM_EVENT_ROUTE_RESOLVED:
+               BUG_ON(rdma->state != P9_RDMA_ADDR_RESOLVED);
+               rdma->state = P9_RDMA_ROUTE_RESOLVED;
+               break;
+
+       case RDMA_CM_EVENT_ESTABLISHED:
+               BUG_ON(rdma->state != P9_RDMA_ROUTE_RESOLVED);
+               rdma->state = P9_RDMA_CONNECTED;
+               break;
+
+       case RDMA_CM_EVENT_DISCONNECTED:
+               if (rdma)
+                       rdma->state = P9_RDMA_CLOSED;
+               if (c)
+                       c->status = Disconnected;
+               break;
+
+       case RDMA_CM_EVENT_TIMEWAIT_EXIT:
+               break;
+
+       case RDMA_CM_EVENT_ADDR_CHANGE:
+       case RDMA_CM_EVENT_ROUTE_ERROR:
+       case RDMA_CM_EVENT_DEVICE_REMOVAL:
+       case RDMA_CM_EVENT_MULTICAST_JOIN:
+       case RDMA_CM_EVENT_MULTICAST_ERROR:
+       case RDMA_CM_EVENT_REJECTED:
+       case RDMA_CM_EVENT_CONNECT_REQUEST:
+       case RDMA_CM_EVENT_CONNECT_RESPONSE:
+       case RDMA_CM_EVENT_CONNECT_ERROR:
+       case RDMA_CM_EVENT_ADDR_ERROR:
+       case RDMA_CM_EVENT_UNREACHABLE:
+               c->status = Disconnected;
+               rdma_disconnect(rdma->cm_id);
+               break;
+       default:
+               BUG();
+       }
+       complete(&rdma->cm_done);
+       return 0;
+}
+
+static void
+handle_recv(struct p9_client *client, struct p9_trans_rdma *rdma,
+           struct p9_rdma_context *c, enum ib_wc_status status, u32 byte_len)
+{
+       struct p9_req_t *req;
+       int err = 0;
+       int16_t tag;
+
+       req = NULL;
+       ib_dma_unmap_single(rdma->cm_id->device, c->busa, client->msize,
+                                                        DMA_FROM_DEVICE);
+
+       if (status != IB_WC_SUCCESS)
+               goto err_out;
+
+       err = p9_parse_header(c->rc, NULL, NULL, &tag, 1);
+       if (err)
+               goto err_out;
+
+       req = p9_tag_lookup(client, tag);
+       if (!req)
+               goto err_out;
+
+       req->rc = c->rc;
+       p9_client_cb(client, req);
+
+       return;
+
+ err_out:
+       P9_DPRINTK(P9_DEBUG_ERROR, "req %p err %d status %d\n",
+                  req, err, status);
+       rdma->state = P9_RDMA_FLUSHING;
+       client->status = Disconnected;
+       return;
+}
+
+static void
+handle_send(struct p9_client *client, struct p9_trans_rdma *rdma,
+           struct p9_rdma_context *c, enum ib_wc_status status, u32 byte_len)
+{
+       ib_dma_unmap_single(rdma->cm_id->device,
+                           c->busa, c->req->tc->size,
+                           DMA_TO_DEVICE);
+}
+
+static void qp_event_handler(struct ib_event *event, void *context)
+{
+       P9_DPRINTK(P9_DEBUG_ERROR, "QP event %d context %p\n", event->event,
+                                                               context);
+}
+
+static void cq_comp_handler(struct ib_cq *cq, void *cq_context)
+{
+       struct p9_client *client = cq_context;
+       struct p9_trans_rdma *rdma = client->trans;
+       int ret;
+       struct ib_wc wc;
+
+       ib_req_notify_cq(rdma->cq, IB_CQ_NEXT_COMP);
+       while ((ret = ib_poll_cq(cq, 1, &wc)) > 0) {
+               struct p9_rdma_context *c = (void *) (unsigned long) wc.wr_id;
+
+               switch (c->wc_op) {
+               case IB_WC_RECV:
+                       atomic_dec(&rdma->rq_count);
+                       handle_recv(client, rdma, c, wc.status, wc.byte_len);
+                       break;
+
+               case IB_WC_SEND:
+                       handle_send(client, rdma, c, wc.status, wc.byte_len);
+                       up(&rdma->sq_sem);
+                       break;
+
+               default:
+                       printk(KERN_ERR "9prdma: unexpected completion type, "
+                              "c->wc_op=%d, wc.opcode=%d, status=%d\n",
+                              c->wc_op, wc.opcode, wc.status);
+                       break;
+               }
+               kfree(c);
+       }
+}
+
+static void cq_event_handler(struct ib_event *e, void *v)
+{
+       P9_DPRINTK(P9_DEBUG_ERROR, "CQ event %d context %p\n", e->event, v);
+}
+
+static void rdma_destroy_trans(struct p9_trans_rdma *rdma)
+{
+       if (!rdma)
+               return;
+
+       if (rdma->dma_mr && !IS_ERR(rdma->dma_mr))
+               ib_dereg_mr(rdma->dma_mr);
+
+       if (rdma->qp && !IS_ERR(rdma->qp))
+               ib_destroy_qp(rdma->qp);
+
+       if (rdma->pd && !IS_ERR(rdma->pd))
+               ib_dealloc_pd(rdma->pd);
+
+       if (rdma->cq && !IS_ERR(rdma->cq))
+               ib_destroy_cq(rdma->cq);
+
+       if (rdma->cm_id && !IS_ERR(rdma->cm_id))
+               rdma_destroy_id(rdma->cm_id);
+
+       kfree(rdma);
+}
+
+static int
+post_recv(struct p9_client *client, struct p9_rdma_context *c)
+{
+       struct p9_trans_rdma *rdma = client->trans;
+       struct ib_recv_wr wr, *bad_wr;
+       struct ib_sge sge;
+
+       c->busa = ib_dma_map_single(rdma->cm_id->device,
+                                   c->rc->sdata, client->msize,
+                                   DMA_FROM_DEVICE);
+       if (ib_dma_mapping_error(rdma->cm_id->device, c->busa))
+               goto error;
+
+       sge.addr = c->busa;
+       sge.length = client->msize;
+       sge.lkey = rdma->lkey;
+
+       wr.next = NULL;
+       c->wc_op = IB_WC_RECV;
+       wr.wr_id = (unsigned long) c;
+       wr.sg_list = &sge;
+       wr.num_sge = 1;
+       return ib_post_recv(rdma->qp, &wr, &bad_wr);
+
+ error:
+       P9_DPRINTK(P9_DEBUG_ERROR, "EIO\n");
+       return -EIO;
+}
+
+static int rdma_request(struct p9_client *client, struct p9_req_t *req)
+{
+       struct p9_trans_rdma *rdma = client->trans;
+       struct ib_send_wr wr, *bad_wr;
+       struct ib_sge sge;
+       int err = 0;
+       unsigned long flags;
+       struct p9_rdma_context *c = NULL;
+       struct p9_rdma_context *rpl_context = NULL;
+
+       /* Allocate an fcall for the reply */
+       rpl_context = kmalloc(sizeof *rpl_context, GFP_KERNEL);
+       if (!rpl_context)
+               goto err_close;
+
+       /*
+        * If the request has a buffer, steal it, otherwise
+        * allocate a new one.  Typically, requests should already
+        * have receive buffers allocated and just swap them around
+        */
+       if (!req->rc) {
+               req->rc = kmalloc(sizeof(struct p9_fcall)+client->msize,
+                                                               GFP_KERNEL);
+               if (req->rc) {
+                       req->rc->sdata = (char *) req->rc +
+                                               sizeof(struct p9_fcall);
+                       req->rc->capacity = client->msize;
+               }
+       }
+       rpl_context->rc = req->rc;
+       if (!rpl_context->rc) {
+               kfree(rpl_context);
+               goto err_close;
+       }
+
+       /*
+        * Post a receive buffer for this request. We need to ensure
+        * there is a reply buffer available for every outstanding
+        * request. A flushed request can result in no reply for an
+        * outstanding request, so we must keep a count to avoid
+        * overflowing the RQ.
+        */
+       if (atomic_inc_return(&rdma->rq_count) <= rdma->rq_depth) {
+               err = post_recv(client, rpl_context);
+               if (err) {
+                       kfree(rpl_context->rc);
+                       kfree(rpl_context);
+                       goto err_close;
+               }
+       } else
+               atomic_dec(&rdma->rq_count);
+
+       /* remove posted receive buffer from request structure */
+       req->rc = NULL;
+
+       /* Post the request */
+       c = kmalloc(sizeof *c, GFP_KERNEL);
+       if (!c)
+               goto err_close;
+       c->req = req;
+
+       c->busa = ib_dma_map_single(rdma->cm_id->device,
+                                   c->req->tc->sdata, c->req->tc->size,
+                                   DMA_TO_DEVICE);
+       if (ib_dma_mapping_error(rdma->cm_id->device, c->busa))
+               goto error;
+
+       sge.addr = c->busa;
+       sge.length = c->req->tc->size;
+       sge.lkey = rdma->lkey;
+
+       wr.next = NULL;
+       c->wc_op = IB_WC_SEND;
+       wr.wr_id = (unsigned long) c;
+       wr.opcode = IB_WR_SEND;
+       wr.send_flags = IB_SEND_SIGNALED;
+       wr.sg_list = &sge;
+       wr.num_sge = 1;
+
+       if (down_interruptible(&rdma->sq_sem))
+               goto error;
+
+       return ib_post_send(rdma->qp, &wr, &bad_wr);
+
+ error:
+       P9_DPRINTK(P9_DEBUG_ERROR, "EIO\n");
+       return -EIO;
+
+ err_close:
+       spin_lock_irqsave(&rdma->req_lock, flags);
+       if (rdma->state < P9_RDMA_CLOSING) {
+               rdma->state = P9_RDMA_CLOSING;
+               spin_unlock_irqrestore(&rdma->req_lock, flags);
+               rdma_disconnect(rdma->cm_id);
+       } else
+               spin_unlock_irqrestore(&rdma->req_lock, flags);
+       return err;
+}
+
+static void rdma_close(struct p9_client *client)
+{
+       struct p9_trans_rdma *rdma;
+
+       if (!client)
+               return;
+
+       rdma = client->trans;
+       if (!rdma)
+               return;
+
+       client->status = Disconnected;
+       rdma_disconnect(rdma->cm_id);
+       rdma_destroy_trans(rdma);
+}
+
+/**
+ * alloc_rdma - Allocate and initialize the rdma transport structure
+ * @msize: MTU
+ * @dotu: Extension attribute
+ * @opts: Mount options structure
+ */
+static struct p9_trans_rdma *alloc_rdma(struct p9_rdma_opts *opts)
+{
+       struct p9_trans_rdma *rdma;
+
+       rdma = kzalloc(sizeof(struct p9_trans_rdma), GFP_KERNEL);
+       if (!rdma)
+               return NULL;
+
+       rdma->sq_depth = opts->sq_depth;
+       rdma->rq_depth = opts->rq_depth;
+       rdma->timeout = opts->timeout;
+       spin_lock_init(&rdma->req_lock);
+       init_completion(&rdma->cm_done);
+       sema_init(&rdma->sq_sem, rdma->sq_depth);
+       atomic_set(&rdma->rq_count, 0);
+
+       return rdma;
+}
+
+/* its not clear to me we can do anything after send has been posted */
+static int rdma_cancel(struct p9_client *client, struct p9_req_t *req)
+{
+       return 1;
+}
+
+/**
+ * trans_create_rdma - Transport method for creating atransport instance
+ * @client: client instance
+ * @addr: IP address string
+ * @args: Mount options string
+ */
+static int
+rdma_create_trans(struct p9_client *client, const char *addr, char *args)
+{
+       int err;
+       struct p9_rdma_opts opts;
+       struct p9_trans_rdma *rdma;
+       struct rdma_conn_param conn_param;
+       struct ib_qp_init_attr qp_attr;
+       struct ib_device_attr devattr;
+
+       /* Parse the transport specific mount options */
+       err = parse_opts(args, &opts);
+       if (err < 0)
+               return err;
+
+       /* Create and initialize the RDMA transport structure */
+       rdma = alloc_rdma(&opts);
+       if (!rdma)
+               return -ENOMEM;
+
+       /* Create the RDMA CM ID */
+       rdma->cm_id = rdma_create_id(p9_cm_event_handler, client, RDMA_PS_TCP);
+       if (IS_ERR(rdma->cm_id))
+               goto error;
+
+       /* Resolve the server's address */
+       rdma->addr.sin_family = AF_INET;
+       rdma->addr.sin_addr.s_addr = in_aton(addr);
+       rdma->addr.sin_port = htons(opts.port);
+       err = rdma_resolve_addr(rdma->cm_id, NULL,
+                               (struct sockaddr *)&rdma->addr,
+                               rdma->timeout);
+       if (err)
+               goto error;
+       err = wait_for_completion_interruptible(&rdma->cm_done);
+       if (err || (rdma->state != P9_RDMA_ADDR_RESOLVED))
+               goto error;
+
+       /* Resolve the route to the server */
+       err = rdma_resolve_route(rdma->cm_id, rdma->timeout);
+       if (err)
+               goto error;
+       err = wait_for_completion_interruptible(&rdma->cm_done);
+       if (err || (rdma->state != P9_RDMA_ROUTE_RESOLVED))
+               goto error;
+
+       /* Query the device attributes */
+       err = ib_query_device(rdma->cm_id->device, &devattr);
+       if (err)
+               goto error;
+
+       /* Create the Completion Queue */
+       rdma->cq = ib_create_cq(rdma->cm_id->device, cq_comp_handler,
+                               cq_event_handler, client,
+                               opts.sq_depth + opts.rq_depth + 1, 0);
+       if (IS_ERR(rdma->cq))
+               goto error;
+       ib_req_notify_cq(rdma->cq, IB_CQ_NEXT_COMP);
+
+       /* Create the Protection Domain */
+       rdma->pd = ib_alloc_pd(rdma->cm_id->device);
+       if (IS_ERR(rdma->pd))
+               goto error;
+
+       /* Cache the DMA lkey in the transport */
+       rdma->dma_mr = NULL;
+       if (devattr.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY)
+               rdma->lkey = rdma->cm_id->device->local_dma_lkey;
+       else {
+               rdma->dma_mr = ib_get_dma_mr(rdma->pd, IB_ACCESS_LOCAL_WRITE);
+               if (IS_ERR(rdma->dma_mr))
+                       goto error;
+               rdma->lkey = rdma->dma_mr->lkey;
+       }
+
+       /* Create the Queue Pair */
+       memset(&qp_attr, 0, sizeof qp_attr);
+       qp_attr.event_handler = qp_event_handler;
+       qp_attr.qp_context = client;
+       qp_attr.cap.max_send_wr = opts.sq_depth;
+       qp_attr.cap.max_recv_wr = opts.rq_depth;
+       qp_attr.cap.max_send_sge = P9_RDMA_SEND_SGE;
+       qp_attr.cap.max_recv_sge = P9_RDMA_RECV_SGE;
+       qp_attr.sq_sig_type = IB_SIGNAL_REQ_WR;
+       qp_attr.qp_type = IB_QPT_RC;
+       qp_attr.send_cq = rdma->cq;
+       qp_attr.recv_cq = rdma->cq;
+       err = rdma_create_qp(rdma->cm_id, rdma->pd, &qp_attr);
+       if (err)
+               goto error;
+       rdma->qp = rdma->cm_id->qp;
+
+       /* Request a connection */
+       memset(&conn_param, 0, sizeof(conn_param));
+       conn_param.private_data = NULL;
+       conn_param.private_data_len = 0;
+       conn_param.responder_resources = P9_RDMA_IRD;
+       conn_param.initiator_depth = P9_RDMA_ORD;
+       err = rdma_connect(rdma->cm_id, &conn_param);
+       if (err)
+               goto error;
+       err = wait_for_completion_interruptible(&rdma->cm_done);
+       if (err || (rdma->state != P9_RDMA_CONNECTED))
+               goto error;
+
+       client->trans = rdma;
+       client->status = Connected;
+
+       return 0;
+
+error:
+       rdma_destroy_trans(rdma);
+       return -ENOTCONN;
+}
+
+static struct p9_trans_module p9_rdma_trans = {
+       .name = "rdma",
+       .maxsize = P9_RDMA_MAXSIZE,
+       .def = 0,
+       .owner = THIS_MODULE,
+       .create = rdma_create_trans,
+       .close = rdma_close,
+       .request = rdma_request,
+       .cancel = rdma_cancel,
+};
+
+/**
+ * p9_trans_rdma_init - Register the 9P RDMA transport driver
+ */
+static int __init p9_trans_rdma_init(void)
+{
+       v9fs_register_trans(&p9_rdma_trans);
+       return 0;
+}
+
+static void __exit p9_trans_rdma_exit(void)
+{
+       v9fs_unregister_trans(&p9_rdma_trans);
+}
+
+module_init(p9_trans_rdma_init);
+module_exit(p9_trans_rdma_exit);
+
+MODULE_AUTHOR("Tom Tucker <tom@opengridcomputing.com>");
+MODULE_DESCRIPTION("RDMA Transport for 9P");
+MODULE_LICENSE("Dual BSD/GPL");
index 8b06fa9004828c937e359df4c3c0d0c0bfa0ecf3..03e389e8d945d2b93b2d31b408a2ee78c6f0c8b9 100644 (file)
@@ -545,9 +545,10 @@ static void cbq_ovl_delay(struct cbq_class *cl)
                        expires = ktime_set(0, 0);
                        expires = ktime_add_ns(expires, PSCHED_US2NS(sched));
                        if (hrtimer_try_to_cancel(&q->delay_timer) &&
-                           ktime_to_ns(ktime_sub(q->delay_timer.expires,
-                                                 expires)) > 0)
-                               q->delay_timer.expires = expires;
+                           ktime_to_ns(ktime_sub(
+                                       hrtimer_get_expires(&q->delay_timer),
+                                       expires)) > 0)
+                               hrtimer_set_expires(&q->delay_timer, expires);
                        hrtimer_restart(&q->delay_timer);
                        cl->delayed = 1;
                        cl->xstats.overactions++;
index c647aab8d418c508c9088789c847fae59745c049..dc504d308ec003b714df60497ca813b017d73112 100644 (file)
@@ -711,28 +711,30 @@ static struct sock *unix_find_other(struct net *net,
                                    int type, unsigned hash, int *error)
 {
        struct sock *u;
-       struct nameidata nd;
+       struct path path;
        int err = 0;
 
        if (sunname->sun_path[0]) {
-               err = path_lookup(sunname->sun_path, LOOKUP_FOLLOW, &nd);
+               struct inode *inode;
+               err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path);
                if (err)
                        goto fail;
-               err = vfs_permission(&nd, MAY_WRITE);
+               inode = path.dentry->d_inode;
+               err = inode_permission(inode, MAY_WRITE);
                if (err)
                        goto put_fail;
 
                err = -ECONNREFUSED;
-               if (!S_ISSOCK(nd.path.dentry->d_inode->i_mode))
+               if (!S_ISSOCK(inode->i_mode))
                        goto put_fail;
-               u = unix_find_socket_byinode(net, nd.path.dentry->d_inode);
+               u = unix_find_socket_byinode(net, inode);
                if (!u)
                        goto put_fail;
 
                if (u->sk_type == type)
-                       touch_atime(nd.path.mnt, nd.path.dentry);
+                       touch_atime(path.mnt, path.dentry);
 
-               path_put(&nd.path);
+               path_put(&path);
 
                err=-EPROTOTYPE;
                if (u->sk_type != type) {
@@ -753,7 +755,7 @@ static struct sock *unix_find_other(struct net *net,
        return u;
 
 put_fail:
-       path_put(&nd.path);
+       path_put(&path);
 fail:
        *error=err;
        return NULL;
index e1fb471cc50182e5e907bef3caa566f8ede7e6d4..4b02f5a0e6560f4c886d413409d5507ffe6b0356 100644 (file)
@@ -13,6 +13,12 @@ config SAMPLE_MARKERS
        help
          This build markers example modules.
 
+config SAMPLE_TRACEPOINTS
+       tristate "Build tracepoints examples -- loadable modules only"
+       depends on TRACEPOINTS && m
+       help
+         This build tracepoints example modules.
+
 config SAMPLE_KOBJECT
        tristate "Build kobject examples"
        help
index 2e02575f779441bf1babe686f50f0b7fb1d3e03e..10eaca89fe17913875f90cf0354a9478978db018 100644 (file)
@@ -1,3 +1,3 @@
 # Makefile for Linux samples code
 
-obj-$(CONFIG_SAMPLES)  += markers/ kobject/ kprobes/
+obj-$(CONFIG_SAMPLES)  += markers/ kobject/ kprobes/ tracepoints/
index c8e099d4d1fdd7d5cec4a7148d259ee6281878cc..2dfb3b32937e03e7621c30212bdc12880f4c7467 100644 (file)
@@ -81,6 +81,7 @@ static void __exit probe_fini(void)
                        probe_array[i].probe_func, &probe_array[i]);
        printk(KERN_INFO "Number of event b : %u\n",
                        atomic_read(&eventb_count));
+       marker_synchronize_unregister();
 }
 
 module_init(probe_init);
diff --git a/samples/tracepoints/Makefile b/samples/tracepoints/Makefile
new file mode 100644 (file)
index 0000000..36479ad
--- /dev/null
@@ -0,0 +1,6 @@
+# builds the tracepoint example kernel modules;
+# then to use one (as root):  insmod <module_name.ko>
+
+obj-$(CONFIG_SAMPLE_TRACEPOINTS) += tracepoint-sample.o
+obj-$(CONFIG_SAMPLE_TRACEPOINTS) += tracepoint-probe-sample.o
+obj-$(CONFIG_SAMPLE_TRACEPOINTS) += tracepoint-probe-sample2.o
diff --git a/samples/tracepoints/tp-samples-trace.h b/samples/tracepoints/tp-samples-trace.h
new file mode 100644 (file)
index 0000000..0216b55
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _TP_SAMPLES_TRACE_H
+#define _TP_SAMPLES_TRACE_H
+
+#include <linux/proc_fs.h>     /* for struct inode and struct file */
+#include <linux/tracepoint.h>
+
+DEFINE_TRACE(subsys_event,
+       TPPROTO(struct inode *inode, struct file *file),
+       TPARGS(inode, file));
+DEFINE_TRACE(subsys_eventb,
+       TPPROTO(void),
+       TPARGS());
+#endif
diff --git a/samples/tracepoints/tracepoint-probe-sample.c b/samples/tracepoints/tracepoint-probe-sample.c
new file mode 100644 (file)
index 0000000..55abfdd
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * tracepoint-probe-sample.c
+ *
+ * sample tracepoint probes.
+ */
+
+#include <linux/module.h>
+#include <linux/file.h>
+#include <linux/dcache.h>
+#include "tp-samples-trace.h"
+
+/*
+ * Here the caller only guarantees locking for struct file and struct inode.
+ * Locking must therefore be done in the probe to use the dentry.
+ */
+static void probe_subsys_event(struct inode *inode, struct file *file)
+{
+       path_get(&file->f_path);
+       dget(file->f_path.dentry);
+       printk(KERN_INFO "Event is encountered with filename %s\n",
+               file->f_path.dentry->d_name.name);
+       dput(file->f_path.dentry);
+       path_put(&file->f_path);
+}
+
+static void probe_subsys_eventb(void)
+{
+       printk(KERN_INFO "Event B is encountered\n");
+}
+
+int __init tp_sample_trace_init(void)
+{
+       int ret;
+
+       ret = register_trace_subsys_event(probe_subsys_event);
+       WARN_ON(ret);
+       ret = register_trace_subsys_eventb(probe_subsys_eventb);
+       WARN_ON(ret);
+
+       return 0;
+}
+
+module_init(tp_sample_trace_init);
+
+void __exit tp_sample_trace_exit(void)
+{
+       unregister_trace_subsys_eventb(probe_subsys_eventb);
+       unregister_trace_subsys_event(probe_subsys_event);
+}
+
+module_exit(tp_sample_trace_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Tracepoint Probes Samples");
diff --git a/samples/tracepoints/tracepoint-probe-sample2.c b/samples/tracepoints/tracepoint-probe-sample2.c
new file mode 100644 (file)
index 0000000..5e9fcf4
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * tracepoint-probe-sample2.c
+ *
+ * 2nd sample tracepoint probes.
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include "tp-samples-trace.h"
+
+/*
+ * Here the caller only guarantees locking for struct file and struct inode.
+ * Locking must therefore be done in the probe to use the dentry.
+ */
+static void probe_subsys_event(struct inode *inode, struct file *file)
+{
+       printk(KERN_INFO "Event is encountered with inode number %lu\n",
+               inode->i_ino);
+}
+
+int __init tp_sample_trace_init(void)
+{
+       int ret;
+
+       ret = register_trace_subsys_event(probe_subsys_event);
+       WARN_ON(ret);
+
+       return 0;
+}
+
+module_init(tp_sample_trace_init);
+
+void __exit tp_sample_trace_exit(void)
+{
+       unregister_trace_subsys_event(probe_subsys_event);
+}
+
+module_exit(tp_sample_trace_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Tracepoint Probes Samples");
diff --git a/samples/tracepoints/tracepoint-sample.c b/samples/tracepoints/tracepoint-sample.c
new file mode 100644 (file)
index 0000000..4ae4b7f
--- /dev/null
@@ -0,0 +1,53 @@
+/* tracepoint-sample.c
+ *
+ * Executes a tracepoint when /proc/tracepoint-example is opened.
+ *
+ * (C) Copyright 2007 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include "tp-samples-trace.h"
+
+struct proc_dir_entry *pentry_example;
+
+static int my_open(struct inode *inode, struct file *file)
+{
+       int i;
+
+       trace_subsys_event(inode, file);
+       for (i = 0; i < 10; i++)
+               trace_subsys_eventb();
+       return -EPERM;
+}
+
+static struct file_operations mark_ops = {
+       .open = my_open,
+};
+
+static int example_init(void)
+{
+       printk(KERN_ALERT "example init\n");
+       pentry_example = proc_create("tracepoint-example", 0444, NULL,
+               &mark_ops);
+       if (!pentry_example)
+               return -EPERM;
+       return 0;
+}
+
+static void example_exit(void)
+{
+       printk(KERN_ALERT "example exit\n");
+       remove_proc_entry("tracepoint-example", NULL);
+}
+
+module_init(example_init)
+module_exit(example_exit)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Tracepoint example");
index 277cfe0b71001e69bc67d3eda6407250d07d7ab8..5ed4cbf1e0e1f412346431a870f1300a2d77a50b 100644 (file)
@@ -198,10 +198,17 @@ cmd_modversions =                                                 \
        fi;
 endif
 
+ifdef CONFIG_FTRACE_MCOUNT_RECORD
+cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl \
+       "$(ARCH)" "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" \
+       "$(MV)" "$(@)";
+endif
+
 define rule_cc_o_c
        $(call echo-cmd,checksrc) $(cmd_checksrc)                         \
        $(call echo-cmd,cc_o_c) $(cmd_cc_o_c);                            \
        $(cmd_modversions)                                                \
+       $(cmd_record_mcount)                                              \
        scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' >    \
                                                      $(dot-target).tmp;  \
        rm -f $(depfile);                                                 \
index 2243353fe55dc00058cc9b96613a7a092e26226b..5e7316e5aa395a4c5da260c1d2890336b4c70039 100644 (file)
 #      dmesg | perl scripts/bootgraph.pl > output.svg
 #
 
-my @rows;
-my %start, %end, %row;
+my %start, %end;
 my $done = 0;
-my $rowcount = 0;
 my $maxtime = 0;
 my $firsttime = 100;
 my $count = 0;
+my %pids;
+
 while (<>) {
        my $line = $_;
        if ($line =~ /([0-9\.]+)\] calling  ([a-zA-Z0-9\_]+)\+/) {
@@ -54,14 +54,8 @@ while (<>) {
                                $firsttime = $1;
                        }
                }
-               $row{$func} = 1;
                if ($line =~ /\@ ([0-9]+)/) {
-                       my $pid = $1;
-                       if (!defined($rows[$pid])) {
-                               $rowcount = $rowcount + 1;
-                               $rows[$pid] = $rowcount;
-                       }
-                       $row{$func} = $rows[$pid];
+                       $pids{$func} = $1;
                }
                $count = $count + 1;
        }
@@ -109,17 +103,25 @@ $styles[11] = "fill:rgb(128,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(
 my $mult = 950.0 / ($maxtime - $firsttime);
 my $threshold = ($maxtime - $firsttime) / 60.0;
 my $stylecounter = 0;
+my %rows;
+my $rowscount = 1;
 while (($key,$value) = each %start) {
        my $duration = $end{$key} - $start{$key};
 
        if ($duration >= $threshold) {
                my $s, $s2, $e, $y;
+               $pid = $pids{$key};
+
+               if (!defined($rows{$pid})) {
+                       $rows{$pid} = $rowscount;
+                       $rowscount = $rowscount + 1;
+               }
                $s = ($value - $firsttime) * $mult;
                $s2 = $s + 6;
                $e = ($end{$key} - $firsttime) * $mult;
                $w = $e - $s;
 
-               $y = $row{$key} * 150;
+               $y = $rows{$pid} * 150;
                $y2 = $y + 4;
 
                $style = $styles[$stylecounter];
index e30bac141b21ee1894f62135b8727efa276fe38e..f88bb3e21cda9c9a29470004f9e964907a1a17bb 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/perl -w
-# (c) 2001, Dave Jones. <davej@codemonkey.org.uk> (the file handling bit)
+# (c) 2001, Dave Jones. <davej@redhat.com> (the file handling bit)
 # (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
 # (c) 2007, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite, etc)
 # Licensed under the terms of the GNU GPL License version 2
index 366f8c7f62bf6de4d82a1ae543e6157a7de07548..41564b142c0451f8512905ee5534bec1910544b3 100755 (executable)
@@ -119,5 +119,5 @@ sed -n -e '/^\#define/ { s/[^_]*__NR_\([^[:space:]]*\).*/\
 \#endif/p }' $1
 }
 
-(ignore_list && syscall_list ${srctree}/include/asm-x86/unistd_32.h) | \
+(ignore_list && syscall_list ${srctree}/arch/x86/include/asm/unistd_32.h) | \
 $* -E -x c - > /dev/null
index fa1a7d565903075ef39d12ba69ecf580b3c37de9..fa8c2dd9c983ef3fa7617c0c87a28cb9ea4546b0 100644 (file)
@@ -4,7 +4,11 @@
 
 PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config
 
+ifdef KBUILD_KCONFIG
+Kconfig := $(KBUILD_KCONFIG)
+else
 Kconfig := arch/$(SRCARCH)/Kconfig
+endif
 
 xconfig: $(obj)/qconf
        $< $(Kconfig)
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
new file mode 100755 (executable)
index 0000000..f56d760
--- /dev/null
@@ -0,0 +1,395 @@
+#!/usr/bin/perl -w
+# (c) 2008, Steven Rostedt <srostedt@redhat.com>
+# Licensed under the terms of the GNU GPL License version 2
+#
+# recordmcount.pl - makes a section called __mcount_loc that holds
+#                   all the offsets to the calls to mcount.
+#
+#
+# What we want to end up with is a section in vmlinux called
+# __mcount_loc that contains a list of pointers to all the
+# call sites in the kernel that call mcount. Later on boot up, the kernel
+# will read this list, save the locations and turn them into nops.
+# When tracing or profiling is later enabled, these locations will then
+# be converted back to pointers to some function.
+#
+# This is no easy feat. This script is called just after the original
+# object is compiled and before it is linked.
+#
+# The references to the call sites are offsets from the section of text
+# that the call site is in. Hence, all functions in a section that
+# has a call site to mcount, will have the offset from the beginning of
+# the section and not the beginning of the function.
+#
+# The trick is to find a way to record the beginning of the section.
+# The way we do this is to look at the first function in the section
+# which will also be the location of that section after final link.
+# e.g.
+#
+#  .section ".text.sched"
+#  .globl my_func
+#  my_func:
+#        [...]
+#        call mcount  (offset: 0x5)
+#        [...]
+#        ret
+#  other_func:
+#        [...]
+#        call mcount (offset: 0x1b)
+#        [...]
+#
+# Both relocation offsets for the mcounts in the above example will be
+# offset from .text.sched. If we make another file called tmp.s with:
+#
+#  .section __mcount_loc
+#  .quad  my_func + 0x5
+#  .quad  my_func + 0x1b
+#
+# We can then compile this tmp.s into tmp.o, and link it to the original
+# object.
+#
+# But this gets hard if my_func is not globl (a static function).
+# In such a case we have:
+#
+#  .section ".text.sched"
+#  my_func:
+#        [...]
+#        call mcount  (offset: 0x5)
+#        [...]
+#        ret
+#  .globl my_func
+#  other_func:
+#        [...]
+#        call mcount (offset: 0x1b)
+#        [...]
+#
+# If we make the tmp.s the same as above, when we link together with
+# the original object, we will end up with two symbols for my_func:
+# one local, one global.  After final compile, we will end up with
+# an undefined reference to my_func.
+#
+# Since local objects can reference local variables, we need to find
+# a way to make tmp.o reference the local objects of the original object
+# file after it is linked together. To do this, we convert the my_func
+# into a global symbol before linking tmp.o. Then after we link tmp.o
+# we will only have a single symbol for my_func that is global.
+# We can convert my_func back into a local symbol and we are done.
+#
+# Here are the steps we take:
+#
+# 1) Record all the local symbols by using 'nm'
+# 2) Use objdump to find all the call site offsets and sections for
+#    mcount.
+# 3) Compile the list into its own object.
+# 4) Do we have to deal with local functions? If not, go to step 8.
+# 5) Make an object that converts these local functions to global symbols
+#    with objcopy.
+# 6) Link together this new object with the list object.
+# 7) Convert the local functions back to local symbols and rename
+#    the result as the original object.
+#    End.
+# 8) Link the object with the list object.
+# 9) Move the result back to the original object.
+#    End.
+#
+
+use strict;
+
+my $P = $0;
+$P =~ s@.*/@@g;
+
+my $V = '0.1';
+
+if ($#ARGV < 6) {
+       print "usage: $P arch objdump objcopy cc ld nm rm mv inputfile\n";
+       print "version: $V\n";
+       exit(1);
+}
+
+my ($arch, $objdump, $objcopy, $cc, $ld, $nm, $rm, $mv, $inputfile) = @ARGV;
+
+$objdump = "objdump" if ((length $objdump) == 0);
+$objcopy = "objcopy" if ((length $objcopy) == 0);
+$cc = "gcc" if ((length $cc) == 0);
+$ld = "ld" if ((length $ld) == 0);
+$nm = "nm" if ((length $nm) == 0);
+$rm = "rm" if ((length $rm) == 0);
+$mv = "mv" if ((length $mv) == 0);
+
+#print STDERR "running: $P '$arch' '$objdump' '$objcopy' '$cc' '$ld' " .
+#    "'$nm' '$rm' '$mv' '$inputfile'\n";
+
+my %locals;            # List of local (static) functions
+my %weak;              # List of weak functions
+my %convert;           # List of local functions used that needs conversion
+
+my $type;
+my $section_regex;     # Find the start of a section
+my $function_regex;    # Find the name of a function
+                       #    (return offset and func name)
+my $mcount_regex;      # Find the call site to mcount (return offset)
+
+if ($arch eq "x86_64") {
+    $section_regex = "Disassembly of section";
+    $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
+    $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount([+-]0x[0-9a-zA-Z]+)?\$";
+    $type = ".quad";
+
+    # force flags for this arch
+    $ld .= " -m elf_x86_64";
+    $objdump .= " -M x86-64";
+    $objcopy .= " -O elf64-x86-64";
+    $cc .= " -m64";
+
+} elsif ($arch eq "i386") {
+    $section_regex = "Disassembly of section";
+    $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
+    $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$";
+    $type = ".long";
+
+    # force flags for this arch
+    $ld .= " -m elf_i386";
+    $objdump .= " -M i386";
+    $objcopy .= " -O elf32-i386";
+    $cc .= " -m32";
+
+} else {
+    die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";
+}
+
+my $text_found = 0;
+my $read_function = 0;
+my $opened = 0;
+my $mcount_section = "__mcount_loc";
+
+my $dirname;
+my $filename;
+my $prefix;
+my $ext;
+
+if ($inputfile =~ m,^(.*)/([^/]*)$,) {
+    $dirname = $1;
+    $filename = $2;
+} else {
+    $dirname = ".";
+    $filename = $inputfile;
+}
+
+if ($filename =~ m,^(.*)(\.\S),) {
+    $prefix = $1;
+    $ext = $2;
+} else {
+    $prefix = $filename;
+    $ext = "";
+}
+
+my $mcount_s = $dirname . "/.tmp_mc_" . $prefix . ".s";
+my $mcount_o = $dirname . "/.tmp_mc_" . $prefix . ".o";
+
+#
+# --globalize-symbols came out in 2.17, we must test the version
+# of objcopy, and if it is less than 2.17, then we can not
+# record local functions.
+my $use_locals = 01;
+my $local_warn_once = 0;
+my $found_version = 0;
+
+open (IN, "$objcopy --version |") || die "error running $objcopy";
+while (<IN>) {
+    if (/objcopy.*\s(\d+)\.(\d+)/) {
+       my $major = $1;
+       my $minor = $2;
+
+       $found_version = 1;
+       if ($major < 2 ||
+           ($major == 2 && $minor < 17)) {
+           $use_locals = 0;
+       }
+       last;
+    }
+}
+close (IN);
+
+if (!$found_version) {
+    print STDERR "WARNING: could not find objcopy version.\n" .
+       "\tDisabling local function references.\n";
+}
+
+
+#
+# Step 1: find all the local (static functions) and weak symbols.
+#        't' is local, 'w/W' is weak (we never use a weak function)
+#
+open (IN, "$nm $inputfile|") || die "error running $nm";
+while (<IN>) {
+    if (/^[0-9a-fA-F]+\s+t\s+(\S+)/) {
+       $locals{$1} = 1;
+    } elsif (/^[0-9a-fA-F]+\s+([wW])\s+(\S+)/) {
+       $weak{$2} = $1;
+    }
+}
+close(IN);
+
+my @offsets;           # Array of offsets of mcount callers
+my $ref_func;          # reference function to use for offsets
+my $offset = 0;                # offset of ref_func to section beginning
+
+##
+# update_funcs - print out the current mcount callers
+#
+#  Go through the list of offsets to callers and write them to
+#  the output file in a format that can be read by an assembler.
+#
+sub update_funcs
+{
+    return if ($#offsets < 0);
+
+    defined($ref_func) || die "No function to reference";
+
+    # A section only had a weak function, to represent it.
+    # Unfortunately, a weak function may be overwritten by another
+    # function of the same name, making all these offsets incorrect.
+    # To be safe, we simply print a warning and bail.
+    if (defined $weak{$ref_func}) {
+       print STDERR
+           "$inputfile: WARNING: referencing weak function" .
+           " $ref_func for mcount\n";
+       return;
+    }
+
+    # is this function static? If so, note this fact.
+    if (defined $locals{$ref_func}) {
+
+       # only use locals if objcopy supports globalize-symbols
+       if (!$use_locals) {
+           return;
+       }
+       $convert{$ref_func} = 1;
+    }
+
+    # Loop through all the mcount caller offsets and print a reference
+    # to the caller based from the ref_func.
+    for (my $i=0; $i <= $#offsets; $i++) {
+       if (!$opened) {
+           open(FILE, ">$mcount_s") || die "can't create $mcount_s\n";
+           $opened = 1;
+           print FILE "\t.section $mcount_section,\"a\",\@progbits\n";
+       }
+       printf FILE "\t%s %s + %d\n", $type, $ref_func, $offsets[$i] - $offset;
+    }
+}
+
+#
+# Step 2: find the sections and mcount call sites
+#
+open(IN, "$objdump -dr $inputfile|") || die "error running $objdump";
+
+my $text;
+
+while (<IN>) {
+    # is it a section?
+    if (/$section_regex/) {
+       $read_function = 1;
+       # print out any recorded offsets
+       update_funcs() if ($text_found);
+
+       # reset all markers and arrays
+       $text_found = 0;
+       undef($ref_func);
+       undef(@offsets);
+
+    # section found, now is this a start of a function?
+    } elsif ($read_function && /$function_regex/) {
+       $text_found = 1;
+       $offset = hex $1;
+       $text = $2;
+
+       # if this is either a local function or a weak function
+       # keep looking for functions that are global that
+       # we can use safely.
+       if (!defined($locals{$text}) && !defined($weak{$text})) {
+           $ref_func = $text;
+           $read_function = 0;
+       } else {
+           # if we already have a function, and this is weak, skip it
+           if (!defined($ref_func) || !defined($weak{$text})) {
+               $ref_func = $text;
+           }
+       }
+    }
+
+    # is this a call site to mcount? If so, record it to print later
+    if ($text_found && /$mcount_regex/) {
+       $offsets[$#offsets + 1] = hex $1;
+    }
+}
+
+# dump out anymore offsets that may have been found
+update_funcs() if ($text_found);
+
+# If we did not find any mcount callers, we are done (do nothing).
+if (!$opened) {
+    exit(0);
+}
+
+close(FILE);
+
+#
+# Step 3: Compile the file that holds the list of call sites to mcount.
+#
+`$cc -o $mcount_o -c $mcount_s`;
+
+my @converts = keys %convert;
+
+#
+# Step 4: Do we have sections that started with local functions?
+#
+if ($#converts >= 0) {
+    my $globallist = "";
+    my $locallist = "";
+
+    foreach my $con (@converts) {
+       $globallist .= " --globalize-symbol $con";
+       $locallist .= " --localize-symbol $con";
+    }
+
+    my $globalobj = $dirname . "/.tmp_gl_" . $filename;
+    my $globalmix = $dirname . "/.tmp_mx_" . $filename;
+
+    #
+    # Step 5: set up each local function as a global
+    #
+    `$objcopy $globallist $inputfile $globalobj`;
+
+    #
+    # Step 6: Link the global version to our list.
+    #
+    `$ld -r $globalobj $mcount_o -o $globalmix`;
+
+    #
+    # Step 7: Convert the local functions back into local symbols
+    #
+    `$objcopy $locallist $globalmix $inputfile`;
+
+    # Remove the temp files
+    `$rm $globalobj $globalmix`;
+
+} else {
+
+    my $mix = $dirname . "/.tmp_mx_" . $filename;
+
+    #
+    # Step 8: Link the object with our list of call sites object.
+    #
+    `$ld -r $inputfile $mcount_o -o $mix`;
+
+    #
+    # Step 9: Move the result back to the original object.
+    #
+    `$mv $mix $inputfile`;
+}
+
+# Clean up the temp files
+`$rm $mcount_o $mcount_s`;
+
+exit(0);
index 576e511990794eacfad7ad525722c4fa077ae852..3e3fde7c1d2bf2a48af6d19d72e47f3adc95514b 100644 (file)
@@ -75,6 +75,7 @@
 #include <linux/string.h>
 #include <linux/selinux.h>
 #include <linux/mutex.h>
+#include <linux/posix-timers.h>
 
 #include "avc.h"
 #include "objsec.h"
@@ -2322,13 +2323,7 @@ static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm)
                        initrlim = init_task.signal->rlim+i;
                        rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur);
                }
-               if (current->signal->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) {
-                       /*
-                        * This will cause RLIMIT_CPU calculations
-                        * to be refigured.
-                        */
-                       current->it_prof_expires = jiffies_to_cputime(1);
-               }
+               update_rlimit_cpu(rlim->rlim_cur);
        }
 
        /* Wake up the parent if it is waiting so that it can
index e6beb92c6933f9df991af076f3ed17fb7b36b214..b4590df0746689c8e3d4493eb894c8442b583055 100644 (file)
@@ -159,7 +159,7 @@ static int i2sbus_add_dev(struct macio_dev *macio,
        struct i2sbus_dev *dev;
        struct device_node *child = NULL, *sound = NULL;
        struct resource *r;
-       int i, layout = 0, rlen;
+       int i, layout = 0, rlen, ok = force;
        static const char *rnames[] = { "i2sbus: %s (control)",
                                        "i2sbus: %s (tx)",
                                        "i2sbus: %s (rx)" };
@@ -192,7 +192,7 @@ static int i2sbus_add_dev(struct macio_dev *macio,
                        layout = *layout_id;
                        snprintf(dev->sound.modalias, 32,
                                 "sound-layout-%d", layout);
-                       force = 1;
+                       ok = 1;
                }
        }
        /* for the time being, until we can handle non-layout-id
@@ -201,7 +201,7 @@ static int i2sbus_add_dev(struct macio_dev *macio,
         * When there are two i2s busses and only one has a layout-id,
         * then this depends on the order, but that isn't important
         * either as the second one in that case is just a modem. */
-       if (!force) {
+       if (!ok) {
                kfree(dev);
                return -ENODEV;
        }
index 1c93eb77cb99fe75856055f04d74d1e3c8007e81..75a0d746fb60ff50a8eccdefab76e67c380d3e9d 100644 (file)
@@ -194,7 +194,7 @@ int __pxa2xx_pcm_open(struct snd_pcm_substream *substream)
                goto out;
 
        ret = -ENOMEM;
-       rtd = kmalloc(sizeof(*rtd), GFP_KERNEL);
+       rtd = kzalloc(sizeof(*rtd), GFP_KERNEL);
        if (!rtd)
                goto out;
        rtd->dma_desc_array =
index 1af62b8b86c6366321a2a707b76f6bcf6ae3e545..e17836680f4980f5fd0d9aad9de4ed674be46a93 100644 (file)
@@ -2283,7 +2283,7 @@ static int snd_pcm_oss_open_file(struct file *file,
        int idx, err;
        struct snd_pcm_oss_file *pcm_oss_file;
        struct snd_pcm_substream *substream;
-       unsigned int f_mode = file->f_mode;
+       fmode_t f_mode = file->f_mode;
 
        if (rpcm_oss_file)
                *rpcm_oss_file = NULL;
index e341f3f83b6a8ee2e1abd619a9014dadc19afd5b..1f42e406311835a5c98aae272d9969ec6d5aa61b 100644 (file)
@@ -34,7 +34,7 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
                chip->thalf = 0;
                if (!atomic_read(&chip->timer_active))
                        return HRTIMER_NORESTART;
-               hrtimer_forward(&chip->timer, chip->timer.expires,
+               hrtimer_forward(&chip->timer, hrtimer_get_expires(&chip->timer),
                                ktime_set(0, chip->ns_rem));
                return HRTIMER_RESTART;
        }
@@ -118,7 +118,8 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
        chip->ns_rem = PCSP_PERIOD_NS();
        ns = (chip->thalf ? PCSP_CALC_NS(timer_cnt) : chip->ns_rem);
        chip->ns_rem -= ns;
-       hrtimer_forward(&chip->timer, chip->timer.expires, ktime_set(0, ns));
+       hrtimer_forward(&chip->timer, hrtimer_get_expires(&chip->timer),
+                                                       ktime_set(0, ns));
        return HRTIMER_RESTART;
 
 exit_nr_unlock2:
index 23018a7c063a3fc553aa73ef29159cbe9d317012..81e1f443d0948b223cdfdaf4d58aeb68452e59fa 100644 (file)
@@ -93,7 +93,7 @@ static struct au1550_state {
        spinlock_t      lock;
        struct mutex open_mutex;
        struct mutex sem;
-       mode_t          open_mode;
+       fmode_t          open_mode;
        wait_queue_head_t open_wait;
 
        struct dmabuf {
index d978b009656405d17f9069c64f604cd632a4729f..1cb13fe56ec46fa617e19fa98c5f46a5034e9e45 100644 (file)
@@ -129,7 +129,7 @@ typedef struct {
     int (*mixer_ioctl)(u_int, u_long); /* optional */
     int (*write_sq_setup)(void);       /* optional */
     int (*read_sq_setup)(void);                /* optional */
-    int (*sq_open)(mode_t);            /* optional */
+    int (*sq_open)(fmode_t);           /* optional */
     int (*state_info)(char *, size_t); /* optional */
     void (*abort_read)(void);          /* optional */
     int min_dsp_speed;
@@ -235,7 +235,7 @@ struct sound_queue {
      */
     int active;
     wait_queue_head_t action_queue, open_queue, sync_queue;
-    int open_mode;
+    fmode_t open_mode;
     int busy, syncing, xruns, died;
 };
 
index 285239d64b8279d133c24617010e7058bfcbe448..4d45bd63718b804afd012cba07e628f457525bdf 100644 (file)
@@ -143,7 +143,7 @@ static int AtaMixerIoctl(u_int cmd, u_long arg);
 static int TTMixerIoctl(u_int cmd, u_long arg);
 static int FalconMixerIoctl(u_int cmd, u_long arg);
 static int AtaWriteSqSetup(void);
-static int AtaSqOpen(mode_t mode);
+static int AtaSqOpen(fmode_t mode);
 static int TTStateInfo(char *buffer, size_t space);
 static int FalconStateInfo(char *buffer, size_t space);
 
@@ -1461,7 +1461,7 @@ static int AtaWriteSqSetup(void)
        return 0 ;
 }
 
-static int AtaSqOpen(mode_t mode)
+static int AtaSqOpen(fmode_t mode)
 {
        write_sq_ignore_int = 1;
        return 0 ;
index 95fc5c681755eafff96d7165c1eeb3b9da72a781..b8239f3168fb80b89506902ab9a064b295216b25 100644 (file)
@@ -212,7 +212,7 @@ static int irq_installed;
 #endif /* MODULE */
 
 /* control over who can modify resources shared between play/record */
-static mode_t shared_resource_owner;
+static fmode_t shared_resource_owner;
 static int shared_resources_initialised;
 
     /*
@@ -668,7 +668,7 @@ static inline void sq_init_waitqueue(struct sound_queue *sq)
 
 #if 0 /* blocking open() */
 static inline void sq_wake_up(struct sound_queue *sq, struct file *file,
-                             mode_t mode)
+                             fmode_t mode)
 {
        if (file->f_mode & mode) {
                sq->busy = 0; /* CHECK: IS THIS OK??? */
@@ -677,7 +677,7 @@ static inline void sq_wake_up(struct sound_queue *sq, struct file *file,
 }
 #endif
 
-static int sq_open2(struct sound_queue *sq, struct file *file, mode_t mode,
+static int sq_open2(struct sound_queue *sq, struct file *file, fmode_t mode,
                    int numbufs, int bufsize)
 {
        int rc = 0;
@@ -891,10 +891,10 @@ static int sq_release(struct inode *inode, struct file *file)
    is the owner - if we have problems.
 */
 
-static int shared_resources_are_mine(mode_t md)
+static int shared_resources_are_mine(fmode_t md)
 {
        if (shared_resource_owner)
-               return (shared_resource_owner & md ) ;
+               return (shared_resource_owner & md) != 0;
        else {
                shared_resource_owner = md ;
                return 1 ;
index 61b3955481c56da1f7b88ca2ac43fd08ed5ef15a..c8be47ec2b7ea25c1a5aa722f44458445a5e7d83 100644 (file)
@@ -211,7 +211,7 @@ typedef struct multisound_dev {
 
        /* State variables */
        enum { msndClassic, msndPinnacle } type;
-       mode_t mode;
+       fmode_t mode;
        unsigned long flags;
 #define F_RESETTING                    0
 #define F_HAVEDIGITAL                  1
index 1a00a3210616231f7c271fe2f621d8a29c21b27c..55271fbe7f49c44274658ce6ba7756c8f5faa5b8 100644 (file)
@@ -110,24 +110,16 @@ struct channel_info {
 #define OPEN_WRITE     PCM_ENABLE_OUTPUT
 #define OPEN_READWRITE (OPEN_READ|OPEN_WRITE)
 
-#if OPEN_READ == FMODE_READ && OPEN_WRITE == FMODE_WRITE
-
-static inline int translate_mode(struct file *file)
-{
-       return file->f_mode;
-}
-
-#else
-
 static inline int translate_mode(struct file *file)
 {
-       return ((file->f_mode & FMODE_READ) ? OPEN_READ : 0) |
-               ((file->f_mode & FMODE_WRITE) ? OPEN_WRITE : 0);
+       if (OPEN_READ == (__force int)FMODE_READ &&
+           OPEN_WRITE == (__force int)FMODE_WRITE)
+               return (__force int)(file->f_mode & (FMODE_READ | FMODE_WRITE));
+       else
+               return ((file->f_mode & FMODE_READ) ? OPEN_READ : 0) |
+                       ((file->f_mode & FMODE_WRITE) ? OPEN_WRITE : 0);
 }
 
-#endif
-
-
 #include "sound_calls.h"
 #include "dev_table.h"
 
index 044453a4ee5b71fa0f09eb964278375c0f464e6d..41562ecde5bbd9fcc6cc41a1b0c5ec1b5f14a181 100644 (file)
@@ -295,7 +295,7 @@ struct cs4297a_state {
        struct mutex open_mutex;
        struct mutex open_sem_adc;
        struct mutex open_sem_dac;
-       mode_t open_mode;
+       fmode_t open_mode;
        wait_queue_head_t open_wait;
        wait_queue_head_t open_wait_adc;
        wait_queue_head_t open_wait_dac;
index dcbb3f739e61ee801b39ebfd5ace060a53f19098..78b8acc7c3b96358330f8223906b3fb64dcc84db 100644 (file)
@@ -1509,7 +1509,7 @@ typedef struct vwsnd_dev {
        struct mutex open_mutex;
        struct mutex io_mutex;
        struct mutex mix_mutex;
-       mode_t          open_mode;
+       fmode_t         open_mode;
        wait_queue_head_t open_wait;
 
        lithium_t       lith;
index e72707cb60a3394cd00334d94bb9a3c483f4bcea..ef4955c73c88cf8000788ff769b70c1e36dc9767 100644 (file)
@@ -4996,7 +4996,7 @@ static struct hda_verb alc260_test_init_verbs[] = {
  */
 
 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
-                                       const char *pfx)
+                                       const char *pfx, int *vol_bits)
 {
        hda_nid_t nid_vol;
        unsigned long vol_val, sw_val;
@@ -5018,10 +5018,14 @@ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
        } else
                return 0; /* N/A */
 
-       snprintf(name, sizeof(name), "%s Playback Volume", pfx);
-       err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
-       if (err < 0)
-               return err;
+       if (!(*vol_bits & (1 << nid_vol))) {
+               /* first control for the volume widget */
+               snprintf(name, sizeof(name), "%s Playback Volume", pfx);
+               err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
+               if (err < 0)
+                       return err;
+               *vol_bits |= (1 << nid_vol);
+       }
        snprintf(name, sizeof(name), "%s Playback Switch", pfx);
        err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
        if (err < 0)
@@ -5035,6 +5039,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
 {
        hda_nid_t nid;
        int err;
+       int vols = 0;
 
        spec->multiout.num_dacs = 1;
        spec->multiout.dac_nids = spec->private_dac_nids;
@@ -5042,21 +5047,22 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
 
        nid = cfg->line_out_pins[0];
        if (nid) {
-               err = alc260_add_playback_controls(spec, nid, "Front");
+               err = alc260_add_playback_controls(spec, nid, "Front", &vols);
                if (err < 0)
                        return err;
        }
 
        nid = cfg->speaker_pins[0];
        if (nid) {
-               err = alc260_add_playback_controls(spec, nid, "Speaker");
+               err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
                if (err < 0)
                        return err;
        }
 
        nid = cfg->hp_pins[0];
        if (nid) {
-               err = alc260_add_playback_controls(spec, nid, "Headphone");
+               err = alc260_add_playback_controls(spec, nid, "Headphone",
+                                                  &vols);
                if (err < 0)
                        return err;
        }
index a2ac7205d45de81706ef520e2c9dca69f5ce503d..788fdc6f326436d8388faf3294c86e5d91274d13 100644 (file)
@@ -1282,7 +1282,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
                        return err;
                spec->multiout.share_spdif = 1;
        }
-       if (spec->dig_in_nid && (!spec->gpio_dir & 0x01)) {
+       if (spec->dig_in_nid && !(spec->gpio_dir & 0x01)) {
                err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
                if (err < 0)
                        return err;
index 05336ed7e4935fdbd0d9f27a1f77e3b0c5c0bef2..cff276ee261e7a2ecca843b23bc74d4fec761df7 100644 (file)
@@ -863,17 +863,21 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
                return -EINVAL;
        }
 
-       /* interface format */
-       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
-       case SND_SOC_DAIFMT_I2S:
+       /*
+        * match both interface format and signal polarities since they
+        * are fixed
+        */
+       switch (fmt & (SND_SOC_DAIFMT_FORMAT_MASK |
+                      SND_SOC_DAIFMT_INV_MASK)) {
+       case (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF):
                break;
-       case SND_SOC_DAIFMT_DSP_A:
+       case (SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF):
                iface_breg |= (0x01 << 6);
                break;
-       case SND_SOC_DAIFMT_RIGHT_J:
+       case (SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_NB_NF):
                iface_breg |= (0x02 << 6);
                break;
-       case SND_SOC_DAIFMT_LEFT_J:
+       case (SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF):
                iface_breg |= (0x03 << 6);
                break;
        default:
index 853b33ae3435297f414eaee086b31bdf6a4b1333..8485a8a9d0ff0e89687eb73a62755d064c8177e6 100644 (file)
@@ -265,7 +265,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
                break;
        case SND_SOC_DAIFMT_DSP_A:
                regs->srgr2     |= FPER(wlen * 2 - 1);
-               regs->srgr1     |= FWID(0);
+               regs->srgr1     |= FWID(wlen * 2 - 2);
                break;
        }
 
@@ -284,7 +284,6 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
 {
        struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
        struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
-       unsigned int temp_fmt = fmt;
 
        if (mcbsp_data->configured)
                return 0;
@@ -307,8 +306,6 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
                /* 0-bit data delay */
                regs->rcr2      |= RDATDLY(0);
                regs->xcr2      |= XDATDLY(0);
-               /* Invert bit clock and FS polarity configuration for DSP_A */
-               temp_fmt ^= SND_SOC_DAIFMT_IB_IF;
                break;
        default:
                /* Unsupported data format */
@@ -332,7 +329,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
        }
 
        /* Set bit clock (CLKX/CLKR) and FS polarities */
-       switch (temp_fmt & SND_SOC_DAIFMT_INV_MASK) {
+       switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
        case SND_SOC_DAIFMT_NB_NF:
                /*
                 * Normal BCLK + FS.